mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 14:38:29 +01:00
Tighten requirements for adding elements to setBlockIndexCandidates
When using assumeutxo, we only need the background chainstate to consider blocks that are on the chain leading to the snapshotted block. Note that this introduces the new invariant that we can only have an assumeutxo snapshot where the snapshotted blockhash is in our block index. Unknown block hashes that are somehow passed in will cause assertion failures when processing new blocks. Includes test fixes and improvements by Andrew Chow and Fabian Jahr.
This commit is contained in:
@@ -49,6 +49,9 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
c1.InitCoinsDB(
|
||||
/*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
|
||||
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
|
||||
c1.LoadGenesisBlock();
|
||||
BlockValidationState val_state;
|
||||
BOOST_CHECK(c1.ActivateBestChain(val_state, nullptr));
|
||||
|
||||
BOOST_CHECK(!manager.IsSnapshotActive());
|
||||
BOOST_CHECK(WITH_LOCK(::cs_main, return !manager.IsSnapshotValidated()));
|
||||
@@ -58,7 +61,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
auto& active_chain = WITH_LOCK(manager.GetMutex(), return manager.ActiveChain());
|
||||
BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain);
|
||||
|
||||
BOOST_CHECK_EQUAL(WITH_LOCK(manager.GetMutex(), return manager.ActiveHeight()), -1);
|
||||
BOOST_CHECK_EQUAL(WITH_LOCK(manager.GetMutex(), return manager.ActiveHeight()), 0);
|
||||
|
||||
auto active_tip = WITH_LOCK(manager.GetMutex(), return manager.ActiveTip());
|
||||
auto exp_tip = c1.m_chain.Tip();
|
||||
@@ -68,7 +71,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
|
||||
// Create a snapshot-based chainstate.
|
||||
//
|
||||
const uint256 snapshot_blockhash = GetRandHash();
|
||||
const uint256 snapshot_blockhash = active_tip->GetBlockHash();
|
||||
Chainstate& c2 = WITH_LOCK(::cs_main, return manager.ActivateExistingSnapshot(
|
||||
&mempool, snapshot_blockhash));
|
||||
chainstates.push_back(&c2);
|
||||
@@ -78,8 +81,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
c2.InitCoinsDB(
|
||||
/*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
|
||||
WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23));
|
||||
// Unlike c1, which doesn't have any blocks. Gets us different tip, height.
|
||||
c2.LoadGenesisBlock();
|
||||
c2.m_chain.SetTip(*active_tip);
|
||||
BlockValidationState _;
|
||||
BOOST_CHECK(c2.ActivateBestChain(_, nullptr));
|
||||
|
||||
@@ -99,16 +101,14 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
auto exp_tip2 = c2.m_chain.Tip();
|
||||
BOOST_CHECK_EQUAL(active_tip2, exp_tip2);
|
||||
|
||||
// Ensure that these pointers actually correspond to different
|
||||
// CCoinsViewCache instances.
|
||||
BOOST_CHECK(exp_tip != exp_tip2);
|
||||
BOOST_CHECK_EQUAL(exp_tip, exp_tip2);
|
||||
|
||||
// Let scheduler events finish running to avoid accessing memory that is going to be unloaded
|
||||
SyncWithValidationInterfaceQueue();
|
||||
}
|
||||
|
||||
//! Test rebalancing the caches associated with each chainstate.
|
||||
BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
BOOST_FIXTURE_TEST_CASE(chainstatemanager_rebalance_caches, TestChain100Setup)
|
||||
{
|
||||
ChainstateManager& manager = *m_node.chainman;
|
||||
CTxMemPool& mempool = *m_node.mempool;
|
||||
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
|
||||
// Create a legacy (IBD) chainstate.
|
||||
//
|
||||
Chainstate& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool));
|
||||
Chainstate& c1 = manager.ActiveChainstate();
|
||||
chainstates.push_back(&c1);
|
||||
c1.InitCoinsDB(
|
||||
/*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
|
||||
@@ -129,8 +129,6 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
c1.InitCoinsCache(1 << 23);
|
||||
BOOST_REQUIRE(c1.LoadGenesisBlock());
|
||||
c1.CoinsTip().SetBestBlock(InsecureRand256());
|
||||
manager.MaybeRebalanceCaches();
|
||||
}
|
||||
|
||||
@@ -139,7 +137,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
|
||||
// Create a snapshot-based chainstate.
|
||||
//
|
||||
Chainstate& c2 = WITH_LOCK(cs_main, return manager.ActivateExistingSnapshot(&mempool, GetRandHash()));
|
||||
CBlockIndex* snapshot_base{WITH_LOCK(manager.GetMutex(), return manager.ActiveChain()[manager.ActiveChain().Height() / 2])};
|
||||
Chainstate& c2 = WITH_LOCK(cs_main, return manager.ActivateExistingSnapshot(&mempool, *snapshot_base->phashBlock));
|
||||
chainstates.push_back(&c2);
|
||||
c2.InitCoinsDB(
|
||||
/*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
|
||||
@@ -147,8 +146,6 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
c2.InitCoinsCache(1 << 23);
|
||||
BOOST_REQUIRE(c2.LoadGenesisBlock());
|
||||
c2.CoinsTip().SetBestBlock(InsecureRand256());
|
||||
manager.MaybeRebalanceCaches();
|
||||
}
|
||||
|
||||
@@ -430,6 +427,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
|
||||
const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
|
||||
|
||||
CBlockIndex* validated_tip{nullptr};
|
||||
CBlockIndex* assumed_base{nullptr};
|
||||
CBlockIndex* assumed_tip{WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip())};
|
||||
|
||||
auto reload_all_block_indexes = [&]() {
|
||||
@@ -468,12 +466,20 @@ 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) {
|
||||
assumed_base = index;
|
||||
BOOST_CHECK(!index->IsAssumedValid());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid);
|
||||
|
||||
Chainstate& cs2 = WITH_LOCK(::cs_main,
|
||||
return chainman.ActivateExistingSnapshot(&mempool, GetRandHash()));
|
||||
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);
|
||||
|
||||
reload_all_block_indexes();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user