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 <stickies-v@protonmail.com>
This commit is contained in:
Martin Zumsande
2025-03-18 16:30:52 -04:00
parent 15fa5b5a90
commit 4c29326183

View File

@@ -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<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
std::multimap<const arith_uint256, CBlockIndex*> 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;
}