Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
test_subjective_billing.cpp
Go to the documentation of this file.
1#define BOOST_TEST_MODULE subjective_billing
2#include <boost/test/included/unit_test.hpp>
3
5
7
8namespace {
9
10using namespace sysio;
11using namespace sysio::chain;
12
13BOOST_AUTO_TEST_SUITE( subjective_billing_test )
14
15BOOST_AUTO_TEST_CASE( subjective_bill_test ) {
16
17 fc::logger log;
18
25 account_name a = "a"_n;
26 account_name b = "b"_n;
27 account_name c = "c"_n;
28
29 const auto now = time_point::now();
30
31 subjective_billing timing_sub_bill;
32 const auto halftime = now + fc::milliseconds(timing_sub_bill.get_expired_accumulator_average_window() * subjective_billing::subjective_time_interval_ms / 2);
33 const auto endtime = now + fc::milliseconds(timing_sub_bill.get_expired_accumulator_average_window() * subjective_billing::subjective_time_interval_ms);
34
35
36 { // Failed transactions remain until expired in subjective billing.
37 subjective_billing sub_bill;
38
39 sub_bill.subjective_bill( id1, now, a, fc::microseconds( 13 ), false );
40 sub_bill.subjective_bill( id2, now, a, fc::microseconds( 11 ), false );
41 sub_bill.subjective_bill( id3, now, b, fc::microseconds( 9 ), false );
42
43 BOOST_CHECK_EQUAL( 13+11, sub_bill.get_subjective_bill(a, now) );
44 BOOST_CHECK_EQUAL( 9, sub_bill.get_subjective_bill(b, now) );
45
46 sub_bill.on_block(log, {}, now);
47 sub_bill.abort_block(); // they all failed so nothing in aborted block
48
49 BOOST_CHECK_EQUAL( 13+11, sub_bill.get_subjective_bill(a, now) );
50 BOOST_CHECK_EQUAL( 9, sub_bill.get_subjective_bill(b, now) );
51
52 // expires transactions but leaves them in the decay at full value
53 sub_bill.remove_expired( log, now + fc::microseconds(1), now, [](){ return false; } );
54
55 BOOST_CHECK_EQUAL( 13+11, sub_bill.get_subjective_bill(a, now) );
56 BOOST_CHECK_EQUAL( 9, sub_bill.get_subjective_bill(b, now) );
57 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(c, now) );
58
59 // ensure that the value decays away at the window
60 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(a, endtime) );
61 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(b, endtime) );
62 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(c, endtime) );
63 }
64 { // db_read_mode HEAD mode, so transactions are immediately reverted
65 subjective_billing sub_bill;
66
67 sub_bill.subjective_bill( id1, now, a, fc::microseconds( 23 ), false );
68 sub_bill.subjective_bill( id2, now, a, fc::microseconds( 19 ), false );
69 sub_bill.subjective_bill( id3, now, b, fc::microseconds( 7 ), false );
70
71 BOOST_CHECK_EQUAL( 23+19, sub_bill.get_subjective_bill(a, now) );
72 BOOST_CHECK_EQUAL( 7, sub_bill.get_subjective_bill(b, now) );
73
74 sub_bill.on_block(log, {}, now); // have not seen any of the transactions come back yet
75 sub_bill.abort_block();
76
77 BOOST_CHECK_EQUAL( 23+19, sub_bill.get_subjective_bill(a, now) );
78 BOOST_CHECK_EQUAL( 7, sub_bill.get_subjective_bill(b, now) );
79
80 sub_bill.on_block(log, {}, now);
81 sub_bill.remove_subjective_billing( id1, 0 ); // simulate seeing id1 come back in block (this is what on_block would do)
82 sub_bill.abort_block();
83
84 BOOST_CHECK_EQUAL( 19, sub_bill.get_subjective_bill(a, now) );
85 BOOST_CHECK_EQUAL( 7, sub_bill.get_subjective_bill(b, now) );
86 }
87 { // db_read_mode SPECULATIVE mode, so transactions are in pending block until aborted
88 subjective_billing sub_bill;
89
90 sub_bill.subjective_bill( id1, now, a, fc::microseconds( 23 ), true );
91 sub_bill.subjective_bill( id2, now, a, fc::microseconds( 19 ), false ); // trx outside of block
92 sub_bill.subjective_bill( id3, now, a, fc::microseconds( 55 ), true );
93 sub_bill.subjective_bill( id4, now, b, fc::microseconds( 3 ), true );
94 sub_bill.subjective_bill( id5, now, b, fc::microseconds( 7 ), true );
95 sub_bill.subjective_bill( id6, now, a, fc::microseconds( 11 ), false ); // trx outside of block
96
97 BOOST_CHECK_EQUAL( 19+11, sub_bill.get_subjective_bill(a, now) ); // should not include what is in the pending block
98 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(b, now) ); // should not include what is in the pending block
99 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(c, now) );
100
101 sub_bill.on_block(log, {}, now); // have not seen any of the transactions come back yet
102 sub_bill.abort_block(); // aborts the pending block, so subjective billing needs to include the reverted trxs
103
104 BOOST_CHECK_EQUAL( 23+19+55+11, sub_bill.get_subjective_bill(a, now) );
105 BOOST_CHECK_EQUAL( 3+7, sub_bill.get_subjective_bill(b, now) );
106
107 sub_bill.on_block(log, {}, now);
108 sub_bill.remove_subjective_billing( id3, 0 ); // simulate seeing id3 come back in block (this is what on_block would do)
109 sub_bill.remove_subjective_billing( id4, 0 ); // simulate seeing id4 come back in block (this is what on_block would do)
110 sub_bill.abort_block();
111
112 BOOST_CHECK_EQUAL( 23+19+11, sub_bill.get_subjective_bill(a, now) );
113 BOOST_CHECK_EQUAL( 7, sub_bill.get_subjective_bill(b, now) );
114 }
115 { // failed handling logic, decay with repeated failures should be exponential, single failures should be linear
116 subjective_billing sub_bill;
117
118 sub_bill.subjective_bill_failure(a, fc::microseconds(1024), now);
119 sub_bill.subjective_bill_failure(b, fc::microseconds(1024), now);
120 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(a, now) );
121 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(b, now) );
122
123 sub_bill.subjective_bill_failure(a, fc::microseconds(1024), halftime);
124 BOOST_CHECK_EQUAL( 512 + 1024, sub_bill.get_subjective_bill(a, halftime) );
125 BOOST_CHECK_EQUAL( 512, sub_bill.get_subjective_bill(b, halftime) );
126
127 sub_bill.subjective_bill_failure(a, fc::microseconds(1024), endtime);
128 BOOST_CHECK_EQUAL( 256 + 512 + 1024, sub_bill.get_subjective_bill(a, endtime) );
129 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(b, endtime) );
130 }
131
132 { // expired handling logic, full billing until expiration then failed/decay logic
133 subjective_billing sub_bill;
134
135 sub_bill.subjective_bill( id1, now, a, fc::microseconds( 1024 ), false );
136 sub_bill.subjective_bill( id2, now + fc::microseconds(1), a, fc::microseconds( 1024 ), false );
137 sub_bill.subjective_bill( id3, now, b, fc::microseconds( 1024 ), false );
138 BOOST_CHECK_EQUAL( 1024 + 1024, sub_bill.get_subjective_bill(a, now) );
139 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(b, now) );
140
141 sub_bill.remove_expired( log, now, now, [](){ return false; } );
142 BOOST_CHECK_EQUAL( 1024 + 1024, sub_bill.get_subjective_bill(a, now) );
143 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(b, now) );
144
145 BOOST_CHECK_EQUAL( 512 + 1024, sub_bill.get_subjective_bill(a, halftime) );
146 BOOST_CHECK_EQUAL( 512, sub_bill.get_subjective_bill(b, halftime) );
147
148 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(a, endtime) );
149 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(b, endtime) );
150
151 sub_bill.remove_expired( log, now + fc::microseconds(1), now, [](){ return false; } );
152 BOOST_CHECK_EQUAL( 1024 + 1024, sub_bill.get_subjective_bill(a, now) );
153 BOOST_CHECK_EQUAL( 1024, sub_bill.get_subjective_bill(b, now) );
154
155 BOOST_CHECK_EQUAL( 512 + 512, sub_bill.get_subjective_bill(a, halftime) );
156 BOOST_CHECK_EQUAL( 512, sub_bill.get_subjective_bill(b, halftime) );
157
158 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(a, endtime) );
159 BOOST_CHECK_EQUAL( 0, sub_bill.get_subjective_bill(b, endtime) );
160 }
161
162}
163
164BOOST_AUTO_TEST_SUITE_END()
165
166}
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
static time_point now()
Definition time.cpp:14
int64_t get_subjective_bill(const account_name &first_auth, const fc::time_point &now) const
void subjective_bill(const transaction_id_type &id, const fc::time_point &expire, const account_name &first_auth, const fc::microseconds &elapsed, bool in_pending_block)
void subjective_bill_failure(const account_name &first_auth, const fc::microseconds &elapsed, const fc::time_point &now)
bool remove_expired(fc::logger &log, const fc::time_point &pending_block_time, const fc::time_point &now, Yield &&yield)
uint32_t get_expired_accumulator_average_window() const
void on_block(fc::logger &log, const block_state_ptr &bsp, const fc::time_point &now)
constexpr microseconds milliseconds(int64_t s)
Definition time.hpp:33
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
Immutable except for fc::from_variant.
Definition name.hpp:43
BOOST_AUTO_TEST_CASE(open_and_create)
Definition test.cpp:42