* Try to make some progress towards making pindexMostWork the active block. * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork. */
| 2712 | * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork. |
| 2713 | */ |
| 2714 | bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) |
| 2715 | { |
| 2716 | AssertLockHeld(cs_main); |
| 2717 | |
| 2718 | const CBlockIndex *pindexOldTip = chainActive.Tip(); |
| 2719 | const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); |
| 2720 | |
| 2721 | // Disconnect active blocks which are no longer in the best chain. |
| 2722 | bool fBlocksDisconnected = false; |
| 2723 | DisconnectedBlockTransactions disconnectpool; |
| 2724 | while (chainActive.Tip() && chainActive.Tip() != pindexFork) { |
| 2725 | if (!DisconnectTip(state, chainparams, &disconnectpool)) { |
| 2726 | // This is likely a fatal error, but keep the mempool consistent, |
| 2727 | // just in case. Only remove from the mempool in this case. |
| 2728 | UpdateMempoolForReorg(disconnectpool, false); |
| 2729 | return false; |
| 2730 | } |
| 2731 | fBlocksDisconnected = true; |
| 2732 | } |
| 2733 | |
| 2734 | // Build list of new blocks to connect. |
| 2735 | std::vector<CBlockIndex*> vpindexToConnect; |
| 2736 | bool fContinue = true; |
| 2737 | int nHeight = pindexFork ? pindexFork->nHeight : -1; |
| 2738 | while (fContinue && nHeight != pindexMostWork->nHeight) { |
| 2739 | // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need |
| 2740 | // a few blocks along the way. |
| 2741 | int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); |
| 2742 | vpindexToConnect.clear(); |
| 2743 | vpindexToConnect.reserve(nTargetHeight - nHeight); |
| 2744 | CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); |
| 2745 | while (pindexIter && pindexIter->nHeight != nHeight) { |
| 2746 | vpindexToConnect.push_back(pindexIter); |
| 2747 | pindexIter = pindexIter->pprev; |
| 2748 | } |
| 2749 | nHeight = nTargetHeight; |
| 2750 | |
| 2751 | // Connect new blocks. |
| 2752 | for (CBlockIndex *pindexConnect : reverse_iterate(vpindexToConnect)) { |
| 2753 | if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) { |
| 2754 | if (state.IsInvalid()) { |
| 2755 | // The block violates a consensus rule. |
| 2756 | if (!state.CorruptionPossible()) { |
| 2757 | InvalidChainFound(vpindexToConnect.front()); |
| 2758 | } |
| 2759 | state = CValidationState(); |
| 2760 | fInvalidFound = true; |
| 2761 | fContinue = false; |
| 2762 | break; |
| 2763 | } else { |
| 2764 | // A system error occurred (disk space, database error, ...). |
| 2765 | // Make the mempool consistent with the current tip, just in case |
| 2766 | // any observers try to use it before shutdown. |
| 2767 | UpdateMempoolForReorg(disconnectpool, false); |
| 2768 | return false; |
| 2769 | } |
| 2770 | } else { |
| 2771 | PruneBlockIndexCandidates(); |
nothing calls this directly
no test coverage detected