| 3334 | } |
| 3335 | |
| 3336 | bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) |
| 3337 | { |
| 3338 | AssertLockNotHeld(m_chainstate_mutex); |
| 3339 | AssertLockNotHeld(::cs_main); |
| 3340 | |
| 3341 | // Genesis block can't be invalidated |
| 3342 | assert(pindex); |
| 3343 | if (pindex->nHeight == 0) return false; |
| 3344 | |
| 3345 | CBlockIndex* to_mark_failed = pindex; |
| 3346 | bool pindex_was_in_chain = false; |
| 3347 | int disconnected = 0; |
| 3348 | |
| 3349 | // We do not allow ActivateBestChain() to run while InvalidateBlock() is |
| 3350 | // running, as that could cause the tip to change while we disconnect |
| 3351 | // blocks. |
| 3352 | LOCK(m_chainstate_mutex); |
| 3353 | |
| 3354 | // We'll be acquiring and releasing cs_main below, to allow the validation |
| 3355 | // callbacks to run. However, we should keep the block index in a |
| 3356 | // consistent state as we disconnect blocks -- in particular we need to |
| 3357 | // add equal-work blocks to setBlockIndexCandidates as we disconnect. |
| 3358 | // To avoid walking the block index repeatedly in search of candidates, |
| 3359 | // build a map once so that we can look up candidate blocks by chain |
| 3360 | // work as we go. |
| 3361 | std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work; |
| 3362 | |
| 3363 | { |
| 3364 | LOCK(cs_main); |
| 3365 | for (const auto& entry : m_blockman.m_block_index) { |
| 3366 | CBlockIndex *candidate = entry.second; |
| 3367 | // We don't need to put anything in our active chain into the |
| 3368 | // multimap, because those candidates will be found and considered |
| 3369 | // as we disconnect. |
| 3370 | // Instead, consider only non-active-chain blocks that have at |
| 3371 | // least as much work as where we expect the new tip to end up. |
| 3372 | if (!m_chain.Contains(candidate) && |
| 3373 | !CBlockIndexWorkComparator()(candidate, pindex->pprev) && |
| 3374 | candidate->IsValid(BLOCK_VALID_TRANSACTIONS) && |
| 3375 | candidate->HaveTxsDownloaded()) { |
| 3376 | candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate)); |
| 3377 | } |
| 3378 | } |
| 3379 | } |
| 3380 | |
| 3381 | // Disconnect (descendants of) pindex, and mark them invalid. |
| 3382 | while (true) { |
| 3383 | if (ShutdownRequested()) break; |
| 3384 | |
| 3385 | // Make sure the queue of validation callbacks doesn't grow unboundedly. |
| 3386 | LimitValidationInterfaceQueue(); |
| 3387 | |
| 3388 | LOCK(cs_main); |
| 3389 | // Lock for as long as disconnectpool is in scope to make sure MaybeUpdateMempoolForReorg is |
| 3390 | // called after DisconnectTip without unlocking in between |
| 3391 | LOCK(MempoolMutex()); |
| 3392 | if (!m_chain.Contains(pindex)) break; |
| 3393 | pindex_was_in_chain = true; |