Skip to content

Commit 9a70883

Browse files
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 <[email protected]>
1 parent 8e39f2d commit 9a70883

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/validation.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3756,7 +3756,15 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
37563756
// Mark out-of-chain descendants of the invalidated block as invalid
37573757
// (possibly replacing a pre-existing BLOCK_FAILED_VALID with BLOCK_FAILED_CHILD)
37583758
// Add any equal or more work headers that are not invalidated to setBlockIndexCandidates
3759+
// Recalculate m_best_header if it became invalid.
37593760
auto candidate_it = highpow_outofchain_headers.lower_bound(invalid_walk_tip->pprev->nChainWork);
3761+
3762+
const bool best_header_needs_update{m_chainman.m_best_header->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip};
3763+
if (best_header_needs_update) {
3764+
// pprev is definitely still valid at this point, but there may be better ones
3765+
m_chainman.m_best_header = invalid_walk_tip->pprev;
3766+
}
3767+
37603768
while (candidate_it != highpow_outofchain_headers.end()) {
37613769
CBlockIndex* candidate{candidate_it->second};
37623770
if (candidate->GetAncestor(invalid_walk_tip->nHeight) == invalid_walk_tip) {
@@ -3765,7 +3773,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
37653773
candidate->nStatus |= BLOCK_FAILED_CHILD;
37663774
m_blockman.m_dirty_blockindex.insert(candidate);
37673775
// If invalidated, the block is irrelevant for setBlockIndexCandidates
3768-
// and can be removed from the cache.
3776+
// and for m_best_header and can be removed from the cache.
37693777
candidate_it = highpow_outofchain_headers.erase(candidate_it);
37703778
continue;
37713779
}
@@ -3776,6 +3784,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
37763784
// Do not remove candidate from the highpow_outofchain_headers cache, because it might be a descendant of the block being invalidated
37773785
// which needs to be marked failed later.
37783786
}
3787+
if (best_header_needs_update &&
3788+
m_chainman.m_best_header->nChainWork < candidate->nChainWork) {
3789+
m_chainman.m_best_header = candidate;
3790+
}
37793791
++candidate_it;
37803792
}
37813793

0 commit comments

Comments
 (0)