validation: Add ancestors of reconsiderblock to setBlockIndexCandidates

When we call reconsiderblock for some block, ResetBlockFailureFlags puts the descendants of that block
into setBlockIndexCandidates (if they meet the criteria, i.e. have more work than the tip etc.)
We also clear the failure flags of the ancestors, but we never put any of those into setBlockIndexCandidates
this is wrong and could lead to failures in CheckBlockIndex().
This commit is contained in:
Martin Zumsande 2024-07-18 12:53:57 -04:00
parent 3679fa167f
commit 4a76a8300f

View file

@ -3777,9 +3777,9 @@ void Chainstate::ResetBlockFailureFlags(CBlockIndex *pindex) {
int nHeight = pindex->nHeight;
// Remove the invalidity flag from this block and all its descendants.
// Remove the invalidity flag from this block and all its descendants and ancestors.
for (auto& [_, block_index] : m_blockman.m_block_index) {
if (!block_index.IsValid() && block_index.GetAncestor(nHeight) == pindex) {
if (!block_index.IsValid() && (block_index.GetAncestor(nHeight) == pindex || pindex->GetAncestor(block_index.nHeight) == &block_index)) {
block_index.nStatus &= ~BLOCK_FAILED_MASK;
m_blockman.m_dirty_blockindex.insert(&block_index);
if (block_index.IsValid(BLOCK_VALID_TRANSACTIONS) && block_index.HaveNumChainTxs() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), &block_index)) {
@ -3792,16 +3792,6 @@ void Chainstate::ResetBlockFailureFlags(CBlockIndex *pindex) {
m_chainman.m_failed_blocks.erase(&block_index);
}
}
// Remove the invalidity flag from all ancestors too.
while (pindex != nullptr) {
if (pindex->nStatus & BLOCK_FAILED_MASK) {
pindex->nStatus &= ~BLOCK_FAILED_MASK;
m_blockman.m_dirty_blockindex.insert(pindex);
m_chainman.m_failed_blocks.erase(pindex);
}
pindex = pindex->pprev;
}
}
void Chainstate::TryAddBlockIndexCandidate(CBlockIndex* pindex)