Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */
| 2702 | |
| 2703 | /** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ |
| 2704 | bool static DisconnectTip(CValidationState &state) { |
| 2705 | CBlockIndex *pindexDelete = chainActive.Tip(); |
| 2706 | assert(pindexDelete); |
| 2707 | // Read block from disk. |
| 2708 | CBlock block; |
| 2709 | if (!ReadBlockFromDisk(block, pindexDelete)) |
| 2710 | return AbortNode(state, "Failed to read block"); |
| 2711 | // Apply the block atomically to the chain state. |
| 2712 | int64_t nStart = GetTimeMicros(); |
| 2713 | { |
| 2714 | CCoinsViewCache view(pcoinsTip); |
| 2715 | if (!DisconnectBlock(block, state, pindexDelete, view)) |
| 2716 | return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); |
| 2717 | assert(view.Flush()); |
| 2718 | } |
| 2719 | LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); |
| 2720 | // Write the chain state to disk, if necessary. |
| 2721 | if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) |
| 2722 | return false; |
| 2723 | // Resurrect mempool transactions from the disconnected block. |
| 2724 | std::vector<uint256> vHashUpdate; |
| 2725 | BOOST_FOREACH(const CTransaction &tx, block.vtx) { |
| 2726 | // ignore validation errors in resurrected transactions |
| 2727 | list<CTransaction> removed; |
| 2728 | CValidationState stateDummy; |
| 2729 | if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { |
| 2730 | mempool.removeRecursive(tx, removed); |
| 2731 | } else if (mempool.exists(tx.GetHash())) { |
| 2732 | vHashUpdate.push_back(tx.GetHash()); |
| 2733 | } |
| 2734 | } |
| 2735 | // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have |
| 2736 | // no in-mempool children, which is generally not true when adding |
| 2737 | // previously-confirmed transactions back to the mempool. |
| 2738 | // UpdateTransactionsFromBlock finds descendants of any transactions in this |
| 2739 | // block that were added back and cleans up the mempool state. |
| 2740 | mempool.UpdateTransactionsFromBlock(vHashUpdate); |
| 2741 | |
| 2742 | // Update chainActive and related variables. |
| 2743 | UpdateTip(pindexDelete->pprev); |
| 2744 | // Let wallets know transactions went from 1-confirmed to |
| 2745 | // 0-confirmed or conflicted: |
| 2746 | BOOST_FOREACH(const CTransaction &tx, block.vtx) { |
| 2747 | SyncWithWallets(tx, NULL, false); |
| 2748 | } |
| 2749 | return true; |
| 2750 | } |
| 2751 | |
| 2752 | static int64_t nTimeReadFromDisk = 0; |
| 2753 | static int64_t nTimeConnectTotal = 0; |
no test coverage detected