From 4c29326183ba3c9d0b198cb2cec37c3119862c19 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 18 Mar 2025 16:30:52 -0400 Subject: [PATCH] validation: cache all headers with enough PoW in invalidateblock We now include blocks without HaveNumChainTxs() / lower validation status than BLOCK_VALID_TRANSACTIONS. These checks are still performed at the spot where we use the cache to insert into setBlockIndexCandidates. This is in preparation for using the cache for more things than just setBlockIndexCandidates candidates in the following commits. Co-authored-by: stickies-v --- src/validation.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index df690f2548b..067e9b1695f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3690,7 +3690,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde // To avoid walking the block index repeatedly in search of candidates, // build a map once so that we can look up candidate blocks by chain // work as we go. - std::multimap candidate_blocks_by_work; + std::multimap highpow_outofchain_headers; { LOCK(cs_main); @@ -3699,13 +3699,12 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde // We don't need to put anything in our active chain into the // multimap, because those candidates will be found and considered // as we disconnect. - // Instead, consider only non-active-chain blocks that have at - // least as much work as where we expect the new tip to end up. + // Instead, consider only non-active-chain blocks that score + // at least as good with CBlockIndexWorkComparator as the new tip. if (!m_chain.Contains(candidate) && - !CBlockIndexWorkComparator()(candidate, pindex->pprev) && - candidate->IsValid(BLOCK_VALID_TRANSACTIONS) && - candidate->HaveNumChainTxs()) { - candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate)); + !CBlockIndexWorkComparator()(candidate, pindex->pprev) && + !(candidate->nStatus & BLOCK_FAILED_MASK)) { + highpow_outofchain_headers.insert({candidate->nChainWork, candidate}); } } } @@ -3755,11 +3754,14 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde } // Add any equal or more work headers to setBlockIndexCandidates - auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->pprev->nChainWork); - while (candidate_it != candidate_blocks_by_work.end()) { - if (!CBlockIndexWorkComparator()(candidate_it->second, invalid_walk_tip->pprev)) { - setBlockIndexCandidates.insert(candidate_it->second); - candidate_it = candidate_blocks_by_work.erase(candidate_it); + auto candidate_it = highpow_outofchain_headers.lower_bound(invalid_walk_tip->pprev->nChainWork); + while (candidate_it != highpow_outofchain_headers.end()) { + CBlockIndex* candidate{candidate_it->second}; + if (!CBlockIndexWorkComparator()(candidate, invalid_walk_tip->pprev) && + candidate->IsValid(BLOCK_VALID_TRANSACTIONS) && + candidate->HaveNumChainTxs()) { + setBlockIndexCandidates.insert(candidate); + candidate_it = highpow_outofchain_headers.erase(candidate_it); } else { ++candidate_it; }