src/validation.cpp
/**
 * Connect a new block to chainActive. pblock is either nullptr or a pointer to a CBlock
 * corresponding to pindexNew, to bypass loading it again from disk.
 *
 * The block is added to connectTrace if connection succeeds.
 */
Connect a new block to chainActive. pblock is either nullptr or a pointer to a CBlock
corresponding to pindexNew, to bypass loading it again from disk.

The block is added to connectTrace if connection succeeds.
Connect a new block to chainActive . pblock is either nullptr or a pointer to a CBlock corresponding to pindexNew to bypass loading it again from disk . The block is added to connectTrace if connection succeeds .
bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool)
{
    assert(pindexNew->pprev == chainActive.Tip());
    int64_t nTime1 = GetTimeMicros();
    std::shared_ptr<const CBlock> pthisBlock;
    if (!pblock) {
        std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
        if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus()))
            return AbortNode(state, "Failed to read block");
        pthisBlock = pblockNew;
    } else {
        pthisBlock = pblock;
    }
    const CBlock& blockConnecting = *pthisBlock;
    std::shared_ptr<std::map<COutPoint, Coin>> removedCoins = std::make_shared<std::map<COutPoint, Coin>>();
    int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
    int64_t nTime3;
    LogPrint(BCLog::BENCH, "  - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
    {
        CCoinsViewCache view(pcoinsTip.get());
        bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams, false, removedCoins);
        GetMainSignals().BlockChecked(blockConnecting, state);
        if (!rv) {
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), FormatStateMessage(state));
        }
        nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
        LogPrint(BCLog::BENCH, "  - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
        bool flushed = view.Flush();
        assert(flushed);
    }
    int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    LogPrint(BCLog::BENCH, "  - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
    if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
        return false;
    int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    LogPrint(BCLog::BENCH, "  - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
    {
        LOCK(cs_main);
        LogPrint(BCLog::HANDLER, "Omni Core handler: block connect begin [height: %d]\n", chainActive.Height());
        mastercore_handler_block_begin(chainActive.Height(), pindexNew);
    }
    mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight);
    disconnectpool.removeForBlock(blockConnecting.vtx);
    chainActive.SetTip(pindexNew);
    UpdateTip(pindexNew, chainparams);
    int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
    LogPrint(BCLog::BENCH, "  - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
    LogPrint(BCLog::BENCH, "- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO, nTimeTotal * MILLI / nBlocksTotal);
    unsigned int nTxIdx = 0;
    unsigned int nNumMetaTxs = 0;
    for (size_t i = 0; i < blockConnecting.vtx.size(); i++) {
        LogPrint(BCLog::HANDLER, "Omni Core handler: new confirmed transaction [height: %d, idx: %u]\n", pindexNew->nHeight, nTxIdx);
        if (mastercore_handler_tx(*blockConnecting.vtx[i], pindexNew->nHeight, nTxIdx++, pindexNew, removedCoins)) ++nNumMetaTxs;
    }
    LogPrint(BCLog::HANDLER, "Omni Core handler: block connect end [new height: %d, found: %u txs]\n", pindexNew->nHeight, nNumMetaTxs);
    mastercore_handler_block_end(pindexNew->nHeight, pindexNew, nNumMetaTxs);
    connectTrace.BlockConnected(pindexNew, std::move(pthisBlock));
    return true;
}
bool CChainState :: ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const std :: shared_ptr < const CBlock > & pblock , ConnectTrace & connectTrace , DisconnectedBlockTransactions & disconnectpool ) { assert ( pindexNew -> pprev == chainActive . Tip ( ) ) ; int64_t nTime1 = GetTimeMicros ( ) ; std :: shared_ptr < const CBlock > pthisBlock ; if ( ! pblock ) { std :: shared_ptr < CBlock > pblockNew = std :: make_shared < CBlock > ( ) ; if ( ! ReadBlockFromDisk ( * pblockNew , pindexNew , chainparams . GetConsensus ( ) ) ) return AbortNode ( state , " " ) ; pthisBlock = pblockNew ; } else { pthisBlock = pblock ; } const CBlock & blockConnecting = * pthisBlock ; std :: shared_ptr < std :: map < COutPoint , Coin > > removedCoins = std :: make_shared < std :: map < COutPoint , Coin > > ( ) ; int64_t nTime2 = GetTimeMicros ( ) ; nTimeReadFromDisk += nTime2 - nTime1 ; int64_t nTime3 ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime2 - nTime1 ) * MILLI , nTimeReadFromDisk * MICRO ) ; { CCoinsViewCache view ( pcoinsTip . get ( ) ) ; bool rv = ConnectBlock ( blockConnecting , state , pindexNew , view , chainparams , false , removedCoins ) ; GetMainSignals ( ) . BlockChecked ( blockConnecting , state ) ; if ( ! rv ) { if ( state . IsInvalid ( ) ) InvalidBlockFound ( pindexNew , state ) ; return error ( " " , __func__ , pindexNew -> GetBlockHash ( ) . ToString ( ) , FormatStateMessage ( state ) ) ; } nTime3 = GetTimeMicros ( ) ; nTimeConnectTotal += nTime3 - nTime2 ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime3 - nTime2 ) * MILLI , nTimeConnectTotal * MICRO , nTimeConnectTotal * MILLI / nBlocksTotal ) ; bool flushed = view . Flush ( ) ; assert ( flushed ) ; } int64_t nTime4 = GetTimeMicros ( ) ; nTimeFlush += nTime4 - nTime3 ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime4 - nTime3 ) * MILLI , nTimeFlush * MICRO , nTimeFlush * MILLI / nBlocksTotal ) ; if ( ! FlushStateToDisk ( chainparams , state , FlushStateMode :: IF_NEEDED ) ) return false ; int64_t nTime5 = GetTimeMicros ( ) ; nTimeChainState += nTime5 - nTime4 ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime5 - nTime4 ) * MILLI , nTimeChainState * MICRO , nTimeChainState * MILLI / nBlocksTotal ) ; { LOCK ( cs_main ) ; LogPrint ( BCLog :: HANDLER , " \n " , chainActive . Height ( ) ) ; mastercore_handler_block_begin ( chainActive . Height ( ) , pindexNew ) ; } mempool . removeForBlock ( blockConnecting . vtx , pindexNew -> nHeight ) ; disconnectpool . removeForBlock ( blockConnecting . vtx ) ; chainActive . SetTip ( pindexNew ) ; UpdateTip ( pindexNew , chainparams ) ; int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect += nTime6 - nTime5 ; nTimeTotal += nTime6 - nTime1 ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime6 - nTime5 ) * MILLI , nTimePostConnect * MICRO , nTimePostConnect * MILLI / nBlocksTotal ) ; LogPrint ( BCLog :: BENCH , " \n " , ( nTime6 - nTime1 ) * MILLI , nTimeTotal * MICRO , nTimeTotal * MILLI / nBlocksTotal ) ; unsigned int nTxIdx = 0 ; unsigned int nNumMetaTxs = 0 ; for ( size_t i = 0 ; i < blockConnecting . vtx . size ( ) ; i ++ ) { LogPrint ( BCLog :: HANDLER , " \n " , pindexNew -> nHeight , nTxIdx ) ; if ( mastercore_handler_tx ( * blockConnecting . vtx [ i ] , pindexNew -> nHeight , nTxIdx ++ , pindexNew , removedCoins ) ) ++ nNumMetaTxs ; } LogPrint ( BCLog :: HANDLER , " \n " , pindexNew -> nHeight , nNumMetaTxs ) ; mastercore_handler_block_end ( pindexNew -> nHeight , pindexNew , nNumMetaTxs ) ; connectTrace . BlockConnected ( pindexNew , std :: move ( pthisBlock ) ) ; return true ; }
Connect a new block to chainActive.
Connect a new block to chainActive .
// Read block from disk. // Map used by Omni to track removals from the UTXO DB for this block. // Apply the block atomically to the chain state. // Write the chain state to disk, if necessary. //! Omni Core: begin block connect notification // Update chainActive & related variables. //! Omni Core: transaction position within the block //! Omni Core: number of meta transactions found //! Omni Core: new confirmed transaction notification //! Omni Core: end of block connect notification