MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / DisconnectTip

Method DisconnectTip

src/validation.cpp:2943–3006  ·  view source on GitHub ↗

Disconnect m_chain's tip. * After calling, the mempool will be in an inconsistent state, with * transactions from disconnected blocks being added to disconnectpool. You * should make the mempool consistent again by calling MaybeUpdateMempoolForReorg. * with cs_main held. * * If disconnectpool is nullptr, then no disconnected transactions are added to * disconnectpool (note that the

Source from the content-addressed store, hash-verified

2941 * in any case).
2942 */
2943bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool)
2944{
2945 AssertLockHeld(cs_main);
2946 if (m_mempool) AssertLockHeld(m_mempool->cs);
2947
2948 CBlockIndex *pindexDelete = m_chain.Tip();
2949 assert(pindexDelete);
2950 assert(pindexDelete->pprev);
2951 // Read block from disk.
2952 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2953 CBlock& block = *pblock;
2954 if (!m_blockman.ReadBlock(block, *pindexDelete)) {
2955 LogError("DisconnectTip(): Failed to read block\n");
2956 return false;
2957 }
2958 // Apply the block atomically to the chain state.
2959 const auto time_start{SteadyClock::now()};
2960 {
2961 CCoinsViewCache view(&CoinsTip());
2962 assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
2963 if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) {
2964 LogError("DisconnectTip(): DisconnectBlock %s failed\n", pindexDelete->GetBlockHash().ToString());
2965 return false;
2966 }
2967 view.Flush(/*reallocate_cache=*/false); // local CCoinsViewCache goes out of scope
2968 }
2969 LogDebug(BCLog::BENCH, "- Disconnect block: %.2fms\n",
2970 Ticks<MillisecondsDouble>(SteadyClock::now() - time_start));
2971
2972 {
2973 // Prune locks that began at or after the tip should be moved backward so they get a chance to reorg
2974 const int max_height_first{pindexDelete->nHeight - 1};
2975 for (auto& prune_lock : m_blockman.m_prune_locks) {
2976 if (prune_lock.second.height_first <= max_height_first) continue;
2977
2978 prune_lock.second.height_first = max_height_first;
2979 LogDebug(BCLog::PRUNE, "%s prune lock moved back to %d\n", prune_lock.first, max_height_first);
2980 }
2981 }
2982
2983 // Write the chain state to disk, if necessary.
2984 if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
2985 return false;
2986 }
2987
2988 if (disconnectpool && m_mempool) {
2989 // Save transactions to re-add to mempool at end of reorg. If any entries are evicted for
2990 // exceeding memory limits, remove them and their descendants from the mempool.
2991 for (auto&& evicted_tx : disconnectpool->AddTransactionsFromBlock(block.vtx)) {
2992 m_mempool->removeRecursive(*evicted_tx, MemPoolRemovalReason::REORG);
2993 }
2994 }
2995
2996 m_chain.SetTip(*pindexDelete->pprev);
2997 m_chainman.UpdateIBDStatus();
2998
2999 UpdateTip(pindexDelete->pprev);
3000 // Let wallets know transactions went from 1-confirmed to

Callers 2

BOOST_FIXTURE_TEST_CASEFunction · 0.80
BOOST_FIXTURE_TEST_CASEFunction · 0.80

Calls 11

removeRecursiveMethod · 0.80
SetTipMethod · 0.80
UpdateIBDStatusMethod · 0.80
TipMethod · 0.45
ReadBlockMethod · 0.45
GetBestBlockMethod · 0.45
GetBlockHashMethod · 0.45
ToStringMethod · 0.45
FlushMethod · 0.45
BlockDisconnectedMethod · 0.45

Tested by 2

BOOST_FIXTURE_TEST_CASEFunction · 0.64
BOOST_FIXTURE_TEST_CASEFunction · 0.64