* Connect a new block to m_chain. 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. */
| 2902 | * The block is added to connectTrace if connection succeeds. |
| 2903 | */ |
| 2904 | bool CChainState::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool, bool& fStall) |
| 2905 | { |
| 2906 | AssertLockHeld(cs_main); |
| 2907 | if (m_mempool) AssertLockHeld(m_mempool->cs); |
| 2908 | |
| 2909 | assert(pindexNew->pprev == m_chain.Tip()); |
| 2910 | // Read block from disk. |
| 2911 | int64_t nTime1 = GetTimeMicros(); |
| 2912 | std::shared_ptr<const CBlock> pthisBlock; |
| 2913 | if (!pblock) { |
| 2914 | std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); |
| 2915 | if (!ReadBlockFromDisk(*pblockNew, pindexNew, m_params.GetConsensus())) { |
| 2916 | return AbortNode(state, "Failed to read block"); |
| 2917 | } |
| 2918 | pthisBlock = pblockNew; |
| 2919 | } else { |
| 2920 | pthisBlock = pblock; |
| 2921 | } |
| 2922 | const CBlock& blockConnecting = *pthisBlock; |
| 2923 | |
| 2924 | const auto& fedpegscripts = GetValidFedpegScripts(pindexNew, m_params.GetConsensus(), false /* nextblock_validation */); |
| 2925 | if (!CheckPeginRipeness(blockConnecting, fedpegscripts)) { |
| 2926 | LogPrintf("STALLING further progress in ConnectTip while waiting for parent chain daemon to catch up! Chain will not grow until this is remedied!\n"); |
| 2927 | fStall = true; |
| 2928 | return true; |
| 2929 | } |
| 2930 | |
| 2931 | // Apply the block atomically to the chain state. |
| 2932 | int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; |
| 2933 | int64_t nTime3; |
| 2934 | LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); |
| 2935 | |
| 2936 | // ELEMENTS: |
| 2937 | // For mempool removal with pegin conflicts |
| 2938 | std::set<std::pair<uint256, COutPoint>> setPeginsSpent; |
| 2939 | |
| 2940 | { |
| 2941 | CCoinsViewCache view(&CoinsTip()); |
| 2942 | bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, &setPeginsSpent); |
| 2943 | GetMainSignals().BlockChecked(blockConnecting, state); |
| 2944 | if (!rv) { |
| 2945 | if (state.IsInvalid()) { |
| 2946 | InvalidBlockFound(pindexNew, state); |
| 2947 | } |
| 2948 | return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), state.ToString()); |
| 2949 | } |
| 2950 | nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2; |
| 2951 | assert(nBlocksTotal > 0); |
| 2952 | LogPrint(BCLog::BENCH, " - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal); |
| 2953 | bool flushed = view.Flush(); |
| 2954 | assert(flushed); |
| 2955 | } |
| 2956 | int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; |
| 2957 | LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal); |
| 2958 | // Write the chain state to disk, if necessary. |
| 2959 | if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) { |
| 2960 | return false; |
| 2961 | } |
nothing calls this directly
no test coverage detected