diff options
| author | Pieter Wuille <[email protected]> | 2019-03-03 13:01:26 -0800 |
|---|---|---|
| committer | Pieter Wuille <[email protected]> | 2019-03-03 13:01:26 -0800 |
| commit | 519b0bc5dc5155b6f7e2362c2105552bb7618ad0 (patch) | |
| tree | 8601e0a0d0816d2ebe6e7cf093d2e3cef0e4ce5d /src/validation.cpp | |
| parent | Optimization: don't add txn back to mempool after 10 invalidates (diff) | |
| download | discoin-519b0bc5dc5155b6f7e2362c2105552bb7618ad0.tar.xz discoin-519b0bc5dc5155b6f7e2362c2105552bb7618ad0.zip | |
Make last disconnected block BLOCK_FAILED_VALID, even when aborted
Diffstat (limited to 'src/validation.cpp')
| -rw-r--r-- | src/validation.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index c112fbdcc..55fd8d99a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -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 // are no blocks that meet the "have data and are not invalid per // 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); setBlockIndexCandidates.erase(invalid_walk_tip); 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 - // the last disconnected block gets marked failed (rather than - // just child of failed) + // Track the last disconnected block, so we can correct its BLOCK_FAILED_CHILD status in future + // iterations, or, if it's the last one, call InvalidChainFound on it. 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); 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. 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; setDirtyBlockIndex.insert(to_mark_failed); setBlockIndexCandidates.erase(to_mark_failed); |