Skip to content

Commit 2283b9c

Browse files
committed
test: add tests for LoadBlockIndex when using multiple chainstates
Incorporates feedback from Russ Yanofsky.
1 parent 0fd599a commit 2283b9c

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/test/validation_chainstatemanager_tests.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,81 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
312312
loaded_snapshot_blockhash);
313313
}
314314

315+
//! Test LoadBlockIndex behavior when multiple chainstates are in use.
316+
//!
317+
//! - First, verfiy that setBlockIndexCandidates is as expected when using a single,
318+
//! fully-validating chainstate.
319+
//!
320+
//! - Then mark a region of the chain BLOCK_ASSUMED_VALID and introduce a second chainstate
321+
//! that will tolerate assumed-valid blocks. Run LoadBlockIndex() and ensure that the first
322+
//! chainstate only contains fully validated blocks and the other chainstate contains all blocks,
323+
//! even those assumed-valid.
324+
//!
325+
BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
326+
{
327+
ChainstateManager& chainman = *Assert(m_node.chainman);
328+
CTxMemPool& mempool = *m_node.mempool;
329+
CChainState& cs1 = chainman.ActiveChainstate();
330+
331+
int num_indexes{0};
332+
int num_assumed_valid{0};
333+
const int expected_assumed_valid{20};
334+
const int last_assumed_valid_idx{40};
335+
const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
336+
337+
CBlockIndex* validated_tip{nullptr};
338+
CBlockIndex* assumed_tip{chainman.ActiveChain().Tip()};
339+
340+
auto reload_all_block_indexes = [&]() {
341+
for (CChainState* cs : chainman.GetAll()) {
342+
LOCK(::cs_main);
343+
cs->UnloadBlockIndex();
344+
BOOST_CHECK(cs->setBlockIndexCandidates.empty());
345+
}
346+
347+
WITH_LOCK(::cs_main, chainman.LoadBlockIndex());
348+
};
349+
350+
// Ensure that without any assumed-valid BlockIndex entries, all entries are considered
351+
// tip candidates.
352+
reload_all_block_indexes();
353+
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), cs1.m_chain.Height() + 1);
354+
355+
// Mark some region of the chain assumed-valid.
356+
for (int i = 0; i <= cs1.m_chain.Height(); ++i) {
357+
auto index = cs1.m_chain[i];
358+
359+
if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
360+
index->nStatus = BlockStatus::BLOCK_VALID_TREE | BlockStatus::BLOCK_ASSUMED_VALID;
361+
}
362+
363+
++num_indexes;
364+
if (index->IsAssumedValid()) ++num_assumed_valid;
365+
366+
// Note the last fully-validated block as the expected validated tip.
367+
if (i == (assumed_valid_start_idx - 1)) {
368+
validated_tip = index;
369+
BOOST_CHECK(!index->IsAssumedValid());
370+
}
371+
}
372+
373+
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);
374+
375+
CChainState& cs2 = WITH_LOCK(::cs_main,
376+
return chainman.InitializeChainstate(&mempool, GetRandHash()));
377+
378+
reload_all_block_indexes();
379+
380+
// The fully validated chain only has candidates up to the start of the assumed-valid
381+
// blocks.
382+
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(validated_tip), 1);
383+
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(assumed_tip), 0);
384+
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), assumed_valid_start_idx);
385+
386+
// The assumed-valid tolerant chain has all blocks as candidates.
387+
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(validated_tip), 1);
388+
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(assumed_tip), 1);
389+
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.size(), num_indexes);
390+
}
391+
315392
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)