Electroneum
Loading...
Searching...
No Matches
hardfork.cpp
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32#include <algorithm>
33#include "gtest/gtest.h"
34
38#include "blockchain_db/testdb.h"
39
40using namespace cryptonote;
41
42#define BLOCKS_PER_YEAR 525960
43#define SECONDS_PER_YEAR 31557600
44
45namespace
46{
47
48class TestDB: public cryptonote::BaseTestDB {
49public:
50 virtual uint64_t height() const override { return blocks.size(); }
51 virtual void add_block( const block& blk
52 , size_t block_weight
53 , uint64_t long_term_block_weight
54 , const difficulty_type& cumulative_difficulty
55 , const uint64_t& coins_generated
56 , uint64_t num_rct_outs
57 , const crypto::hash& blk_hash
58 ) override {
59 blocks.push_back(blk);
60 }
61 virtual void remove_block() override { blocks.pop_back(); }
62 virtual block get_block_from_height(const uint64_t& height) const override {
63 return blocks.at(height);
64 }
65 virtual void set_hard_fork_version(uint64_t height, uint8_t version) override {
66 if (versions.size() <= height)
67 versions.resize(height+1);
68 versions[height] = version;
69 }
70 virtual uint8_t get_hard_fork_version(uint64_t height) const override {
71 return versions.at(height);
72 }
73
74private:
75 std::vector<block> blocks;
76 std::deque<uint8_t> versions;
77};
78
79}
80
81static cryptonote::block mkblock(uint8_t version, uint8_t vote)
82{
85 b.minor_version = vote;
86 return b;
87}
88
89static cryptonote::block mkblock(const HardFork &hf, uint64_t height, uint8_t vote)
90{
92 b.major_version = hf.get(height);
93 b.minor_version = vote;
94 return b;
95}
96
97TEST(major, Only)
98{
99 TestDB db;
100 HardFork hf(db, 1, 0, 0, 0, 1, 0); // no voting
101
102 // v h t
103 ASSERT_TRUE(hf.add_fork(1, 0, 0));
104 ASSERT_TRUE(hf.add_fork(2, 2, 1));
105 hf.init();
106
107 // block height 0, only version 1 is accepted
108 ASSERT_FALSE(hf.add(mkblock(0, 2), 0));
109 ASSERT_FALSE(hf.add(mkblock(2, 2), 0));
110 ASSERT_TRUE(hf.add(mkblock(1, 2), 0));
111 db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash());
112
113 // block height 1, only version 1 is accepted
114 ASSERT_FALSE(hf.add(mkblock(0, 2), 1));
115 ASSERT_FALSE(hf.add(mkblock(2, 2), 1));
116 ASSERT_TRUE(hf.add(mkblock(1, 2), 1));
117 db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash());
118
119 // block height 2, only version 2 is accepted
120 ASSERT_FALSE(hf.add(mkblock(0, 2), 2));
121 ASSERT_FALSE(hf.add(mkblock(1, 2), 2));
122 ASSERT_FALSE(hf.add(mkblock(3, 2), 2));
123 ASSERT_TRUE(hf.add(mkblock(2, 2), 2));
124 db.add_block(mkblock(2, 1), 0, 0, 0, 0, 0, crypto::hash());
125}
126
127TEST(empty_hardforks, Success)
128{
129 TestDB db;
130 HardFork hf(db);
131
132 ASSERT_TRUE(hf.add_fork(1, 0, 0));
133 hf.init();
135 ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready);
136
137 for (uint64_t h = 0; h <= 10; ++h) {
138 db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
139 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
140 }
141 ASSERT_EQ(hf.get(0), 1);
142 ASSERT_EQ(hf.get(1), 1);
143 ASSERT_EQ(hf.get(10), 1);
144}
145
146TEST(ordering, Success)
147{
148 TestDB db;
149 HardFork hf(db);
150
151 ASSERT_TRUE(hf.add_fork(2, 2, 1));
152 ASSERT_FALSE(hf.add_fork(3, 3, 1));
153 ASSERT_FALSE(hf.add_fork(3, 2, 2));
154 ASSERT_FALSE(hf.add_fork(2, 3, 2));
155 ASSERT_TRUE(hf.add_fork(3, 10, 2));
156 ASSERT_TRUE(hf.add_fork(4, 20, 3));
157 ASSERT_FALSE(hf.add_fork(5, 5, 4));
158}
159
160TEST(check_for_height, Success)
161{
162 TestDB db;
163 HardFork hf(db, 1, 0, 0, 0, 1, 0); // no voting
164
165 ASSERT_TRUE(hf.add_fork(1, 0, 0));
166 ASSERT_TRUE(hf.add_fork(2, 5, 1));
167 hf.init();
168
169 for (uint64_t h = 0; h <= 4; ++h) {
170 ASSERT_TRUE(hf.check_for_height(mkblock(1, 1), h));
171 ASSERT_FALSE(hf.check_for_height(mkblock(2, 2), h)); // block version is too high
172 db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
173 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
174 }
175
176 for (uint64_t h = 5; h <= 10; ++h) {
177 ASSERT_FALSE(hf.check_for_height(mkblock(1, 1), h)); // block version is too low
178 ASSERT_TRUE(hf.check_for_height(mkblock(2, 2), h));
179 db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash());
180 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
181 }
182}
183
184TEST(get, next_version)
185{
186 TestDB db;
187 HardFork hf(db);
188
189 ASSERT_TRUE(hf.add_fork(1, 0, 0));
190 ASSERT_TRUE(hf.add_fork(2, 5, 1));
191 ASSERT_TRUE(hf.add_fork(4, 10, 2));
192 hf.init();
193
194 for (uint64_t h = 0; h <= 4; ++h) {
196 db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash());
197 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
198 }
199
200 for (uint64_t h = 5; h <= 9; ++h) {
202 db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash());
203 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
204 }
205
206 for (uint64_t h = 10; h <= 15; ++h) {
208 db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, 0, crypto::hash());
209 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
210 }
211}
212
235
236TEST(steps_asap, Success)
237{
238 TestDB db;
239 HardFork hf(db, 1,0,1,1,1);
240
241 // v h t
242 ASSERT_TRUE(hf.add_fork(1, 0, 0));
243 ASSERT_TRUE(hf.add_fork(4, 2, 1));
244 ASSERT_TRUE(hf.add_fork(7, 4, 2));
245 ASSERT_TRUE(hf.add_fork(9, 6, 3));
246 hf.init();
247
248 for (uint64_t h = 0; h < 10; ++h) {
249 db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, 0, crypto::hash());
250 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
251 }
252
253 ASSERT_EQ(hf.get(0), 1);
254 ASSERT_EQ(hf.get(1), 1);
255 ASSERT_EQ(hf.get(2), 4);
256 ASSERT_EQ(hf.get(3), 4);
257 ASSERT_EQ(hf.get(4), 7);
258 ASSERT_EQ(hf.get(5), 7);
259 ASSERT_EQ(hf.get(6), 9);
260 ASSERT_EQ(hf.get(7), 9);
261 ASSERT_EQ(hf.get(8), 9);
262 ASSERT_EQ(hf.get(9), 9);
263}
264
265TEST(steps_1, Success)
266{
267 TestDB db;
268 HardFork hf(db, 1,0,1,1,1);
269
270 ASSERT_TRUE(hf.add_fork(1, 0, 0));
271 for (int n = 1 ; n < 10; ++n)
272 ASSERT_TRUE(hf.add_fork(n+1, n, n));
273 hf.init();
274
275 for (uint64_t h = 0 ; h < 10; ++h) {
276 db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, 0, crypto::hash());
277 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
278 }
279
280 for (uint64_t h = 0; h < 10; ++h) {
281 ASSERT_EQ(hf.get(h), std::max(1,(int)h));
282 }
283}
284
285TEST(reorganize, Same)
286{
287 for (int history = 1; history <= 12; ++history) {
288 TestDB db;
289 HardFork hf(db, 1, 0, 1, 1, history, 100);
290
291 // v h t
292 ASSERT_TRUE(hf.add_fork(1, 0, 0));
293 ASSERT_TRUE(hf.add_fork(4, 2, 1));
294 ASSERT_TRUE(hf.add_fork(7, 4, 2));
295 ASSERT_TRUE(hf.add_fork(9, 6, 3));
296 hf.init();
297
298 // index 0 1 2 3 4 5 6 7 8 9
299 static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
300 for (uint64_t h = 0; h < 20; ++h) {
301 db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
302 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
303 }
304
305 for (uint64_t rh = 0; rh < 20; ++rh) {
307 for (int hh = 0; hh < 20; ++hh) {
308 uint8_t version = hh >= history ? block_versions[hh - history] : 1;
309 ASSERT_EQ(hf.get(hh), version);
310 }
311 }
312 }
313}
314
315TEST(reorganize, Changed)
316{
317 TestDB db;
318 HardFork hf(db, 1, 0, 1, 1, 4, 100);
319
320 // v h t
321 ASSERT_TRUE(hf.add_fork(1, 0, 0));
322 ASSERT_TRUE(hf.add_fork(4, 2, 1));
323 ASSERT_TRUE(hf.add_fork(7, 4, 2));
324 ASSERT_TRUE(hf.add_fork(9, 6, 3));
325 hf.init();
326
327 // fork 4 7 9
328 // index 0 1 2 3 4 5 6 7 8 9
329 static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
330 static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9 };
331 for (uint64_t h = 0; h < 16; ++h) {
332 db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
333 ASSERT_TRUE (hf.add(db.get_block_from_height(h), h));
334 }
335
336 for (uint64_t rh = 0; rh < 16; ++rh) {
338 for (int hh = 0; hh < 16; ++hh) {
339 ASSERT_EQ(hf.get(hh), expected_versions[hh]);
340 }
341 }
342
343 // delay a bit for 9, and go back to 1 to check it stays at 9
344 static const uint8_t block_versions_new[] = { 1, 1, 4, 4, 7, 7, 4, 7, 7, 7, 9, 9, 9, 9, 9, 1 };
345 static const uint8_t expected_versions_new[] = { 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 7, 7, 7, 9, 9 };
346 for (uint64_t h = 3; h < 16; ++h) {
347 db.remove_block();
348 }
349 ASSERT_EQ(db.height(), 3);
351 for (uint64_t h = 3; h < 16; ++h) {
352 db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, 0, crypto::hash());
353 bool ret = hf.add(db.get_block_from_height(h), h);
354 ASSERT_EQ (ret, h < 15);
355 }
356 db.remove_block(); // last block added to the blockchain, but not hf
357 ASSERT_EQ(db.height(), 15);
358 for (int hh = 0; hh < 15; ++hh) {
359 ASSERT_EQ(hf.get(hh), expected_versions_new[hh]);
360 }
361}
362
364{
365 for (int threshold = 87; threshold <= 88; ++threshold) {
366 TestDB db;
367 HardFork hf(db, 1, 0, 1, 1, 8, threshold);
368
369 // v h t
370 ASSERT_TRUE(hf.add_fork(1, 0, 0));
371 ASSERT_TRUE(hf.add_fork(2, 2, 1));
372 hf.init();
373
374 for (uint64_t h = 0; h <= 8; ++h) {
375 uint8_t v = 1 + !!(h % 8);
376 db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, 0, crypto::hash());
377 bool ret = hf.add(db.get_block_from_height(h), h);
378 if (h >= 8 && threshold == 87) {
379 // for threshold 87, we reach the treshold at height 7, so from height 8, hard fork to version 2, but 8 tries to add 1
380 ASSERT_FALSE(ret);
381 }
382 else {
383 // for threshold 88, we never reach the threshold
384 ASSERT_TRUE(ret);
385 uint8_t expected = threshold == 88 ? 1 : h < 8 ? 1 : 2;
386 ASSERT_EQ(hf.get(h), expected);
387 }
388 }
389 }
390}
391
392TEST(voting, different_thresholds)
393{
394 for (int threshold = 87; threshold <= 88; ++threshold) {
395 TestDB db;
396 HardFork hf(db, 1, 0, 1, 1, 4, 50); // window size 4
397
398 // v h t
399 ASSERT_TRUE(hf.add_fork(1, 0, 0));
400 ASSERT_TRUE(hf.add_fork(2, 5, 0, 1)); // asap
401 ASSERT_TRUE(hf.add_fork(3, 10, 100, 2)); // all votes
402 ASSERT_TRUE(hf.add_fork(4, 15, 3)); // default 50% votes
403 hf.init();
404
405 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
406 static const uint8_t block_versions[] = { 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };
407 static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
408
409 for (uint64_t h = 0; h < sizeof(block_versions) / sizeof(block_versions[0]); ++h) {
410 db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
411 bool ret = hf.add(db.get_block_from_height(h), h);
412 ASSERT_EQ(ret, true);
413 }
414 for (uint64_t h = 0; h < sizeof(expected_versions) / sizeof(expected_versions[0]); ++h) {
415 ASSERT_EQ(hf.get(h), expected_versions[h]);
416 }
417 }
418}
419
420TEST(voting, info)
421{
422 TestDB db;
423 HardFork hf(db, 1, 0, 1, 1, 4, 50); // window size 4, default threshold 50%
424
425 // v h ts
426 ASSERT_TRUE(hf.add_fork(1, 0, 0));
427 // v h thr ts
428 ASSERT_TRUE(hf.add_fork(2, 5, 0, 1)); // asap
429 ASSERT_TRUE(hf.add_fork(3, 10, 100, 2)); // all votes
430 // v h ts
431 ASSERT_TRUE(hf.add_fork(4, 15, 3)); // default 50% votes
432 hf.init();
433
434 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
435 static const uint8_t block_versions[] = { 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };
436 static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
437 static const uint8_t expected_thresholds[] = { 0, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 2, 2, 2, 2 };
438
439 for (uint64_t h = 0; h < sizeof(block_versions) / sizeof(block_versions[0]); ++h) {
440 uint32_t window, votes, threshold;
441 uint64_t earliest_height;
442 uint8_t voting;
443
444 ASSERT_TRUE(hf.get_voting_info(1, window, votes, threshold, earliest_height, voting));
445 ASSERT_EQ(std::min<uint64_t>(h, 4), votes);
446 ASSERT_EQ(0, earliest_height);
447
448 ASSERT_EQ(hf.get_current_version() >= 2, hf.get_voting_info(2, window, votes, threshold, earliest_height, voting));
449 ASSERT_EQ(std::min<uint64_t>(h <= 3 ? 0 : h - 3, 4), votes);
450 ASSERT_EQ(5, earliest_height);
451
452 ASSERT_EQ(hf.get_current_version() >= 3, hf.get_voting_info(3, window, votes, threshold, earliest_height, voting));
453 ASSERT_EQ(std::min<uint64_t>(h <= 8 ? 0 : h - 8, 4), votes);
454 ASSERT_EQ(10, earliest_height);
455
456 ASSERT_EQ(hf.get_current_version() == 4, hf.get_voting_info(4, window, votes, threshold, earliest_height, voting));
457 ASSERT_EQ(std::min<uint64_t>(h <= 14 ? 0 : h - 14, 4), votes);
458 ASSERT_EQ(15, earliest_height);
459
460 ASSERT_EQ(std::min<uint64_t>(h, 4), window);
461 ASSERT_EQ(expected_thresholds[h], threshold);
462 ASSERT_EQ(4, voting);
463
464 db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash());
465 ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
466 }
467}
468
469TEST(new_blocks, denied)
470{
471 TestDB db;
472 HardFork hf(db, 1, 0, 1, 1, 4, 50);
473
474 // v h t
475 ASSERT_TRUE(hf.add_fork(1, 0, 0));
476 ASSERT_TRUE(hf.add_fork(2, 2, 1));
477 hf.init();
478
479 ASSERT_TRUE(hf.add(mkblock(1, 1), 0));
480 ASSERT_TRUE(hf.add(mkblock(1, 1), 1));
481 ASSERT_TRUE(hf.add(mkblock(1, 1), 2));
482 ASSERT_TRUE(hf.add(mkblock(1, 2), 3));
483 ASSERT_TRUE(hf.add(mkblock(1, 1), 4));
484 ASSERT_TRUE(hf.add(mkblock(1, 1), 5));
485 ASSERT_TRUE(hf.add(mkblock(1, 1), 6));
486 ASSERT_TRUE(hf.add(mkblock(1, 2), 7));
487 ASSERT_TRUE(hf.add(mkblock(1, 2), 8)); // we reach 50% of the last 4
488 ASSERT_FALSE(hf.add(mkblock(2, 1), 9)); // so this one can't get added
489 ASSERT_TRUE(hf.add(mkblock(2, 2), 9));
490}
491
492TEST(new_version, early)
493{
494 TestDB db;
495 HardFork hf(db, 1, 0, 1, 1, 4, 50);
496
497 // v h t
498 ASSERT_TRUE(hf.add_fork(1, 0, 0));
499 ASSERT_TRUE(hf.add_fork(2, 4, 1));
500 hf.init();
501
502 ASSERT_TRUE(hf.add(mkblock(1, 2), 0));
503 ASSERT_TRUE(hf.add(mkblock(1, 2), 1)); // we have enough votes already
504 ASSERT_TRUE(hf.add(mkblock(1, 2), 2));
505 ASSERT_TRUE(hf.add(mkblock(1, 1), 3)); // we accept a previous version because we did not switch, even with all the votes
506 ASSERT_TRUE(hf.add(mkblock(2, 2), 4)); // but have to wait for the declared height anyway
507 ASSERT_TRUE(hf.add(mkblock(2, 2), 5));
508 ASSERT_FALSE(hf.add(mkblock(2, 1), 6)); // we don't accept 1 anymore
509 ASSERT_TRUE(hf.add(mkblock(2, 2), 7)); // but we do accept 2
510}
511
512TEST(reorganize, changed)
513{
514 TestDB db;
515 HardFork hf(db, 1, 0, 1, 1, 4, 50);
516
517 // v h t
518 ASSERT_TRUE(hf.add_fork(1, 0, 0));
519 ASSERT_TRUE(hf.add_fork(2, 2, 1));
520 ASSERT_TRUE(hf.add_fork(3, 5, 2));
521 ASSERT_TRUE(hf.add_fork(4, 555, 222));
522 hf.init();
523
524#define ADD(v, h, a) \
525 do { \
526 cryptonote::block b = mkblock(hf, h, v); \
527 db.add_block(b, 0, 0, 0, 0, 0, crypto::hash()); \
528 ASSERT_##a(hf.add(b, h)); \
529 } while(0)
530#define ADD_TRUE(v, h) ADD(v, h, TRUE)
531#define ADD_FALSE(v, h) ADD(v, h, FALSE)
532
533 ADD_TRUE(1, 0);
534 ADD_TRUE(1, 1);
535 ADD_TRUE(2, 2);
536 ADD_TRUE(2, 3); // switch to 2 here
537 ADD_TRUE(2, 4);
538 ADD_TRUE(2, 5);
539 ADD_TRUE(2, 6);
541 ADD_TRUE(3, 7);
542 ADD_TRUE(4, 8);
543 ADD_TRUE(4, 9);
545
546 // pop a few blocks and check current version goes back down
547 db.remove_block();
550 db.remove_block();
553 db.remove_block();
555
556 // add blocks again, but remaining at 2
557 ADD_TRUE(2, 7);
558 ADD_TRUE(2, 8);
559 ADD_TRUE(2, 9);
560 ASSERT_EQ(hf.get_current_version(), 2); // we did not bump to 3 this time
561}
562
563TEST(get, higher)
564{
565 TestDB db;
566 HardFork hf(db, 1, 0, 1, 1, 4, 50);
567
568 // v h t
569 ASSERT_TRUE(hf.add_fork(1, 0, 0));
570 ASSERT_TRUE(hf.add_fork(2, 2, 1));
571 ASSERT_TRUE(hf.add_fork(3, 5, 2));
572 hf.init();
573
582}
583
584TEST(get, earliest_ideal_height)
585{
586 TestDB db;
587 HardFork hf(db, 1, 0, 1, 1, 4, 50);
588
589 // v h t
590 ASSERT_TRUE(hf.add_fork(1, 0, 0));
591 ASSERT_TRUE(hf.add_fork(2, 2, 1));
592 ASSERT_TRUE(hf.add_fork(5, 5, 2));
593 ASSERT_TRUE(hf.add_fork(6, 10, 3));
594 ASSERT_TRUE(hf.add_fork(9, 15, 4));
595 hf.init();
596
606 ASSERT_EQ(hf.get_earliest_ideal_height_for_version(10), std::numeric_limits<uint64_t>::max());
607}
608
uint64_t height
uint8_t version
time_t time
uint8_t threshold
uint8_t get_ideal_version() const
returns the latest "ideal" version
Definition hardfork.cpp:367
bool add(const cryptonote::block &block, uint64_t height)
add a new block
Definition hardfork.cpp:164
void init()
initialize the object
Definition hardfork.cpp:169
uint8_t get_current_version() const
returns the current version
Definition hardfork.cpp:361
bool reorganize_from_block_height(uint64_t height)
called when the blockchain is reorganized
Definition hardfork.cpp:202
bool get_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
returns information about current voting state
Definition hardfork.cpp:409
uint8_t get_next_version() const
returns the next version
Definition hardfork.cpp:397
bool add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time)
add a new hardfork height
Definition hardfork.cpp:74
static const time_t DEFAULT_UPDATE_TIME
Definition hardfork.h:50
static const time_t DEFAULT_FORKED_TIME
Definition hardfork.h:49
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
Definition hardfork.cpp:384
bool check_for_height(const cryptonote::block &block, uint64_t height) const
same as check, but for a particular height, rather than the top
Definition hardfork.cpp:129
State get_state(time_t t) const
returns current state at the given time
Definition hardfork.cpp:327
uint8_t get(uint64_t height) const
returns the hard fork version for the given block height
Definition hardfork.cpp:348
#define ASSERT_EQ(val1, val2)
Definition gtest.h:1956
#define ASSERT_FALSE(condition)
Definition gtest.h:1868
#define TEST(test_case_name, test_name)
Definition gtest.h:2187
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
void get(std::istream &input, bool &res)
Definition io.h:62
POD_CLASS hash
Definition hash.h:50
Holds cryptonote related classes and helpers.
Definition ban.cpp:40
boost::multiprecision::uint128_t difficulty_type
Definition difficulty.h:43
CXA_THROW_INFO_T * info
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
#define BLOCKS_PER_YEAR
Definition hardfork.cpp:42
#define SECONDS_PER_YEAR
Definition hardfork.cpp:43
#define ADD_TRUE(v, h)