mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 06:52:36 +01:00
test: add tests for LoadBlockIndex when using multiple chainstates
Incorporates feedback from Russ Yanofsky.
This commit is contained in:
parent
0fd599a51a
commit
2283b9cd1e
1 changed files with 77 additions and 0 deletions
|
@ -312,4 +312,81 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
|
|||
loaded_snapshot_blockhash);
|
||||
}
|
||||
|
||||
//! Test LoadBlockIndex behavior when multiple chainstates are in use.
|
||||
//!
|
||||
//! - First, verfiy that setBlockIndexCandidates is as expected when using a single,
|
||||
//! fully-validating chainstate.
|
||||
//!
|
||||
//! - Then mark a region of the chain BLOCK_ASSUMED_VALID and introduce a second chainstate
|
||||
//! that will tolerate assumed-valid blocks. Run LoadBlockIndex() and ensure that the first
|
||||
//! chainstate only contains fully validated blocks and the other chainstate contains all blocks,
|
||||
//! even those assumed-valid.
|
||||
//!
|
||||
BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
|
||||
{
|
||||
ChainstateManager& chainman = *Assert(m_node.chainman);
|
||||
CTxMemPool& mempool = *m_node.mempool;
|
||||
CChainState& cs1 = chainman.ActiveChainstate();
|
||||
|
||||
int num_indexes{0};
|
||||
int num_assumed_valid{0};
|
||||
const int expected_assumed_valid{20};
|
||||
const int last_assumed_valid_idx{40};
|
||||
const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
|
||||
|
||||
CBlockIndex* validated_tip{nullptr};
|
||||
CBlockIndex* assumed_tip{chainman.ActiveChain().Tip()};
|
||||
|
||||
auto reload_all_block_indexes = [&]() {
|
||||
for (CChainState* cs : chainman.GetAll()) {
|
||||
LOCK(::cs_main);
|
||||
cs->UnloadBlockIndex();
|
||||
BOOST_CHECK(cs->setBlockIndexCandidates.empty());
|
||||
}
|
||||
|
||||
WITH_LOCK(::cs_main, chainman.LoadBlockIndex());
|
||||
};
|
||||
|
||||
// Ensure that without any assumed-valid BlockIndex entries, all entries are considered
|
||||
// tip candidates.
|
||||
reload_all_block_indexes();
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), cs1.m_chain.Height() + 1);
|
||||
|
||||
// Mark some region of the chain assumed-valid.
|
||||
for (int i = 0; i <= cs1.m_chain.Height(); ++i) {
|
||||
auto index = cs1.m_chain[i];
|
||||
|
||||
if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
|
||||
index->nStatus = BlockStatus::BLOCK_VALID_TREE | BlockStatus::BLOCK_ASSUMED_VALID;
|
||||
}
|
||||
|
||||
++num_indexes;
|
||||
if (index->IsAssumedValid()) ++num_assumed_valid;
|
||||
|
||||
// Note the last fully-validated block as the expected validated tip.
|
||||
if (i == (assumed_valid_start_idx - 1)) {
|
||||
validated_tip = index;
|
||||
BOOST_CHECK(!index->IsAssumedValid());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);
|
||||
|
||||
CChainState& cs2 = WITH_LOCK(::cs_main,
|
||||
return chainman.InitializeChainstate(&mempool, GetRandHash()));
|
||||
|
||||
reload_all_block_indexes();
|
||||
|
||||
// The fully validated chain only has candidates up to the start of the assumed-valid
|
||||
// blocks.
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(validated_tip), 1);
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(assumed_tip), 0);
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), assumed_valid_start_idx);
|
||||
|
||||
// The assumed-valid tolerant chain has all blocks as candidates.
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(validated_tip), 1);
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(assumed_tip), 1);
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.size(), num_indexes);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Add table
Reference in a new issue