31 #include "gtest/gtest.h" 35 #include "blockchain_db/testdb.h" 37 #define TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW 5000 42 class TestDB:
public cryptonote::BaseTestDB
52 TestDB() { m_open =
true; }
62 blocks.push_back({block_weight, long_term_block_weight});
65 virtual size_t get_block_weight(
const uint64_t &h)
const override {
return blocks[h].weight; }
66 virtual uint64_t get_block_long_term_weight(
const uint64_t &h)
const override {
return blocks[h].long_term_weight; }
67 virtual std::vector<uint64_t> get_block_weights(
uint64_t start_height,
size_t count)
const override {
68 std::vector<uint64_t> ret;
70 while (
count-- && start_height <
blocks.size()) ret.push_back(
blocks[start_height++].weight);
73 virtual std::vector<uint64_t> get_long_term_block_weights(
uint64_t start_height,
size_t count)
const override {
74 std::vector<uint64_t> ret;
76 while (
count-- && start_height <
blocks.size()) ret.push_back(
blocks[start_height++].long_term_weight);
90 *block_height = h - 1;
93 virtual void pop_block(
cryptonote::block &blk, std::vector<cryptonote::transaction> &txs)
override {
blocks.pop_back(); }
96 std::vector<block_t>
blocks;
103 lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff;
109 #define PREFIX_WINDOW(hf_version,window) \ 110 std::unique_ptr<cryptonote::Blockchain> bc; \ 111 cryptonote::tx_memory_pool txpool(*bc); \ 112 bc.reset(new cryptonote::Blockchain(txpool)); \ 113 struct get_test_options { \ 114 const std::pair<uint8_t, uint64_t> hard_forks[3]; \ 115 const cryptonote::test_options test_options = { \ 119 get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \ 121 cryptonote::Blockchain *blockchain = bc.get(); \ 122 bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \ 125 #define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW) 127 TEST(long_term_block_weight, empty_short)
131 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
137 TEST(long_term_block_weight, identical_before_fork)
144 uint64_t ltw = bc->get_next_long_term_block_weight(w);
145 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
146 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
150 ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h));
154 TEST(long_term_block_weight, identical_after_fork_before_long_term_window)
163 uint64_t ltw = bc->get_next_long_term_block_weight(w);
164 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
165 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
169 ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h));
173 TEST(long_term_block_weight, ceiling_at_30000000)
180 uint64_t ltw = bc->get_next_long_term_block_weight(w);
181 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
182 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
184 ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), 15000000);
185 ASSERT_EQ(bc->get_current_cumulative_block_weight_limit(), 30000000);
188 TEST(long_term_block_weight, multi_pop)
195 uint64_t ltw = bc->get_next_long_term_block_weight(w);
196 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
197 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
200 const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
201 const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
204 for (
uint64_t h = 0; h < num_pop; ++h)
206 size_t w = bc->get_current_cumulative_block_weight_limit();
207 uint64_t ltw = bc->get_next_long_term_block_weight(w);
208 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
209 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
213 std::vector<cryptonote::transaction> txs;
214 for (
uint64_t h = 0; h < num_pop; ++h)
215 bc->get_db().pop_block(b, txs);
216 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
218 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
219 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
222 TEST(long_term_block_weight, multiple_updates)
229 uint64_t ltw = bc->get_next_long_term_block_weight(w);
230 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
231 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
232 const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
233 const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
234 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
235 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
236 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
237 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
238 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
239 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
240 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
241 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
242 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
246 TEST(long_term_block_weight, pop_invariant_max)
253 uint64_t ltw = bc->get_next_long_term_block_weight(w);
254 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
255 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
258 for (
int n = 0; n < 1000; ++n)
261 int remove = 1 + (n * 17) % 8;
262 int add = (n * 23) % 12;
265 uint64_t old_ltbw[16], h0 = bc->get_db().height() -
remove - 1;
266 for (
int i = -2; i <
remove; ++i)
268 old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i);
271 for (
int i = 0; i <
remove; ++i)
274 std::vector<cryptonote::transaction> txs;
275 bc->get_db().pop_block(b, txs);
276 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
278 for (
int i = 0; i < add; ++i)
281 uint64_t ltw = bc->get_next_long_term_block_weight(w);
282 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, bc->get_db().height(), bc->get_db().height(), {});
283 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
287 for (
int i = -2; i < std::min(add,
remove); ++i)
289 ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]);
294 TEST(long_term_block_weight, pop_invariant_random)
300 lcg_seed = bc->get_db().height();
303 uint64_t ltw = bc->get_next_long_term_block_weight(w);
304 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
305 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
308 for (
int n = 0; n < 1000; ++n)
311 int remove = 1 + (n * 17) % 8;
312 int add = (n * 23) % 123;
315 uint64_t old_ltbw[16], h0 = bc->get_db().height() -
remove - 1;
316 for (
int i = -2; i <
remove; ++i)
318 old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i);
321 for (
int i = 0; i <
remove; ++i)
324 std::vector<cryptonote::transaction> txs;
325 bc->get_db().pop_block(b, txs);
326 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
327 const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
328 const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
329 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
330 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
331 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
333 for (
int i = 0; i < add; ++i)
335 lcg_seed = bc->get_db().height();
338 uint64_t ltw = bc->get_next_long_term_block_weight(w);
339 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, bc->get_db().height(), bc->get_db().height(), {});
340 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
341 const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
342 const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
343 ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
344 ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median());
345 ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit());
349 for (
int i = -2; i < std::min(add,
remove); ++i)
351 ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]);
356 TEST(long_term_block_weight, long_growth_spike_and_drop)
360 uint64_t long_term_effective_median_block_weight;
366 uint64_t ltw = bc->get_next_long_term_block_weight(w);
367 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
368 ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
370 ASSERT_EQ(long_term_effective_median_block_weight, 300000);
377 size_t w = 300000 + t * 30000;
378 uint64_t ltw = bc->get_next_long_term_block_weight(w);
379 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
380 ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
382 ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
383 ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
388 size_t w = bc->get_current_cumulative_block_weight_limit();
389 uint64_t ltw = bc->get_next_long_term_block_weight(w);
390 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
391 ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
393 ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
394 ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
399 size_t w = bc->get_current_cumulative_block_weight_median() * .25;
400 uint64_t ltw = bc->get_next_long_term_block_weight(w);
401 bc->get_db().add_block(std::make_pair(
cryptonote::block(),
""), w, ltw, h, h, {});
402 ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
404 ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
405 ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09);
TEST(long_term_block_weight, empty_short)
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V8
#define ASSERT_EQ(val1, val2)
#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT
mdb_size_t count(MDB_cursor *cur)
#define PREFIX(hf_version)
#define ASSERT_GT(val1, val2)
unsigned __int64 uint64_t
#define TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW
#define ASSERT_LT(val1, val2)
#define CRYPTONOTE_REWARD_BLOCKS_WINDOW
boost::multiprecision::uint128_t difficulty_type
#define ASSERT_TRUE(condition)
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5