mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 06:28:31 +01:00
Fix initialization of setBlockIndexCandidates when working with multiple chainstates
When using assumeutxo and multiple chainstates are active, the background chainstate should consider all HAVE_DATA blocks that are ancestors of the snapshotted block and that have more work than the tip as potential candidates.
This commit is contained in:
@@ -412,7 +412,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, SnapshotTestSetup)
|
||||
//! - 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.
|
||||
//! except those marked assume-valid, because those entries don't HAVE_DATA.
|
||||
//!
|
||||
BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
|
||||
{
|
||||
@@ -444,16 +444,17 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
|
||||
WITH_LOCK(::cs_main, chainman.LoadBlockIndex());
|
||||
};
|
||||
|
||||
// Ensure that without any assumed-valid BlockIndex entries, all entries are considered
|
||||
// tip candidates.
|
||||
// Ensure that without any assumed-valid BlockIndex entries, only the current tip is
|
||||
// considered as a candidate.
|
||||
reload_all_block_indexes();
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), cs1.m_chain.Height() + 1);
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), 1);
|
||||
|
||||
// Mark some region of the chain assumed-valid.
|
||||
// Mark some region of the chain assumed-valid, and remove the HAVE_DATA flag.
|
||||
for (int i = 0; i <= cs1.m_chain.Height(); ++i) {
|
||||
LOCK(::cs_main);
|
||||
auto index = cs1.m_chain[i];
|
||||
|
||||
// Blocks with heights in range [20, 40) are marked ASSUMED_VALID
|
||||
if (i < last_assumed_valid_idx && i >= assumed_valid_start_idx) {
|
||||
index->nStatus = BlockStatus::BLOCK_VALID_TREE | BlockStatus::BLOCK_ASSUMED_VALID;
|
||||
}
|
||||
@@ -466,33 +467,41 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
|
||||
validated_tip = index;
|
||||
BOOST_CHECK(!index->IsAssumedValid());
|
||||
}
|
||||
// Note the block after the last assumed valid block as the snapshot base
|
||||
if (i == last_assumed_valid_idx) {
|
||||
// Note the last assumed valid block as the snapshot base
|
||||
if (i == last_assumed_valid_idx - 1) {
|
||||
assumed_base = index;
|
||||
BOOST_CHECK(index->IsAssumedValid());
|
||||
} else if (i == last_assumed_valid_idx) {
|
||||
BOOST_CHECK(!index->IsAssumedValid());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);
|
||||
|
||||
// Note: cs2's tip is not set when ActivateExistingSnapshot is called.
|
||||
Chainstate& cs2 = WITH_LOCK(::cs_main,
|
||||
return chainman.ActivateExistingSnapshot(&mempool, *assumed_base->phashBlock));
|
||||
|
||||
// Set tip of the fully validated chain to be the validated tip
|
||||
cs1.m_chain.SetTip(*validated_tip);
|
||||
|
||||
// Set tip of the assume-valid-based chain to the assume-valid block
|
||||
cs2.m_chain.SetTip(*assumed_base);
|
||||
|
||||
reload_all_block_indexes();
|
||||
|
||||
// The fully validated chain only has candidates up to the start of the assumed-valid
|
||||
// blocks.
|
||||
// The fully validated chain should have the current validated tip
|
||||
// and the assumed valid base as candidates.
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), 2);
|
||||
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);
|
||||
BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(assumed_base), 1);
|
||||
|
||||
// The assumed-valid tolerant chain has all blocks as candidates.
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(validated_tip), 1);
|
||||
// The assumed-valid tolerant chain has the assumed valid base as a
|
||||
// candidate, but otherwise has none of the assumed-valid (which do not
|
||||
// HAVE_DATA) blocks as candidates.
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(validated_tip), 0);
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.count(assumed_tip), 1);
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.size(), num_indexes);
|
||||
BOOST_CHECK_EQUAL(cs2.setBlockIndexCandidates.size(), num_indexes - last_assumed_valid_idx + 1);
|
||||
}
|
||||
|
||||
//! Ensure that snapshot chainstates initialize properly when found on disk.
|
||||
|
||||
Reference in New Issue
Block a user