src/validation.cpp
/**
 * Try to make some progress towards making pindexMostWork the active block.
 * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork.
 *
 * @returns true unless a system error occurred
 */
Try to make some progress towards making pindexMostWork the active block.
pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork.

@returns true unless a system error occurred
Try to make some progress towards making pindexMostWork the active block . pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork . @returns true unless a system error occurred
bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
{
    AssertLockHeld(cs_main);
    AssertLockHeld(m_mempool.cs);
    const CBlockIndex *pindexOldTip = m_chain.Tip();
    const CBlockIndex *pindexFork = m_chain.FindFork(pindexMostWork);
    bool fBlocksDisconnected = false;
    DisconnectedBlockTransactions disconnectpool;
    while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
        if (!DisconnectTip(state, chainparams, &disconnectpool)) {
            UpdateMempoolForReorg(m_mempool, disconnectpool, false);
            AbortNode(state, "Failed to disconnect block; see debug.log for details");
            return false;
        }
        fBlocksDisconnected = true;
    }
    std::vector<CBlockIndex*> vpindexToConnect;
    bool fContinue = true;
    int nHeight = pindexFork ? pindexFork->nHeight : -1;
    while (fContinue && nHeight != pindexMostWork->nHeight) {
        int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
        vpindexToConnect.clear();
        vpindexToConnect.reserve(nTargetHeight - nHeight);
        CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
        while (pindexIter && pindexIter->nHeight != nHeight) {
            vpindexToConnect.push_back(pindexIter);
            pindexIter = pindexIter->pprev;
        }
        nHeight = nTargetHeight;
        for (CBlockIndex *pindexConnect : reverse_iterate(vpindexToConnect)) {
            if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
                if (state.IsInvalid()) {
                    if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
                        InvalidChainFound(vpindexToConnect.front());
                    }
                    if (!state.m_preserve_state) {
                        state = BlockValidationState();
                    }
                    fInvalidFound = true;
                    fContinue = false;
                    break;
                } else {
                    UpdateMempoolForReorg(m_mempool, disconnectpool, false);
                    return false;
                }
            } else {
                PruneBlockIndexCandidates();
                if (!pindexOldTip || m_chain.Tip()->nChainWork > pindexOldTip->nChainWork) {
                    fContinue = false;
                    break;
                }
            }
        }
    }
    if (fBlocksDisconnected) {
        UpdateMempoolForReorg(m_mempool, disconnectpool, true);
    }
    m_mempool.check(&CoinsTip());
    if (fInvalidFound)
        CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
    else
        CheckForkWarningConditions();
    return true;
}
bool CChainState :: ActivateBestChainStep ( BlockValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const std :: shared_ptr < const CBlock > & pblock , bool & fInvalidFound , ConnectTrace & connectTrace ) { AssertLockHeld ( cs_main ) ; AssertLockHeld ( m_mempool . cs ) ; const CBlockIndex * pindexOldTip = m_chain . Tip ( ) ; const CBlockIndex * pindexFork = m_chain . FindFork ( pindexMostWork ) ; bool fBlocksDisconnected = false ; DisconnectedBlockTransactions disconnectpool ; while ( m_chain . Tip ( ) && m_chain . Tip ( ) != pindexFork ) { if ( ! DisconnectTip ( state , chainparams , & disconnectpool ) ) { UpdateMempoolForReorg ( m_mempool , disconnectpool , false ) ; AbortNode ( state , " " ) ; return false ; } fBlocksDisconnected = true ; } std :: vector < CBlockIndex * > vpindexToConnect ; bool fContinue = true ; int nHeight = pindexFork ? pindexFork -> nHeight : -1 ; while ( fContinue && nHeight != pindexMostWork -> nHeight ) { int nTargetHeight = std :: min ( nHeight + 32 , pindexMostWork -> nHeight ) ; vpindexToConnect . clear ( ) ; vpindexToConnect . reserve ( nTargetHeight - nHeight ) ; CBlockIndex * pindexIter = pindexMostWork -> GetAncestor ( nTargetHeight ) ; while ( pindexIter && pindexIter -> nHeight != nHeight ) { vpindexToConnect . push_back ( pindexIter ) ; pindexIter = pindexIter -> pprev ; } nHeight = nTargetHeight ; for ( CBlockIndex * pindexConnect : reverse_iterate ( vpindexToConnect ) ) { if ( ! ConnectTip ( state , chainparams , pindexConnect , pindexConnect == pindexMostWork ? pblock : std :: shared_ptr < const CBlock > ( ) , connectTrace , disconnectpool ) ) { if ( state . IsInvalid ( ) ) { if ( state . GetResult ( ) != BlockValidationResult :: BLOCK_MUTATED ) { InvalidChainFound ( vpindexToConnect . front ( ) ) ; } if ( ! state . m_preserve_state ) { state = BlockValidationState ( ) ; } fInvalidFound = true ; fContinue = false ; break ; } else { UpdateMempoolForReorg ( m_mempool , disconnectpool , false ) ; return false ; } } else { PruneBlockIndexCandidates ( ) ; if ( ! pindexOldTip || m_chain . Tip ( ) -> nChainWork > pindexOldTip -> nChainWork ) { fContinue = false ; break ; } } } } if ( fBlocksDisconnected ) { UpdateMempoolForReorg ( m_mempool , disconnectpool , true ) ; } m_mempool . check ( & CoinsTip ( ) ) ; if ( fInvalidFound ) CheckForkWarningConditionsOnNewFork ( vpindexToConnect . back ( ) ) ; else CheckForkWarningConditions ( ) ; return true ; }
Try to make some progress towards making pindexMostWork the active block.
Try to make some progress towards making pindexMostWork the active block .
// Disconnect active blocks which are no longer in the best chain. // This is likely a fatal error, but keep the mempool consistent, // just in case. Only remove from the mempool in this case. // If we're unable to disconnect a block during normal operation, // then that is a failure of our local system -- we should abort // rather than stay on a less work chain. // Build list of new blocks to connect. // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need // a few blocks along the way. // Connect new blocks. // The block violates a consensus rule. // A system error occurred (disk space, database error, ...). // Make the mempool consistent with the current tip, just in case // any observers try to use it before shutdown. // We're in a better position than we were. Return temporarily to release the lock. // If any blocks were disconnected, disconnectpool may be non empty.  Add // any disconnected transactions back to the mempool. // Callbacks/notifications for a new best chain.