From 69baddc91033d2e42947260cde0f6780959f16b2 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Mon, 9 Mar 2026 16:40:24 +0700 Subject: [PATCH] validation: do not add the snapshot block to candidates of bg chainstate The snapshot block needs to be added to the candidates set of the assumed-valid chain because it will be the tip of that chainstate right after snapshot activation. However, adding it also to the background chainstate is not necessary for anything. Before, the index would linger in the set without being connectable. It will be eventually added to the set as part of the normal block download - no extra logic is necessary here. --- src/test/validation_chainstatemanager_tests.cpp | 17 +++++------------ src/validation.cpp | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 2847116976f..fe06499012f 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -551,8 +551,8 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup) // check contents below. reload_all_block_indexes(); - // The fully validated chain should only have the current validated tip and - // the assumed valid base as candidates, blocks 90 and 110. Specifically: + // The fully validated chain should only have the current validated tip + // as a candidate (block 90). Specifically: // // - It does not have blocks 0-89 because they contain less work than the // chain tip. @@ -560,20 +560,13 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup) // - It has block 90 because it has data and equal work to the chain tip, // (since it is the chain tip). // - // - It does not have blocks 91-109 because they do not contain data. - // - // - It has block 110 even though it does not have data, because - // LoadBlockIndex has a special case to always add the snapshot block as a - // candidate. The special case is only actually intended to apply to the - // snapshot chainstate cs2, not the background chainstate cs1, but it is - // written broadly and applies to both. + // - It does not have blocks 91-110 because they do not contain data. // // - It does not have any blocks after height 110 because cs1 is a background - // chainstate, and only blocks where are ancestors of the snapshot block + // chainstate, and only blocks that are ancestors of the snapshot block // are added as candidates for the background chainstate. - BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), 2); + BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.size(), 1); BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(validated_tip), 1); - BOOST_CHECK_EQUAL(cs1.setBlockIndexCandidates.count(assumed_base), 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 diff --git a/src/validation.cpp b/src/validation.cpp index 5c02ec2341c..afbd809be7f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4921,7 +4921,7 @@ void Chainstate::PopulateBlockIndexCandidates() // With assumeutxo, the snapshot block is a candidate for the tip, but it // may not have BLOCK_VALID_TRANSACTIONS (e.g. if we haven't yet downloaded // the block), so we special-case it here. - if (pindex == SnapshotBase() || pindex == TargetBlock() || + if (pindex == SnapshotBase() || (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->HaveNumChainTxs() || pindex->pprev == nullptr))) { TryAddBlockIndexCandidate(pindex);