@@ -30,12 +30,12 @@ using node::BlockManager;
30
30
using node::KernelNotifications;
31
31
using node::SnapshotMetadata;
32
32
33
- BOOST_FIXTURE_TEST_SUITE (validation_chainstatemanager_tests, ChainTestingSetup )
33
+ BOOST_FIXTURE_TEST_SUITE (validation_chainstatemanager_tests, TestingSetup )
34
34
35
35
// ! Basic tests for ChainstateManager.
36
36
// !
37
37
// ! First create a legacy (IBD) chainstate, then create a snapshot chainstate.
38
- BOOST_AUTO_TEST_CASE (chainstatemanager)
38
+ BOOST_FIXTURE_TEST_CASE (chainstatemanager, TestChain100Setup )
39
39
{
40
40
ChainstateManager& manager = *m_node.chainman ;
41
41
CTxMemPool& mempool = *m_node.mempool ;
@@ -46,14 +46,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
46
46
47
47
// Create a legacy (IBD) chainstate.
48
48
//
49
- Chainstate& c1 = WITH_LOCK (::cs_main, return manager.InitializeChainstate (&mempool) );
49
+ Chainstate& c1 = manager.ActiveChainstate ( );
50
50
chainstates.push_back (&c1);
51
- c1.InitCoinsDB (
52
- /* cache_size_bytes=*/ 1 << 23 , /* in_memory=*/ true , /* should_wipe=*/ false );
53
- WITH_LOCK (::cs_main, c1.InitCoinsCache (1 << 23 ));
54
- c1.LoadGenesisBlock ();
55
- BlockValidationState val_state;
56
- BOOST_CHECK (c1.ActivateBestChain (val_state, nullptr ));
57
51
58
52
BOOST_CHECK (!manager.IsSnapshotActive ());
59
53
BOOST_CHECK (WITH_LOCK (::cs_main, return !manager.IsSnapshotValidated ()));
@@ -63,8 +57,9 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
63
57
auto & active_chain = WITH_LOCK (manager.GetMutex (), return manager.ActiveChain ());
64
58
BOOST_CHECK_EQUAL (&active_chain, &c1.m_chain );
65
59
66
- BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return manager.ActiveHeight ()), 0 );
67
-
60
+ // Get to a valid assumeutxo tip (per chainparams);
61
+ mineBlocks (10 );
62
+ BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return manager.ActiveHeight ()), 110 );
68
63
auto active_tip = WITH_LOCK (manager.GetMutex (), return manager.ActiveTip ());
69
64
auto exp_tip = c1.m_chain .Tip ();
70
65
BOOST_CHECK_EQUAL (active_tip, exp_tip);
@@ -77,16 +72,19 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
77
72
Chainstate& c2 = WITH_LOCK (::cs_main, return manager.ActivateExistingSnapshot (
78
73
&mempool, snapshot_blockhash));
79
74
chainstates.push_back (&c2);
80
-
81
- BOOST_CHECK_EQUAL (manager.SnapshotBlockhash ().value (), snapshot_blockhash);
82
-
83
75
c2.InitCoinsDB (
84
76
/* cache_size_bytes=*/ 1 << 23 , /* in_memory=*/ true , /* should_wipe=*/ false );
85
- WITH_LOCK (::cs_main, c2.InitCoinsCache (1 << 23 ));
86
- c2.m_chain .SetTip (*active_tip);
77
+ {
78
+ LOCK (::cs_main);
79
+ c2.InitCoinsCache (1 << 23 );
80
+ c2.CoinsTip ().SetBestBlock (active_tip->GetBlockHash ());
81
+ c2.setBlockIndexCandidates .insert (manager.m_blockman .LookupBlockIndex (active_tip->GetBlockHash ()));
82
+ c2.LoadChainTip ();
83
+ }
87
84
BlockValidationState _;
88
85
BOOST_CHECK (c2.ActivateBestChain (_, nullptr ));
89
86
87
+ BOOST_CHECK_EQUAL (manager.SnapshotBlockhash ().value (), snapshot_blockhash);
90
88
BOOST_CHECK (manager.IsSnapshotActive ());
91
89
BOOST_CHECK (WITH_LOCK (::cs_main, return !manager.IsSnapshotValidated ()));
92
90
BOOST_CHECK_EQUAL (&c2, &manager.ActiveChainstate ());
@@ -97,13 +95,15 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
97
95
auto & active_chain2 = WITH_LOCK (manager.GetMutex (), return manager.ActiveChain ());
98
96
BOOST_CHECK_EQUAL (&active_chain2, &c2.m_chain );
99
97
100
- BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return manager.ActiveHeight ()), 0 );
98
+ BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return manager.ActiveHeight ()), 110 );
99
+ mineBlocks (1 );
100
+ BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return manager.ActiveHeight ()), 111 );
101
+ BOOST_CHECK_EQUAL (WITH_LOCK (manager.GetMutex (), return c1.m_chain .Height ()), 110 );
101
102
102
103
auto active_tip2 = WITH_LOCK (manager.GetMutex (), return manager.ActiveTip ());
103
- auto exp_tip2 = c2.m_chain .Tip ();
104
- BOOST_CHECK_EQUAL (active_tip2, exp_tip2);
105
-
106
- BOOST_CHECK_EQUAL (exp_tip, exp_tip2);
104
+ BOOST_CHECK_EQUAL (active_tip, active_tip2->pprev );
105
+ BOOST_CHECK_EQUAL (active_tip, c1.m_chain .Tip ());
106
+ BOOST_CHECK_EQUAL (active_tip2, c2.m_chain .Tip ());
107
107
108
108
// Let scheduler events finish running to avoid accessing memory that is going to be unloaded
109
109
SyncWithValidationInterfaceQueue ();
@@ -125,9 +125,6 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_rebalance_caches, TestChain100Setup)
125
125
//
126
126
Chainstate& c1 = manager.ActiveChainstate ();
127
127
chainstates.push_back (&c1);
128
- c1.InitCoinsDB (
129
- /* cache_size_bytes=*/ 1 << 23 , /* in_memory=*/ true , /* should_wipe=*/ false );
130
-
131
128
{
132
129
LOCK (::cs_main);
133
130
c1.InitCoinsCache (1 << 23 );
@@ -431,13 +428,20 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
431
428
432
429
int num_indexes{0 };
433
430
int num_assumed_valid{0 };
431
+ // Blocks in range [assumed_valid_start_idx, last_assumed_valid_idx) will be
432
+ // marked as assumed-valid and not having data.
434
433
const int expected_assumed_valid{20 };
435
- const int last_assumed_valid_idx{40 };
434
+ const int last_assumed_valid_idx{111 };
436
435
const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
437
436
437
+ // Mine to height 120, past the hardcoded regtest assumeutxo snapshot at
438
+ // height 110
439
+ mineBlocks (20 );
440
+
438
441
CBlockIndex* validated_tip{nullptr };
439
442
CBlockIndex* assumed_base{nullptr };
440
443
CBlockIndex* assumed_tip{WITH_LOCK (chainman.GetMutex (), return chainman.ActiveChain ().Tip ())};
444
+ BOOST_CHECK_EQUAL (assumed_tip->nHeight , 120 );
441
445
442
446
auto reload_all_block_indexes = [&]() {
443
447
// For completeness, we also reset the block sequence counters to
@@ -463,7 +467,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
463
467
LOCK (::cs_main);
464
468
auto index = cs1.m_chain [i];
465
469
466
- // Blocks with heights in range [20, 40) are marked ASSUMED_VALID
470
+ // Blocks with heights in range [91, 110] are marked ASSUMED_VALID
467
471
if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
468
472
index->nStatus = BlockStatus::BLOCK_VALID_TREE | BlockStatus::BLOCK_ASSUMED_VALID;
469
473
}
@@ -497,19 +501,62 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
497
501
// Set tip of the assume-valid-based chain to the assume-valid block
498
502
cs2.m_chain .SetTip (*assumed_base);
499
503
504
+ // Sanity check test variables.
505
+ BOOST_CHECK_EQUAL (num_indexes, 121 ); // 121 total blocks, including genesis
506
+ BOOST_CHECK_EQUAL (assumed_tip->nHeight , 120 ); // original chain has height 120
507
+ BOOST_CHECK_EQUAL (validated_tip->nHeight , 90 ); // current cs1 chain has height 90
508
+ BOOST_CHECK_EQUAL (assumed_base->nHeight , 110 ); // current cs2 chain has height 110
509
+
510
+ // Regenerate cs1.setBlockIndexCandidates and cs2.setBlockIndexCandidate and
511
+ // check contents below.
500
512
reload_all_block_indexes ();
501
513
502
- // The fully validated chain should have the current validated tip
503
- // and the assumed valid base as candidates.
514
+ // The fully validated chain should only have the current validated tip and
515
+ // the assumed valid base as candidates, blocks 90 and 110. Specifically:
516
+ //
517
+ // - It does not have blocks 0-89 because they contain less work than the
518
+ // chain tip.
519
+ //
520
+ // - It has block 90 because it has data and equal work to the chain tip,
521
+ // (since it is the chain tip).
522
+ //
523
+ // - It does not have blocks 91-109 because they do not contain data.
524
+ //
525
+ // - It has block 110 even though it does not have data, because
526
+ // LoadBlockIndex has a special case to always add the snapshot block as a
527
+ // candidate. The special case is only actually intended to apply to the
528
+ // snapshot chainstate cs2, not the background chainstate cs1, but it is
529
+ // written broadly and applies to both.
530
+ //
531
+ // - It does not have any blocks after height 110 because cs1 is a background
532
+ // chainstate, and only blocks where are ancestors of the snapshot block
533
+ // are added as candidates for the background chainstate.
504
534
BOOST_CHECK_EQUAL (cs1.setBlockIndexCandidates .size (), 2 );
505
535
BOOST_CHECK_EQUAL (cs1.setBlockIndexCandidates .count (validated_tip), 1 );
506
536
BOOST_CHECK_EQUAL (cs1.setBlockIndexCandidates .count (assumed_base), 1 );
507
537
508
538
// The assumed-valid tolerant chain has the assumed valid base as a
509
539
// candidate, but otherwise has none of the assumed-valid (which do not
510
540
// HAVE_DATA) blocks as candidates.
541
+ //
542
+ // Specifically:
543
+ // - All blocks below height 110 are not candidates, because cs2 chain tip
544
+ // has height 110 and they have less work than it does.
545
+ //
546
+ // - Block 110 is a candidate even though it does not have data, because it
547
+ // is the snapshot block, which is assumed valid.
548
+ //
549
+ // - Blocks 111-120 are added because they have data.
550
+
551
+ // Check that block 90 is absent
511
552
BOOST_CHECK_EQUAL (cs2.setBlockIndexCandidates .count (validated_tip), 0 );
553
+ // Check that block 109 is absent
554
+ BOOST_CHECK_EQUAL (cs2.setBlockIndexCandidates .count (assumed_base->pprev ), 0 );
555
+ // Check that block 110 is present
556
+ BOOST_CHECK_EQUAL (cs2.setBlockIndexCandidates .count (assumed_base), 1 );
557
+ // Check that block 120 is present
512
558
BOOST_CHECK_EQUAL (cs2.setBlockIndexCandidates .count (assumed_tip), 1 );
559
+ // Check that 11 blocks total are present.
513
560
BOOST_CHECK_EQUAL (cs2.setBlockIndexCandidates .size (), num_indexes - last_assumed_valid_idx + 1 );
514
561
}
515
562
0 commit comments