src/validation.cpp
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
    // Note that while we're often called here from ProcessNewBlock, this is
    // far from a guarantee. Things in the P2P/RPC will often end up calling
    // us in the middle of ProcessNewBlock - do not assume pblock is set
    // sanely for performance or correctness!

    CBlockIndex *pindexMostWork = nullptr;
    CBlockIndex *pindexNewTip = nullptr;
    do {
        boost::this_thread::interruption_point();

        const CBlockIndex *pindexFork;
        bool fInitialDownload;
        {
            LOCK(cs_main);
            ConnectTrace connectTrace(mempool); // Destructed before cs_main is unlocked

            CBlockIndex *pindexOldTip = chainActive.Tip();
            if (pindexMostWork == nullptr) {
                pindexMostWork = FindMostWorkChain();
            }

            // Whether we have anything to do at all.
            if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip())
                return true;

            bool fInvalidFound = false;
            std::shared_ptr<const CBlock> nullBlockPtr;
            if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
                return false;

            if (fInvalidFound) {
                // Wipe cache, we may need another branch now.
                pindexMostWork = nullptr;
            }

            pindexNewTip = chainActive.Tip();
            pindexFork = chainActive.FindFork(pindexOldTip);
            fInitialDownload = IsInitialBlockDownload();

            for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
                assert(trace.pblock && trace.pindex);
                GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
            }
        }

        // When we reach this point, we switched to a new tip (stored in pindexNewTip).

        // Notifications/callbacks that can run without cs_main

        // Notify external listeners about the new tip.
        GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);

        // Always notify the UI if a new block tip was connected
        if (pindexFork != pindexNewTip) {
            uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
        }
    } while (pindexNewTip != pindexMostWork);
    CheckBlockIndex(chainparams.GetConsensus());

    // Write changes periodically to disk, after relay.
    if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
        return false;
    }

    return true;
}
/**
 * Make the best chain active, in multiple steps. The result is either failure
 * or an activated best chain. pblock is either nullptr or a pointer to a block
 * that is already loaded (to avoid loading it again from disk).
 */
Make the best chain active, in multiple steps. The result is either failure
or an activated best chain. pblock is either nullptr or a pointer to a block
that is already loaded (to avoid loading it again from disk).
Make the best chain active in multiple steps . The result is either failure or an activated best chain . pblock is either nullptr or a pointer to a block that is already loaded ( to avoid loading it again from disk ) .
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
    CBlockIndex *pindexMostWork = nullptr;
    CBlockIndex *pindexNewTip = nullptr;
    do {
        boost::this_thread::interruption_point();
        const CBlockIndex *pindexFork;
        bool fInitialDownload;
        {
            LOCK(cs_main);
            ConnectTrace connectTrace(mempool); 
            CBlockIndex *pindexOldTip = chainActive.Tip();
            if (pindexMostWork == nullptr) {
                pindexMostWork = FindMostWorkChain();
            }
            if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip())
                return true;
            bool fInvalidFound = false;
            std::shared_ptr<const CBlock> nullBlockPtr;
            if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
                return false;
            if (fInvalidFound) {
                pindexMostWork = nullptr;
            }
            pindexNewTip = chainActive.Tip();
            pindexFork = chainActive.FindFork(pindexOldTip);
            fInitialDownload = IsInitialBlockDownload();
            for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
                assert(trace.pblock && trace.pindex);
                GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
            }
        }
        GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
        if (pindexFork != pindexNewTip) {
            uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
        }
    } while (pindexNewTip != pindexMostWork);
    CheckBlockIndex(chainparams.GetConsensus());
    if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
        return false;
    }
    return true;
}
bool ActivateBestChain ( CValidationState & state , const CChainParams & chainparams , std :: shared_ptr < const CBlock > pblock ) { CBlockIndex * pindexMostWork = nullptr ; CBlockIndex * pindexNewTip = nullptr ; do { boost :: this_thread :: interruption_point ( ) ; const CBlockIndex * pindexFork ; bool fInitialDownload ; { LOCK ( cs_main ) ; ConnectTrace connectTrace ( mempool ) ; CBlockIndex * pindexOldTip = chainActive . Tip ( ) ; if ( pindexMostWork == nullptr ) { pindexMostWork = FindMostWorkChain ( ) ; } if ( pindexMostWork == nullptr || pindexMostWork == chainActive . Tip ( ) ) return true ; bool fInvalidFound = false ; std :: shared_ptr < const CBlock > nullBlockPtr ; if ( ! ActivateBestChainStep ( state , chainparams , pindexMostWork , pblock && pblock -> GetHash ( ) == pindexMostWork -> GetBlockHash ( ) ? pblock : nullBlockPtr , fInvalidFound , connectTrace ) ) return false ; if ( fInvalidFound ) { pindexMostWork = nullptr ; } pindexNewTip = chainActive . Tip ( ) ; pindexFork = chainActive . FindFork ( pindexOldTip ) ; fInitialDownload = IsInitialBlockDownload ( ) ; for ( const PerBlockConnectTrace & trace : connectTrace . GetBlocksConnected ( ) ) { assert ( trace . pblock && trace . pindex ) ; GetMainSignals ( ) . BlockConnected ( trace . pblock , trace . pindex , trace . conflictedTxs ) ; } } GetMainSignals ( ) . UpdatedBlockTip ( pindexNewTip , pindexFork , fInitialDownload ) ; if ( pindexFork != pindexNewTip ) { uiInterface . NotifyBlockTip ( fInitialDownload , pindexNewTip ) ; } } while ( pindexNewTip != pindexMostWork ) ; CheckBlockIndex ( chainparams . GetConsensus ( ) ) ; if ( ! FlushStateToDisk ( state , FLUSH_STATE_PERIODIC ) ) { return false ; } return true ; }
Make the best chain active, in multiple steps.
Make the best chain active in multiple steps .
// Note that while we're often called here from ProcessNewBlock, this is // far from a guarantee. Things in the P2P/RPC will often end up calling // us in the middle of ProcessNewBlock - do not assume pblock is set // sanely for performance or correctness! // Destructed before cs_main is unlocked // Whether we have anything to do at all. // Wipe cache, we may need another branch now. // When we reach this point, we switched to a new tip (stored in pindexNewTip). // Notifications/callbacks that can run without cs_main // Notify external listeners about the new tip. // Always notify the UI if a new block tip was connected // Write changes periodically to disk, after relay.