mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 14:53:43 +01:00
validation: in invalidateblock, calculate m_best_header right away
Before, m_best_header would be calculated only after disconnecting multiple blocks, letting go of cs_main in the meantime. This is in preparation for adding checks to CheckBlockIndex() requiring that m_best_header is the most-work header not known to be invalid. Co-authored-by: stringintech <stringintech@gmail.com>
This commit is contained in:
@@ -3756,7 +3756,15 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
||||
// Mark out-of-chain descendants of the invalidated block as invalid
|
||||
// (possibly replacing a pre-existing BLOCK_FAILED_VALID with BLOCK_FAILED_CHILD)
|
||||
// Add any equal or more work headers that are not invalidated to setBlockIndexCandidates
|
||||
// Recalculate m_best_header if it became invalid.
|
||||
auto candidate_it = highpow_outofchain_headers.lower_bound(invalid_walk_tip->pprev->nChainWork);
|
||||
|
||||
const bool best_header_needs_update{m_chainman.m_best_header->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip};
|
||||
if (best_header_needs_update) {
|
||||
// pprev is definitely still valid at this point, but there may be better ones
|
||||
m_chainman.m_best_header = invalid_walk_tip->pprev;
|
||||
}
|
||||
|
||||
while (candidate_it != highpow_outofchain_headers.end()) {
|
||||
CBlockIndex* candidate{candidate_it->second};
|
||||
if (candidate->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip) {
|
||||
@@ -3765,7 +3773,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
||||
candidate->nStatus |= BLOCK_FAILED_CHILD;
|
||||
m_blockman.m_dirty_blockindex.insert(candidate);
|
||||
// If invalidated, the block is irrelevant for setBlockIndexCandidates
|
||||
// and can be removed from the cache.
|
||||
// and for m_best_header and can be removed from the cache.
|
||||
candidate_it = highpow_outofchain_headers.erase(candidate_it);
|
||||
continue;
|
||||
}
|
||||
@@ -3776,6 +3784,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
||||
// Do not remove candidate from the highpow_outofchain_headers cache, because it might be a descendant of the block being invalidated
|
||||
// which needs to be marked failed later.
|
||||
}
|
||||
if (best_header_needs_update &&
|
||||
m_chainman.m_best_header->nChainWork < candidate->nChainWork) {
|
||||
m_chainman.m_best_header = candidate;
|
||||
}
|
||||
++candidate_it;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user