| 2961 | } |
| 2962 | |
| 2963 | bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex) |
| 2964 | { |
| 2965 | AssertLockHeld(cs_main); |
| 2966 | |
| 2967 | // We first disconnect backwards and then mark the blocks as invalid. |
| 2968 | // This prevents a case where pruned nodes may fail to invalidateblock |
| 2969 | // and be left unable to start as they have no tip candidates (as there |
| 2970 | // are no blocks that meet the "have data and are not invalid per |
| 2971 | // nStatus" criteria for inclusion in setBlockIndexCandidates). |
| 2972 | |
| 2973 | bool pindex_was_in_chain = false; |
| 2974 | CBlockIndex *invalid_walk_tip = chainActive.Tip(); |
| 2975 | |
| 2976 | DisconnectedBlockTransactions disconnectpool; |
| 2977 | while (chainActive.Contains(pindex)) { |
| 2978 | pindex_was_in_chain = true; |
| 2979 | // ActivateBestChain considers blocks already in chainActive |
| 2980 | // unconditionally valid already, so force disconnect away from it. |
| 2981 | if (!DisconnectTip(state, chainparams, &disconnectpool)) { |
| 2982 | // It's probably hopeless to try to make the mempool consistent |
| 2983 | // here if DisconnectTip failed, but we can try. |
| 2984 | UpdateMempoolForReorg(disconnectpool, false); |
| 2985 | return false; |
| 2986 | } |
| 2987 | } |
| 2988 | |
| 2989 | // Now mark the blocks we just disconnected as descendants invalid |
| 2990 | // (note this may not be all descendants). |
| 2991 | while (pindex_was_in_chain && invalid_walk_tip != pindex) { |
| 2992 | invalid_walk_tip->nStatus |= BLOCK_FAILED_CHILD; |
| 2993 | setDirtyBlockIndex.insert(invalid_walk_tip); |
| 2994 | setBlockIndexCandidates.erase(invalid_walk_tip); |
| 2995 | invalid_walk_tip = invalid_walk_tip->pprev; |
| 2996 | } |
| 2997 | |
| 2998 | // Mark the block itself as invalid. |
| 2999 | pindex->nStatus |= BLOCK_FAILED_VALID; |
| 3000 | setDirtyBlockIndex.insert(pindex); |
| 3001 | setBlockIndexCandidates.erase(pindex); |
| 3002 | m_failed_blocks.insert(pindex); |
| 3003 | |
| 3004 | // DisconnectTip will add transactions to disconnectpool; try to add these |
| 3005 | // back to the mempool. |
| 3006 | UpdateMempoolForReorg(disconnectpool, true); |
| 3007 | |
| 3008 | // The resulting new best tip may not be in setBlockIndexCandidates anymore, so |
| 3009 | // add it again. |
| 3010 | BlockMap::iterator it = mapBlockIndex.begin(); |
| 3011 | while (it != mapBlockIndex.end()) { |
| 3012 | if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) { |
| 3013 | setBlockIndexCandidates.insert(it->second); |
| 3014 | } |
| 3015 | it++; |
| 3016 | } |
| 3017 | |
| 3018 | InvalidChainFound(pindex); |
| 3019 | |
| 3020 | // Only notify about a new block tip if the active chain was modified. |
no test coverage detected