validation: fix traversal condition to mark BLOCK_FAILED_CHILD

this block of code is not reached on master since other than
initialisation, all other iterations have invalid_walk_tip
and to_mark_failed pointers in some form of this layout
where 1, 2, 3 and 4 are block heights.

	invalid_walk_tip
	  ↓
1 <- 2 <- 3 <- 4
	       ↑
	      to_mark_failed

fix it so that blocks are correctly marked as BLOCK_FAILED_CHILD
if it's a descendant of BLOCK_FAILED_VALID block.
This commit is contained in:
stratospher 2025-02-07 09:29:31 +05:30
parent f93d6cb0ca
commit c99667583d

View file

@ -3747,7 +3747,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
m_blockman.m_dirty_blockindex.insert(invalid_walk_tip); m_blockman.m_dirty_blockindex.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)) { if (invalid_walk_tip == to_mark_failed->pprev && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
// We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children // We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
// need to be BLOCK_FAILED_CHILD instead. // need to be BLOCK_FAILED_CHILD instead.
to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD; to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;