@@ -2829,25 +2829,30 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
2829
2829
// and be left unable to start as they have no tip candidates (as there
2830
2830
// are no blocks that meet the "have data and are not invalid per
2831
2831
// nStatus" criteria for inclusion in setBlockIndexCandidates).
2832
- invalid_walk_tip->nStatus |= BLOCK_FAILED_CHILD ;
2832
+ invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID ;
2833
2833
setDirtyBlockIndex.insert (invalid_walk_tip);
2834
2834
setBlockIndexCandidates.erase (invalid_walk_tip);
2835
2835
setBlockIndexCandidates.insert (invalid_walk_tip->pprev );
2836
+ if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
2837
+ // We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
2838
+ // need to be BLOCK_FAILED_CHILD instead.
2839
+ to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
2840
+ setDirtyBlockIndex.insert (to_mark_failed);
2841
+ }
2836
2842
2837
- // If we abort invalidation after this iteration, make sure
2838
- // the last disconnected block gets marked failed (rather than
2839
- // just child of failed)
2843
+ // Track the last disconnected block, so we can correct its BLOCK_FAILED_CHILD status in future
2844
+ // iterations, or, if it's the last one, call InvalidChainFound on it.
2840
2845
to_mark_failed = invalid_walk_tip;
2841
2846
}
2842
2847
2843
2848
{
2844
- // Mark pindex (or the last disconnected block) as invalid, regardless of whether it was in the main chain or not.
2845
2849
LOCK (cs_main);
2846
2850
if (chainActive.Contains (to_mark_failed)) {
2847
2851
// If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
2848
2852
return false ;
2849
2853
}
2850
2854
2855
+ // Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
2851
2856
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
2852
2857
setDirtyBlockIndex.insert (to_mark_failed);
2853
2858
setBlockIndexCandidates.erase (to_mark_failed);
0 commit comments