src/validation.cpp
/**
 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
 * corresponding to pindexNew, to bypass loading it again from disk.
 *
 * The block is always added to connectTrace (either after loading from disk or by copying
 * pblock) - if that is not intended, care must be taken to remove the last entry in
 * blocksConnected in case of failure.
 */
Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
corresponding to pindexNew, to bypass loading it again from disk.

The block is always added to connectTrace (either after loading from disk or by copying
pblock) - if that is not intended, care must be taken to remove the last entry in
blocksConnected in case of failure.
Connect a new block to chainActive . pblock is either NULL or a pointer to a CBlock corresponding to pindexNew to bypass loading it again from disk . The block is always added to connectTrace ( either after loading from disk or by copying pblock ) - if that is not intended care must be taken to remove the last entry in blocksConnected in case of failure .
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace)
{
    const int stopatblocknumber = GetArg("-stopatblock", 0);
    if (stopatblocknumber > 0 && pindexNew->nHeight >= stopatblocknumber) {
        return false;
    }
    assert(pindexNew->pprev == chainActive.Tip());
    int64_t nTime1 = GetTimeMicros();
    if (!pblock) {
        std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
        connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew);
        if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus()))
            return AbortNode(state, "Failed to read block");
    } else {
        connectTrace.blocksConnected.emplace_back(pindexNew, pblock);
    }
    const CBlock& blockConnecting = *connectTrace.blocksConnected.back().second;
    int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
    int64_t nTime3;
    LogPrint("bench", "  - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
    {
        CCoinsViewCache view(pcoinsTip);
        bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
        GetMainSignals().BlockChecked(blockConnecting, state);
        if (!rv) {
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
        }
        nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
        LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
        bool flushed = view.Flush();
        assert(flushed);
    }
    int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
    if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
        return false;
    int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
    mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight);
    UpdateTip(pindexNew, chainparams);
    int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
    LogPrint("bench", "  - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
    LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
    return true;
}
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const std :: shared_ptr < const CBlock > & pblock , ConnectTrace & connectTrace ) { const int stopatblocknumber = GetArg ( " " , 0 ) ; if ( stopatblocknumber > 0 && pindexNew -> nHeight >= stopatblocknumber ) { return false ; } assert ( pindexNew -> pprev == chainActive . Tip ( ) ) ; int64_t nTime1 = GetTimeMicros ( ) ; if ( ! pblock ) { std :: shared_ptr < CBlock > pblockNew = std :: make_shared < CBlock > ( ) ; connectTrace . blocksConnected . emplace_back ( pindexNew , pblockNew ) ; if ( ! ReadBlockFromDisk ( * pblockNew , pindexNew , chainparams . GetConsensus ( ) ) ) return AbortNode ( state , " " ) ; } else { connectTrace . blocksConnected . emplace_back ( pindexNew , pblock ) ; } const CBlock & blockConnecting = * connectTrace . blocksConnected . back ( ) . second ; int64_t nTime2 = GetTimeMicros ( ) ; nTimeReadFromDisk += nTime2 - nTime1 ; int64_t nTime3 ; LogPrint ( " " , " \n " , ( nTime2 - nTime1 ) * 0.001 , nTimeReadFromDisk * 0.000001 ) ; { CCoinsViewCache view ( pcoinsTip ) ; bool rv = ConnectBlock ( blockConnecting , state , pindexNew , view , chainparams ) ; GetMainSignals ( ) . BlockChecked ( blockConnecting , state ) ; if ( ! rv ) { if ( state . IsInvalid ( ) ) InvalidBlockFound ( pindexNew , state ) ; return error ( " " , pindexNew -> GetBlockHash ( ) . ToString ( ) ) ; } nTime3 = GetTimeMicros ( ) ; nTimeConnectTotal += nTime3 - nTime2 ; LogPrint ( " " , " \n " , ( nTime3 - nTime2 ) * 0.001 , nTimeConnectTotal * 0.000001 ) ; bool flushed = view . Flush ( ) ; assert ( flushed ) ; } int64_t nTime4 = GetTimeMicros ( ) ; nTimeFlush += nTime4 - nTime3 ; LogPrint ( " " , " \n " , ( nTime4 - nTime3 ) * 0.001 , nTimeFlush * 0.000001 ) ; if ( ! FlushStateToDisk ( state , FLUSH_STATE_IF_NEEDED ) ) return false ; int64_t nTime5 = GetTimeMicros ( ) ; nTimeChainState += nTime5 - nTime4 ; LogPrint ( " " , " \n " , ( nTime5 - nTime4 ) * 0.001 , nTimeChainState * 0.000001 ) ; mempool . removeForBlock ( blockConnecting . vtx , pindexNew -> nHeight ) ; UpdateTip ( pindexNew , chainparams ) ; int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect += nTime6 - nTime5 ; nTimeTotal += nTime6 - nTime1 ; LogPrint ( " " , " \n " , ( nTime6 - nTime5 ) * 0.001 , nTimePostConnect * 0.000001 ) ; LogPrint ( " " , " \n " , ( nTime6 - nTime1 ) * 0.001 , nTimeTotal * 0.000001 ) ; return true ; }
Connect a new block to chainActive.
Connect a new block to chainActive .
// Read block from disk. // Apply the block atomically to the chain state. // Write the chain state to disk, if necessary. // Remove conflicting transactions from the mempool.; // Update chainActive & related variables.