Make last disconnected block BLOCK_FAILED_VALID, even when aborted
This commit is contained in:
parent
8d220417cd
commit
519b0bc5dc
1 changed files with 10 additions and 5 deletions
|
@ -2829,25 +2829,30 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
|
||||||
// and be left unable to start as they have no tip candidates (as there
|
// and be left unable to start as they have no tip candidates (as there
|
||||||
// are no blocks that meet the "have data and are not invalid per
|
// are no blocks that meet the "have data and are not invalid per
|
||||||
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
||||||
invalid_walk_tip->nStatus |= BLOCK_FAILED_CHILD;
|
invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
|
||||||
setDirtyBlockIndex.insert(invalid_walk_tip);
|
setDirtyBlockIndex.insert(invalid_walk_tip);
|
||||||
setBlockIndexCandidates.erase(invalid_walk_tip);
|
setBlockIndexCandidates.erase(invalid_walk_tip);
|
||||||
setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
|
setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
|
||||||
|
if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
|
||||||
|
// We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
|
||||||
|
// need to be BLOCK_FAILED_CHILD instead.
|
||||||
|
to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
|
||||||
|
setDirtyBlockIndex.insert(to_mark_failed);
|
||||||
|
}
|
||||||
|
|
||||||
// If we abort invalidation after this iteration, make sure
|
// Track the last disconnected block, so we can correct its BLOCK_FAILED_CHILD status in future
|
||||||
// the last disconnected block gets marked failed (rather than
|
// iterations, or, if it's the last one, call InvalidChainFound on it.
|
||||||
// just child of failed)
|
|
||||||
to_mark_failed = invalid_walk_tip;
|
to_mark_failed = invalid_walk_tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Mark pindex (or the last disconnected block) as invalid, regardless of whether it was in the main chain or not.
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
if (chainActive.Contains(to_mark_failed)) {
|
if (chainActive.Contains(to_mark_failed)) {
|
||||||
// If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
|
// If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
|
||||||
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
|
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
|
||||||
setDirtyBlockIndex.insert(to_mark_failed);
|
setDirtyBlockIndex.insert(to_mark_failed);
|
||||||
setBlockIndexCandidates.erase(to_mark_failed);
|
setBlockIndexCandidates.erase(to_mark_failed);
|
||||||
|
|
Loading…
Reference in a new issue