Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 3,059 Lines • ▼ Show 20 Lines | while (true) { | ||||
// We immediately mark the disconnected blocks as invalid. | // We immediately mark the disconnected blocks as invalid. | ||||
// This prevents a case where pruned nodes may fail to invalidateblock | // This prevents a case where pruned nodes may fail to invalidateblock | ||||
// 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 = | invalid_walk_tip->nStatus = | ||||
invalidate ? invalid_walk_tip->nStatus.withFailedParent() | invalidate ? invalid_walk_tip->nStatus.withFailed() | ||||
: invalid_walk_tip->nStatus.withParkedParent(); | : invalid_walk_tip->nStatus.withParked(); | ||||
setDirtyBlockIndex.insert(invalid_walk_tip); | setDirtyBlockIndex.insert(invalid_walk_tip); | ||||
setBlockIndexCandidates.insert(invalid_walk_tip->pprev); | setBlockIndexCandidates.insert(invalid_walk_tip->pprev); | ||||
// If we abort invalidation after this iteration, make sure | if (invalid_walk_tip->pprev == to_mark_failed_or_parked && | ||||
// the last disconnected block gets marked failed (rather than | (invalidate ? to_mark_failed_or_parked->nStatus.hasFailed() | ||||
// just child of failed) | : to_mark_failed_or_parked->nStatus.isParked())) { | ||||
// We only want to mark the last disconnected block as | |||||
// Failed (or Parked); its children need to be FailedParent (or | |||||
// ParkedParent) instead. | |||||
to_mark_failed_or_parked->nStatus = | |||||
(invalidate | |||||
? to_mark_failed_or_parked->nStatus.withFailed(false) | |||||
.withFailedParent() | |||||
: to_mark_failed_or_parked->nStatus.withParked(false) | |||||
.withParkedParent()); | |||||
setDirtyBlockIndex.insert(to_mark_failed_or_parked); | |||||
} | |||||
// Track the last disconnected block, so we can correct its | |||||
// FailedParent (or ParkedParent) status in future iterations, or, if | |||||
// it's the last one, call InvalidChainFound on it. | |||||
to_mark_failed_or_parked = invalid_walk_tip; | to_mark_failed_or_parked = invalid_walk_tip; | ||||
} | } | ||||
{ | { | ||||
// Mark pindex (or the last disconnected block) as invalid or parked, | |||||
// regardless of whether it was in the main chain or not. | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (chainActive.Contains(to_mark_failed_or_parked)) { | if (chainActive.Contains(to_mark_failed_or_parked)) { | ||||
// If the to-be-marked invalid block is in the active chain, | // If the to-be-marked invalid block is in the active chain, | ||||
// something is interfering and we can't proceed. | // something is interfering and we can't proceed. | ||||
return false; | return false; | ||||
} | } | ||||
// Mark pindex (or the last disconnected block) as invalid (or parked), | |||||
// even when it never was in the main chain. | |||||
to_mark_failed_or_parked->nStatus = | to_mark_failed_or_parked->nStatus = | ||||
invalidate ? to_mark_failed_or_parked->nStatus.withFailed() | invalidate ? to_mark_failed_or_parked->nStatus.withFailed() | ||||
: to_mark_failed_or_parked->nStatus.withParked(); | : to_mark_failed_or_parked->nStatus.withParked(); | ||||
setDirtyBlockIndex.insert(to_mark_failed_or_parked); | setDirtyBlockIndex.insert(to_mark_failed_or_parked); | ||||
if (invalidate) { | if (invalidate) { | ||||
m_failed_blocks.insert(to_mark_failed_or_parked); | m_failed_blocks.insert(to_mark_failed_or_parked); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,588 Lines • Show Last 20 Lines |