LCOV - code coverage report
Current view: top level - src - validation.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 2786 3097 90.0 %
Date: 2026-06-25 07:23:43 Functions: 186 189 98.4 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 The Bitcoin Core developers
       3             : // Copyright (c) 2014-2025 The Dash Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include <validation.h>
       8             : 
       9             : #include <arith_uint256.h>
      10             : #include <chain.h>
      11             : #include <chainparams.h>
      12             : #include <checkqueue.h>
      13             : #include <consensus/amount.h>
      14             : #include <consensus/consensus.h>
      15             : #include <consensus/merkle.h>
      16             : #include <consensus/tx_check.h>
      17             : #include <consensus/tx_verify.h>
      18             : #include <consensus/validation.h>
      19             : #include <cuckoocache.h>
      20             : #include <flatfile.h>
      21             : #include <hash.h>
      22             : #include <kernel/coinstats.h>
      23             : #include <logging.h>
      24             : #include <logging/timer.h>
      25             : #include <node/blockstorage.h>
      26             : #include <node/interface_ui.h>
      27             : #include <node/utxo_snapshot.h>
      28             : #include <policy/policy.h>
      29             : #include <policy/settings.h>
      30             : #include <pow.h>
      31             : #include <primitives/block.h>
      32             : #include <primitives/transaction.h>
      33             : #include <script/script.h>
      34             : #include <script/sigcache.h>
      35             : #include <shutdown.h>
      36             : 
      37             : #include <timedata.h>
      38             : #include <tinyformat.h>
      39             : #include <txdb.h>
      40             : #include <txmempool.h>
      41             : #include <uint256.h>
      42             : #include <undo.h>
      43             : #include <util/check.h>
      44             : #include <util/hasher.h>
      45             : #include <util/strencodings.h>
      46             : #include <util/trace.h>
      47             : #include <util/translation.h>
      48             : #include <util/system.h>
      49             : #include <validationinterface.h>
      50             : #include <warnings.h>
      51             : 
      52             : #include <chainlock/chainlock.h>
      53             : #include <evo/chainhelper.h>
      54             : #include <evo/deterministicmns.h>
      55             : #include <evo/evodb.h>
      56             : #include <evo/specialtx.h>
      57             : #include <evo/specialtxman.h>
      58             : #include <masternode/payments.h>
      59             : #include <stats/client.h>
      60             : #include <util/std23.h>
      61             : 
      62             : #include <algorithm>
      63             : #include <cassert>
      64             : #include <deque>
      65             : #include <numeric>
      66             : #include <optional>
      67             : #include <ranges>
      68             : #include <string>
      69             : 
      70             : using kernel::CCoinsStats;
      71             : using kernel::CoinStatsHashType;
      72             : using kernel::ComputeUTXOStats;
      73             : 
      74             : using node::BlockManager;
      75             : using node::BlockMap;
      76             : using node::CBlockIndexHeightOnlyComparator;
      77             : using node::CBlockIndexWorkComparator;
      78             : using node::fImporting;
      79             : using node::fPruneMode;
      80             : using node::fReindex;
      81             : using node::ReadBlockFromDisk;
      82             : using node::SnapshotMetadata;
      83             : using node::UndoReadFromDisk;
      84             : using node::UnlinkPrunedFiles;
      85             : 
      86             : #define MICRO 0.000001
      87             : #define MILLI 0.001
      88             : 
      89             : /** Maximum kilobytes for transactions to store for processing during reorg */
      90             : static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE = 20000;
      91             : /** Time to wait between writing blocks/block index to disk. */
      92             : static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1};
      93             : /** Time to wait between flushing chainstate to disk. */
      94             : static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL{24};
      95             : /** Maximum age of our tip for us to be considered current for fee estimation */
      96             : static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE{3};
      97        3308 : const std::vector<std::string> CHECKLEVEL_DOC {
      98        3308 :     "level 0 reads the blocks from disk",
      99        3308 :     "level 1 verifies block validity",
     100        3308 :     "level 2 verifies undo data",
     101        3308 :     "level 3 checks disconnection of tip blocks",
     102        3308 :     "level 4 tries to reconnect the blocks",
     103        3308 :     "each level includes the checks of the previous levels",
     104             : };
     105             : /** The number of blocks to keep below the deepest prune lock.
     106             :  *  There is nothing special about this number. It is higher than what we
     107             :  *  expect to see in regular mainnet reorgs, but not so high that it would
     108             :  *  noticeably interfere with the pruning mechanism.
     109             :  * */
     110             : static constexpr int PRUNE_LOCK_BUFFER{10};
     111             : 
     112             : /**
     113             :  * Mutex to guard access to validation specific variables, such as reading
     114             :  * or changing the chainstate.
     115             :  *
     116             :  * This may also need to be locked when updating the transaction pool, e.g. on
     117             :  * AcceptToMemoryPool. See CTxMemPool::cs comment for details.
     118             :  *
     119             :  * The transaction pool has a separate lock to allow reading from it and the
     120             :  * chainstate at the same time.
     121             :  */
     122        3308 : RecursiveMutex cs_main;
     123             : 
     124             : GlobalMutex g_best_block_mutex;
     125             : std::condition_variable g_best_block_cv;
     126             : uint256 g_best_block;
     127             : bool g_parallel_script_checks{false};
     128             : bool fRequireStandard = true;
     129             : bool fCheckBlockIndex = false;
     130             : bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
     131             : int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
     132             : 
     133             : uint256 hashAssumeValid;
     134        3308 : arith_uint256 nMinimumChainWork;
     135             : 
     136             : // Forward declaration to break dependency over node/transaction.h
     137             : namespace node
     138             : {
     139             : CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
     140             : } // namespace node
     141             : using node::GetTransaction;
     142             : 
     143       11160 : const CBlockIndex* CChainState::FindForkInGlobalIndex(const CBlockLocator& locator) const
     144             : {
     145       11160 :     AssertLockHeld(cs_main);
     146             : 
     147             :     // Find the latest block common to locator and chain - we expect that
     148             :     // locator.vHave is sorted descending by height.
     149       14676 :     for (const uint256& hash : locator.vHave) {
     150       14627 :         const CBlockIndex* pindex{m_blockman.LookupBlockIndex(hash)};
     151       14627 :         if (pindex) {
     152       11731 :             if (m_chain.Contains(pindex)) {
     153       11111 :                 return pindex;
     154             :             }
     155         620 :         }
     156             :     }
     157          49 :     return m_chain.Genesis();
     158       11160 : }
     159             : 
     160             : bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
     161             :                        const CCoinsViewCache& inputs, unsigned int flags, bool cacheSigStore,
     162             :                        bool cacheFullScriptStore, PrecomputedTransactionData& txdata,
     163             :                        std::vector<CScriptCheck>* pvChecks = nullptr)
     164             :                        EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     165             : 
     166       62200 : bool CheckFinalTxAtTip(const CBlockIndex& active_chain_tip, const CTransaction& tx)
     167             : {
     168       62200 :     AssertLockHeld(cs_main);
     169             : 
     170             :     // CheckFinalTxAtTip() uses active_chain_tip.Height()+1 to evaluate
     171             :     // nLockTime because when IsFinalTx() is called within
     172             :     // AcceptBlock(), the height of the block *being*
     173             :     // evaluated is what is used. Thus if we want to know if a
     174             :     // transaction can be part of the *next* block, we need to call
     175             :     // IsFinalTx() with one more than active_chain_tip.Height().
     176       62200 :     const int nBlockHeight = active_chain_tip.nHeight + 1;
     177             : 
     178             :     // BIP113 requires that time-locked transactions have nLockTime set to
     179             :     // less than the median time of the previous block they're contained in.
     180             :     // When the next block is created its previous block will be the current
     181             :     // chain tip, so we use that to calculate the median time passed to
     182             :     // IsFinalTx().
     183       62200 :     const int64_t nBlockTime{active_chain_tip.GetMedianTimePast()};
     184             : 
     185       62200 :     return IsFinalTx(tx, nBlockHeight, nBlockTime);
     186             : }
     187             : 
     188             : namespace {
     189             : /**
     190             :  * A helper which calculates heights of inputs of a given transaction.
     191             :  *
     192             :  * @param[in] tip    The current chain tip. If an input belongs to a mempool
     193             :  *                   transaction, we assume it will be confirmed in the next block.
     194             :  * @param[in] coins  Any CCoinsView that provides access to the relevant coins.
     195             :  * @param[in] tx     The transaction being evaluated.
     196             :  *
     197             :  * @returns A vector of input heights or nullopt, in case of an error.
     198             :  */
     199       47412 : std::optional<std::vector<int>> CalculatePrevHeights(
     200             :     const CBlockIndex& tip,
     201             :     const CCoinsView& coins,
     202             :     const CTransaction& tx)
     203             : {
     204       47412 :     std::vector<int> prev_heights;
     205       47412 :     prev_heights.resize(tx.vin.size());
     206      164193 :     for (size_t i = 0; i < tx.vin.size(); ++i) {
     207      116781 :         const CTxIn& txin = tx.vin[i];
     208      116781 :         Coin coin;
     209      116781 :         if (!coins.GetCoin(txin.prevout, coin)) {
     210           0 :             LogPrintf("ERROR: %s: Missing input %d in transaction \'%s\'\n", __func__, i, tx.GetHash().GetHex());
     211           0 :             return std::nullopt;
     212             :         }
     213      116781 :         if (coin.nHeight == MEMPOOL_HEIGHT) {
     214             :             // Assume all mempool transaction confirm in the next block.
     215       18161 :             prev_heights[i] = tip.nHeight + 1;
     216       18161 :         } else {
     217       98620 :             prev_heights[i] = coin.nHeight;
     218             :         }
     219      116781 :     }
     220       47412 :     return prev_heights;
     221       47412 : }
     222             : } // namespace
     223             : 
     224       47412 : std::optional<LockPoints> CalculateLockPointsAtTip(
     225             :     CBlockIndex* tip,
     226             :     const CCoinsView& coins_view,
     227             :     const CTransaction& tx)
     228             : {
     229       47412 :     assert(tip);
     230             : 
     231       47412 :     auto prev_heights{CalculatePrevHeights(*tip, coins_view, tx)};
     232       47412 :     if (!prev_heights.has_value()) return std::nullopt;
     233             : 
     234       47412 :     CBlockIndex next_tip;
     235       47412 :     next_tip.pprev = tip;
     236             :     // When SequenceLocks() is called within ConnectBlock(), the height
     237             :     // of the block *being* evaluated is what is used.
     238             :     // Thus if we want to know if a transaction can be part of the
     239             :     // *next* block, we need to use one more than active_chainstate.m_chain.Height()
     240       47412 :     next_tip.nHeight = tip->nHeight + 1;
     241      142236 :     const auto [min_height, min_time] = CalculateSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, prev_heights.value(), next_tip);
     242             : 
     243             :     // Also store the hash of the block with the highest height of
     244             :     // all the blocks which have sequence locked prevouts.
     245             :     // This hash needs to still be on the chain
     246             :     // for these LockPoint calculations to be valid
     247             :     // Note: It is impossible to correctly calculate a maxInputBlock
     248             :     // if any of the sequence locked inputs depend on unconfirmed txs,
     249             :     // except in the special case where the relative lock time/height
     250             :     // is 0, which is equivalent to no sequence lock. Since we assume
     251             :     // input height of tip+1 for mempool txs and test the resulting
     252             :     // min_height and min_time from CalculateSequenceLocks against tip+1.
     253       47412 :     int max_input_height{0};
     254      164193 :     for (const int height : prev_heights.value()) {
     255             :         // Can ignore mempool inputs since we'll fail if they had non-zero locks
     256      116781 :         if (height != next_tip.nHeight) {
     257      113184 :             max_input_height = std::max(max_input_height, height);
     258      113184 :         }
     259             :     }
     260             : 
     261             :     // tip->GetAncestor(max_input_height) should never return a nullptr
     262             :     // because max_input_height is always less than the tip height.
     263             :     // It would, however, be a bad bug to continue execution, since a
     264             :     // LockPoints object with the maxInputBlock member set to nullptr
     265             :     // signifies no relative lock time.
     266      142236 :     return LockPoints{min_height, min_time, Assert(tip->GetAncestor(max_input_height))};
     267       47412 : }
     268             : 
     269       49568 : bool CheckSequenceLocksAtTip(CBlockIndex* tip,
     270             :                              const LockPoints& lock_points)
     271             : {
     272       49568 :     assert(tip != nullptr);
     273             : 
     274       49568 :     CBlockIndex index;
     275       49568 :     index.pprev = tip;
     276             :     // CheckSequenceLocksAtTip() uses active_chainstate.m_chain.Height()+1 to evaluate
     277             :     // height based locks because when SequenceLocks() is called within
     278             :     // ConnectBlock(), the height of the block *being*
     279             :     // evaluated is what is used.
     280             :     // Thus if we want to know if a transaction can be part of the
     281             :     // *next* block, we need to use one more than active_chainstate.m_chain.Height()
     282       49568 :     index.nHeight = tip->nHeight + 1;
     283             : 
     284       49568 :     return EvaluateSequenceLocks(index, {lock_points.height, lock_points.time});
     285             : }
     286             : 
     287       28256 : bool GetUTXOCoin(CChainState& active_chainstate, const COutPoint& outpoint, Coin& coin)
     288             : {
     289       28256 :     LOCK(cs_main);
     290       28256 :     if (!active_chainstate.CoinsTip().GetCoin(outpoint, coin))
     291          24 :         return false;
     292       28232 :     if (coin.IsSpent())
     293           0 :         return false;
     294       28232 :     return true;
     295       28256 : }
     296             : 
     297        3758 : int GetUTXOHeight(CChainState& active_chainstate, const COutPoint& outpoint)
     298             : {
     299             :     // -1 means UTXO is yet unknown or already spent
     300        3758 :     Coin coin;
     301        3758 :     return GetUTXOCoin(active_chainstate, outpoint, coin) ? coin.nHeight : -1;
     302        3758 : }
     303             : 
     304        3758 : int GetUTXOConfirmations(CChainState& active_chainstate, const COutPoint& outpoint)
     305             : {
     306             :     // -1 means UTXO is yet unknown or already spent
     307        3758 :     LOCK(cs_main);
     308        3758 :     int nPrevoutHeight = GetUTXOHeight(active_chainstate, outpoint);
     309        3758 :     return (nPrevoutHeight > -1 && active_chainstate.m_chain.Tip()) ? active_chainstate.m_chain.Height() - nPrevoutHeight + 1 : -1;
     310        3758 : }
     311             : 
     312      754127 : static bool ContextualCheckTransaction(const CTransaction& tx, TxValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
     313             : {
     314      754127 :     bool fDIP0001Active_context = DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DIP0001);
     315      754127 :     bool fDIP0003Active_context = DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DIP0003);
     316             : 
     317      754127 :     if (fDIP0003Active_context) {
     318             :         // check version 3 transaction types
     319      420422 :         if (tx.IsSpecialTxVersion()) {
     320      411885 :             if (tx.nType != TRANSACTION_NORMAL &&
     321      411398 :                 tx.nType != TRANSACTION_PROVIDER_REGISTER &&
     322      408037 :                 tx.nType != TRANSACTION_PROVIDER_UPDATE_SERVICE &&
     323      404637 :                 tx.nType != TRANSACTION_PROVIDER_UPDATE_REGISTRAR &&
     324      404506 :                 tx.nType != TRANSACTION_PROVIDER_UPDATE_REVOKE &&
     325      404416 :                 tx.nType != TRANSACTION_COINBASE &&
     326      237798 :                 tx.nType != TRANSACTION_QUORUM_COMMITMENT &&
     327        4234 :                 tx.nType != TRANSACTION_MNHF_SIGNAL &&
     328        3482 :                 tx.nType != TRANSACTION_ASSET_LOCK &&
     329         487 :                 tx.nType != TRANSACTION_ASSET_UNLOCK) {
     330           0 :                 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-type");
     331             :             }
     332      411398 :             if (tx.IsCoinBase() && tx.nType != TRANSACTION_COINBASE)
     333           0 :                 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-cb-type");
     334      420422 :         } else if (tx.nType != TRANSACTION_NORMAL) {
     335           0 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-type");
     336             :         }
     337      420422 :     }
     338             : 
     339             :     // Size limits
     340      754127 :     if (fDIP0001Active_context && ::GetSerializeSize(tx, PROTOCOL_VERSION) > MAX_STANDARD_TX_SIZE)
     341           0 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
     342             : 
     343      754127 :     return true;
     344      754127 : }
     345             : 
     346             : // Returns the script flags which should be checked for a given block
     347             : static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const ChainstateManager& chainman);
     348             : 
     349       42380 : static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age)
     350             :     EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
     351             : {
     352       42380 :     AssertLockHeld(::cs_main);
     353       42380 :     AssertLockHeld(pool.cs);
     354       42380 :     int expired = pool.Expire(GetTime<std::chrono::seconds>() - age);
     355       42380 :     if (expired != 0) {
     356           4 :         LogPrint(BCLog::MEMPOOL, "Expired %i transactions from the memory pool\n", expired);
     357           4 :     }
     358             : 
     359       42380 :     std::vector<COutPoint> vNoSpendsRemaining;
     360       42380 :     pool.TrimToSize(limit, &vNoSpendsRemaining);
     361       42388 :     for (const COutPoint& removed : vNoSpendsRemaining)
     362           8 :         coins_cache.Uncache(removed);
     363       42380 : }
     364             : 
     365       35566 : static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
     366             : {
     367       35566 :     AssertLockHeld(cs_main);
     368       35566 :     if (active_chainstate.IsInitialBlockDownload())
     369          68 :         return false;
     370       35498 :     if (active_chainstate.m_chain.Tip()->GetBlockTime() < count_seconds(GetTime<std::chrono::seconds>() - MAX_FEE_ESTIMATION_TIP_AGE))
     371         248 :         return false;
     372       35250 :     if (active_chainstate.m_chain.Height() < active_chainstate.m_chainman.m_best_header->nHeight - 1) {
     373          17 :         return false;
     374             :     }
     375       35233 :     return true;
     376       35566 : }
     377             : 
     378        6481 : void CChainState::MaybeUpdateMempoolForReorg(
     379             :     DisconnectedBlockTransactions& disconnectpool,
     380             :     bool fAddToMempool)
     381             : {
     382        6481 :     if (!m_mempool) return;
     383             : 
     384        6481 :     AssertLockHeld(cs_main);
     385        6481 :     AssertLockHeld(m_mempool->cs);
     386        6481 :     std::vector<uint256> vHashUpdate;
     387             :     // disconnectpool's insertion_order index sorts the entries from
     388             :     // oldest to newest, but the oldest entry will be the last tx from the
     389             :     // latest mined block that was disconnected.
     390             :     // Iterate disconnectpool in reverse, so that we add transactions
     391             :     // back to the mempool starting with the earliest transaction that had
     392             :     // been previously seen in a block.
     393        6481 :     auto it = disconnectpool.queuedTx.get<insertion_order>().rbegin();
     394       34280 :     while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
     395             :         // ignore validation errors in resurrected transactions
     396       40996 :         if (!fAddToMempool || (*it)->IsCoinBase() ||
     397       13197 :             AcceptToMemoryPool(*this, *it, GetTime(),
     398       13197 :                 /*bypass_limits=*/true, /*test_accept=*/false).m_result_type !=
     399             :                     MempoolAcceptResult::ResultType::VALID) {
     400             :             // If the transaction doesn't make it in to the mempool, remove any
     401             :             // transactions that depend on it (which would now be orphans).
     402       26814 :             m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
     403       27799 :         } else if (m_mempool->exists((*it)->GetHash())) {
     404         985 :             vHashUpdate.push_back((*it)->GetHash());
     405         985 :         }
     406       27799 :         ++it;
     407             :     }
     408        6481 :     disconnectpool.queuedTx.clear();
     409             :     // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have
     410             :     // no in-mempool children, which is generally not true when adding
     411             :     // previously-confirmed transactions back to the mempool.
     412             :     // UpdateTransactionsFromBlock finds descendants of any transactions in
     413             :     // the disconnectpool that were added back and cleans up the mempool state.
     414        6481 :     const uint64_t ancestor_count_limit = gArgs.GetIntArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
     415        6481 :     const uint64_t ancestor_size_limit = gArgs.GetIntArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
     416        6481 :     m_mempool->UpdateTransactionsFromBlock(vHashUpdate, ancestor_size_limit, ancestor_count_limit);
     417             : 
     418             :     // Predicate to use for filtering transactions in removeForReorg.
     419             :     // Checks whether the transaction is still final and, if it spends a coinbase output, mature.
     420             :     // Also updates valid entries' cached LockPoints if needed.
     421             :     // If false, the tx is still valid and its lockpoints are updated.
     422             :     // If true, the tx would be invalid in the next block; remove this entry and all of its descendants.
     423        8671 :     const auto filter_final_and_mature = [this](CTxMemPool::txiter it)
     424             :         EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
     425        2190 :         AssertLockHeld(m_mempool->cs);
     426        2190 :         AssertLockHeld(::cs_main);
     427        2190 :         const CTransaction& tx = it->GetTx();
     428             : 
     429             :         // The transaction must be final.
     430        2190 :         if (!CheckFinalTxAtTip(*Assert(m_chain.Tip()), tx)) return true;
     431             : 
     432        2185 :         const LockPoints& lp = it->GetLockPoints();
     433             :         // CheckSequenceLocksAtTip checks if the transaction will be final in the next block to be
     434             :         // created on top of the new chain.
     435        2185 :         if (TestLockPointValidity(m_chain, lp)) {
     436        2156 :             if (!CheckSequenceLocksAtTip(m_chain.Tip(), lp)) {
     437          10 :                 return true;
     438             :             }
     439        2146 :         } else {
     440          29 :             const CCoinsViewMemPool view_mempool{&CoinsTip(), *m_mempool};
     441          29 :             const std::optional<LockPoints> new_lock_points{CalculateLockPointsAtTip(m_chain.Tip(), view_mempool, tx)};
     442          29 :             if (new_lock_points.has_value() && CheckSequenceLocksAtTip(m_chain.Tip(), *new_lock_points)) {
     443             :                 // Now update the mempool entry lockpoints as well.
     444          46 :                 m_mempool->mapTx.modify(it, [&new_lock_points](CTxMemPoolEntry& e) { e.UpdateLockPoints(*new_lock_points); });
     445          23 :             } else {
     446           6 :                 return true;
     447             :             }
     448          29 :         }
     449             : 
     450             :         // If the transaction spends any coinbase outputs, it must be mature.
     451        2169 :         if (it->GetSpendsCoinbase()) {
     452        1165 :             for (const CTxIn& txin : tx.vin) {
     453         654 :                 auto it2 = m_mempool->mapTx.find(txin.prevout.hash);
     454         654 :                 if (it2 != m_mempool->mapTx.end())
     455           8 :                     continue;
     456         646 :                 const Coin& coin{CoinsTip().AccessCoin(txin.prevout)};
     457         646 :                 assert(!coin.IsSpent());
     458         646 :                 const auto mempool_spend_height{m_chain.Tip()->nHeight + 1};
     459         646 :                 if (coin.IsCoinBase() && mempool_spend_height - coin.nHeight < COINBASE_MATURITY) {
     460          14 :                     return true;
     461             :                 }
     462             :             }
     463         511 :         }
     464             :         // Transaction is still valid and cached LockPoints are updated.
     465        2155 :         return false;
     466        2190 :     };
     467             : 
     468             :     // We also need to remove any now-immature transactions
     469        6481 :     m_mempool->removeForReorg(m_chain, filter_final_and_mature);
     470             :     // Re-limit mempool size, in case we added any transactions
     471        6481 :     LimitMempoolSize(
     472        6481 :         *m_mempool,
     473        6481 :         this->CoinsTip(),
     474        6481 :         gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
     475        6481 :         std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
     476        6481 : }
     477             : 
     478             : /**
     479             : * Checks to avoid mempool polluting consensus critical paths since cached
     480             : * signature and script validity results will be reused if we validate this
     481             : * transaction again during block validation.
     482             : * */
     483       44871 : static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationState& state,
     484             :                 const CCoinsViewCache& view, const CTxMemPool& pool,
     485             :                 unsigned int flags, PrecomputedTransactionData& txdata, CCoinsViewCache& coins_tip)
     486             :                 EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
     487             : {
     488       44871 :     AssertLockHeld(cs_main);
     489       44871 :     AssertLockHeld(pool.cs);
     490             : 
     491       44871 :     assert(!tx.IsCoinBase());
     492      153105 :     for (const CTxIn& txin : tx.vin) {
     493      108234 :         const Coin& coin = view.AccessCoin(txin.prevout);
     494             : 
     495             :         // This coin was checked in PreChecks and MemPoolAccept
     496             :         // has been holding cs_main since then.
     497      108234 :         Assume(!coin.IsSpent());
     498      108234 :         if (coin.IsSpent()) return false;
     499             : 
     500             :         // If the Coin is available, there are 2 possibilities:
     501             :         // it is available in our current ChainstateActive UTXO set,
     502             :         // or it's a UTXO provided by a transaction in our mempool.
     503             :         // Ensure the scriptPubKeys in Coins from CoinsView are correct.
     504      108234 :         const CTransactionRef& txFrom = pool.get(txin.prevout.hash);
     505      108234 :         if (txFrom) {
     506       16120 :             assert(txFrom->GetHash() == txin.prevout.hash);
     507       16120 :             assert(txFrom->vout.size() > txin.prevout.n);
     508       16120 :             assert(txFrom->vout[txin.prevout.n] == coin.out);
     509       16120 :         } else {
     510       92114 :             const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.prevout);
     511       92114 :             assert(!coinFromUTXOSet.IsSpent());
     512       92114 :             assert(coinFromUTXOSet.out == coin.out);
     513             :         }
     514      108234 :     }
     515             : 
     516             :     // Call CheckInputScripts() to cache signature and script validity against current tip consensus rules.
     517       44871 :     return CheckInputScripts(tx, state, view, flags, /* cacheSigStore = */ true, /* cacheFullScriptStore = */ true, txdata);
     518       44871 : }
     519             : 
     520             : namespace {
     521             : 
     522             : class MemPoolAccept
     523             : {
     524             : public:
     525      182190 :     explicit MemPoolAccept(CTxMemPool& mempool, CChainState& active_chainstate) :
     526       60730 :         m_pool(mempool),
     527       60730 :         m_view(&m_dummy),
     528       60730 :         m_viewmempool(&active_chainstate.CoinsTip(), m_pool),
     529       60730 :         m_active_chainstate(active_chainstate),
     530       60730 :         m_chain_helper(active_chainstate.ChainHelper()),
     531       60730 :         m_limit_ancestors(gArgs.GetIntArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT)),
     532       60730 :         m_limit_ancestor_size(gArgs.GetIntArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
     533       60730 :         m_limit_descendants(gArgs.GetIntArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)),
     534      121460 :         m_limit_descendant_size(gArgs.GetIntArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {
     535      121460 :     }
     536             : 
     537             :     // We put the arguments we're handed into a struct, so we can pass them
     538             :     // around easier.
     539             :     struct ATMPArgs {
     540             :         const CChainParams& m_chainparams;
     541             :         const int64_t m_accept_time;
     542             :         const bool m_bypass_limits;
     543             :         /*
     544             :          * Return any outpoints which were not previously present in the coins
     545             :          * cache, but were added as a result of validating the tx for mempool
     546             :          * acceptance. This allows the caller to optionally remove the cache
     547             :          * additions if the associated transaction ends up being rejected by
     548             :          * the mempool.
     549             :          */
     550             :         std::vector<COutPoint>& m_coins_to_uncache;
     551             :         const bool m_test_accept;
     552             :         /** When true, the mempool will not be trimmed when individual transactions are submitted in
     553             :          * Finalize(). Instead, limits should be enforced at the end to ensure the package is not
     554             :          * partially submitted.
     555             :          */
     556             :         const bool m_package_submission;
     557             :         /** When true, use package feerates instead of individual transaction feerates for fee-based
     558             :          * policies such as mempool min fee and min relay fee.
     559             :          */
     560             :         const bool m_package_feerates;
     561             : 
     562             :         /** Parameters for single transaction mempool validation. */
     563       60566 :         static ATMPArgs SingleAccept(const CChainParams& chainparams, int64_t accept_time,
     564             :                                      bool bypass_limits, std::vector<COutPoint>& coins_to_uncache,
     565             :                                      bool test_accept) {
     566      121132 :             return ATMPArgs{/* m_chainparams */ chainparams,
     567       60566 :                             /* m_accept_time */ accept_time,
     568       60566 :                             /* m_bypass_limits */ bypass_limits,
     569       60566 :                             /* m_coins_to_uncache */ coins_to_uncache,
     570       60566 :                             /* m_test_accept */ test_accept,
     571             :                             /* m_package_submission */ false,
     572             :                             /* m_package_feerates */ false,
     573             :             };
     574             :         }
     575             : 
     576             :         /** Parameters for test package mempool validation through testmempoolaccept. */
     577         134 :         static ATMPArgs PackageTestAccept(const CChainParams& chainparams, int64_t accept_time,
     578             :                                           std::vector<COutPoint>& coins_to_uncache) {
     579         268 :             return ATMPArgs{/* m_chainparams */ chainparams,
     580         134 :                             /* m_accept_time */ accept_time,
     581             :                             /* m_bypass_limits */ false,
     582         134 :                             /* m_coins_to_uncache */ coins_to_uncache,
     583             :                             /* m_test_accept */ true,
     584             :                             /* m_package_submission */ false, // not submitting to mempool
     585             :                             /* m_package_feerates */ false,
     586             :             };
     587             :         }
     588             : 
     589             :         /** Parameters for child-with-unconfirmed-parents package validation. */
     590          30 :         static ATMPArgs PackageChildWithParents(const CChainParams& chainparams, int64_t accept_time,
     591             :                                                 std::vector<COutPoint>& coins_to_uncache) {
     592          60 :             return ATMPArgs{/* m_chainparams */ chainparams,
     593          30 :                             /* m_accept_time */ accept_time,
     594             :                             /* m_bypass_limits */ false,
     595          30 :                             /* m_coins_to_uncache */ coins_to_uncache,
     596             :                             /* m_test_accept */ false,
     597             :                             /* m_package_submission */ true,
     598             :                             /* m_package_feerates */ true,
     599             :             };
     600             :         }
     601             : 
     602             :         /** Parameters for a single transaction within a package. */
     603          25 :         static ATMPArgs SingleInPackageAccept(const ATMPArgs& package_args) {
     604          50 :             return ATMPArgs{/* m_chainparams */ package_args.m_chainparams,
     605          25 :                             /* m_accept_time */ package_args.m_accept_time,
     606             :                             /* m_bypass_limits */ false,
     607          25 :                             /* m_coins_to_uncache */ package_args.m_coins_to_uncache,
     608          25 :                             /* m_test_accept */ package_args.m_test_accept,
     609             :                             /* m_package_submission */ false,
     610             :                             /* m_package_feerates */ false, // only 1 transaction
     611             :             };
     612             :         }
     613             : 
     614             :     private:
     615             :         // Private ctor to avoid exposing details to clients and allowing the possibility of
     616             :         // mixing up the order of the arguments. Use static functions above instead.
     617      121510 :         ATMPArgs(const CChainParams& chainparams,
     618             :                  int64_t accept_time,
     619             :                  bool bypass_limits,
     620             :                  std::vector<COutPoint>& coins_to_uncache,
     621             :                  bool test_accept,
     622             :                  bool package_submission,
     623             :                  bool package_feerates)
     624       60755 :             : m_chainparams{chainparams},
     625       60755 :               m_accept_time{accept_time},
     626       60755 :               m_bypass_limits{bypass_limits},
     627       60755 :               m_coins_to_uncache{coins_to_uncache},
     628       60755 :               m_test_accept{test_accept},
     629       60755 :               m_package_submission{package_submission},
     630       60755 :               m_package_feerates{package_feerates}
     631       60755 :         {
     632      121510 :         }
     633             :     };
     634             : 
     635             :     // Single transaction acceptance
     636             :     MempoolAcceptResult AcceptSingleTransaction(const CTransactionRef& ptx, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     637             : 
     638             :     /**
     639             :     * Multiple transaction acceptance. Transactions may or may not be interdependent, but must not
     640             :     * conflict with each other, and the transactions cannot already be in the mempool. Parents must
     641             :     * come before children if any dependencies exist.
     642             :     */
     643             :     PackageMempoolAcceptResult AcceptMultipleTransactions(const std::vector<CTransactionRef>& txns, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     644             : 
     645             :     /**
     646             :      * Package (more specific than just multiple transactions) acceptance. Package must be a child
     647             :      * with all of its unconfirmed parents, and topologically sorted.
     648             :      */
     649             :     PackageMempoolAcceptResult AcceptPackage(const Package& package, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     650             : 
     651             : private:
     652             :     // All the intermediate state that gets passed between the various levels
     653             :     // of checking a given transaction.
     654             :     struct Workspace {
     655      123862 :         explicit Workspace(const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
     656             :         /** All mempool ancestors of this transaction. */
     657             :         CTxMemPool::setEntries m_ancestors;
     658             :         /** Mempool entry constructed for this transaction. Constructed in PreChecks() but not
     659             :          * inserted into the mempool until Finalize(). */
     660             :         std::unique_ptr<CTxMemPoolEntry> m_entry;
     661             : 
     662             :         /** Size of the transaction as used by the mempool, calculated using serialized size
     663             :          * of the transaction and sigops. */
     664             :         int64_t m_vsize;
     665             :         /** Fees paid by this transaction: total input amounts subtracted by total output amounts. */
     666             :         CAmount m_base_fees;
     667             :         /** Base fees + any fee delta set by the user with prioritisetransaction. */
     668             :         CAmount m_modified_fees;
     669             : 
     670             :         const CTransactionRef& m_ptx;
     671             :         /** Txid. */
     672             :         const uint256& m_hash;
     673             :         TxValidationState m_state;
     674             :         /** A temporary cache containing serialized transaction data for signature verification.
     675             :          * Reused across PolicyScriptChecks and ConsensusScriptChecks. */
     676             :         PrecomputedTransactionData m_precomputed_txdata;
     677             :     };
     678             : 
     679             :     // Run the policy checks on a given transaction, excluding any script checks.
     680             :     // Looks up inputs, calculates feerate, considers replacement, evaluates
     681             :     // package limits, etc. As this function can be invoked for "free" by a peer,
     682             :     // only tests that are fast should be done here (to avoid CPU DoS).
     683             :     bool PreChecks(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     684             : 
     685             :     // Enforce package mempool ancestor/descendant limits (distinct from individual
     686             :     // ancestor/descendant limits done in PreChecks).
     687             :     bool PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
     688             :                               PackageValidationState& package_state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     689             : 
     690             :     // Run the script checks using our policy flags. As this can be slow, we should
     691             :     // only invoke this on transactions that have otherwise passed policy checks.
     692             :     bool PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     693             : 
     694             :     // Re-run the script checks, using consensus flags, and try to cache the
     695             :     // result in the scriptcache. This should be done after
     696             :     // PolicyScriptChecks(). This requires that all inputs either be in our
     697             :     // utxo set or in the mempool.
     698             :     bool ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     699             : 
     700             :     // Try to add the transaction to the mempool, removing any conflicts first.
     701             :     // Returns true if the transaction is in the mempool after any size
     702             :     // limiting is performed, false otherwise.
     703             :     bool Finalize(const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     704             : 
     705             :     // Submit all transactions to the mempool and call ConsensusScriptChecks to add to the script
     706             :     // cache - should only be called after successful validation of all transactions in the package.
     707             :     // The package may end up partially-submitted after size limiting; returns true if all
     708             :     // transactions are successfully added to the mempool, false otherwise.
     709             :     bool SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& workspaces, PackageValidationState& package_state,
     710             :                        std::map<const uint256, const MempoolAcceptResult>& results)
     711             :          EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
     712             : 
     713             :     // Compare a package's feerate against minimum allowed.
     714       44782 :     bool CheckFeeRate(size_t package_size, CAmount package_fee, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_pool.cs)
     715             :     {
     716       44782 :         AssertLockHeld(::cs_main);
     717       44782 :         AssertLockHeld(m_pool.cs);
     718       44782 :         CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(package_size);
     719       44782 :         if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
     720          10 :             return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));
     721             :         }
     722             : 
     723       44772 :         if (package_fee < ::minRelayTxFee.GetFee(package_size)) {
     724           0 :             return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met", strprintf("%d < %d", package_fee, ::minRelayTxFee.GetFee(package_size)));
     725             :         }
     726       44772 :         return true;
     727       44782 :     }
     728             : 
     729             : private:
     730             :     CTxMemPool& m_pool;
     731             :     CCoinsViewCache m_view;
     732             :     CCoinsViewMemPool m_viewmempool;
     733             :     CCoinsView m_dummy;
     734             :     CChainState& m_active_chainstate;
     735             :     CChainstateHelper& m_chain_helper;
     736             : 
     737             :     // The package limits in effect at the time of invocation.
     738             :     const size_t m_limit_ancestors;
     739             :     const size_t m_limit_ancestor_size;
     740             :     // These may be modified while evaluating a transaction (eg to account for
     741             :     // in-mempool conflicts; see below).
     742             :     size_t m_limit_descendants;
     743             :     size_t m_limit_descendant_size;
     744             : };
     745             : 
     746       61878 : bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
     747             : {
     748       61878 :     AssertLockHeld(cs_main);
     749       61878 :     AssertLockHeld(m_pool.cs);
     750       61878 :     const CTransactionRef& ptx = ws.m_ptx;
     751       61878 :     const CTransaction& tx = *ws.m_ptx;
     752       61878 :     const uint256& hash = ws.m_hash;
     753             : 
     754             :     // Copy/alias what we need out of args
     755       61878 :     const CChainParams& chainparams = args.m_chainparams;
     756       61878 :     const int64_t nAcceptTime = args.m_accept_time;
     757       61878 :     const bool bypass_limits = args.m_bypass_limits;
     758       61878 :     std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
     759             : 
     760             :     // Alias what we need out of ws
     761       61878 :     TxValidationState& state = ws.m_state;
     762       61878 :     std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
     763             : 
     764       61878 :     if (!CheckTransaction(tx, state)) {
     765          42 :         return false; // state filled in by CheckTransaction
     766             :     }
     767             : 
     768       61836 :     if (!ContextualCheckTransaction(tx, state, chainparams.GetConsensus(), m_active_chainstate.m_chain.Tip()))
     769           0 :         return error("%s: ContextualCheckTransaction: %s, %s", __func__, hash.ToString(), state.ToString());
     770             : 
     771       61836 :     if (tx.IsSpecialTxVersion() && tx.nType == TRANSACTION_QUORUM_COMMITMENT) {
     772             :         // quorum commitment is not allowed outside of blocks
     773        1417 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "qc-not-allowed");
     774             :     }
     775             : 
     776             :     // Coinbase is only valid in a block, not as a loose transaction
     777       60419 :     if (tx.IsCoinBase())
     778           3 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "coinbase");
     779             : 
     780             :     // Rather not work on nonstandard transactions (unless -testnet/-regtest)
     781       60416 :     std::string reason;
     782       60416 :     if (fRequireStandard && !IsStandardTx(tx, reason))
     783         389 :         return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
     784             : 
     785       60027 :     if (fRequireStandard && !IsStandardSpecialTx(tx, reason))
     786           3 :         return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
     787             : 
     788             :     // Do not work on transactions that are too small.
     789             :     // A transaction with 1 empty scriptSig input and 1 P2SH output has size of 83 bytes.
     790             :     // Transactions smaller than this are not relayed to mitigate CVE-2017-12842 by not relaying
     791             :     // 64-byte transactions.
     792       60024 :     if (::GetSerializeSize(tx, PROTOCOL_VERSION) < MIN_STANDARD_TX_SIZE)
     793          19 :         return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "tx-size-small");
     794             : 
     795             :     // Only accept nLockTime-using transactions that can be mined in the next
     796             :     // block; we don't want our mempool filled up with transactions that can't
     797             :     // be mined yet.
     798       60005 :     if (!CheckFinalTxAtTip(*Assert(m_active_chainstate.m_chain.Tip()), tx)) {
     799         255 :         return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final");
     800             :     }
     801             : 
     802             :     // is it already in the memory pool?
     803       59750 :     if (m_pool.exists(hash)) {
     804          53 :         ::g_stats_client->inc("transactions.duplicate", 1.0f);
     805          53 :         return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-in-mempool");
     806             :     }
     807             : 
     808       59697 :     if (auto conflictLockOpt = m_chain_helper.ConflictingISLockIfAny(tx); conflictLockOpt.has_value()) {
     809           4 :         auto& [_, conflict_txid] = conflictLockOpt.value();
     810             : 
     811           2 :         uint256 hashBlock;
     812           6 :         if (auto txConflict = GetTransaction(nullptr, &m_pool, conflict_txid, chainparams.GetConsensus(), hashBlock); txConflict) {
     813           2 :             GetMainSignals().NotifyInstantSendDoubleSpendAttempt(ptx, txConflict);
     814           2 :         }
     815           2 :         LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflict_txid.ToString());
     816           2 :         return state.Invalid(TxValidationResult::TX_CONFLICT_LOCK, "tx-txlock-conflict");
     817             :     }
     818             : 
     819       59695 :     if (m_chain_helper.IsInstantSendWaitingForTx(hash)) {
     820          32 :         m_pool.removeConflicts(tx);
     821          32 :         m_pool.removeProTxConflicts(tx);
     822          32 :     } else {
     823             :         // Check for conflicts with in-memory transactions
     824      198829 :         for (const CTxIn &txin : tx.vin)
     825             :         {
     826      139175 :             const CTransaction* ptxConflicting = m_pool.GetConflictTx(txin.prevout);
     827      139175 :             if (ptxConflicting)
     828             :             {
     829             :                 // Transaction conflicts with mempool and RBF doesn't exist in Dash
     830           9 :                 return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-mempool-conflict");
     831             :             }
     832             :         }
     833             :     }
     834       59686 :     m_view.SetBackend(m_viewmempool);
     835             : 
     836       59686 :     const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip();
     837             :     // do all inputs exist?
     838      176511 :     for (const CTxIn& txin : tx.vin) {
     839      129136 :         if (!coins_cache.HaveCoinInCache(txin.prevout)) {
     840       44762 :             coins_to_uncache.push_back(txin.prevout);
     841       44762 :         }
     842             : 
     843             :         // Note: this call may add txin.prevout to the coins cache
     844             :         // (coins_cache.cacheCoins) by way of FetchCoin(). It should be removed
     845             :         // later (via coins_to_uncache) if this tx turns out to be invalid.
     846      129136 :         if (!m_view.HaveCoin(txin.prevout)) {
     847             :             // Are inputs missing because we already have the tx?
     848      221173 :             for (size_t out = 0; out < tx.vout.size(); out++) {
     849             :                 // Optimistically just do efficient check of cache for outputs
     850      208879 :                 if (coins_cache.HaveCoinInCache(COutPoint(hash, out))) {
     851          17 :                     return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-known");
     852             :                 }
     853      208862 :             }
     854             :             // Otherwise assume this might be an orphan tx for which we just haven't seen parents yet
     855       12294 :             return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent");
     856             :         }
     857             :     }
     858             : 
     859             :     // This is const, but calls into the back end CoinsViews. The CCoinsViewDB at the bottom of the
     860             :     // hierarchy brings the best block into scope. See CCoinsViewDB::GetBestBlock().
     861       47375 :     m_view.GetBestBlock();
     862             : 
     863             :     // we have all inputs cached now, so switch back to dummy (to protect
     864             :     // against bugs where we pull more inputs from disk that miss being added
     865             :     // to coins_to_uncache)
     866       47375 :     m_view.SetBackend(m_dummy);
     867             : 
     868       47375 :     assert(m_active_chainstate.m_blockman.LookupBlockIndex(m_view.GetBestBlock()) == m_active_chainstate.m_chain.Tip());
     869             : 
     870             :     // Only accept BIP68 sequence locked transactions that can be mined in the next
     871             :     // block; we don't want our mempool filled up with transactions that can't
     872             :     // be mined yet.
     873             :     // Pass in m_view which has all of the relevant inputs cached. Note that, since m_view's
     874             :     // backend was removed, it no longer pulls coins from the mempool.
     875       47375 :     const std::optional<LockPoints> lock_points{CalculateLockPointsAtTip(m_active_chainstate.m_chain.Tip(), m_view, tx)};
     876       47375 :     if (!lock_points.has_value() || !CheckSequenceLocksAtTip(m_active_chainstate.m_chain.Tip(), *lock_points)) {
     877        1087 :         return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
     878             :     }
     879             : 
     880             :     // The mempool holds txs for the next block, so pass height+1 to CheckTxInputs
     881       46288 :     if (!Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_chain.Height() + 1, ws.m_base_fees)) {
     882          17 :         return false; // state filled in by CheckTxInputs
     883             :     }
     884             : 
     885       46271 :     if (fRequireStandard && !AreInputsStandard(tx, m_view)) {
     886           0 :         return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
     887             :     }
     888             : 
     889       46271 :     unsigned int nSigOps = GetTransactionSigOpCount(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
     890             : 
     891             :     // ws.m_modified_fees includes any fee deltas from PrioritiseTransaction
     892       46271 :     ws.m_modified_fees = ws.m_base_fees;
     893       46271 :     m_pool.ApplyDelta(hash, ws.m_modified_fees);
     894             : 
     895             :     // Keep track of transactions that spend a coinbase, which we re-scan
     896             :     // during reorgs to ensure COINBASE_MATURITY is still met.
     897       46271 :     bool fSpendsCoinbase = false;
     898      142416 :     for (const CTxIn &txin : tx.vin) {
     899      104407 :         const Coin &coin = m_view.AccessCoin(txin.prevout);
     900      104407 :         if (coin.IsCoinBase()) {
     901        8262 :             fSpendsCoinbase = true;
     902        8262 :             break;
     903             :         }
     904             :     }
     905             : 
     906       46271 :     entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
     907       46271 :             fSpendsCoinbase, nSigOps, lock_points.value()));
     908       46271 :     ws.m_vsize = entry->GetTxSize();
     909             : 
     910       46271 :     if (nSigOps > MAX_STANDARD_TX_SIGOPS)
     911          20 :         return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
     912          10 :                 strprintf("%d", nSigOps));
     913             : 
     914             :     // No individual transactions are allowed below the min relay feerate except from disconnected blocks.
     915             :     // This requirement, unlike CheckFeeRate, cannot be bypassed using m_package_feerates because,
     916             :     // while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant
     917             :     // method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear
     918             :     // due to a replacement.
     919             :     // Checking of fee for MNHF_SIGNAL should be skipped: mnhf does not have
     920             :     // inputs, outputs, or fee
     921       46261 :     if (!tx.IsSpecialTxVersion() || tx.nType != TRANSACTION_MNHF_SIGNAL) {
     922       45917 :         if (!bypass_limits && ws.m_modified_fees < ::minRelayTxFee.GetFee(ws.m_vsize)) {
     923         130 :             return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met",
     924          65 :                                  strprintf("%d < %d", ws.m_modified_fees, ::minRelayTxFee.GetFee(ws.m_vsize)));
     925             :         }
     926             :         // No individual transactions are allowed below the mempool min feerate except from disconnected
     927             :         // blocks and transactions in a package. Package transactions will be checked using package
     928             :         // feerate later.
     929       45852 :         if (!bypass_limits && !args.m_package_feerates && !CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state)) return false;
     930       45843 :     }
     931             : 
     932             :     // Calculate in-mempool ancestors, up to a limit.
     933       46187 :     std::string errString;
     934       46187 :     if (!m_pool.CalculateMemPoolAncestors(*entry, ws.m_ancestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
     935         114 :         ws.m_ancestors.clear();
     936             :         // If CalculateMemPoolAncestors fails second time, we want the original error string.
     937         114 :         std::string dummy_err_string;
     938             :         // If the new transaction is relatively small (up to 40k weight)
     939             :         // and has at most one ancestor (ie ancestor limit of 2, including
     940             :         // the new transaction), allow it if its parent has exactly the
     941             :         // descendant limit descendants.
     942             :         //
     943             :         // This allows protocols which rely on distrusting counterparties
     944             :         // being able to broadcast descendants of an unconfirmed transaction
     945             :         // to be secure by simply only having two immediately-spendable
     946             :         // outputs - one for each counterparty. For more info on the uses for
     947             :         // this, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html
     948         170 :         if (ws.m_vsize > EXTRA_DESCENDANT_TX_SIZE_LIMIT ||
     949          56 :                 !m_pool.CalculateMemPoolAncestors(*entry, ws.m_ancestors, 2, m_limit_ancestor_size, m_limit_descendants + 1, m_limit_descendant_size + EXTRA_DESCENDANT_TX_SIZE_LIMIT, dummy_err_string)) {
     950         111 :             return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too-long-mempool-chain", errString);
     951             :         }
     952         114 :     }
     953             : 
     954             :     // check special TXs after all the other checks. If we'd do this before the other checks, we might end up
     955             :     // DoS scoring a node for non-critical errors, e.g. duplicate keys because a TX is received that was already
     956             :     // mined
     957             :     // NOTE: we use UTXO here and do NOT allow mempool txes as masternode collaterals
     958       46076 :     if (!m_chain_helper.special_tx->CheckSpecialTx(tx, m_active_chainstate.m_chain.Tip(), m_active_chainstate.CoinsTip(), true, state))
     959          15 :         return false;
     960             : 
     961       46061 :     if (m_pool.existsProviderTxConflict(tx)) {
     962           0 :         return state.Invalid(TxValidationResult::TX_CONFLICT, "protx-dup");
     963             :     }
     964             : 
     965       46061 :     return true;
     966       61878 : }
     967             : 
     968         127 : bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
     969             :                                          PackageValidationState& package_state)
     970             : {
     971         127 :     AssertLockHeld(cs_main);
     972         127 :     AssertLockHeld(m_pool.cs);
     973             : 
     974             :     // CheckPackageLimits expects the package transactions to not already be in the mempool.
     975        1302 :     assert(std::all_of(txns.cbegin(), txns.cend(), [this](const auto& tx)
     976             :                        { return !m_pool.exists(tx->GetHash());}));
     977             : 
     978         127 :     std::string err_string;
     979         254 :     if (!m_pool.CheckPackageLimits(txns, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants,
     980         127 :                                    m_limit_descendant_size, err_string)) {
     981             :         // This is a package-wide error, separate from an individual transaction error.
     982          20 :         return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-mempool-limits", err_string);
     983             :     }
     984         107 :    return true;
     985         127 : }
     986             : 
     987       45938 : bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws)
     988             : {
     989       45938 :     AssertLockHeld(cs_main);
     990       45938 :     AssertLockHeld(m_pool.cs);
     991       45938 :     const CTransaction& tx = *ws.m_ptx;
     992       45938 :     TxValidationState& state = ws.m_state;
     993             : 
     994       45938 :     constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
     995             : 
     996             :     // Check input scripts and signatures.
     997             :     // This is done last to help prevent CPU exhaustion denial-of-service attacks.
     998       45938 :     if (!CheckInputScripts(tx, state, m_view, scriptVerifyFlags, true, false, ws.m_precomputed_txdata)) {
     999          22 :         return false; // state filled in by CheckInputScripts
    1000             :     }
    1001             : 
    1002       45916 :     return true;
    1003       45938 : }
    1004             : 
    1005       44871 : bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
    1006             : {
    1007       44871 :     AssertLockHeld(cs_main);
    1008       44871 :     AssertLockHeld(m_pool.cs);
    1009       44871 :     const CTransaction& tx = *ws.m_ptx;
    1010       44871 :     const uint256& hash = ws.m_hash;
    1011       44871 :     TxValidationState& state = ws.m_state;
    1012             : 
    1013             :     // Check again against the current block tip's script verification
    1014             :     // flags to cache our script execution flags. This is, of course,
    1015             :     // useless if the next block has different script flags from the
    1016             :     // previous one, but because the cache tracks script flags for us it
    1017             :     // will auto-invalidate and we'll just have a few blocks of extra
    1018             :     // misses on soft-fork activation.
    1019             :     //
    1020             :     // This is also useful in case of bugs in the standard flags that cause
    1021             :     // transactions to pass as valid when they're actually invalid. For
    1022             :     // instance the STRICTENC flag was incorrectly allowing certain
    1023             :     // CHECKSIG NOT scripts to pass, even though they were invalid.
    1024             :     //
    1025             :     // There is a similar check in CreateNewBlock() to prevent creating
    1026             :     // invalid blocks (using TestBlockValidity), however allowing such
    1027             :     // transactions into the mempool can be exploited as a DoS attack.
    1028       44871 :     unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
    1029       89742 :     if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
    1030       44871 :                                         ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
    1031           0 :         LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString());
    1032           0 :         return Assume(false);
    1033             :     }
    1034             : 
    1035       44871 :     return true;
    1036       44871 : }
    1037             : 
    1038       36890 : bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
    1039             : {
    1040       36890 :     AssertLockHeld(cs_main);
    1041       36890 :     AssertLockHeld(m_pool.cs);
    1042       36890 :     const CTransaction& tx = *ws.m_ptx;
    1043       36890 :     const uint256& hash = ws.m_hash;
    1044       36890 :     TxValidationState& state = ws.m_state;
    1045       36890 :     const bool bypass_limits = args.m_bypass_limits;
    1046             : 
    1047       36890 :     std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
    1048             : 
    1049             :     // This transaction should only count for fee estimation if:
    1050             :     // - it's not being re-added during a reorg which bypasses typical mempool fee limits
    1051             :     // - the node is not behind
    1052             :     // - the transaction is not dependent on any other transactions in the mempool
    1053             :     // - it's not part of a package. Since package relay is not currently supported, this
    1054             :     // transaction has not necessarily been accepted to miners' mempools.
    1055             :     // - the transaction is not a zero fee transaction
    1056       73453 :     bool validForFeeEstimation = (ws.m_modified_fees != 0) &&
    1057       36563 :                                  !bypass_limits && !args.m_package_submission && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
    1058             : 
    1059             :     // Store transaction in memory
    1060       36890 :     m_pool.addUnchecked(*entry, ws.m_ancestors, validForFeeEstimation);
    1061       36890 :     CAmount nValueOut = tx.GetValueOut();
    1062       36890 :     unsigned int nSigOps = GetTransactionSigOpCount(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
    1063             : 
    1064       36890 :     ::g_stats_client->count("transactions.sizeBytes", entry->GetTxSize(), 1.0f);
    1065       36890 :     ::g_stats_client->count("transactions.fees", ws.m_modified_fees, 1.0f);
    1066       36890 :     ::g_stats_client->count("transactions.inputValue", nValueOut - ws.m_modified_fees, 1.0f);
    1067       36890 :     ::g_stats_client->count("transactions.outputValue", nValueOut, 1.0f);
    1068       36890 :     ::g_stats_client->count("transactions.sigOps", nSigOps, 1.0f);
    1069             : 
    1070             :     // Add memory address index
    1071       36890 :     m_pool.addAddressIndex(*entry, m_view);
    1072             : 
    1073             :     // Add memory spent index
    1074       36890 :     m_pool.addSpentIndex(*entry, m_view);
    1075             : 
    1076             :     // trim mempool and check if tx was trimmed
    1077             :     // If we are validating a package, don't trim here because we could evict a previous transaction
    1078             :     // in the package. LimitMempoolSize() should be called at the very end to make sure the mempool
    1079             :     // is still within limits and package submission happens atomically.
    1080       36890 :     if (!args.m_package_submission && !bypass_limits) {
    1081       35893 :         LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
    1082       35893 :         if (!m_pool.exists(hash))
    1083           0 :             return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
    1084       35893 :     }
    1085       36890 :     return true;
    1086       36890 : }
    1087             : 
    1088           6 : bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& workspaces,
    1089             :                                   PackageValidationState& package_state,
    1090             :                                   std::map<const uint256, const MempoolAcceptResult>& results)
    1091             : {
    1092           6 :     AssertLockHeld(cs_main);
    1093           6 :     AssertLockHeld(m_pool.cs);
    1094             :     // Sanity check: none of the transactions should be in the mempool.
    1095          18 :     assert(std::all_of(workspaces.cbegin(), workspaces.cend(), [this](const auto& ws){
    1096             :         return !m_pool.exists(ws.m_ptx->GetHash()); }));
    1097             : 
    1098           6 :     bool all_submitted = true;
    1099             :     // ConsensusScriptChecks adds to the script cache and is therefore consensus-critical;
    1100             :     // CheckInputsFromMempoolAndCache asserts that transactions only spend coins available from the
    1101             :     // mempool or UTXO set. Submit each transaction to the mempool immediately after calling
    1102             :     // ConsensusScriptChecks to make the outputs available for subsequent transactions.
    1103          18 :     for (Workspace& ws : workspaces) {
    1104          12 :         if (!ConsensusScriptChecks(args, ws)) {
    1105           0 :             results.emplace(ws.m_ptx->GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1106             :             // Since PolicyScriptChecks() passed, this should never fail.
    1107           0 :             Assume(false);
    1108           0 :             all_submitted = false;
    1109           0 :             package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR,
    1110           0 :                                   strprintf("BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s",
    1111           0 :                                             ws.m_ptx->GetHash().ToString()));
    1112           0 :         }
    1113             : 
    1114             :         // Re-calculate mempool ancestors to call addUnchecked(). They may have changed since the
    1115             :         // last calculation done in PreChecks, since package ancestors have already been submitted.
    1116          12 :         std::string unused_err_string;
    1117          24 :         if(!m_pool.CalculateMemPoolAncestors(*ws.m_entry, ws.m_ancestors, m_limit_ancestors,
    1118          12 :                                              m_limit_ancestor_size, m_limit_descendants,
    1119          12 :                                              m_limit_descendant_size, unused_err_string)) {
    1120           0 :             results.emplace(ws.m_ptx->GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1121             :             // Since PreChecks() and PackageMempoolChecks() both enforce limits, this should never fail.
    1122           0 :             Assume(false);
    1123           0 :             all_submitted = false;
    1124           0 :             package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR,
    1125           0 :                                   strprintf("BUG! Mempool ancestors or descendants were underestimated: %s",
    1126           0 :                                             ws.m_ptx->GetHash().ToString()));
    1127           0 :         }
    1128             :         // If we call LimitMempoolSize() for each individual Finalize(), the mempool will not take
    1129             :         // the transaction's descendant feerate into account because it hasn't seen them yet. Also,
    1130             :         // we risk evicting a transaction that a subsequent package transaction depends on. Instead,
    1131             :         // allow the mempool to temporarily bypass limits, the maximum package size) while
    1132             :         // submitting transactions individually and then trim at the very end.
    1133          12 :         if (!Finalize(args, ws)) {
    1134           0 :             results.emplace(ws.m_ptx->GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1135             :             // Since LimitMempoolSize() won't be called, this should never fail.
    1136           0 :             Assume(false);
    1137           0 :             all_submitted = false;
    1138           0 :             package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR,
    1139           0 :                                   strprintf("BUG! Adding to mempool failed: %s", ws.m_ptx->GetHash().ToString()));
    1140           0 :         }
    1141          12 :     }
    1142             : 
    1143             :     // It may or may not be the case that all the transactions made it into the mempool. Regardless,
    1144             :     // make sure we haven't exceeded max mempool size.
    1145          12 :     LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(),
    1146           6 :                      gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
    1147           6 :                      std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
    1148             : 
    1149             :     // Find the wtxids of the transactions that made it into the mempool. Allow partial submission,
    1150             :     // but don't report success unless they all made it into the mempool.
    1151          18 :     for (Workspace& ws : workspaces) {
    1152          12 :         if (m_pool.exists(ws.m_ptx->GetHash())) {
    1153          16 :             results.emplace(ws.m_ptx->GetHash(),
    1154           8 :                 MempoolAcceptResult::Success(ws.m_vsize, ws.m_base_fees));
    1155           8 :             GetMainSignals().TransactionAddedToMempool(ws.m_ptx, args.m_accept_time, m_pool.GetAndIncrementSequence());
    1156           8 :         } else {
    1157           4 :             all_submitted = false;
    1158           4 :             ws.m_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
    1159           4 :             package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
    1160           4 :             results.emplace(ws.m_ptx->GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1161             :         }
    1162             :     }
    1163           6 :     return all_submitted;
    1164           0 : }
    1165             : 
    1166       60687 : MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef& ptx, ATMPArgs& args)
    1167             : {
    1168       60687 :     auto start = Now<SteadyMilliseconds>();
    1169       60687 :     AssertLockHeld(cs_main);
    1170       60687 :     LOCK(m_pool.cs); // mempool "read lock" (held through GetMainSignals().TransactionAddedToMempool())
    1171             : 
    1172       60687 :     Workspace ws(ptx);
    1173             : 
    1174       60687 :     if (!PreChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
    1175             : 
    1176             :     // Perform the inexpensive checks first and avoid hashing and signature verification unless
    1177             :     // those checks pass, to mitigate CPU exhaustion denial-of-service attacks.
    1178       44879 :     if (!PolicyScriptChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
    1179             : 
    1180       44859 :     if (!ConsensusScriptChecks(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
    1181             : 
    1182             :     // Tx was accepted, but not added
    1183       44859 :     if (args.m_test_accept) {
    1184        7981 :         return MempoolAcceptResult::Success(ws.m_vsize, ws.m_base_fees);
    1185             :     }
    1186             : 
    1187       36878 :     if (!Finalize(args, ws)) return MempoolAcceptResult::Failure(ws.m_state);
    1188             : 
    1189       36878 :     GetMainSignals().TransactionAddedToMempool(ptx, args.m_accept_time, m_pool.GetAndIncrementSequence());
    1190             : 
    1191       36878 :     const CTransaction& tx = *ptx;
    1192       36878 :     auto finish = Now<SteadyMilliseconds>();
    1193       36878 :     auto diff = finish - start;
    1194       36878 :     ::g_stats_client->timing("AcceptToMemoryPool_ms", count_milliseconds(diff), 1.0f);
    1195       36878 :     ::g_stats_client->inc("transactions.accepted", 1.0f);
    1196       36878 :     ::g_stats_client->count("transactions.inputs", tx.vin.size(), 1.0f);
    1197       36878 :     ::g_stats_client->count("transactions.outputs", tx.vout.size(), 1.0f);
    1198             : 
    1199       36878 :     return MempoolAcceptResult::Success(ws.m_vsize, ws.m_base_fees);
    1200       60687 : }
    1201             : 
    1202         143 : PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::vector<CTransactionRef>& txns, ATMPArgs& args)
    1203             : {
    1204         143 :     AssertLockHeld(cs_main);
    1205             : 
    1206             :     // These context-free package limits can be done before taking the mempool lock.
    1207         143 :     PackageValidationState package_state;
    1208         143 :     if (!CheckPackage(txns, package_state)) return PackageMempoolAcceptResult(package_state, {});
    1209             : 
    1210         137 :     std::vector<Workspace> workspaces{};
    1211         137 :     workspaces.reserve(txns.size());
    1212         137 :     std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
    1213        1244 :                    [](const auto& tx) { return Workspace(tx); });
    1214         137 :     std::map<const uint256, const MempoolAcceptResult> results;
    1215             : 
    1216         137 :     LOCK(m_pool.cs);
    1217             : 
    1218             :     // Do all PreChecks first and fail fast to avoid running expensive script checks when unnecessary.
    1219        1319 :     for (Workspace& ws : workspaces) {
    1220        1191 :         if (!PreChecks(args, ws)) {
    1221           9 :             package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
    1222             :             // Exit early to avoid doing pointless work. Update the failed tx result; the rest are unfinished.
    1223           9 :             results.emplace(ws.m_ptx->GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1224           9 :             return PackageMempoolAcceptResult(package_state, std::move(results));
    1225             :         }
    1226        1182 :         m_viewmempool.PackageAddTransaction(ws.m_ptx);
    1227             :     }
    1228             : 
    1229             :     // Transactions must meet two minimum feerates: the mempool minimum fee and min relay fee.
    1230             :     // For transactions consisting of exactly one child and its parents, it suffices to use the
    1231             :     // package feerate (total modified fees / total size) to check this requirement.
    1232         128 :     const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
    1233        1177 :         [](int64_t sum, auto& ws) { return sum + ws.m_vsize; });
    1234         128 :     const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0},
    1235        1177 :         [](CAmount sum, auto& ws) { return sum + ws.m_modified_fees; });
    1236         128 :     const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize);
    1237         128 :     TxValidationState placeholder_state;
    1238         135 :     if (args.m_package_feerates &&
    1239           7 :         !CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) {
    1240           1 :         package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-fee-too-low");
    1241           1 :         return PackageMempoolAcceptResult(package_state, package_feerate, {});
    1242             :     }
    1243             : 
    1244             :     // Apply package mempool ancestor/descendant limits. Skip if there is only one transaction,
    1245             :     // because it's unnecessary. Also, CPFP carve out can increase the limit for individual
    1246             :     // transactions, but this exemption is not extended to packages in CheckPackageLimits().
    1247         127 :     std::string err_string;
    1248         127 :     if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) {
    1249          20 :         return PackageMempoolAcceptResult(package_state, package_feerate, std::move(results));
    1250             :     }
    1251             : 
    1252        1164 :     for (Workspace& ws : workspaces) {
    1253        1059 :         if (!PolicyScriptChecks(args, ws)) {
    1254             :             // Exit early to avoid doing pointless work. Update the failed tx result; the rest are unfinished.
    1255           2 :             package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
    1256           2 :             results.emplace(ws.m_ptx -> GetHash(), MempoolAcceptResult::Failure(ws.m_state));
    1257           2 :             return PackageMempoolAcceptResult(package_state, package_feerate, std::move(results));
    1258             :         }
    1259        1057 :         if (args.m_test_accept) {
    1260             :             // When test_accept=true, transactions that pass PolicyScriptChecks are valid because there are
    1261             :             // no further mempool checks (passing PolicyScriptChecks implies passing ConsensusScriptChecks).
    1262        1045 :             results.emplace(ws.m_ptx->GetHash(),
    1263        1045 :                             MempoolAcceptResult::Success(ws.m_vsize, ws.m_base_fees));
    1264        1045 :         }
    1265             :     }
    1266             : 
    1267         105 :     if (args.m_test_accept) return PackageMempoolAcceptResult(package_state, package_feerate, std::move(results));
    1268             : 
    1269           6 :     if (!SubmitPackage(args, workspaces, package_state, results)) {
    1270             :         // PackageValidationState filled in by SubmitPackage().
    1271           2 :         return PackageMempoolAcceptResult(package_state, package_feerate, std::move(results));
    1272             :     }
    1273             : 
    1274           4 :     return PackageMempoolAcceptResult(package_state, package_feerate, std::move(results));
    1275         143 : }
    1276             : 
    1277          30 : PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package, ATMPArgs& args)
    1278             : {
    1279          30 :     AssertLockHeld(cs_main);
    1280          30 :     PackageValidationState package_state;
    1281             : 
    1282             :     // Check that the package is well-formed. If it isn't, we won't try to validate any of the
    1283             :     // transactions and thus won't return any MempoolAcceptResults, just a package-wide error.
    1284             : 
    1285             :     // Context-free package checks.
    1286          30 :     if (!CheckPackage(package, package_state)) return PackageMempoolAcceptResult(package_state, {});
    1287             : 
    1288             :     // All transactions in the package must be a parent of the last transaction. This is just an
    1289             :     // opportunity for us to fail fast on a context-free check without taking the mempool lock.
    1290          30 :     if (!IsChildWithParents(package)) {
    1291           4 :         package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-not-child-with-parents");
    1292           4 :         return PackageMempoolAcceptResult(package_state, {});
    1293             :     }
    1294             : 
    1295             :     // IsChildWithParents() guarantees the package is > 1 transactions.
    1296          26 :     assert(package.size() > 1);
    1297             :     // The package must be 1 child with all of its unconfirmed parents. The package is expected to
    1298             :     // be sorted, so the last transaction is the child.
    1299          26 :     const auto& child = package.back();
    1300          26 :     std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
    1301          26 :     std::transform(package.cbegin(), package.cend() - 1,
    1302          26 :                    std::inserter(unconfirmed_parent_txids, unconfirmed_parent_txids.end()),
    1303         126 :                    [](const auto& tx) { return tx->GetHash(); });
    1304             : 
    1305             :     // All child inputs must refer to a preceding package transaction or a confirmed UTXO. The only
    1306             :     // way to verify this is to look up the child's inputs in our current coins view (not including
    1307             :     // mempool), and enforce that all parents not present in the package be available at chain tip.
    1308             :     // Since this check can bring new coins into the coins cache, keep track of these coins and
    1309             :     // uncache them if we don't end up submitting this package to the mempool.
    1310          26 :     const CCoinsViewCache& coins_tip_cache = m_active_chainstate.CoinsTip();
    1311         153 :     for (const auto& input : child->vin) {
    1312         127 :         if (!coins_tip_cache.HaveCoinInCache(input.prevout)) {
    1313         127 :             args.m_coins_to_uncache.push_back(input.prevout);
    1314         127 :         }
    1315             :     }
    1316             :     // Using the MemPoolAccept m_view cache allows us to look up these same coins faster later.
    1317             :     // This should be connecting directly to CoinsTip, not to m_viewmempool, because we specifically
    1318             :     // require inputs to be confirmed if they aren't in the package.
    1319          26 :     m_view.SetBackend(m_active_chainstate.CoinsTip());
    1320         153 :     const auto package_or_confirmed = [this, &unconfirmed_parent_txids](const auto& input) {
    1321         127 :          return unconfirmed_parent_txids.count(input.prevout.hash) > 0 || m_view.HaveCoin(input.prevout);
    1322             :     };
    1323          26 :     if (!std::all_of(child->vin.cbegin(), child->vin.cend(), package_or_confirmed)) {
    1324           1 :         package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-not-child-with-unconfirmed-parents");
    1325           1 :         return PackageMempoolAcceptResult(package_state, {});
    1326             :     }
    1327             :     // Protect against bugs where we pull more inputs from disk that miss being added to
    1328             :     // coins_to_uncache. The backend will be connected again when needed in PreChecks.
    1329          25 :     m_view.SetBackend(m_dummy);
    1330             : 
    1331          25 :     LOCK(m_pool.cs);
    1332          25 :     std::map<const uint256, const MempoolAcceptResult> results;
    1333             :     // Node operators are free to set their mempool policies however they please, nodes may receive
    1334             :     // transactions in different orders, and malicious counterparties may try to take advantage of
    1335             :     // policy differences to pin or delay propagation of transactions. As such, it's possible for
    1336             :     // some package transaction(s) to already be in the mempool, and we don't want to reject the
    1337             :     // entire package in that case (as that could be a censorship vector). De-duplicate the
    1338             :     // transactions that are already in the mempool, and only call AcceptMultipleTransactions() with
    1339             :     // the new transactions. This ensures we don't double-count transaction counts and sizes when
    1340             :     // checking ancestor/descendant limits, or double-count transaction fees for fee-related policy.
    1341          25 :     ATMPArgs single_args = ATMPArgs::SingleInPackageAccept(args);
    1342          25 :     bool quit_early{false};
    1343          25 :     std::vector<CTransactionRef> txns_new;
    1344         175 :     for (const auto& tx : package) {
    1345         150 :         const auto& txid = tx->GetHash();
    1346             :         // There are 2 possibilities: already in mempool or not in mempool. An already confirmed tx
    1347             :         // is treated as one not in mempool, because all we know is that the inputs aren't available.
    1348         150 :         if (m_pool.exists(txid)) {
    1349             :             // Exact transaction already exists in the mempool.
    1350          29 :             auto iter = m_pool.GetIter(txid);
    1351          29 :             assert(iter != std::nullopt);
    1352          29 :             results.emplace(txid, MempoolAcceptResult::MempoolTx(iter.value()->GetTxSize(), iter.value()->GetFee()));
    1353          29 :         } else {
    1354             :             // Transaction does not already exist in the mempool.
    1355             :             // Try submitting the transaction on its own.
    1356         121 :             const auto single_res = AcceptSingleTransaction(tx, single_args);
    1357         121 :             if (single_res.m_result_type == MempoolAcceptResult::ResultType::VALID) {
    1358             :                 // The transaction succeeded on its own and is now in the mempool. Don't include it
    1359             :                 // in package validation, because its fees should only be "used" once.
    1360         104 :                 assert(m_pool.exists(txid));
    1361         104 :                 results.emplace(txid, single_res);
    1362         129 :             } else if (single_res.m_state.GetResult() != TxValidationResult::TX_MEMPOOL_POLICY &&
    1363           8 :                        single_res.m_state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) {
    1364             :                 // Package validation policy only differs from individual policy in its evaluation
    1365             :                 // of feerate. For example, if a transaction fails here due to violation of a
    1366             :                 // consensus rule, the result will not change when it is submitted as part of a
    1367             :                 // package. To minimize the amount of repeated work, unless the transaction fails
    1368             :                 // due to feerate or missing inputs (its parent is a previous transaction in the
    1369             :                 // package that failed due to feerate), don't run package validation. Note that this
    1370             :                 // decision might not make sense if different types of packages are allowed in the
    1371             :                 // future.  Continue individually validating the rest of the transactions, because
    1372             :                 // some of them may still be valid.
    1373           0 :                 quit_early = true;
    1374           0 :             } else {
    1375          17 :                 txns_new.push_back(tx);
    1376             :             }
    1377         121 :         }
    1378             :     }
    1379             : 
    1380             :     // Nothing to do if the entire package has already been submitted.
    1381          25 :     if (quit_early || txns_new.empty()) {
    1382             :         // No package feerate when no package validation was done.
    1383          16 :         return PackageMempoolAcceptResult(package_state, std::move(results));
    1384             :     }
    1385             :     // Validate the (deduplicated) transactions as a package.
    1386           9 :     auto submission_result = AcceptMultipleTransactions(txns_new, args);
    1387             :     // Include already-in-mempool transaction results in the final result.
    1388          12 :     for (const auto& [txid, mempoolaccept_res] : results) {
    1389           6 :         submission_result.m_tx_results.emplace(txid, mempoolaccept_res);
    1390             :     }
    1391           9 :     if (submission_result.m_state.IsValid()) assert(submission_result.m_package_feerate.has_value());
    1392           9 :     return submission_result;
    1393          39 : }
    1394             : 
    1395             : } // anon namespace
    1396             : 
    1397       60566 : MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, const CTransactionRef& tx,
    1398             :                                        int64_t accept_time, bool bypass_limits, bool test_accept)
    1399             :     EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
    1400             : {
    1401       60566 :     const CChainParams& chainparams{active_chainstate.m_params};
    1402       60566 :     assert(active_chainstate.GetMempool() != nullptr);
    1403       60566 :     CTxMemPool& pool{*active_chainstate.GetMempool()};
    1404             : 
    1405       60566 :     std::vector<COutPoint> coins_to_uncache;
    1406       60566 :     auto args = MemPoolAccept::ATMPArgs::SingleAccept(chainparams, accept_time, bypass_limits, coins_to_uncache, test_accept);
    1407       60566 :     MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
    1408       60566 :     if (result.m_result_type != MempoolAcceptResult::ResultType::VALID || test_accept) {
    1409       23792 :         if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
    1410       15811 :             LogPrint(BCLog::MEMPOOL, "%s: %s %s (%s)\n", __func__, tx->GetHash().ToString(), result.m_state.GetRejectReason(), result.m_state.GetDebugMessage());
    1411       15811 :         }
    1412             : 
    1413             :         // Remove coins that were not present in the coins cache before calling;
    1414             :         // AcceptSingleTransaction(); this is to prevent memory DoS in case we receive a large
    1415             :         // number of invalid transactions that attempt to overrun the in-memory coins cache
    1416             :         // (`CCoinsViewCache::cacheCoins`).
    1417             : 
    1418       51648 :         for (const COutPoint& hashTx : coins_to_uncache)
    1419       27856 :             active_chainstate.CoinsTip().Uncache(hashTx);
    1420       23792 :     }
    1421             :     // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
    1422       60566 :     BlockValidationState state_dummy;
    1423       60566 :     active_chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
    1424       60566 :     return result;
    1425       60566 : }
    1426             : 
    1427         164 : PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTxMemPool& pool,
    1428             :                                              const Package& package, bool test_accept)
    1429             : {
    1430         164 :     AssertLockHeld(cs_main);
    1431         164 :     assert(!package.empty());
    1432        1664 :     assert(std::all_of(package.cbegin(), package.cend(), [](const auto& tx){return tx != nullptr;}));
    1433             : 
    1434         164 :     std::vector<COutPoint> coins_to_uncache;
    1435         164 :     const CChainParams& chainparams = active_chainstate.m_params;
    1436         328 :     auto result = [&]() EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
    1437         164 :         AssertLockHeld(cs_main);
    1438         164 :         if (test_accept) {
    1439         134 :             auto args = MemPoolAccept::ATMPArgs::PackageTestAccept(chainparams, GetTime(), coins_to_uncache);
    1440         134 :             return MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args);
    1441             :         } else {
    1442          30 :             auto args = MemPoolAccept::ATMPArgs::PackageChildWithParents(chainparams, GetTime(), coins_to_uncache);
    1443          30 :             return MemPoolAccept(pool, active_chainstate).AcceptPackage(package, args);
    1444             :         }
    1445         164 :     }();
    1446             : 
    1447             :     // Uncache coins pertaining to transactions that were not submitted to the mempool.
    1448         164 :     if (test_accept || result.m_state.IsInvalid()) {
    1449        2062 :         for (const COutPoint& hashTx : coins_to_uncache) {
    1450        1918 :             active_chainstate.CoinsTip().Uncache(hashTx);
    1451             :         }
    1452         144 :     }
    1453             :     // Ensure the coins cache is still within limits.
    1454         164 :     BlockValidationState state_dummy;
    1455         164 :     active_chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
    1456         164 :     return result;
    1457         164 : }
    1458             : 
    1459      570217 : double ConvertBitsToDouble(unsigned int nBits)
    1460             : {
    1461      570217 :     int nShift = (nBits >> 24) & 0xff;
    1462             : 
    1463      570217 :     double dDiff = (double)0x0000ffff / (double)(nBits & 0x00ffffff);
    1464             : 
    1465      570245 :     while (nShift < 29)
    1466             :     {
    1467          28 :         dDiff *= 256.0;
    1468          28 :         nShift++;
    1469             :     }
    1470     2280242 :     while (nShift > 29)
    1471             :     {
    1472     1710025 :         dDiff /= 256.0;
    1473     1710025 :         nShift--;
    1474             :     }
    1475             : 
    1476      570217 :     return dDiff;
    1477             : }
    1478             : 
    1479             : /*
    1480             : NOTE:   unlike bitcoin we are using PREVIOUS block height here,
    1481             :         might be a good idea to change this to use prev bits
    1482             :         but current height to avoid confusion.
    1483             : */
    1484      543645 : static std::pair<CAmount, CAmount> GetBlockSubsidyHelper(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
    1485             : {
    1486             :     double dDiff;
    1487             :     CAmount nSubsidyBase;
    1488             : 
    1489      543645 :     if (nPrevHeight <= 4500 && Params().NetworkIDString() == CBaseChainParams::MAIN) {
    1490             :         /* a bug which caused diff to not be correctly calculated */
    1491         153 :         dDiff = (double)0x0000ffff / (double)(nPrevBits & 0x00ffffff);
    1492         153 :     } else {
    1493      543492 :         dDiff = ConvertBitsToDouble(nPrevBits);
    1494             :     }
    1495             : 
    1496      543645 :     const bool isDevnet = Params().NetworkIDString() == CBaseChainParams::DEVNET;
    1497      543645 :     const bool force_fixed_base_subsidy = fV20Active || (isDevnet && nPrevHeight >= consensusParams.nHighSubsidyBlocks);
    1498      543645 :     if (force_fixed_base_subsidy) {
    1499             :         // Originally, nSubsidyBase calculations relied on difficulty. Once Platform is live,
    1500             :         // it must be able to calculate platformReward. However, we don't want it to constantly
    1501             :         // get blocks difficulty from the payment chain, so we set the nSubsidyBase to a fixed
    1502             :         // value starting from V20 activation. Note, that it doesn't affect mainnet really
    1503             :         // because blocks difficulty there is very high already.
    1504             :         // Devnets get fixed nSubsidyBase starting from nHighSubsidyBlocks to better mimic mainnet.
    1505      248246 :         nSubsidyBase = 5;
    1506      543645 :     } else if (nPrevHeight < 5465) {
    1507             :         // Early ages...
    1508             :         // 1111/((x+1)^2)
    1509      295393 :         nSubsidyBase = (1111.0 / (pow((dDiff+1.0),2.0)));
    1510      295393 :         if(nSubsidyBase > 500) nSubsidyBase = 500;
    1511           2 :         else if(nSubsidyBase < 1) nSubsidyBase = 1;
    1512      295399 :     } else if (nPrevHeight < 17000 || (dDiff <= 75 && nPrevHeight < 24000)) {
    1513             :         // CPU mining era
    1514             :         // 11111/(((x+51)/6)^2)
    1515           2 :         nSubsidyBase = (11111.0 / (pow((dDiff+51.0)/6.0,2.0)));
    1516           2 :         if(nSubsidyBase > 500) nSubsidyBase = 500;
    1517           2 :         else if(nSubsidyBase < 25) nSubsidyBase = 25;
    1518           2 :     } else {
    1519             :         // GPU/ASIC mining era
    1520             :         // 2222222/(((x+2600)/9)^2)
    1521           4 :         nSubsidyBase = (2222222.0 / (pow((dDiff+2600.0)/9.0,2.0)));
    1522           4 :         if(nSubsidyBase > 25) nSubsidyBase = 25;
    1523           4 :         else if(nSubsidyBase < 5) nSubsidyBase = 5;
    1524             :     }
    1525             : 
    1526      543645 :     CAmount nSubsidy = nSubsidyBase * COIN;
    1527             : 
    1528             :     // yearly decline of production by ~7.1% per year, projected ~18M coins max by year 2050+.
    1529     1387510 :     for (int i = consensusParams.nSubsidyHalvingInterval; i <= nPrevHeight; i += consensusParams.nSubsidyHalvingInterval) {
    1530      843865 :         nSubsidy -= nSubsidy/14;
    1531      843865 :     }
    1532             : 
    1533      543645 :     if (nPrevHeight < consensusParams.nHighSubsidyBlocks) {
    1534           0 :         assert(isDevnet);
    1535           0 :         nSubsidy *= consensusParams.nHighSubsidyFactor;
    1536           0 :     }
    1537             : 
    1538      543645 :     CAmount nSuperblockPart{};
    1539             :     // Hard fork to reduce the block reward by 10 extra percent (allowing budget/superblocks)
    1540      543645 :     if (nPrevHeight > consensusParams.nBudgetPaymentsStartBlock) {
    1541             :         // Once v20 is active, the treasury is 20% instead of 10%
    1542       63464 :         nSuperblockPart = nSubsidy / (fV20Active ? 5 : 10);
    1543       63464 :     }
    1544      543645 :     return {nSubsidy - nSuperblockPart, nSuperblockPart};
    1545             : }
    1546             : 
    1547        2040 : CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
    1548             : {
    1549        2040 :     const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active);
    1550        2040 :     return nSuperblock;
    1551             : }
    1552             : 
    1553      541605 : CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
    1554             : {
    1555      541605 :     const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active);
    1556      541605 :     return nSubsidy;
    1557             : }
    1558             : 
    1559      453933 : CAmount GetBlockSubsidy(const CBlockIndex* const pindex, const Consensus::Params& consensusParams)
    1560             : {
    1561      453933 :     if (pindex->pprev == nullptr) return Params().GenesisBlock().vtx[0]->GetValueOut();
    1562      453921 :     const bool isV20Active{DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_V20)};
    1563      453921 :     return GetBlockSubsidyInner(pindex->pprev->nBits, pindex->pprev->nHeight, consensusParams, isV20Active);
    1564      453933 : }
    1565             : 
    1566      507216 : CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fV20Active)
    1567             : {
    1568      507216 :     CAmount ret = blockValue/5; // start at 20%
    1569             : 
    1570      507216 :     const int nMNPIBlock = Params().GetConsensus().nMasternodePaymentsIncreaseBlock;
    1571      507216 :     const int nMNPIPeriod = Params().GetConsensus().nMasternodePaymentsIncreasePeriod;
    1572      507216 :     const int nReallocActivationHeight = Params().GetConsensus().BRRHeight;
    1573             : 
    1574             :                                                                       // mainnet:
    1575      507216 :     if(nHeight > nMNPIBlock)                  ret += blockValue / 20; // 158000 - 25.0% - 2014-10-24
    1576      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 1)) ret += blockValue / 20; // 175280 - 30.0% - 2014-11-25
    1577      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 2)) ret += blockValue / 20; // 192560 - 35.0% - 2014-12-26
    1578      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 3)) ret += blockValue / 40; // 209840 - 37.5% - 2015-01-26
    1579      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 4)) ret += blockValue / 40; // 227120 - 40.0% - 2015-02-27
    1580      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 5)) ret += blockValue / 40; // 244400 - 42.5% - 2015-03-30
    1581      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 6)) ret += blockValue / 40; // 261680 - 45.0% - 2015-05-01
    1582      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 7)) ret += blockValue / 40; // 278960 - 47.5% - 2015-06-01
    1583      507216 :     if(nHeight > nMNPIBlock+(nMNPIPeriod* 9)) ret += blockValue / 40; // 313520 - 50.0% - 2015-08-03
    1584             : 
    1585      507216 :     if (nHeight < nReallocActivationHeight) {
    1586             :         // Block Reward Realocation is not activated yet, nothing to do
    1587        2920 :         return ret;
    1588             :     }
    1589             : 
    1590      504296 :     int nSuperblockCycle = Params().GetConsensus().nSuperblockCycle;
    1591             :     // Actual realocation starts in the cycle next to one activation happens in
    1592      504296 :     int nReallocStart = nReallocActivationHeight - nReallocActivationHeight % nSuperblockCycle + nSuperblockCycle;
    1593             : 
    1594      504296 :     if (nHeight < nReallocStart) {
    1595             :         // Activated but we have to wait for the next cycle to start realocation, nothing to do
    1596       10415 :         return ret;
    1597             :     }
    1598             : 
    1599      493881 :     if (fV20Active) {
    1600             :         // Once MNRewardReallocated activates, block reward is 80% of block subsidy (+ tx fees) since treasury is 20%
    1601             :         // Since the MN reward needs to be equal to 60% of the block subsidy (according to the proposal), MN reward is set to 75% of the block reward.
    1602             :         // Previous reallocation periods are dropped.
    1603      389042 :         return blockValue * 3 / 4;
    1604             :     }
    1605             : 
    1606             :     // Periods used to reallocate the masternode reward from 50% to 60%
    1607      104839 :     static std::vector<int> vecPeriods{
    1608             :         513, // Period 1:  51.3%
    1609             :         526, // Period 2:  52.6%
    1610             :         533, // Period 3:  53.3%
    1611             :         540, // Period 4:  54%
    1612             :         546, // Period 5:  54.6%
    1613             :         552, // Period 6:  55.2%
    1614             :         557, // Period 7:  55.7%
    1615             :         562, // Period 8:  56.2%
    1616             :         567, // Period 9:  56.7%
    1617             :         572, // Period 10: 57.2%
    1618             :         577, // Period 11: 57.7%
    1619             :         582, // Period 12: 58.2%
    1620             :         585, // Period 13: 58.5%
    1621             :         588, // Period 14: 58.8%
    1622             :         591, // Period 15: 59.1%
    1623             :         594, // Period 16: 59.4%
    1624             :         597, // Period 17: 59.7%
    1625             :         599, // Period 18: 59.9%
    1626             :         600  // Period 19: 60%
    1627             :     };
    1628             : 
    1629      104839 :     int nReallocCycle = nSuperblockCycle * 3;
    1630      104839 :     int nCurrentPeriod = std::min<int>((nHeight - nReallocStart) / nReallocCycle, vecPeriods.size() - 1);
    1631             : 
    1632      104839 :     return static_cast<CAmount>(blockValue * vecPeriods[nCurrentPeriod] / 1000);
    1633      507216 : }
    1634             : 
    1635        9190 : CoinsViews::CoinsViews(
    1636             :     fs::path ldb_name,
    1637             :     size_t cache_size_bytes,
    1638             :     bool in_memory,
    1639        3064 :     bool should_wipe) : m_dbview(
    1640        3064 :                             gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
    1641        6128 :                         m_catcherview(&m_dbview) {}
    1642             : 
    1643        3062 : void CoinsViews::InitCache()
    1644             : {
    1645        3062 :     AssertLockHeld(::cs_main);
    1646        3062 :     m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
    1647        3062 : }
    1648             : 
    1649        6154 : CChainState::CChainState(CTxMemPool* mempool,
    1650             :                          BlockManager& blockman,
    1651             :                          ChainstateManager& chainman,
    1652             :                          CEvoDB& evoDb,
    1653             :                          const std::unique_ptr<CChainstateHelper>& chain_helper,
    1654             :                          std::optional<uint256> from_snapshot_blockhash)
    1655             :     : m_mempool(mempool),
    1656             :       m_chain_helper(chain_helper),
    1657             :       m_evoDb(evoDb),
    1658             :       m_blockman(blockman),
    1659             :       m_params(chainman.GetParams()),
    1660             :       m_chainman(chainman),
    1661        3077 :       m_from_snapshot_blockhash(from_snapshot_blockhash) {}
    1662             : 
    1663        3064 : void CChainState::InitCoinsDB(
    1664             :     size_t cache_size_bytes,
    1665             :     bool in_memory,
    1666             :     bool should_wipe,
    1667             :     fs::path leveldb_name)
    1668             : {
    1669        3064 :     if (m_from_snapshot_blockhash) {
    1670          10 :         leveldb_name += "_" + m_from_snapshot_blockhash->ToString();
    1671          10 :     }
    1672             : 
    1673        3064 :     m_coins_views = std::make_unique<CoinsViews>(
    1674             :         leveldb_name, cache_size_bytes, in_memory, should_wipe);
    1675        3064 : }
    1676             : 
    1677        3062 : void CChainState::InitCoinsCache(size_t cache_size_bytes)
    1678             : {
    1679        3062 :     AssertLockHeld(::cs_main);
    1680        3062 :     assert(m_coins_views != nullptr);
    1681        3062 :     m_coinstip_cache_size_bytes = cache_size_bytes;
    1682        3062 :     m_coins_views->InitCache();
    1683        3062 : }
    1684             : 
    1685             : // Note that though this is marked const, we may end up modifying `m_cached_finished_ibd`, which
    1686             : // is a performance-related implementation detail. This function must be marked
    1687             : // `const` so that `CValidationInterface` clients (which are given a `const CChainState*`)
    1688             : // can call it.
    1689             : //
    1690     4801739 : bool CChainState::IsInitialBlockDownload() const
    1691             : {
    1692             :     // Optimization: pre-test latch before taking the lock.
    1693     4801739 :     if (m_cached_finished_ibd.load(std::memory_order_relaxed))
    1694     4650490 :         return false;
    1695             : 
    1696      151249 :     LOCK(cs_main);
    1697      151249 :     if (m_cached_finished_ibd.load(std::memory_order_relaxed))
    1698           0 :         return false;
    1699      151249 :     if (fImporting || fReindex)
    1700       86489 :         return true;
    1701       64760 :     if (m_chain.Tip() == nullptr)
    1702          19 :         return true;
    1703       64741 :     if (m_chain.Tip()->nChainWork < nMinimumChainWork)
    1704        5532 :         return true;
    1705       59209 :     if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
    1706       56352 :         return true;
    1707        2857 :     LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
    1708        2857 :     m_cached_finished_ibd.store(true, std::memory_order_relaxed);
    1709        2857 :     return false;
    1710     4801739 : }
    1711             : 
    1712           4 : static void AlertNotify(const std::string& strMessage)
    1713             : {
    1714           4 :     uiInterface.NotifyAlertChanged();
    1715             : #if HAVE_SYSTEM
    1716           4 :     std::string strCmd = gArgs.GetArg("-alertnotify", "");
    1717           4 :     if (strCmd.empty()) return;
    1718             : 
    1719             :     // Alert text should be plain ascii coming from a trusted source, but to
    1720             :     // be safe we first strip anything not in safeChars, then add single quotes around
    1721             :     // the whole string before passing it to the shell:
    1722           4 :     std::string singleQuote("'");
    1723           4 :     std::string safeStatus = SanitizeString(strMessage);
    1724           4 :     safeStatus = singleQuote+safeStatus+singleQuote;
    1725           4 :     ReplaceAll(strCmd, "%s", safeStatus);
    1726             : 
    1727           4 :     std::thread t(runCommand, strCmd);
    1728           4 :     t.detach(); // thread runs free
    1729             : #endif
    1730           4 : }
    1731             : 
    1732      247064 : void CChainState::CheckForkWarningConditions()
    1733             : {
    1734      247064 :     AssertLockHeld(cs_main);
    1735             : 
    1736             :     // Before we get past initial download, we cannot reliably alert about forks
    1737             :     // (we assume we don't get stuck on a fork before finishing our initial sync)
    1738      247064 :     if (IsInitialBlockDownload()) {
    1739       17180 :         return;
    1740             :     }
    1741             : 
    1742      229884 :     if (m_chainman.m_best_invalid && m_chainman.m_best_invalid->nChainWork > m_chain.Tip()->nChainWork + (GetBlockProof(*m_chain.Tip()) * 6)) {
    1743          32 :         LogPrintf("%s: Warning: Found invalid chain which has higher work (at least ~6 blocks worth of work) than our best chain.\nChain state database corruption likely.\n", __func__);
    1744          32 :         SetfLargeWorkInvalidChainFound(true);
    1745          32 :     } else {
    1746      229852 :         SetfLargeWorkInvalidChainFound(false);
    1747             :     }
    1748      247064 : }
    1749             : 
    1750             : // Called both upon regular invalid block discovery *and* InvalidateBlock
    1751        1592 : void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
    1752             : {
    1753        1592 :     AssertLockHeld(cs_main);
    1754             : 
    1755        1592 :     ::g_stats_client->inc("warnings.InvalidChainFound", 1.0f);
    1756             : 
    1757        1592 :     if (!m_chainman.m_best_invalid || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork) {
    1758         353 :         m_chainman.m_best_invalid = pindexNew;
    1759         353 :     }
    1760        1592 :     if (m_chainman.m_best_header != nullptr && m_chainman.m_best_header->GetAncestor(pindexNew->nHeight) == pindexNew) {
    1761         632 :         m_chainman.m_best_header = m_chain.Tip();
    1762         632 :     }
    1763             : 
    1764        1592 :     LogPrintf("%s: invalid block=%s  height=%d  log2_work=%f  date=%s\n", __func__,
    1765             :       pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
    1766             :       log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
    1767        1592 :     CBlockIndex *tip = m_chain.Tip();
    1768        1592 :     assert (tip);
    1769        1592 :     LogPrintf("%s:  current best=%s  height=%d  log2_work=%f  date=%s\n", __func__,
    1770             :       tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
    1771             :       FormatISO8601DateTime(tip->GetBlockTime()));
    1772        1592 :     CheckForkWarningConditions();
    1773        1592 : }
    1774             : 
    1775          31 : void CChainState::ConflictingChainFound(CBlockIndex* pindexNew)
    1776             : {
    1777          31 :     AssertLockHeld(cs_main);
    1778             : 
    1779          31 :     ::g_stats_client->inc("warnings.ConflictingChainFound", 1.0f);
    1780             : 
    1781          31 :     LogPrintf("%s: conflicting block=%s  height=%d  log2_work=%f  date=%s\n", __func__,
    1782             :       pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
    1783             :       log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
    1784          31 :     CBlockIndex *tip = m_chain.Tip();
    1785          31 :     assert (tip);
    1786          31 :     LogPrintf("%s:  current best=%s  height=%d  log2_work=%f  date=%s\n", __func__,
    1787             :       tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
    1788             :       FormatISO8601DateTime(tip->GetBlockTime()));
    1789          31 :     CheckForkWarningConditions();
    1790          31 : }
    1791             : 
    1792             : // Same as InvalidChainFound, above, except not called directly from InvalidateBlock,
    1793             : // which does its own setBlockIndexCandidates manageent.
    1794         673 : void CChainState::InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state)
    1795             : {
    1796         673 :     AssertLockHeld(cs_main);
    1797             : 
    1798         673 :     ::g_stats_client->inc("warnings.InvalidBlockFound", 1.0f);
    1799         673 :     if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
    1800         673 :         pindex->nStatus |= BLOCK_FAILED_VALID;
    1801         673 :         m_chainman.m_failed_blocks.insert(pindex);
    1802         673 :         m_blockman.m_dirty_blockindex.insert(pindex);
    1803         673 :         setBlockIndexCandidates.erase(pindex);
    1804         673 :         InvalidChainFound(pindex);
    1805         673 :     }
    1806         673 : }
    1807             : 
    1808      742258 : void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
    1809             : {
    1810             :     // mark inputs spent
    1811      742258 :     if (!tx.IsCoinBase()) {
    1812      396764 :         txundo.vprevout.reserve(tx.vin.size());
    1813      627779 :         for (const CTxIn &txin : tx.vin) {
    1814      231015 :             txundo.vprevout.emplace_back();
    1815      231015 :             bool is_spent = inputs.SpendCoin(txin.prevout, &txundo.vprevout.back());
    1816      231015 :             assert(is_spent);
    1817             :         }
    1818      396764 :     }
    1819             :     // add outputs
    1820      742258 :     AddCoins(inputs, tx, nHeight);
    1821      742258 : }
    1822             : 
    1823      354775 : bool CScriptCheck::operator()() {
    1824      354775 :     const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
    1825      354775 :     PrecomputedTransactionData txdata(*ptxTo);
    1826      354775 :     return VerifyScript(scriptSig, m_tx_out.scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, m_tx_out.nValue, txdata, cacheStore), &error);
    1827      354775 : }
    1828             : 
    1829        3308 : static CuckooCache::cache<uint256, SignatureCacheHasher> g_scriptExecutionCache;
    1830        3308 : static CSHA256 g_scriptExecutionCacheHasher;
    1831             : 
    1832        3651 : void InitScriptExecutionCache() {
    1833             :     // Setup the salted hasher
    1834        3651 :     uint256 nonce = GetRandHash();
    1835             :     // We want the nonce to be 64 bytes long to force the hasher to process
    1836             :     // this chunk, which makes later hash computations more efficient. We
    1837             :     // just write our 32-byte entropy twice to fill the 64 bytes.
    1838        3651 :     g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
    1839        3651 :     g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
    1840             :     // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
    1841             :     // setup_bytes creates the minimum possible cache (2 elements).
    1842        3651 :     size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
    1843        3651 :     size_t nElems = g_scriptExecutionCache.setup_bytes(nMaxCacheSize);
    1844        3651 :     LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
    1845             :             (nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
    1846        3651 : }
    1847             : 
    1848             : /**
    1849             :  * Check whether all of this transaction's input scripts succeed.
    1850             :  *
    1851             :  * This involves ECDSA signature checks so can be computationally intensive. This function should
    1852             :  * only be called after the cheap sanity checks in CheckTxInputs passed.
    1853             :  *
    1854             :  * If pvChecks is not nullptr, script checks are pushed onto it instead of being performed inline. Any
    1855             :  * script checks which are not necessary (eg due to script execution cache hits) are, obviously,
    1856             :  * not pushed onto pvChecks/run.
    1857             :  *
    1858             :  * Setting cacheSigStore/cacheFullScriptStore to false will remove elements from the corresponding cache
    1859             :  * which are matched. This is useful for checking blocks where we will likely never need the cache
    1860             :  * entry again.
    1861             :  *
    1862             :  * Note that we may set state.reason to NOT_STANDARD for extra soft-fork flags in flags, block-checking
    1863             :  * callers should probably reset it to CONSENSUS in such cases.
    1864             :  *
    1865             :  * Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp
    1866             :  */
    1867      534785 : bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
    1868             :                        const CCoinsViewCache& inputs, unsigned int flags, bool cacheSigStore,
    1869             :                        bool cacheFullScriptStore, PrecomputedTransactionData& txdata,
    1870             :                        std::vector<CScriptCheck>* pvChecks)
    1871             : {
    1872      534785 :     auto start = Now<SteadyMilliseconds>();
    1873      534785 :     if (tx.IsCoinBase()) return true;
    1874             : 
    1875      534785 :     if (pvChecks) {
    1876      402887 :         pvChecks->reserve(tx.vin.size());
    1877      402887 :     }
    1878             : 
    1879             :     // First check if script executions have been cached with the same
    1880             :     // flags. Note that this assumes that the inputs provided are
    1881             :     // correct (ie that the transaction hash which is in tx's prevouts
    1882             :     // properly commits to the scriptPubKey in the inputs view of that
    1883             :     // transaction).
    1884      534785 :     uint256 hashCacheEntry;
    1885      534785 :     CSHA256 hasher = g_scriptExecutionCacheHasher;
    1886      534785 :     hasher.Write(tx.GetHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin());
    1887      534785 :     AssertLockHeld(cs_main); //TODO: Remove this requirement by making CuckooCache not require external locks
    1888      534785 :     if (g_scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) {
    1889       71943 :         return true;
    1890             :     }
    1891             : 
    1892      462842 :     if (!txdata.m_ready) {
    1893      359684 :         txdata.Init(tx, {});
    1894      359684 :     }
    1895             : 
    1896      792219 :     for (unsigned int i = 0; i < tx.vin.size(); i++) {
    1897      355812 :         const COutPoint &prevout = tx.vin[i].prevout;
    1898      355812 :         const Coin& coin = inputs.AccessCoin(prevout);
    1899      355812 :         assert(!coin.IsSpent());
    1900             : 
    1901             :         // We very carefully only pass in things to CScriptCheck which
    1902             :         // are clearly committed to by tx' witness hash. This provides
    1903             :         // a sanity check that our caching is not introducing consensus
    1904             :         // failures through additional data in, eg, the coins being
    1905             :         // spent being checked as a part of CScriptCheck.
    1906             : 
    1907             :         // Verify signature
    1908      355812 :         CScriptCheck check(coin.out, tx, i, flags, cacheSigStore, &txdata);
    1909      355812 :         if (pvChecks) {
    1910      135267 :             pvChecks->push_back(CScriptCheck());
    1911      135267 :             check.swap(pvChecks->back());
    1912      355812 :         } else if (!check()) {
    1913       26435 :             const bool hasNonMandatoryFlags = (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) != 0;
    1914             : 
    1915       26435 :             if (hasNonMandatoryFlags) {
    1916             :                 // Check whether the failure was caused by a
    1917             :                 // non-mandatory script verification check, such as
    1918             :                 // non-standard DER encodings or non-null dummy
    1919             :                 // arguments; if so, ensure we return NOT_STANDARD
    1920             :                 // instead of CONSENSUS to avoid downstream users
    1921             :                 // splitting the network between upgraded and
    1922             :                 // non-upgraded nodes by banning CONSENSUS-failing
    1923             :                 // data providers.
    1924       52868 :                 CScriptCheck check2(coin.out, tx, i,
    1925       26434 :                         (flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS), cacheSigStore, &txdata);
    1926       26434 :                 if (check2())
    1927       18903 :                     return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
    1928       26434 :             }
    1929             :             // MANDATORY flag failures correspond to
    1930             :             // TxValidationResult::TX_CONSENSUS. Because CONSENSUS
    1931             :             // failures are the most serious case of validation
    1932             :             // failures, we may need to consider using
    1933             :             // RECENT_CONSENSUS_CHANGE for any script failure that
    1934             :             // could be due to non-upgraded nodes which we may want to
    1935             :             // support, to avoid splitting the network (but this
    1936             :             // depends on the details of how net_processing handles
    1937             :             // such errors).
    1938        7532 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
    1939             :         }
    1940      355812 :     }
    1941             : 
    1942      436407 :     if (cacheFullScriptStore && !pvChecks) {
    1943             :         // We executed all of the provided scripts, and were told to
    1944             :         // cache the result. Do so now.
    1945       48317 :         g_scriptExecutionCache.insert(hashCacheEntry);
    1946       48317 :     }
    1947             : 
    1948      436407 :     auto finish = Now<SteadyMilliseconds>();
    1949      436407 :     auto diff = finish - start;
    1950      436407 :     ::g_stats_client->timing("CheckInputScripts_ms", count_milliseconds(diff), 1.0f);
    1951      436407 :     return true;
    1952      534785 : }
    1953             : 
    1954           2 : bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage)
    1955             : {
    1956           2 :     AbortNode(strMessage, userMessage);
    1957           2 :     return state.Error(strMessage);
    1958           0 : }
    1959             : 
    1960             : /**
    1961             :  * Restore the UTXO in a Coin at a given COutPoint
    1962             :  * @param undo The Coin to be restored.
    1963             :  * @param view The coins view to which to apply the changes.
    1964             :  * @param out The out point that corresponds to the tx input.
    1965             :  * @return A DisconnectResult as an int
    1966             :  */
    1967       56435 : int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out)
    1968             : {
    1969       56435 :     bool fClean = true;
    1970             : 
    1971       56435 :     if (view.HaveCoin(out)) fClean = false; // overwriting transaction output
    1972             : 
    1973       56435 :     if (undo.nHeight == 0) {
    1974             :         // Missing undo metadata (height and coinbase). Older versions included this
    1975             :         // information only in undo records for the last spend of a transactions'
    1976             :         // outputs. This implies that it must be present for some other output of the same tx.
    1977           0 :         const Coin& alternate = AccessByTxid(view, out.hash);
    1978           0 :         if (!alternate.IsSpent()) {
    1979           0 :             undo.nHeight = alternate.nHeight;
    1980           0 :             undo.fCoinBase = alternate.fCoinBase;
    1981           0 :         } else {
    1982           0 :             return DISCONNECT_FAILED; // adding output for transaction without known metadata
    1983             :         }
    1984           0 :     }
    1985             :     // If the coin already exists as an unspent coin in the cache, then the
    1986             :     // possible_overwrite parameter to AddCoin must be set to true. We have
    1987             :     // already checked whether an unspent coin exists above using HaveCoin, so
    1988             :     // we don't need to guess. When fClean is false, an unspent coin already
    1989             :     // existed and it is an overwrite.
    1990       56435 :     view.AddCoin(out, std::move(undo), !fClean);
    1991             : 
    1992       56435 :     return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
    1993       56435 : }
    1994             : 
    1995             : /** Undo the effects of this block (with given index) on the UTXO set represented by coins.
    1996             :  *  When FAILED is returned, view is left in an indeterminate state. */
    1997       26568 : DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
    1998             : {
    1999       26568 :     AssertLockHeld(cs_main);
    2000       26568 :     assert(m_chain_helper);
    2001             : 
    2002       26568 :     bool fDIP0003Active = DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
    2003       26568 :     if (fDIP0003Active && !m_evoDb.VerifyBestBlock(pindex->GetBlockHash())) {
    2004             :         // Nodes that upgraded after DIP3 activation will have to reindex to ensure evodb consistency
    2005           2 :         AbortNode("Found EvoDB inconsistency, you must reindex to continue");
    2006           0 :         return DISCONNECT_FAILED;
    2007             :     }
    2008             : 
    2009       26568 :     auto start = Now<SteadyMilliseconds>();
    2010             : 
    2011       26568 :     bool fClean = true;
    2012             : 
    2013       26568 :     CBlockUndo blockUndo;
    2014       26568 :     if (!UndoReadFromDisk(blockUndo, pindex)) {
    2015           2 :         error("DisconnectBlock(): failure reading undo data");
    2016           2 :         return DISCONNECT_FAILED;
    2017             :     }
    2018             : 
    2019       26566 :     if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) {
    2020           0 :         error("DisconnectBlock(): block and undo data inconsistent");
    2021           0 :         return DISCONNECT_FAILED;
    2022             :     }
    2023             : 
    2024       26566 :     std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
    2025       26566 :     if (!m_chain_helper->special_tx->UndoSpecialTxsInBlock(block, pindex, mnlist_updates_opt)) {
    2026           0 :         error("DisconnectBlock(): UndoSpecialTxsInBlock failed");
    2027           0 :         return DISCONNECT_FAILED;
    2028             :     }
    2029             : 
    2030             :     // Ignore blocks that contain transactions which are 'overwritten' by later transactions,
    2031             :     // unless those are already completely spent.
    2032             :     // See https://github.com/bitcoin/bitcoin/issues/22596 for additional information.
    2033             :     // Note: the blocks specified here are different than the ones used in ConnectBlock because DisconnectBlock
    2034             :     // unwinds the blocks in reverse. As a result, the inconsistency is not discovered until the earlier
    2035             :     // blocks with the duplicate coinbase transactions are disconnected.
    2036       53132 :     bool fEnforceBIP30 = !((pindex->nHeight==91722 && pindex->GetBlockHash() == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) ||
    2037       26566 :                            (pindex->nHeight==91812 && pindex->GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f")));
    2038             : 
    2039             :     // undo transactions in reverse order
    2040       92131 :     for (int i = block.vtx.size() - 1; i >= 0; i--) {
    2041       65567 :         const CTransaction &tx = *(block.vtx[i]);
    2042       65567 :         uint256 hash = tx.GetHash();
    2043       65567 :         bool is_coinbase = tx.IsCoinBase();
    2044       65567 :         bool is_bip30_exception = (is_coinbase && !fEnforceBIP30);
    2045             : 
    2046             :         // Check that all outputs are available and match the outputs in the block itself
    2047             :         // exactly.
    2048      158883 :         for (size_t o = 0; o < tx.vout.size(); o++) {
    2049       93318 :             if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
    2050       86336 :                 COutPoint out(hash, o);
    2051       86336 :                 Coin coin;
    2052       86336 :                 bool is_spent = view.SpendCoin(out, &coin);
    2053       86334 :                 if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight || is_coinbase != coin.fCoinBase) {
    2054           0 :                     if (!is_bip30_exception) {
    2055           0 :                         fClean = false; // transaction output mismatch
    2056           0 :                     }
    2057           0 :                 }
    2058       86336 :             }
    2059       93316 :         }
    2060             : 
    2061             :         // restore inputs
    2062       65565 :         if (i > 0) { // not coinbases
    2063       39001 :             CTxUndo &txundo = blockUndo.vtxundo[i-1];
    2064       39001 :             if (txundo.vprevout.size() != tx.vin.size()) {
    2065           0 :                 error("DisconnectBlock(): transaction and undo data inconsistent");
    2066           0 :                 return DISCONNECT_FAILED;
    2067             :             }
    2068       93603 :             for (unsigned int j = tx.vin.size(); j > 0;) {
    2069       54602 :                 --j;
    2070       54602 :                 const COutPoint& out = tx.vin[j].prevout;
    2071       54602 :                 int res = ApplyTxInUndo(std::move(txundo.vprevout[j]), view, out);
    2072       54602 :                 if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED;
    2073       54602 :                 fClean = fClean && res != DISCONNECT_UNCLEAN;
    2074             :             }
    2075             :             // At this point, all of txundo.vprevout should have been moved out.
    2076       39001 :         }
    2077       65565 :     }
    2078             : 
    2079             :     // move best block pointer to prevout block
    2080       26564 :     view.SetBestBlock(pindex->pprev->GetBlockHash());
    2081       26564 :     m_evoDb.WriteBestBlock(pindex->pprev->GetBlockHash());
    2082             : 
    2083       26564 :     if (mnlist_updates_opt.has_value()) {
    2084        8080 :         auto& mnlu = mnlist_updates_opt.value();
    2085        8080 :         GetMainSignals().NotifyMasternodeListChanged(true, mnlu.old_list, mnlu.diff);
    2086        8080 :         uiInterface.NotifyMasternodeListChanged(mnlu.new_list, pindex->pprev);
    2087        8080 :     }
    2088             : 
    2089       26564 :     auto finish = Now<SteadyMilliseconds>();
    2090       26564 :     auto diff = finish - start;
    2091       26564 :     ::g_stats_client->timing("DisconnectBlock_ms", count_milliseconds(diff), 1.0f);
    2092             : 
    2093       26564 :     return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
    2094       26568 : }
    2095             : 
    2096        3308 : static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
    2097             : 
    2098        3199 : void StartScriptCheckWorkerThreads(int threads_num)
    2099             : {
    2100        3199 :     scriptcheckqueue.StartWorkerThreads(threads_num);
    2101        3199 : }
    2102             : 
    2103        3214 : void StopScriptCheckWorkerThreads()
    2104             : {
    2105        3214 :     scriptcheckqueue.StopWorkerThreads();
    2106        3214 : }
    2107             : 
    2108             : /**
    2109             :  * Threshold condition checker that triggers when unknown versionbits are seen on the network.
    2110             :  */
    2111             : class WarningBitsConditionChecker : public AbstractThresholdConditionChecker
    2112             : {
    2113             : private:
    2114             :     const ChainstateManager& m_chainman;
    2115             :     int m_bit;
    2116             : 
    2117             : public:
    2118    14446640 :     explicit WarningBitsConditionChecker(const ChainstateManager& chainman, int bit) : m_chainman{chainman}, m_bit(bit) {}
    2119             : 
    2120     7223320 :     int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
    2121     7223320 :     int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
    2122     7223320 :     int SignalHeight(const CBlockIndex* const pindex, const Consensus::Params& params) const override { return 0; }
    2123     7223320 :     int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
    2124       22529 :     int Threshold(const Consensus::Params& params, int nAttempt) const override { return params.nRuleChangeActivationThreshold; }
    2125             : 
    2126      834429 :     bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
    2127             :     {
    2128     1668858 :         return pindex->nHeight >= params.MinBIP9WarningHeight &&
    2129      834429 :                ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
    2130      772369 :                ((pindex->nVersion >> m_bit) & 1) != 0 &&
    2131       26491 :                ((m_chainman.m_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> m_bit) & 1) == 0;
    2132             :     }
    2133             : };
    2134             : 
    2135      386142 : static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const ChainstateManager& chainman)
    2136             : {
    2137      386142 :     unsigned int flags = SCRIPT_VERIFY_NONE;
    2138             : 
    2139             :     // Start enforcing P2SH (BIP16)
    2140             :     // It always active on Dash chains
    2141      386142 :     flags |= SCRIPT_VERIFY_P2SH;
    2142             : 
    2143             :     // Enforce the DERSIG (BIP66) rule
    2144      386142 :     if (DeploymentActiveAt(*pindex, chainman.GetConsensus(), Consensus::DEPLOYMENT_DERSIG)) {
    2145      385185 :         flags |= SCRIPT_VERIFY_DERSIG;
    2146      385185 :     }
    2147             : 
    2148             :     // Enforce CHECKLOCKTIMEVERIFY (BIP65)
    2149      386142 :     if (DeploymentActiveAt(*pindex, chainman.GetConsensus(), Consensus::DEPLOYMENT_CLTV)) {
    2150      385556 :         flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
    2151      385556 :     }
    2152             : 
    2153             :     // Enforce CHECKSEQUENCEVERIFY (BIP112)
    2154      386142 :     if (DeploymentActiveAt(*pindex, chainman.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
    2155      382155 :         flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
    2156      382155 :     }
    2157             : 
    2158             :     // Enforce BIP147 NULLDUMMY
    2159      386142 :     if (DeploymentActiveAt(*pindex, chainman.GetConsensus(), Consensus::DEPLOYMENT_BIP147)) {
    2160      385564 :         flags |= SCRIPT_VERIFY_NULLDUMMY;
    2161      385564 :     }
    2162             : 
    2163      386142 :     return flags;
    2164             : }
    2165             : 
    2166             : 
    2167             : 
    2168             : static int64_t nTimeCheck = 0;
    2169             : static int64_t nTimeForks = 0;
    2170             : static int64_t nTimeVerify = 0;
    2171             : static int64_t nTimeUndo = 0;
    2172             : static int64_t nTimeISFilter = 0;
    2173             : static int64_t nTimeSubsidy = 0;
    2174             : static int64_t nTimeValueValid = 0;
    2175             : static int64_t nTimePayeeValid = 0;
    2176             : static int64_t nTimeProcessSpecial = 0;
    2177             : static int64_t nTimeDashSpecific = 0;
    2178             : static int64_t nTimeConnect = 0;
    2179             : static int64_t nTimeIndexWrite = 0;
    2180             : static int64_t nTimeTotal = 0;
    2181             : static int64_t nBlocksTotal = 0;
    2182             : 
    2183             : /** Apply the effects of this block (with given index) on the UTXO set represented by coins.
    2184             :  *  Validity checks that depend on the UTXO set are also done; ConnectBlock()
    2185             :  *  can fail if those validity checks fail (among other reasons). */
    2186      342348 : bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
    2187             :                                CCoinsViewCache& view, bool fJustCheck)
    2188             : {
    2189      342348 :     int64_t nTimeStart = GetTimeMicros();
    2190             : 
    2191      342348 :     AssertLockHeld(cs_main);
    2192      342348 :     assert(pindex);
    2193             : 
    2194      342348 :     uint256 block_hash{block.GetHash()};
    2195      342348 :     assert(*pindex->phashBlock == block_hash);
    2196             : 
    2197      342348 :     assert(m_chain_helper);
    2198             : 
    2199             :     // Check it again in case a previous version let a bad block in
    2200             :     // NOTE: We don't currently (re-)invoke ContextualCheckBlock() or
    2201             :     // ContextualCheckBlockHeader() here. This means that if we add a new
    2202             :     // consensus rule that is enforced in one of those two functions, then we
    2203             :     // may have let in a block that violates the rule prior to updating the
    2204             :     // software, and we would NOT be enforcing the rule here. Fully solving
    2205             :     // upgrade from one software version to the next after a consensus rule
    2206             :     // change is potentially tricky and issue-specific (see NeedsRedownload()
    2207             :     // for one approach that was used for BIP 141 deployment).
    2208             :     // Also, currently the rule against blocks more than 2 hours in the future
    2209             :     // is enforced in ContextualCheckBlockHeader(); we wouldn't want to
    2210             :     // re-enforce that rule here (at least until we make it impossible for
    2211             :     // GetAdjustedTime() to go backward).
    2212      342348 :     if (!CheckBlock(block, state, m_params.GetConsensus(), !fJustCheck, !fJustCheck)) {
    2213           0 :         if (state.GetResult() == BlockValidationResult::BLOCK_MUTATED) {
    2214             :             // We don't write down blocks to disk if they may have been
    2215             :             // corrupted, so this should be impossible unless we're having hardware
    2216             :             // problems.
    2217           0 :             return AbortNode(state, "Corrupt block found indicating potential hardware failure; shutting down");
    2218             :         }
    2219           0 :         return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
    2220             :     }
    2221             : 
    2222      342348 :     if (pindex->pprev && pindex->phashBlock && m_chain_helper->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
    2223           0 :         LogPrintf("ERROR: %s: conflicting with chainlock\n", __func__);
    2224           0 :         return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock");
    2225             :     }
    2226             : 
    2227             :     // verify that the view's current state corresponds to the previous block
    2228      342348 :     uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash();
    2229      342348 :     assert(hashPrevBlock == view.GetBestBlock());
    2230             : 
    2231      342348 :     if (pindex->pprev) {
    2232      341274 :         bool fDIP0003Active = DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
    2233      341274 :         if (fDIP0003Active && !m_evoDb.VerifyBestBlock(pindex->pprev->GetBlockHash())) {
    2234             :             // Nodes that upgraded after DIP3 activation will have to reindex to ensure evodb consistency
    2235           0 :             return AbortNode(state, "Found EvoDB inconsistency, you must reindex to continue");
    2236             :         }
    2237      341274 :     }
    2238      342348 :     nBlocksTotal++;
    2239             : 
    2240             :     // Special case for the genesis block, skipping connection of its transactions
    2241             :     // (its coinbase is unspendable)
    2242      342348 :     if (block_hash == m_params.GetConsensus().hashGenesisBlock) {
    2243        1074 :         if (!fJustCheck)
    2244        1074 :             view.SetBestBlock(pindex->GetBlockHash());
    2245        1074 :         return true;
    2246             :     }
    2247             : 
    2248      341274 :     bool fScriptChecks = true;
    2249      341274 :     if (!hashAssumeValid.IsNull()) {
    2250             :         // We've been configured with the hash of a block which has been externally verified to have a valid history.
    2251             :         // A suitable default value is included with the software and updated from time to time.  Because validity
    2252             :         //  relative to a piece of software is an objective fact these defaults can be easily reviewed.
    2253             :         // This setting doesn't force the selection of any particular chain but makes validating some faster by
    2254             :         //  effectively caching the result of part of the verification.
    2255         740 :         BlockMap::const_iterator  it = m_blockman.m_block_index.find(hashAssumeValid);
    2256         740 :         if (it != m_blockman.m_block_index.end()) {
    2257        1012 :             if (it->second.GetAncestor(pindex->nHeight) == pindex &&
    2258         408 :                 m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex &&
    2259         408 :                 m_chainman.m_best_header->nChainWork >= nMinimumChainWork) {
    2260             :                 // This block is a member of the assumed verified chain and an ancestor of the best header.
    2261             :                 // Script verification is skipped when connecting blocks under the
    2262             :                 // assumevalid block. Assuming the assumevalid block is valid this
    2263             :                 // is safe because block merkle hashes are still computed and checked,
    2264             :                 // Of course, if an assumed valid block is invalid due to false scriptSigs
    2265             :                 // this optimization would allow an invalid chain to be accepted.
    2266             :                 // The equivalent time check discourages hash power from extorting the network via DOS attack
    2267             :                 //  into accepting an invalid block through telling users they must manually set assumevalid.
    2268             :                 //  Requiring a software change or burying the invalid block, regardless of the setting, makes
    2269             :                 //  it hard to hide the implication of the demand.  This also avoids having release candidates
    2270             :                 //  that are hardly doing any signature verification at all in testing without having to
    2271             :                 //  artificially set the default assumed verified block further back.
    2272             :                 // The test against nMinimumChainWork prevents the skipping when denied access to any chain at
    2273             :                 //  least as good as the expected chain.
    2274         408 :                 fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
    2275         408 :             }
    2276         604 :         }
    2277         740 :     }
    2278             : 
    2279      341274 :     int64_t nTime1 = GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart;
    2280      341274 :     LogPrint(BCLog::BENCHMARK, "    - Sanity checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime1 - nTimeStart), nTimeCheck * MICRO, nTimeCheck * MILLI / nBlocksTotal);
    2281             : 
    2282             :     // Do not allow blocks that contain transactions which 'overwrite' older transactions,
    2283             :     // unless those are already completely spent.
    2284             :     // If such overwrites are allowed, coinbases and transactions depending upon those
    2285             :     // can be duplicated to remove the ability to spend the first instance -- even after
    2286             :     // being sent to another address.
    2287             :     // See BIP30, CVE-2012-1909, and http://r6.ca/blog/20120206T005236Z.html for more information.
    2288             :     // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC.
    2289             :     // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
    2290             :     // two in the chain that violate it. This prevents exploiting the issue against nodes during their
    2291             :     // initial block download.
    2292      341274 :     bool fEnforceBIP30 = !IsBIP30Repeat(*pindex);
    2293             : 
    2294             :     // Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
    2295             :     // with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs.  But by the
    2296             :     // time BIP34 activated, in each of the existing pairs the duplicate coinbase had overwritten the first
    2297             :     // before the first had been spent.  Since those coinbases are sufficiently buried it's no longer possible to create further
    2298             :     // duplicate transactions descending from the known pairs either.
    2299             :     // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check.
    2300      341274 :     assert(pindex->pprev);
    2301      341274 :     CBlockIndex* pindexBIP34height = pindex->pprev->GetAncestor(m_params.GetConsensus().BIP34Height);
    2302             :     //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
    2303      682548 :     fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == m_params.GetConsensus().BIP34Hash));
    2304             : 
    2305      341274 :     if (fEnforceBIP30) {
    2306     1046683 :         for (const auto& tx : block.vtx) {
    2307     1846735 :             for (size_t o = 0; o < tx->vout.size(); o++) {
    2308     1141326 :                 if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
    2309           3 :                     LogPrintf("ERROR: ConnectBlock(): tried to overwrite transaction\n");
    2310           3 :                     return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-BIP30");
    2311             :                 }
    2312     1141323 :             }
    2313             :         }
    2314      341271 :     }
    2315             : 
    2316             :     /// DASH: Check superblock start
    2317             : 
    2318             :     // make sure old budget is the real one
    2319      341351 :     if (pindex->nHeight == m_params.GetConsensus().nSuperblockStartBlock &&
    2320          80 :         m_params.GetConsensus().nSuperblockStartHash != uint256() &&
    2321           0 :         block_hash != m_params.GetConsensus().nSuperblockStartHash) {
    2322           0 :             LogPrintf("ERROR: ConnectBlock(): invalid superblock start\n");
    2323           0 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-sb-start");
    2324             :     }
    2325             :     /// END DASH
    2326             : 
    2327             :     // Enforce BIP68 (sequence locks)
    2328      341271 :     int nLockTimeFlags = 0;
    2329      341271 :     if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
    2330      337874 :         nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
    2331      337874 :     }
    2332             : 
    2333             :     // Get the script flags for this block
    2334      341271 :     unsigned int flags{GetBlockScriptFlags(pindex, m_chainman)};
    2335             : 
    2336      341271 :     int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
    2337      341271 :     LogPrint(BCLog::BENCHMARK, "    - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
    2338             : 
    2339      341271 :     CBlockUndo blockundo;
    2340             : 
    2341             :     // Precomputed transaction data pointers must not be invalidated
    2342             :     // until after `control` has run the script checks (potentially
    2343             :     // in multiple threads). Preallocate the vector size so a new allocation
    2344             :     // doesn't invalidate pointers into the vector, and keep txsdata in scope
    2345             :     // for as long as `control`.
    2346      341271 :     std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
    2347      341271 :     CCheckQueueControl<CScriptCheck> control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr);
    2348             : 
    2349      341271 :     std::vector<int> prevheights;
    2350      341271 :     CAmount nFees = 0;
    2351      341271 :     int nInputs = 0;
    2352      341271 :     unsigned int nSigOps = 0;
    2353      341271 :     blockundo.vtxundo.reserve(block.vtx.size() - 1);
    2354      341271 :     bool fDIP0001Active_context = DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_DIP0001);
    2355             : 
    2356             :     // MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
    2357      341271 :     std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
    2358      341271 :     if (!m_chain_helper->special_tx->ProcessSpecialTxsInBlock(block, pindex, view, fJustCheck, fScriptChecks, state, mnlist_updates_opt)) {
    2359          56 :         return error("ConnectBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
    2360          56 :                      pindex->GetBlockHash().ToString(), state.ToString());
    2361             :     }
    2362             : 
    2363      341215 :     int64_t nTime2_1 = GetTimeMicros(); nTimeProcessSpecial += nTime2_1 - nTime2;
    2364      341215 :     LogPrint(BCLog::BENCHMARK, "      - ProcessSpecialTxsInBlock: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2_1 - nTime2), nTimeProcessSpecial * MICRO, nTimeProcessSpecial * MILLI / nBlocksTotal);
    2365             : 
    2366     1046206 :     for (unsigned int i = 0; i < block.vtx.size(); i++)
    2367             :     {
    2368      705280 :         const CTransaction &tx = *(block.vtx[i]);
    2369             : 
    2370      705280 :         nInputs += tx.vin.size();
    2371             : 
    2372      705280 :         if (!tx.IsCoinBase())
    2373             :         {
    2374      364065 :             CAmount txfee = 0;
    2375      364065 :             TxValidationState tx_state;
    2376      364065 :             if (!Consensus::CheckTxInputs(tx, tx_state, view, pindex->nHeight, txfee)) {
    2377             :                 // Any transaction validation failure in ConnectBlock is a block consensus failure
    2378          64 :                 LogPrintf("ERROR: %s: Consensus::CheckTxInputs: %s, %s\n", __func__, tx.GetHash().ToString(), state.ToString());
    2379         128 :                 return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
    2380          64 :                             tx_state.GetRejectReason(), tx_state.GetDebugMessage());
    2381             :             }
    2382      364001 :             nFees += txfee;
    2383      364001 :             if (!MoneyRange(nFees)) {
    2384           0 :                 LogPrintf("ERROR: %s: accumulated fee in the block out of range.\n", __func__);
    2385           0 :                 return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange");
    2386             :             }
    2387             : 
    2388             :             // Check that transaction is BIP68 final
    2389             :             // BIP68 lock checks (as opposed to nLockTime checks) must
    2390             :             // be in ConnectBlock because they require the UTXO set
    2391      364001 :             prevheights.resize(tx.vin.size());
    2392      562253 :             for (size_t j = 0; j < tx.vin.size(); j++) {
    2393      198252 :                 prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight;
    2394      198252 :             }
    2395             : 
    2396      364001 :             if (!SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
    2397          24 :                 LogPrintf("ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
    2398          24 :                 return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal");
    2399             :             }
    2400      364065 :         }
    2401             : 
    2402             :         // GetTransactionSigOpCount counts 2 types of sigops:
    2403             :         // * legacy (always)
    2404             :         // * p2sh (when P2SH enabled in flags and excludes coinbase)
    2405      705192 :         nSigOps += GetTransactionSigOpCount(tx, view, flags);
    2406      705192 :         if (nSigOps > MaxBlockSigOps(fDIP0001Active_context)) {
    2407           3 :             LogPrintf("ERROR: ConnectBlock(): too many sigops\n");
    2408           3 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops");
    2409             :         }
    2410             : 
    2411      705189 :         if (!tx.IsCoinBase())
    2412             :         {
    2413             : 
    2414      363974 :             std::vector<CScriptCheck> vChecks;
    2415      363974 :             bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
    2416      363974 :             TxValidationState tx_state;
    2417      363974 :             if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
    2418             :                 // Any transaction validation failure in ConnectBlock is a block consensus failure
    2419         396 :                 state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
    2420         198 :                               tx_state.GetRejectReason(), tx_state.GetDebugMessage());
    2421         198 :                 LogPrintf("ERROR: ConnectBlock(): CheckInputScripts on %s failed with %s\n",
    2422             :                     tx.GetHash().ToString(), state.ToString());
    2423         198 :                 return false;
    2424             :             }
    2425      363776 :             control.Add(vChecks);
    2426      363974 :         }
    2427             : 
    2428      704991 :         CTxUndo undoDummy;
    2429      704991 :         if (i > 0) {
    2430      363776 :             blockundo.vtxundo.emplace_back();
    2431      363776 :         }
    2432      704991 :         UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
    2433      704991 :     }
    2434             : 
    2435      340926 :     int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
    2436      340926 :     LogPrint(BCLog::BENCHMARK, "      - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);
    2437             : 
    2438             : 
    2439      340926 :     if (!control.Wait()) {
    2440           5 :         LogPrintf("ERROR: %s: CheckQueue failed\n", __func__);
    2441           5 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "block-validation-failed");
    2442             :     }
    2443      340921 :     int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
    2444      340921 :     LogPrint(BCLog::BENCHMARK, "    - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal);
    2445             : 
    2446             : 
    2447             :     // DASH
    2448             : 
    2449             :     // It's possible that we simply don't have enough data and this could fail
    2450             :     // (i.e. block itself could be a correct one and we need to store it),
    2451             :     // that's why this is in ConnectBlock. Could be the other way around however -
    2452             :     // the peer who sent us this block is missing some data and wasn't able
    2453             :     // to recognize that block is actually invalid.
    2454             : 
    2455             :     // DASH : CHECK TRANSACTIONS FOR INSTANTSEND
    2456             : 
    2457      340921 :     if (!IsInitialBlockDownload()) {
    2458             :         // Require other nodes to comply, send them some data in case they are missing it.
    2459      323381 :         const bool has_chainlock = m_chain_helper->HasChainLock(pindex->nHeight, pindex->GetBlockHash());
    2460      988984 :         for (const auto& tx : block.vtx) {
    2461             :             // skip txes that have no inputs
    2462      665654 :             if (tx->vin.empty()) continue;
    2463      441052 :             while (auto conflictLockOpt = m_chain_helper->ConflictingISLockIfAny(*tx)) {
    2464         182 :                 auto [conflict_islock_hash, conflict_txid] = conflictLockOpt.value();
    2465          91 :                 if (has_chainlock) {
    2466          40 :                     LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n", tx->GetHash().ToString(), conflict_islock_hash.ToString());
    2467          40 :                     m_chain_helper->RemoveConflictingISLockByTx(*tx);
    2468          40 :                 } else {
    2469             :                     // The node which relayed this should switch to correct chain.
    2470             :                     // TODO: relay instantsend data/proof.
    2471          51 :                     LogPrintf("ERROR: ConnectBlock(DASH): transaction %s conflicts with transaction lock %s\n", tx->GetHash().ToString(), conflict_txid.ToString());
    2472          51 :                     return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "conflict-tx-lock");
    2473             :                 }
    2474             :             }
    2475             :         }
    2476      323330 :     }
    2477             : 
    2478      340870 :     int64_t nTime5_1 = GetTimeMicros(); nTimeISFilter += nTime5_1 - nTime4;
    2479      340870 :     LogPrint(BCLog::BENCHMARK, "      - IS filter: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_1 - nTime4), nTimeISFilter * MICRO, nTimeISFilter * MILLI / nBlocksTotal);
    2480             : 
    2481             :     // DASH : MODIFIED TO CHECK MASTERNODE PAYMENTS AND SUPERBLOCKS
    2482             : 
    2483             :     // TODO: resync data (both ways?) and try to reprocess this block later.
    2484      340870 :     CAmount blockSubsidy = GetBlockSubsidy(pindex, m_params.GetConsensus());
    2485      340870 :     CAmount feeReward = nFees;
    2486      340870 :     std::string strError;
    2487             : 
    2488      340870 :     int64_t nTime5_2 = GetTimeMicros(); nTimeSubsidy += nTime5_2 - nTime5_1;
    2489      340870 :     LogPrint(BCLog::BENCHMARK, "      - GetBlockSubsidy: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_2 - nTime5_1), nTimeSubsidy * MICRO, nTimeSubsidy * MILLI / nBlocksTotal);
    2490             : 
    2491      340870 :     const bool check_superblock = m_chain_helper->IsSuperblockValidationRequired(pindex);
    2492             : 
    2493      340870 :     if (!m_chain_helper->mn_payments->IsBlockValueValid(block, pindex->pprev, blockSubsidy + feeReward, strError, check_superblock)) {
    2494             :         // NOTE: Do not punish, the node might be missing governance data
    2495          20 :         LogPrintf("ERROR: ConnectBlock(DASH): %s\n", strError);
    2496          20 :         return state.Invalid(BlockValidationResult::BLOCK_RESULT_UNSET, "bad-cb-amount");
    2497             :     }
    2498             : 
    2499      340850 :     int64_t nTime5_3 = GetTimeMicros(); nTimeValueValid += nTime5_3 - nTime5_2;
    2500      340850 :     LogPrint(BCLog::BENCHMARK, "      - IsBlockValueValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_3 - nTime5_2), nTimeValueValid * MICRO, nTimeValueValid * MILLI / nBlocksTotal);
    2501             : 
    2502      340850 :     if (!m_chain_helper->mn_payments->IsBlockPayeeValid(*block.vtx[0], pindex->pprev, blockSubsidy, feeReward, check_superblock)) {
    2503             :         // NOTE: Do not punish, the node might be missing governance data
    2504         256 :         LogPrintf("ERROR: ConnectBlock(DASH): couldn't find masternode or superblock payments\n");
    2505         256 :         return state.Invalid(BlockValidationResult::BLOCK_RESULT_UNSET, "bad-cb-payee");
    2506             :     }
    2507             : 
    2508      340594 :     int64_t nTime5_4 = GetTimeMicros(); nTimePayeeValid += nTime5_4 - nTime5_3;
    2509      340594 :     LogPrint(BCLog::BENCHMARK, "      - IsBlockPayeeValid: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_4 - nTime5_3), nTimePayeeValid * MICRO, nTimePayeeValid * MILLI / nBlocksTotal);
    2510             : 
    2511      340594 :     int64_t nTime5 = GetTimeMicros(); nTimeDashSpecific += nTime5 - nTime4;
    2512      340594 :     LogPrint(BCLog::BENCHMARK, "    - Dash specific: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5 - nTime4), nTimeDashSpecific * MICRO, nTimeDashSpecific * MILLI / nBlocksTotal);
    2513             : 
    2514             :     // END DASH
    2515             : 
    2516      340594 :     if (fJustCheck)
    2517       87612 :         return true;
    2518             : 
    2519      252982 :     int64_t nTime6 = GetTimeMicros();
    2520             : 
    2521      252982 :     if (!m_blockman.WriteUndoDataForBlock(blockundo, state, *pindex)) {
    2522           0 :         return false;
    2523             :     }
    2524             : 
    2525      252982 :     int64_t nTime7 = GetTimeMicros(); nTimeUndo += nTime7 - nTime6;
    2526      252982 :     LogPrint(BCLog::BENCHMARK, "    - Write undo data: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime7 - nTime6), nTimeUndo * MICRO, nTimeUndo * MILLI / nBlocksTotal);
    2527             : 
    2528      252982 :     if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
    2529      246789 :         pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
    2530      246789 :         m_blockman.m_dirty_blockindex.insert(pindex);
    2531      246789 :     }
    2532             : 
    2533      252982 :     int64_t nTime8 = GetTimeMicros(); nTimeIndexWrite += nTime8 - nTime7;
    2534      252982 :     LogPrint(BCLog::BENCHMARK, "      - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime8 - nTime7), nTimeIndexWrite * MICRO, nTimeIndexWrite * MILLI / nBlocksTotal);
    2535             : 
    2536             :     // add this block to the view's block chain
    2537      252982 :     view.SetBestBlock(pindex->GetBlockHash());
    2538      252982 :     m_evoDb.WriteBestBlock(pindex->GetBlockHash());
    2539             : 
    2540      252982 :     if (mnlist_updates_opt.has_value()) {
    2541       97425 :         const auto& mnlu = mnlist_updates_opt.value();
    2542       97425 :         GetMainSignals().NotifyMasternodeListChanged(false, mnlu.old_list, mnlu.diff);
    2543       97425 :         uiInterface.NotifyMasternodeListChanged(mnlu.new_list, pindex);
    2544       97425 :     }
    2545             : 
    2546      252982 :     ::g_stats_client->timing("ConnectBlock_ms", (nTime8 - nTimeStart) / 1000, 1.0f);
    2547             : 
    2548             :     TRACE6(validation, block_connected,
    2549             :         block_hash.data(),
    2550             :         pindex->nHeight,
    2551             :         block.vtx.size(),
    2552             :         nInputs,
    2553             :         nSigOps,
    2554             :         nTime8 - nTimeStart // in microseconds (µs)
    2555             :     );
    2556             : 
    2557      252982 :     return true;
    2558      342348 : }
    2559             : 
    2560      810091 : CoinsCacheSizeState CChainState::GetCoinsCacheSizeState()
    2561             : {
    2562      810091 :     AssertLockHeld(::cs_main);
    2563      810091 :     return this->GetCoinsCacheSizeState(
    2564      810091 :         m_coinstip_cache_size_bytes,
    2565      810091 :         gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
    2566           0 : }
    2567             : 
    2568      810093 : CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(
    2569             :     size_t max_coins_cache_size_bytes,
    2570             :     size_t max_mempool_size_bytes)
    2571             : {
    2572      810093 :     AssertLockHeld(::cs_main);
    2573      810093 :     const int64_t nMempoolUsage = m_mempool ? m_mempool->DynamicMemoryUsage() : 0;
    2574      810093 :     int64_t cacheSize = CoinsTip().DynamicMemoryUsage();
    2575      810093 :     int64_t nTotalSpace =
    2576      810093 :         max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
    2577             : 
    2578             :     //! No need to periodic flush if at least this much space still available.
    2579             :     static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;  // 10MB
    2580      810093 :     int64_t large_threshold =
    2581      810093 :         std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
    2582             : 
    2583      810093 :     if (cacheSize > nTotalSpace) {
    2584           1 :         LogPrintf("Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
    2585           1 :         return CoinsCacheSizeState::CRITICAL;
    2586      810092 :     } else if (cacheSize > large_threshold) {
    2587           1 :         return CoinsCacheSizeState::LARGE;
    2588             :     }
    2589      810091 :     return CoinsCacheSizeState::OK;
    2590      810093 : }
    2591             : 
    2592      810091 : bool CChainState::FlushStateToDisk(
    2593             :     BlockValidationState &state,
    2594             :     FlushStateMode mode,
    2595             :     int nManualPruneHeight)
    2596             : {
    2597      810091 :     LOCK(cs_main);
    2598      810091 :     assert(this->CanFlushToDisk());
    2599      810091 :     std::set<int> setFilesToPrune;
    2600      810091 :     bool full_flush_completed = false;
    2601             : 
    2602      810091 :     const size_t coins_count = CoinsTip().GetCacheSize();
    2603      810091 :     const size_t coins_mem_usage = CoinsTip().DynamicMemoryUsage();
    2604             : 
    2605             :     try {
    2606             :     {
    2607      810091 :         bool fFlushForPrune = false;
    2608      810091 :         bool fDoFullFlush = false;
    2609             : 
    2610      810091 :         CoinsCacheSizeState cache_state = GetCoinsCacheSizeState();
    2611      810091 :         LOCK(m_blockman.cs_LastBlockFile);
    2612      810091 :         if (fPruneMode && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !fReindex) {
    2613             :             // make sure we don't prune above any of the prune locks bestblocks
    2614             :             // pruning is height-based
    2615          30 :             int last_prune{m_chain.Height()}; // last height we can prune
    2616          30 :             std::optional<std::string> limiting_lock; // prune lock that actually was the limiting factor, only used for logging
    2617             : 
    2618          30 :             for (const auto& prune_lock : m_blockman.m_prune_locks) {
    2619           0 :                 if (prune_lock.second.height_first == std::numeric_limits<int>::max()) continue;
    2620             :                 // Remove the buffer and one additional block here to get actual height that is outside of the buffer
    2621           0 :                 const int lock_height{prune_lock.second.height_first - PRUNE_LOCK_BUFFER - 1};
    2622           0 :                 last_prune = std::max(1, std::min(last_prune, lock_height));
    2623           0 :                 if (last_prune == lock_height) {
    2624           0 :                     limiting_lock = prune_lock.first;
    2625           0 :                 }
    2626             :             }
    2627             : 
    2628          30 :             if (limiting_lock) {
    2629           0 :                 LogPrint(BCLog::PRUNE, "%s limited pruning to height %d\n", limiting_lock.value(), last_prune);
    2630           0 :             }
    2631             : 
    2632          30 :             if (nManualPruneHeight > 0) {
    2633           0 :                 LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune (manual)", BCLog::BENCHMARK);
    2634             : 
    2635           0 :                 m_blockman.FindFilesToPruneManual(setFilesToPrune, std::min(last_prune, nManualPruneHeight), m_chain.Height());
    2636           0 :             } else {
    2637          30 :                 LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCHMARK);
    2638             : 
    2639          30 :                 m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload());
    2640          30 :                 m_blockman.m_check_for_pruning = false;
    2641          30 :             }
    2642          30 :             if (!setFilesToPrune.empty()) {
    2643           0 :                 fFlushForPrune = true;
    2644           0 :                 if (!m_blockman.m_have_pruned) {
    2645           0 :                     m_blockman.m_block_tree_db->WriteFlag("prunedblockfiles", true);
    2646           0 :                     m_blockman.m_have_pruned = true;
    2647           0 :                 }
    2648           0 :             }
    2649          30 :         }
    2650      810091 :         const auto nNow{SteadyClock::now()};
    2651             :         // Avoid writing/flushing immediately after startup.
    2652      810091 :         if (m_last_write == decltype(m_last_write){}) {
    2653        3055 :             m_last_write = nNow;
    2654        3055 :         }
    2655      810091 :         if (m_last_flush == decltype(m_last_flush){}) {
    2656        3055 :             m_last_flush = nNow;
    2657        3055 :         }
    2658             :         // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
    2659      810091 :         bool fCacheLarge = mode == FlushStateMode::PERIODIC && cache_state >= CoinsCacheSizeState::LARGE;
    2660             :         // The cache is over the limit, we have to write now.
    2661      810091 :         bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
    2662             :         // The evodb cache is too large
    2663      810091 :         bool fEvoDbCacheCritical = mode == FlushStateMode::IF_NEEDED && m_evoDb.GetMemoryUsage() >= (64 << 20);
    2664             :         // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
    2665      810091 :         bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow > m_last_write + DATABASE_WRITE_INTERVAL;
    2666             :         // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
    2667      810091 :         bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && nNow > m_last_flush + DATABASE_FLUSH_INTERVAL;
    2668             :         // Combine all conditions that result in a full cache flush.
    2669      810091 :         fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fEvoDbCacheCritical || fPeriodicFlush || fFlushForPrune;
    2670             :         // Write blocks and block index to disk.
    2671      810091 :         if (fDoFullFlush || fPeriodicWrite) {
    2672             :             // Ensure we can write block index
    2673        7520 :             if (!CheckDiskSpace(gArgs.GetBlocksDirPath())) {
    2674           0 :                 return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
    2675             :             }
    2676             :             // First make sure all block and undo data is flushed to disk.
    2677             :             {
    2678        7520 :                 LOG_TIME_MILLIS_WITH_CATEGORY("write block and undo data to disk", BCLog::BENCHMARK);
    2679             : 
    2680             :                 // First make sure all block and undo data is flushed to disk.
    2681        7520 :                 m_blockman.FlushBlockFile();
    2682        7520 :             }
    2683             : 
    2684             :             // Then update all block file information (which may refer to block and undo files).
    2685             :             {
    2686        7520 :                 LOG_TIME_MILLIS_WITH_CATEGORY("write block index to disk", BCLog::BENCHMARK);
    2687             : 
    2688        7520 :                 if (!m_blockman.WriteBlockIndexDB()) {
    2689           0 :                     return AbortNode(state, "Failed to write to block index database");
    2690             :                 }
    2691        7520 :             }
    2692             :             // Finally remove any pruned files
    2693        7520 :             if (fFlushForPrune) {
    2694           0 :                 LOG_TIME_MILLIS_WITH_CATEGORY("unlink pruned files", BCLog::BENCHMARK);
    2695             : 
    2696           0 :                 UnlinkPrunedFiles(setFilesToPrune);
    2697           0 :             }
    2698        7520 :             m_last_write = nNow;
    2699        7520 :         }
    2700             :         // Flush best chain related state. This can only be done if the blocks / block index write was also done.
    2701      810091 :         if (fDoFullFlush && !CoinsTip().GetBestBlock().IsNull()) {
    2702             :             {
    2703        7520 :                 LOG_TIME_MILLIS_WITH_CATEGORY(strprintf("write coins cache to disk (%d coins, %.2fkB)",
    2704             :                     coins_count, coins_mem_usage / 1000), BCLog::BENCHMARK);
    2705             : 
    2706             :                 // Typical Coin structures on disk are around 48 bytes in size.
    2707             :                 // Pushing a new one to the database can cause it to be written
    2708             :                 // twice (once in the log, and once in the tables). This is already
    2709             :                 // an overestimation, as most will delete an existing entry or
    2710             :                 // overwrite one. Still, use a conservative safety factor of 2.
    2711        7520 :                 if (!CheckDiskSpace(gArgs.GetDataDirNet(), 48 * 2 * 2 * CoinsTip().GetCacheSize())) {
    2712           0 :                     return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
    2713             :                 }
    2714             :                 // Flush the chainstate (which may refer to block index entries).
    2715        7520 :                 if (!CoinsTip().Flush())
    2716           0 :                     return AbortNode(state, "Failed to write to coin database");
    2717        7520 :             }
    2718             :             {
    2719        7520 :                 LOG_TIME_SECONDS("write evodb cache to disk");
    2720        7520 :                 if (!m_evoDb.CommitRootTransaction()) {
    2721           0 :                     return AbortNode(state, "Failed to commit EvoDB");
    2722             :                 }
    2723        7520 :             }
    2724        7520 :             m_last_flush = nNow;
    2725        7520 :             full_flush_completed = true;
    2726             :             TRACE5(utxocache, flush,
    2727             :                    int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - nNow)},
    2728             :                    (uint32_t)mode,
    2729             :                    (uint64_t)coins_count,
    2730             :                    (uint64_t)coins_mem_usage,
    2731             :                    (bool)fFlushForPrune);
    2732        7520 :         }
    2733      810091 :     }
    2734      810091 :     if (full_flush_completed) {
    2735             :         // Update best block in wallet (so we can detect restored wallets).
    2736        7520 :         GetMainSignals().ChainStateFlushed(m_chain.GetLocator());
    2737        7520 :     }
    2738      810091 :     } catch (const std::runtime_error& e) {
    2739           0 :         return AbortNode(state, std::string("System error while flushing: ") + e.what());
    2740           0 :     }
    2741      810091 :     return true;
    2742      810091 : }
    2743             : 
    2744        7506 : void CChainState::ForceFlushStateToDisk()
    2745             : {
    2746        7506 :     BlockValidationState state;
    2747        7506 :     if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
    2748           0 :         LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
    2749           0 :     }
    2750        7506 : }
    2751             : 
    2752          26 : void CChainState::PruneAndFlush()
    2753             : {
    2754          26 :     BlockValidationState state;
    2755          26 :     m_blockman.m_check_for_pruning = true;
    2756          26 :     if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) {
    2757           0 :         LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
    2758           0 :     }
    2759          26 : }
    2760             : 
    2761           8 : static void DoWarning(const bilingual_str& warning)
    2762             : {
    2763             :     static bool fWarned = false;
    2764           8 :     SetMiscWarning(warning);
    2765           8 :     if (!fWarned) {
    2766           4 :         AlertNotify(warning.original);
    2767           4 :         fWarned = true;
    2768           4 :     }
    2769           8 : }
    2770             : 
    2771             : /** Private helper function that concatenates warning messages. */
    2772         288 : static void AppendWarning(bilingual_str& res, const bilingual_str& warn)
    2773             : {
    2774         288 :     if (!res.empty()) res += Untranslated(", ");
    2775         288 :     res += warn;
    2776         288 : }
    2777             : 
    2778      267787 : static void UpdateTipLog(
    2779             :     const CCoinsViewCache& coins_tip,
    2780             :     const CBlockIndex* tip,
    2781             :     const CChainParams& params,
    2782             :     const CEvoDB& evo_db,
    2783             :     const std::string& func_name,
    2784             :     const std::string& prefix,
    2785             :     const std::string& warning_messages) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
    2786             : {
    2787             : 
    2788      267787 :     AssertLockHeld(::cs_main);
    2789      267787 :     LogPrintf("%s%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo) evodb_cache=%.1fMiB%s\n",
    2790             :         prefix, func_name,
    2791             :         tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion,
    2792             :         log(tip->nChainWork.getdouble()) / log(2.0), (unsigned long)tip->nChainTx,
    2793             :         FormatISO8601DateTime(tip->GetBlockTime()),
    2794             :         GuessVerificationProgress(params.TxData(), tip),
    2795             :         coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)),
    2796             :         coins_tip.GetCacheSize(),
    2797             :         evo_db.GetMemoryUsage() * (1.0 / (1 << 20)),
    2798             :         !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : "");
    2799      267787 : }
    2800             : 
    2801      267788 : void CChainState::UpdateTip(const CBlockIndex* pindexNew)
    2802             : {
    2803      267788 :     AssertLockHeld(::cs_main);
    2804      267788 :     const auto& coins_tip = this->CoinsTip();
    2805             : 
    2806             :     // The remainder of the function isn't relevant if we are not acting on
    2807             :     // the active chainstate, so return if need be.
    2808      267788 :     if (this != &m_chainman.ActiveChainstate()) {
    2809             :         // Only log every so often so that we don't bury log messages at the tip.
    2810           1 :         constexpr int BACKGROUND_LOG_INTERVAL = 2000;
    2811           1 :         if (pindexNew->nHeight % BACKGROUND_LOG_INTERVAL == 0) {
    2812           0 :             UpdateTipLog(coins_tip, pindexNew, m_params, m_evoDb, __func__, "[background validation] ", "");
    2813           0 :         }
    2814           1 :         return;
    2815             :     }
    2816             : 
    2817             :     // New best block
    2818      267787 :     if (m_mempool) {
    2819      267686 :         m_mempool->AddTransactionsUpdated(1);
    2820      267686 :     }
    2821             : 
    2822             :     {
    2823      267787 :         LOCK(g_best_block_mutex);
    2824      267787 :         g_best_block = pindexNew->GetBlockHash();
    2825      267787 :         g_best_block_cv.notify_all();
    2826      267787 :     }
    2827             : 
    2828      267787 :     bilingual_str warning_messages;
    2829      267787 :     if (!this->IsInitialBlockDownload())
    2830             :     {
    2831      249080 :         const CBlockIndex* pindex = pindexNew;
    2832     7472400 :         for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
    2833     7223320 :             WarningBitsConditionChecker checker(m_chainman, bit);
    2834     7223320 :             ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), m_chainman.m_warningcache.at(bit));
    2835     7223320 :             if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) {
    2836         296 :                 const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit);
    2837         296 :                 if (state == ThresholdState::ACTIVE) {
    2838           8 :                     DoWarning(warning);
    2839           8 :                 } else {
    2840         288 :                     AppendWarning(warning_messages, warning);
    2841             :                 }
    2842         296 :             }
    2843     7223320 :         }
    2844      249080 :     }
    2845      267787 :     UpdateTipLog(coins_tip, pindexNew, m_params, m_evoDb, __func__, "", warning_messages.original);
    2846      267788 : }
    2847             : 
    2848             : /** Disconnect m_chain's tip.
    2849             :   * After calling, the mempool will be in an inconsistent state, with
    2850             :   * transactions from disconnected blocks being added to disconnectpool.  You
    2851             :   * should make the mempool consistent again by calling MaybeUpdateMempoolForReorg.
    2852             :   * with cs_main held.
    2853             :   *
    2854             :   * If disconnectpool is nullptr, then no disconnected transactions are added to
    2855             :   * disconnectpool (note that the caller is responsible for mempool consistency
    2856             :   * in any case).
    2857             :   */
    2858       14625 : bool CChainState::DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool)
    2859             : {
    2860       14625 :     AssertLockHeld(cs_main);
    2861       14625 :     if (m_mempool) AssertLockHeld(m_mempool->cs);
    2862             : 
    2863       14625 :     int64_t nTime1 = GetTimeMicros();
    2864             : 
    2865       14625 :     CBlockIndex *pindexDelete = m_chain.Tip();
    2866       14625 :     assert(pindexDelete);
    2867       14625 :     assert(pindexDelete->pprev);
    2868             :     // Read block from disk.
    2869       14625 :     std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
    2870       14625 :     CBlock& block = *pblock;
    2871       14625 :     if (!ReadBlockFromDisk(block, pindexDelete, m_params.GetConsensus())) {
    2872           0 :         return error("DisconnectTip(): Failed to read block");
    2873             :     }
    2874             :     // Apply the block atomically to the chain state.
    2875       14625 :     int64_t nStart = GetTimeMicros();
    2876             :     {
    2877       14625 :         auto dbTx = m_evoDb.BeginTransaction();
    2878             : 
    2879       14625 :         CCoinsViewCache view(&CoinsTip());
    2880       14625 :         assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
    2881       14625 :         if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
    2882           2 :             return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
    2883       14623 :         bool flushed = view.Flush();
    2884       14623 :         assert(flushed);
    2885       14623 :         dbTx->Commit();
    2886       14625 :     }
    2887       14623 :     LogPrint(BCLog::BENCHMARK, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI);
    2888             : 
    2889             :     {
    2890             :         // Prune locks that began at or after the tip should be moved backward so they get a chance to reorg
    2891       14623 :         const int max_height_first{pindexDelete->nHeight - 1};
    2892       17621 :         for (auto& prune_lock : m_blockman.m_prune_locks) {
    2893        2998 :             if (prune_lock.second.height_first <= max_height_first) continue;
    2894             : 
    2895        2998 :             prune_lock.second.height_first = max_height_first;
    2896        2998 :             LogPrint(BCLog::PRUNE, "%s prune lock moved back to %d\n", prune_lock.first, max_height_first);
    2897             :         }
    2898             :     }
    2899             : 
    2900             :     // Write the chain state to disk, if necessary.
    2901       14623 :     if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
    2902           0 :         return false;
    2903             :     }
    2904             : 
    2905       14623 :     if (disconnectpool && m_mempool) {
    2906             :         // Save transactions to re-add to mempool at end of reorg
    2907       52802 :         for (auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
    2908       38179 :             disconnectpool->addTransaction(*it);
    2909       38179 :         }
    2910       24238 :         while (disconnectpool->DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
    2911             :             // Drop the earliest entry, and remove its children from the mempool.
    2912        9615 :             auto it = disconnectpool->queuedTx.get<insertion_order>().begin();
    2913        9615 :             m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
    2914        9615 :             disconnectpool->removeEntry(it);
    2915             :         }
    2916       14623 :     }
    2917             : 
    2918       14623 :     m_chain.SetTip(*pindexDelete->pprev);
    2919             : 
    2920       14623 :     UpdateTip(pindexDelete->pprev);
    2921             :     // Let wallets know transactions went from 1-confirmed to
    2922             :     // 0-confirmed or conflicted:
    2923       14623 :     GetMainSignals().BlockDisconnected(pblock, pindexDelete);
    2924             : 
    2925       14623 :     int64_t nTime2 = GetTimeMicros();
    2926             : 
    2927       14623 :     unsigned int nSigOps = 0;
    2928       52802 :     for (const auto& tx : block.vtx) {
    2929       38179 :         nSigOps += GetLegacySigOpCount(*tx);
    2930             :     }
    2931       14623 :     ::g_stats_client->timing("DisconnectTip_ms", (nTime2 - nTime1) / 1000, 1.0f);
    2932       14623 :     ::g_stats_client->gauge("blocks.tip.SizeBytes", ::GetSerializeSize(block, PROTOCOL_VERSION), 1.0f);
    2933       14623 :     ::g_stats_client->gauge("blocks.tip.Height", m_chain.Height(), 1.0f);
    2934       14623 :     ::g_stats_client->gauge("blocks.tip.Version", block.nVersion, 1.0f);
    2935       14623 :     ::g_stats_client->gauge("blocks.tip.NumTransactions", block.vtx.size(), 1.0f);
    2936       14623 :     ::g_stats_client->gauge("blocks.tip.SigOps", nSigOps, 1.0f);
    2937       14623 :     return true;
    2938       14625 : }
    2939             : 
    2940             : static int64_t nTimeConnectTotal = 0;
    2941             : static int64_t nTimeFlush = 0;
    2942             : static int64_t nTimeChainState = 0;
    2943             : static int64_t nTimePostConnect = 0;
    2944             : 
    2945             : struct PerBlockConnectTrace {
    2946      526952 :     CBlockIndex* pindex = nullptr;
    2947             :     std::shared_ptr<const CBlock> pblock;
    2948     1580856 :     PerBlockConnectTrace() = default;
    2949             : };
    2950             : /**
    2951             :  * Used to track blocks whose transactions were applied to the UTXO state as a
    2952             :  * part of a single ActivateBestChainStep call.
    2953             :  *
    2954             :  * This class is single-use, once you call GetBlocksConnected() you have to throw
    2955             :  * it away and make a new one.
    2956             :  */
    2957             : class ConnectTrace {
    2958             : private:
    2959             :     std::vector<PerBlockConnectTrace> blocksConnected;
    2960             : 
    2961             : public:
    2962      547574 :     explicit ConnectTrace() : blocksConnected(1) {}
    2963             : 
    2964      253165 :     void BlockConnected(CBlockIndex* pindex, std::shared_ptr<const CBlock> pblock) {
    2965      253165 :         assert(!blocksConnected.back().pindex);
    2966      253165 :         assert(pindex);
    2967      253165 :         assert(pblock);
    2968      253165 :         blocksConnected.back().pindex = pindex;
    2969      253165 :         blocksConnected.back().pblock = std::move(pblock);
    2970      253165 :         blocksConnected.emplace_back();
    2971      253165 :     }
    2972             : 
    2973      245441 :     std::vector<PerBlockConnectTrace>& GetBlocksConnected() {
    2974             :         // We always keep one extra block at the end of our list because
    2975             :         // blocks are added after all the conflicted transactions have
    2976             :         // been filled in. Thus, the last entry should always be an empty
    2977             :         // one waiting for the transactions from the next block. We pop
    2978             :         // the last entry here to make sure the list we return is sane.
    2979      245441 :         assert(!blocksConnected.back().pindex);
    2980      245441 :         blocksConnected.pop_back();
    2981      245441 :         return blocksConnected;
    2982             :     }
    2983             : };
    2984             : 
    2985             : /**
    2986             :  * Connect a new block to m_chain. pblock is either nullptr or a pointer to a CBlock
    2987             :  * corresponding to pindexNew, to bypass loading it again from disk.
    2988             :  *
    2989             :  * The block is added to connectTrace if connection succeeds.
    2990             :  */
    2991      253838 : bool CChainState::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool)
    2992             : {
    2993      253838 :     AssertLockHeld(cs_main);
    2994      253838 :     if (m_mempool) AssertLockHeld(m_mempool->cs);
    2995             : 
    2996      253838 :     assert(pindexNew->pprev == m_chain.Tip());
    2997             :     // Read block from disk.
    2998      253838 :     int64_t nTime1 = GetTimeMicros();
    2999      253838 :     std::shared_ptr<const CBlock> pthisBlock;
    3000      253838 :     if (!pblock) {
    3001       30043 :         std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
    3002       30043 :         if (!ReadBlockFromDisk(*pblockNew, pindexNew, m_params.GetConsensus())) {
    3003           0 :             return AbortNode(state, "Failed to read block");
    3004             :         }
    3005       30043 :         pthisBlock = pblockNew;
    3006       30043 :     } else {
    3007      223795 :         LogPrint(BCLog::BENCHMARK, "  - Using cached block\n");
    3008      223795 :         pthisBlock = pblock;
    3009             :     }
    3010      253838 :     const CBlock& blockConnecting = *pthisBlock;
    3011             :     // Apply the block atomically to the chain state.
    3012      253838 :     int64_t nTime2 = GetTimeMicros();
    3013             :     int64_t nTime3;
    3014             :     // When adding aggregate statistics in the future, keep in mind that
    3015             :     // nBlocksTotal may be zero until the ConnectBlock() call below.
    3016      253838 :     LogPrint(BCLog::BENCHMARK, "  - Load block from disk: %.2fms\n", (nTime2 - nTime1) * MILLI);
    3017             :     {
    3018      253838 :         auto dbTx = m_evoDb.BeginTransaction();
    3019             : 
    3020      253838 :         CCoinsViewCache view(&CoinsTip());
    3021      253838 :         bool rv = ConnectBlock(blockConnecting, state, pindexNew, view);
    3022      253838 :         GetMainSignals().BlockChecked(blockConnecting, state);
    3023      253838 :         if (!rv) {
    3024         673 :             if (state.IsInvalid())
    3025         673 :                 InvalidBlockFound(pindexNew, state);
    3026         673 :             return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), state.ToString());
    3027             :         }
    3028      253165 :         nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
    3029      253165 :         assert(nBlocksTotal > 0);
    3030      253165 :         LogPrint(BCLog::BENCHMARK, "  - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
    3031      253165 :         bool flushed = view.Flush();
    3032      253165 :         assert(flushed);
    3033      253165 :         dbTx->Commit();
    3034      253838 :     }
    3035      253165 :     int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    3036      253165 :     LogPrint(BCLog::BENCHMARK, "  - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
    3037             :     // Write the chain state to disk, if necessary.
    3038      253165 :     if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
    3039           0 :         return false;
    3040             :     }
    3041      253165 :     int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    3042      253165 :     LogPrint(BCLog::BENCHMARK, "  - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
    3043             :     // Remove conflicting transactions from the mempool.;
    3044      253165 :     if (m_mempool) {
    3045      253064 :         m_mempool->removeForBlock(blockConnecting.vtx, pindexNew->nHeight);
    3046      253064 :         m_mempool->removeExpiredAssetUnlock(pindexNew->nHeight);
    3047      253064 :         disconnectpool.removeForBlock(blockConnecting.vtx);
    3048      253064 :     }
    3049             :     // Update m_chain & related variables.
    3050      253165 :     m_chain.SetTip(*pindexNew);
    3051      253165 :     UpdateTip(pindexNew);
    3052             : 
    3053      253165 :     int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
    3054      253165 :     LogPrint(BCLog::BENCHMARK, "  - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
    3055      253165 :     LogPrint(BCLog::BENCHMARK, "- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO, nTimeTotal * MILLI / nBlocksTotal);
    3056             : 
    3057      253165 :     unsigned int nSigOps = 0;
    3058      786864 :     for (const auto& tx : blockConnecting.vtx) {
    3059      533699 :         nSigOps += GetLegacySigOpCount(*tx);
    3060             :     }
    3061      253165 :     ::g_stats_client->timing("ConnectTip_ms", (nTime6 - nTime1) / 1000, 1.0f);
    3062      253165 :     ::g_stats_client->gauge("blocks.tip.SizeBytes", ::GetSerializeSize(blockConnecting, PROTOCOL_VERSION), 1.0f);
    3063      253165 :     ::g_stats_client->gauge("blocks.tip.Height", m_chain.Height(), 1.0f);
    3064      253165 :     ::g_stats_client->gauge("blocks.tip.Version", blockConnecting.nVersion, 1.0f);
    3065      253165 :     ::g_stats_client->gauge("blocks.tip.NumTransactions", blockConnecting.vtx.size(), 1.0f);
    3066      253165 :     ::g_stats_client->gauge("blocks.tip.SigOps", nSigOps, 1.0f);
    3067             : 
    3068      253165 :     connectTrace.BlockConnected(pindexNew, std::move(pthisBlock));
    3069      253165 :     return true;
    3070      253838 : }
    3071             : 
    3072             : /**
    3073             :  * Return the tip of the chain with the most work in it, that isn't
    3074             :  * known to be invalid (it's however far from certain to be valid).
    3075             :  */
    3076      255470 : CBlockIndex* CChainState::FindMostWorkChain()
    3077             : {
    3078      255470 :     AssertLockHeld(::cs_main);
    3079      255470 :     do {
    3080      255573 :         CBlockIndex *pindexNew = nullptr;
    3081             : 
    3082             :         // Find the best candidate header.
    3083             :         {
    3084      255573 :             std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
    3085      255573 :             if (it == setBlockIndexCandidates.rend())
    3086           0 :                 return nullptr;
    3087      255573 :             pindexNew = *it;
    3088             :         }
    3089             : 
    3090             :         // Check whether all blocks on the path between the currently active chain and the candidate are valid.
    3091             :         // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
    3092      255573 :         CBlockIndex *pindexTest = pindexNew;
    3093      255573 :         bool fInvalidAncestor = false;
    3094      509498 :         while (pindexTest && !m_chain.Contains(pindexTest)) {
    3095      254028 :             assert(pindexTest->HaveTxsDownloaded() || pindexTest->nHeight == 0);
    3096             : 
    3097             :             // Pruned nodes may have entries in setBlockIndexCandidates for
    3098             :             // which block files have been deleted.  Remove those as candidates
    3099             :             // for the most work chain if we come across them; we can't switch
    3100             :             // to a chain unless we have all the non-active-chain parent blocks.
    3101      254028 :             bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
    3102      254028 :             bool fConflictingChain = pindexTest->nStatus & BLOCK_CONFLICT_CHAINLOCK;
    3103      254028 :             bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
    3104      254028 :             if (fFailedChain || fMissingData || fConflictingChain) {
    3105             :                 // Candidate chain is not usable (either invalid or conflicting or missing data)
    3106         103 :                 if (fFailedChain && (m_chainman.m_best_invalid == nullptr || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork)) {
    3107           5 :                     m_chainman.m_best_invalid = pindexNew;
    3108           5 :                 }
    3109         103 :                 CBlockIndex *pindexFailed = pindexNew;
    3110             :                 // Remove the entire chain from the set.
    3111         153 :                 while (pindexTest != pindexFailed) {
    3112          50 :                     if (fFailedChain) {
    3113          50 :                         pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
    3114          50 :                     } else if (fConflictingChain) {
    3115             :                         // We don't need data for conflciting blocks
    3116           0 :                         pindexFailed->nStatus |= BLOCK_CONFLICT_CHAINLOCK;
    3117           0 :                     } else if (fMissingData) {
    3118             :                         // If we're missing data, then add back to m_blocks_unlinked,
    3119             :                         // so that if the block arrives in the future we can try adding
    3120             :                         // to setBlockIndexCandidates again.
    3121           0 :                         m_blockman.m_blocks_unlinked.insert(
    3122           0 :                             std::make_pair(pindexFailed->pprev, pindexFailed));
    3123           0 :                     }
    3124          50 :                     setBlockIndexCandidates.erase(pindexFailed);
    3125          50 :                     pindexFailed = pindexFailed->pprev;
    3126             :                 }
    3127         103 :                 setBlockIndexCandidates.erase(pindexTest);
    3128         103 :                 fInvalidAncestor = true;
    3129         103 :                 break;
    3130             :             }
    3131      253925 :             pindexTest = pindexTest->pprev;
    3132             :         }
    3133      255573 :         if (!fInvalidAncestor)
    3134      255470 :             return pindexNew;
    3135         103 :     } while(true);
    3136      255470 : }
    3137             : 
    3138             : /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
    3139      255157 : void CChainState::PruneBlockIndexCandidates() {
    3140             :     // Note that we can't delete the current block itself, as we may need to return to it later in case a
    3141             :     // reorganization to a better block fails.
    3142      255157 :     std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
    3143      818458 :     while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, m_chain.Tip())) {
    3144      563301 :         setBlockIndexCandidates.erase(it++);
    3145             :     }
    3146             :     // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
    3147      255157 :     assert(!setBlockIndexCandidates.empty());
    3148      255157 : }
    3149             : 
    3150             : /**
    3151             :  * Try to make some progress towards making pindexMostWork the active block.
    3152             :  * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork.
    3153             :  *
    3154             :  * @returns true unless a system error occurred
    3155             :  */
    3156      245443 : bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
    3157             : {
    3158      245443 :     AssertLockHeld(cs_main);
    3159      245443 :     if (m_mempool) AssertLockHeld(m_mempool->cs);
    3160             : 
    3161      245443 :     const CBlockIndex* pindexOldTip = m_chain.Tip();
    3162      245443 :     const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
    3163             : 
    3164             :     // Disconnect active blocks which are no longer in the best chain.
    3165      245443 :     bool fBlocksDisconnected = false;
    3166      245443 :     DisconnectedBlockTransactions disconnectpool;
    3167      253877 :     while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
    3168        8436 :         if (!DisconnectTip(state, &disconnectpool)) {
    3169             :             // This is likely a fatal error, but keep the mempool consistent,
    3170             :             // just in case. Only remove from the mempool in this case.
    3171           2 :             MaybeUpdateMempoolForReorg(disconnectpool, false);
    3172             : 
    3173             :             // If we're unable to disconnect a block during normal operation,
    3174             :             // then that is a failure of our local system -- we should abort
    3175             :             // rather than stay on a less work chain.
    3176           2 :             AbortNode(state, "Failed to disconnect block; see debug.log for details");
    3177           2 :             return false;
    3178             :         }
    3179        8434 :         fBlocksDisconnected = true;
    3180             :     }
    3181             : 
    3182             :     // Build list of new blocks to connect (in descending height order).
    3183      245441 :     std::vector<CBlockIndex*> vpindexToConnect;
    3184      245441 :     bool fContinue = true;
    3185      245441 :     int nHeight = pindexFork ? pindexFork->nHeight : -1;
    3186      491103 :     while (fContinue && nHeight != pindexMostWork->nHeight) {
    3187             :         // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
    3188             :         // a few blocks along the way.
    3189      245662 :         int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
    3190      245662 :         vpindexToConnect.clear();
    3191      245662 :         vpindexToConnect.reserve(nTargetHeight - nHeight);
    3192      245662 :         CBlockIndex* pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
    3193      959204 :         while (pindexIter && pindexIter->nHeight != nHeight) {
    3194      713542 :             vpindexToConnect.push_back(pindexIter);
    3195      713542 :             pindexIter = pindexIter->pprev;
    3196             :         }
    3197      245662 :         nHeight = nTargetHeight;
    3198             : 
    3199             :         // Connect new blocks.
    3200      254087 :         for (CBlockIndex* pindexConnect : vpindexToConnect | std::views::reverse) {
    3201      253838 :             if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
    3202         673 :                 if (state.IsInvalid()) {
    3203             :                     // The block violates a consensus rule.
    3204         673 :                     if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
    3205         673 :                         InvalidChainFound(vpindexToConnect.front());
    3206         673 :                     }
    3207         673 :                     state = BlockValidationState();
    3208         673 :                     fInvalidFound = true;
    3209         673 :                     fContinue = false;
    3210         673 :                     break;
    3211             :                 } else {
    3212             :                     // A system error occurred (disk space, database error, ...).
    3213             :                     // Make the mempool consistent with the current tip, just in case
    3214             :                     // any observers try to use it before shutdown.
    3215           0 :                     MaybeUpdateMempoolForReorg(disconnectpool, false);
    3216           0 :                     return false;
    3217             :                 }
    3218             :             } else {
    3219      253165 :                 PruneBlockIndexCandidates();
    3220      253165 :                 if (!pindexOldTip || m_chain.Tip()->nChainWork > pindexOldTip->nChainWork) {
    3221             :                     // We're in a better position than we were. Return temporarily to release the lock.
    3222      244740 :                     fContinue = false;
    3223      244740 :                     break;
    3224             :                 }
    3225             :             }
    3226             :         }
    3227             :     }
    3228             : 
    3229      245441 :     if (fBlocksDisconnected) {
    3230             :         // If any blocks were disconnected, disconnectpool may be non empty.  Add
    3231             :         // any disconnected transactions back to the mempool.
    3232         306 :         MaybeUpdateMempoolForReorg(disconnectpool, true);
    3233         306 :     }
    3234      245441 :     if (m_mempool) m_mempool->check(this->CoinsTip(), this->m_chain.Height() + 1);
    3235             : 
    3236      245441 :     CheckForkWarningConditions();
    3237             : 
    3238      245441 :     return true;
    3239      245443 : }
    3240             : 
    3241      461257 : static SynchronizationState GetSynchronizationState(bool init)
    3242             : {
    3243      461257 :     if (!init) return SynchronizationState::POST_INIT;
    3244       28302 :     if (::fReindex) return SynchronizationState::INIT_REINDEX;
    3245       18142 :     return SynchronizationState::INIT_DOWNLOAD;
    3246      461257 : }
    3247             : 
    3248      485100 : static bool NotifyHeaderTip(CChainState& chainstate) LOCKS_EXCLUDED(cs_main) {
    3249      485100 :     bool fNotify = false;
    3250      485100 :     bool fInitialBlockDownload = false;
    3251             :     static CBlockIndex* pindexHeaderOld = nullptr;
    3252      485100 :     CBlockIndex* pindexHeader = nullptr;
    3253             :     {
    3254      485100 :         LOCK(cs_main);
    3255      485100 :         pindexHeader = chainstate.m_chainman.m_best_header;
    3256             : 
    3257      485100 :         if (pindexHeader != pindexHeaderOld) {
    3258      216239 :             fNotify = true;
    3259      216239 :             fInitialBlockDownload = chainstate.IsInitialBlockDownload();
    3260      216239 :             pindexHeaderOld = pindexHeader;
    3261      216239 :         }
    3262      485100 :     }
    3263             :     // Send block tip changed notifications without cs_main
    3264      485100 :     if (fNotify) {
    3265      216239 :         uiInterface.NotifyHeaderTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader);
    3266      216239 :         GetMainSignals().NotifyHeaderTip(pindexHeader, fInitialBlockDownload);
    3267      216239 :     }
    3268      485100 :     return fNotify;
    3269           0 : }
    3270             : 
    3271      280157 : static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main) {
    3272      280157 :     AssertLockNotHeld(cs_main);
    3273             : 
    3274      280157 :     if (GetMainSignals().CallbacksPending() > 10) {
    3275        6893 :         SyncWithValidationInterfaceQueue();
    3276        6893 :     }
    3277      280157 : }
    3278             : 
    3279      254797 : bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
    3280             : {
    3281      254797 :     AssertLockNotHeld(m_chainstate_mutex);
    3282             : 
    3283             :     // Note that while we're often called here from ProcessNewBlock, this is
    3284             :     // far from a guarantee. Things in the P2P/RPC will often end up calling
    3285             :     // us in the middle of ProcessNewBlock - do not assume pblock is set
    3286             :     // sanely for performance or correctness!
    3287      254797 :     AssertLockNotHeld(::cs_main);
    3288             : 
    3289             :     // ABC maintains a fair degree of expensive-to-calculate internal state
    3290             :     // because this function periodically releases cs_main so that it does not lock up other threads for too long
    3291             :     // during large connects - and to allow for e.g. the callback queue to drain
    3292             :     // we use m_chainstate_mutex to enforce mutual exclusion so that only one caller may execute this function at a time
    3293      254797 :     LOCK(m_chainstate_mutex);
    3294             : 
    3295      254797 :     auto start = Now<SteadyMilliseconds>();
    3296             : 
    3297      254797 :     CBlockIndex *pindexMostWork = nullptr;
    3298      254797 :     CBlockIndex *pindexNewTip = nullptr;
    3299      254797 :     int nStopAtHeight = gArgs.GetIntArg("-stopatheight", DEFAULT_STOPATHEIGHT);
    3300      254797 :     do {
    3301             :         // Block until the validation queue drains. This should largely
    3302             :         // never happen in normal operation, however may happen during
    3303             :         // reindex, causing memory blowup if we run too far ahead.
    3304             :         // Note that if a validationinterface callback ends up calling
    3305             :         // ActivateBestChain this may lead to a deadlock! We should
    3306             :         // probably have a DEBUG_LOCKORDER test for this in the future.
    3307      500207 :         LimitValidationInterfaceQueue();
    3308             : 
    3309             :         {
    3310      273769 :             LOCK(cs_main);
    3311             :             // Lock transaction pool for at least as long as it takes for connectTrace to be consumed
    3312      179107 :             LOCK(MempoolMutex());
    3313      179107 :             CBlockIndex* starting_tip = m_chain.Tip();
    3314      273769 :             bool blocks_connected = false;
    3315      273769 :             do {
    3316             :                 // We absolutely may not unlock cs_main until we've made forward progress
    3317             :                 // (with the exception of shutdown due to hardware issues, low disk space, etc).
    3318      368449 :                 ConnectTrace connectTrace; // Destructed before cs_main is unlocked
    3319             : 
    3320      273787 :                 if (pindexMostWork == nullptr) {
    3321      255470 :                     pindexMostWork = FindMostWorkChain();
    3322      255470 :                 }
    3323             : 
    3324             :                 // Whether we have anything to do at all.
    3325      273787 :                 if (pindexMostWork == nullptr || pindexMostWork == m_chain.Tip()) {
    3326       28344 :                     break;
    3327             :                 }
    3328             : 
    3329      245443 :                 bool fInvalidFound = false;
    3330      245443 :                 std::shared_ptr<const CBlock> nullBlockPtr;
    3331      245443 :                 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
    3332             :                     // A system error occurred
    3333           2 :                     return false;
    3334             :                 }
    3335      245441 :                 blocks_connected = true;
    3336             : 
    3337      245441 :                 if (fInvalidFound) {
    3338             :                     // Wipe cache, we may need another branch now.
    3339         673 :                     pindexMostWork = nullptr;
    3340         673 :                 }
    3341      245441 :                 pindexNewTip = m_chain.Tip();
    3342             : 
    3343      498606 :                 for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
    3344      253165 :                     assert(trace.pblock && trace.pindex);
    3345      253165 :                     GetMainSignals().BlockConnected(trace.pblock, trace.pindex);
    3346             :                 }
    3347      518154 :             } while (!m_chain.Tip() || (starting_tip && CBlockIndexWorkComparator()(m_chain.Tip(), starting_tip)));
    3348      273767 :             if (!blocks_connected) return true;
    3349             : 
    3350      245423 :             const CBlockIndex* pindexFork = m_chain.FindFork(starting_tip);
    3351      245423 :             bool fInitialDownload = IsInitialBlockDownload();
    3352             : 
    3353             :             // Notify external listeners about the new tip.
    3354             :             // Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
    3355      245423 :             if (pindexFork != pindexNewTip) {
    3356             :                 // Notify ValidationInterface subscribers
    3357      244750 :                 GetMainSignals().SynchronousUpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
    3358      244750 :                 GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
    3359             : 
    3360             :                 // Always notify the UI if a new block tip was connected
    3361      244750 :                 uiInterface.NotifyBlockTip(GetSynchronizationState(fInitialDownload), pindexNewTip);
    3362      244750 :             }
    3363      368427 :         }
    3364             :         // When we reach this point, we switched to a new tip (stored in pindexNewTip).
    3365             : 
    3366      245423 :         if (nStopAtHeight && pindexNewTip && pindexNewTip->nHeight >= nStopAtHeight) StartShutdown();
    3367             : 
    3368             :         // We check shutdown only after giving ActivateBestChainStep a chance to run once so that we
    3369             :         // never shutdown before connecting the genesis block during LoadChainTip(). Previously this
    3370             :         // caused an assert() failure during shutdown in such cases as the UTXO DB flushing checks
    3371             :         // that the best block hash is non-null.
    3372      245423 :         if (ShutdownRequested()) break;
    3373      245410 :     } while (pindexNewTip != pindexMostWork);
    3374          13 :     CheckBlockIndex();
    3375             : 
    3376      226451 :     auto finish = Now<SteadyMilliseconds>();
    3377      226451 :     auto diff = finish - start;
    3378      226451 :     ::g_stats_client->timing("ActivateBestChain_ms", count_milliseconds(diff), 1.0f);
    3379             : 
    3380             :     // Write changes periodically to disk, after relay.
    3381      226451 :     if (!FlushStateToDisk(state, FlushStateMode::PERIODIC)) {
    3382           0 :         return false;
    3383             :     }
    3384             : 
    3385      226451 :     return true;
    3386     1633855 : }
    3387             : 
    3388          18 : bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)
    3389             : {
    3390          18 :     AssertLockNotHeld(m_chainstate_mutex);
    3391          18 :     AssertLockNotHeld(::cs_main);
    3392             :     {
    3393          18 :         LOCK(cs_main);
    3394          18 :         if (pindex->nChainWork < m_chain.Tip()->nChainWork) {
    3395             :             // Nothing to do, this block is not at the tip.
    3396           2 :             return true;
    3397             :         }
    3398          16 :         if (m_chain.Tip()->nChainWork > nLastPreciousChainwork) {
    3399             :             // The chain has been extended since the last call, reset the counter.
    3400           8 :             nBlockReverseSequenceId = -1;
    3401           8 :         }
    3402          16 :         nLastPreciousChainwork = m_chain.Tip()->nChainWork;
    3403          16 :         setBlockIndexCandidates.erase(pindex);
    3404          16 :         pindex->nSequenceId = nBlockReverseSequenceId;
    3405          16 :         if (nBlockReverseSequenceId > std::numeric_limits<int32_t>::min()) {
    3406             :             // We can't keep reducing the counter if somebody really wants to
    3407             :             // call preciousblock 2**31-1 times on the same set of tips...
    3408          16 :             nBlockReverseSequenceId--;
    3409          16 :         }
    3410          16 :         if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && !(pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK) && pindex->HaveTxsDownloaded()) {
    3411          16 :             setBlockIndexCandidates.insert(pindex);
    3412          16 :             PruneBlockIndexCandidates();
    3413          16 :         }
    3414          18 :     }
    3415             : 
    3416          16 :     return ActivateBestChain(state, std::shared_ptr<const CBlock>());
    3417          18 : }
    3418             : 
    3419         246 : bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex)
    3420             : {
    3421         246 :     AssertLockNotHeld(m_chainstate_mutex);
    3422         246 :     AssertLockNotHeld(::cs_main);
    3423             : 
    3424             :     // Genesis block can't be invalidated
    3425         246 :     assert(pindex);
    3426         246 :     if (pindex->nHeight == 0) return false;
    3427             : 
    3428         246 :     CBlockIndex* to_mark_failed = pindex;
    3429         246 :     bool pindex_was_in_chain = false;
    3430         246 :     int disconnected = 0;
    3431             : 
    3432             :     // We do not allow ActivateBestChain() to run while InvalidateBlock() is
    3433             :     // running, as that could cause the tip to change while we disconnect
    3434             :     // blocks.
    3435         246 :     LOCK(m_chainstate_mutex);
    3436             : 
    3437             :     // We'll be acquiring and releasing cs_main below, to allow the validation
    3438             :     // callbacks to run. However, we should keep the block index in a
    3439             :     // consistent state as we disconnect blocks -- in particular we need to
    3440             :     // add equal-work blocks to setBlockIndexCandidates as we disconnect.
    3441             :     // To avoid walking the block index repeatedly in search of candidates,
    3442             :     // build a map once so that we can look up candidate blocks by chain
    3443             :     // work as we go.
    3444         246 :     std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
    3445             : 
    3446             :     {
    3447         246 :         LOCK(cs_main);
    3448       53142 :         for (auto& entry : m_blockman.m_block_index) {
    3449       52896 :             CBlockIndex* candidate = &entry.second;
    3450             :             // We don't need to put anything in our active chain into the
    3451             :             // multimap, because those candidates will be found and considered
    3452             :             // as we disconnect.
    3453             :             // Instead, consider only non-active-chain blocks that have at
    3454             :             // least as much work as where we expect the new tip to end up.
    3455       54589 :             if (!m_chain.Contains(candidate) &&
    3456        1693 :                     !CBlockIndexWorkComparator()(candidate, pindex->pprev) &&
    3457         840 :                     candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
    3458          89 :                     candidate->HaveTxsDownloaded()) {
    3459          89 :                 candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate));
    3460          89 :             }
    3461             :         }
    3462         246 :     }
    3463             : 
    3464             :     // Disconnect (descendants of) pindex, and mark them invalid.
    3465        6388 :     while (true) {
    3466        6388 :         if (ShutdownRequested()) break;
    3467             : 
    3468             :         // Make sure the queue of validation callbacks doesn't grow unboundedly.
    3469        6388 :         LimitValidationInterfaceQueue();
    3470             : 
    3471        6388 :         LOCK(cs_main);
    3472             :         // Lock for as long as disconnectpool is in scope to make sure MaybeUpdateMempoolForReorg is
    3473             :         // called after DisconnectTip without unlocking in between
    3474        6388 :         LOCK(MempoolMutex());
    3475        6388 :         if (!m_chain.Contains(pindex)) break;
    3476        6142 :         pindex_was_in_chain = true;
    3477        6142 :         CBlockIndex *invalid_walk_tip = m_chain.Tip();
    3478        6142 :         const CBlockIndex* pindexOldTip = m_chain.Tip();
    3479             : 
    3480        6142 :         if (pindex == m_chainman.m_best_header) {
    3481         230 :             m_chainman.m_best_invalid = m_chainman.m_best_header;
    3482         230 :             m_chainman.m_best_header = m_chainman.m_best_header->pprev;
    3483         230 :         }
    3484             : 
    3485             :         // ActivateBestChain considers blocks already in m_chain
    3486             :         // unconditionally valid already, so force disconnect away from it.
    3487        6142 :         DisconnectedBlockTransactions disconnectpool;
    3488        6142 :         bool ret = DisconnectTip(state, &disconnectpool);
    3489             :         // DisconnectTip will add transactions to disconnectpool.
    3490             :         // Adjust the mempool to be consistent with the new tip, adding
    3491             :         // transactions back to the mempool if disconnecting was successful,
    3492             :         // and we're not doing a very deep invalidation (in which case
    3493             :         // keeping the mempool up to date is probably futile anyway).
    3494        6142 :         MaybeUpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
    3495        6142 :         if (!ret) return false;
    3496        6142 :         assert(invalid_walk_tip->pprev == m_chain.Tip());
    3497             : 
    3498        6142 :         if (pindexOldTip == m_chainman.m_best_header) {
    3499        5877 :             m_chainman.m_best_invalid = m_chainman.m_best_header;
    3500        5877 :             m_chainman.m_best_header = m_chainman.m_best_header->pprev;
    3501        5877 :         }
    3502             : 
    3503             :         // We immediately mark the disconnected blocks as invalid.
    3504             :         // This prevents a case where pruned nodes may fail to invalidateblock
    3505             :         // and be left unable to start as they have no tip candidates (as there
    3506             :         // are no blocks that meet the "have data and are not invalid per
    3507             :         // nStatus" criteria for inclusion in setBlockIndexCandidates).
    3508        6142 :         invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
    3509        6142 :         m_blockman.m_dirty_blockindex.insert(invalid_walk_tip);
    3510        6142 :         setBlockIndexCandidates.erase(invalid_walk_tip);
    3511        6142 :         setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
    3512        6142 :         if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
    3513             :             // We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
    3514             :             // need to be BLOCK_FAILED_CHILD instead.
    3515           0 :             to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
    3516           0 :             m_blockman.m_dirty_blockindex.insert(to_mark_failed);
    3517           0 :         }
    3518             : 
    3519             :         // Add any equal or more work headers to setBlockIndexCandidates
    3520        6142 :         auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->pprev->nChainWork);
    3521        6234 :         while (candidate_it != candidate_blocks_by_work.end()) {
    3522          92 :             if (!CBlockIndexWorkComparator()(candidate_it->second, invalid_walk_tip->pprev)) {
    3523          89 :                 setBlockIndexCandidates.insert(candidate_it->second);
    3524          89 :                 candidate_it = candidate_blocks_by_work.erase(candidate_it);
    3525          89 :             } else {
    3526           3 :                 ++candidate_it;
    3527             :             }
    3528             :         }
    3529             : 
    3530             :         // Track the last disconnected block, so we can correct its BLOCK_FAILED_CHILD status in future
    3531             :         // iterations, or, if it's the last one, call InvalidChainFound on it.
    3532        6142 :         to_mark_failed = invalid_walk_tip;
    3533        6388 :     }
    3534             : 
    3535         246 :     CheckBlockIndex();
    3536             : 
    3537             :     {
    3538         246 :         LOCK(cs_main);
    3539         246 :         if (m_chain.Contains(to_mark_failed)) {
    3540             :             // If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
    3541           0 :             return false;
    3542             :         }
    3543             : 
    3544             :         // Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
    3545         246 :         to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
    3546         246 :         m_blockman.m_dirty_blockindex.insert(to_mark_failed);
    3547         246 :         setBlockIndexCandidates.erase(to_mark_failed);
    3548         246 :         m_chainman.m_failed_blocks.insert(to_mark_failed);
    3549             : 
    3550             :         // If any new blocks somehow arrived while we were disconnecting
    3551             :         // (above), then the pre-calculation of what should go into
    3552             :         // setBlockIndexCandidates may have missed entries. This would
    3553             :         // technically be an inconsistency in the block index, but if we clean
    3554             :         // it up here, this should be an essentially unobservable error.
    3555             :         // Loop back over all block index entries and add any missing entries
    3556             :         // to setBlockIndexCandidates.
    3557      143994 :         for (auto& [_, block_index] : m_blockman.m_block_index) {
    3558       52896 :             if (block_index.IsValid(BLOCK_VALID_TRANSACTIONS) && !(block_index.nStatus & BLOCK_CONFLICT_CHAINLOCK) && block_index.HaveTxsDownloaded() && !setBlockIndexCandidates.value_comp()(&block_index, m_chain.Tip())) {
    3559         592 :                 setBlockIndexCandidates.insert(&block_index);
    3560         296 :             }
    3561             :         }
    3562             : 
    3563         246 :         InvalidChainFound(to_mark_failed);
    3564         246 :         GetMainSignals().SynchronousUpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
    3565         246 :         GetMainSignals().UpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
    3566         246 :     }
    3567             : 
    3568             :     // Only notify about a new block tip if the active chain was modified.
    3569         246 :     if (pindex_was_in_chain) {
    3570         242 :         uiInterface.NotifyBlockTip(GetSynchronizationState(IsInitialBlockDownload()), to_mark_failed->pprev);
    3571         242 :     }
    3572         246 :     return true;
    3573         246 : }
    3574             : 
    3575       59085 : void CChainState::EnforceBlock(BlockValidationState& state, const CBlockIndex *pindex)
    3576             : {
    3577       59085 :     AssertLockNotHeld(m_chainstate_mutex);
    3578       59085 :     AssertLockNotHeld(::cs_main);
    3579             : 
    3580       59085 :     LOCK2(m_chainstate_mutex, ::cs_main);
    3581             : 
    3582       59085 :     const CBlockIndex* pindex_walk = pindex;
    3583             : 
    3584       59169 :     while (pindex_walk && !m_chain.Contains(pindex_walk)) {
    3585             :         // Mark all blocks that have the same prevBlockHash but are not equal to blockHash as conflicting
    3586          84 :         auto itp = m_blockman.m_prev_block_index.equal_range(pindex_walk->pprev->GetBlockHash());
    3587         199 :         for (auto jt = itp.first; jt != itp.second; ++jt) {
    3588         115 :             if (jt->second == pindex_walk) {
    3589          84 :                 continue;
    3590             :             }
    3591          31 :             if (!MarkConflictingBlock(state, jt->second)) {
    3592           0 :                 LogPrintf("CChainState::%s -- MarkConflictingBlock failed: %s\n", __func__, state.ToString());
    3593             :                 // This should not have happened and we are in a state were it's not safe to continue anymore
    3594           0 :                 assert(false);
    3595             :             }
    3596          31 :             LogPrintf("CChainState::%s -- marked block %s as conflicting\n",
    3597             :                       __func__, jt->second->GetBlockHash().ToString());
    3598          31 :         }
    3599          84 :         pindex_walk = pindex_walk->pprev;
    3600             :     }
    3601             :     // In case blocks from the enforced chain are invalid at the moment, reconsider them.
    3602       59085 :     if (!pindex->IsValid()) {
    3603          53 :         ResetBlockFailureFlags(m_blockman.LookupBlockIndex(pindex->GetBlockHash()));
    3604          53 :     }
    3605       59085 : }
    3606             : 
    3607          31 : bool CChainState::MarkConflictingBlock(BlockValidationState& state, CBlockIndex *pindex)
    3608             : {
    3609          31 :     AssertLockHeld(cs_main);
    3610             : 
    3611             :     // We first disconnect backwards and then mark the blocks as conflicting.
    3612             : 
    3613          31 :     bool pindex_was_in_chain = false;
    3614          31 :     CBlockIndex *conflicting_walk_tip = m_chain.Tip();
    3615             : 
    3616          31 :     if (pindex == m_chainman.m_best_header) {
    3617          20 :         m_chainman.m_best_header = m_chainman.m_best_header->pprev;
    3618          20 :     }
    3619             : 
    3620             :     {
    3621          31 :     LOCK(MempoolMutex()); // Lock for as long as disconnectpool is in scope to make sure UpdateMempoolForReorg is called after DisconnectTip without unlocking in between
    3622          31 :     DisconnectedBlockTransactions disconnectpool;
    3623          78 :     while (m_chain.Contains(pindex)) {
    3624          47 :         const CBlockIndex* pindexOldTip = m_chain.Tip();
    3625          47 :         pindex_was_in_chain = true;
    3626             :         // ActivateBestChain considers blocks already in m_chain
    3627             :         // unconditionally valid already, so force disconnect away from it.
    3628          47 :         if (!DisconnectTip(state, &disconnectpool)) {
    3629             :             // It's probably hopeless to try to make the mempool consistent
    3630             :             // here if DisconnectTip failed, but we can try.
    3631           0 :             MaybeUpdateMempoolForReorg(disconnectpool, false);
    3632           0 :             return false;
    3633             :         }
    3634          47 :         if (pindexOldTip == m_chainman.m_best_header) {
    3635          15 :             m_chainman.m_best_header = m_chainman.m_best_header->pprev;
    3636          15 :         }
    3637             :     }
    3638             : 
    3639             :     // Now mark the blocks we just disconnected as descendants conflicting
    3640             :     // (note this may not be all descendants).
    3641          52 :     while (pindex_was_in_chain && conflicting_walk_tip != pindex) {
    3642          21 :         conflicting_walk_tip->nStatus |= BLOCK_CONFLICT_CHAINLOCK;
    3643          21 :         setBlockIndexCandidates.erase(conflicting_walk_tip);
    3644          21 :         conflicting_walk_tip = conflicting_walk_tip->pprev;
    3645             :     }
    3646             : 
    3647             :     // Mark the block itself as conflicting.
    3648          31 :     pindex->nStatus |= BLOCK_CONFLICT_CHAINLOCK;
    3649          31 :     setBlockIndexCandidates.erase(pindex);
    3650             : 
    3651             :     // DisconnectTip will add transactions to disconnectpool; try to add these
    3652             :     // back to the mempool.
    3653          31 :         MaybeUpdateMempoolForReorg(disconnectpool, true);
    3654          31 :     } // m_mempool.cs
    3655             : 
    3656             :     // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
    3657             :     // add it again.
    3658          31 :     BlockMap::iterator it = m_blockman.m_block_index.begin();
    3659        8732 :     while (it != m_blockman.m_block_index.end()) {
    3660        8701 :         if (it->second.IsValid(BLOCK_VALID_TRANSACTIONS) && !(it->second.nStatus & BLOCK_CONFLICT_CHAINLOCK) && it->second.HaveTxsDownloaded() && !setBlockIndexCandidates.value_comp()(&it->second, m_chain.Tip())) {
    3661          34 :             setBlockIndexCandidates.insert(&it->second);
    3662          34 :         }
    3663        8701 :         it++;
    3664             :     }
    3665             : 
    3666          31 :     ConflictingChainFound(pindex);
    3667          31 :     GetMainSignals().SynchronousUpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
    3668          31 :     GetMainSignals().UpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
    3669             : 
    3670             :     // Only notify about a new block tip if the active chain was modified.
    3671          31 :     if (pindex_was_in_chain) {
    3672          26 :         uiInterface.NotifyBlockTip(GetSynchronizationState(IsInitialBlockDownload()), pindex->pprev);
    3673          26 :     }
    3674          31 :     return true;
    3675          31 : }
    3676             : 
    3677        2093 : void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex, bool ignore_chainlocks) {
    3678        2093 :     AssertLockHeld(cs_main);
    3679             : 
    3680        2093 :     if (!pindex) {
    3681        1962 :         if (m_chainman.m_best_invalid && m_chainman.m_best_invalid->GetAncestor(m_chain.Height()) == m_chain.Tip()) {
    3682           7 :             LogPrintf("%s: the best known invalid block (%s) is ahead of our tip, reconsidering\n",
    3683             :                     __func__, m_chainman.m_best_invalid->GetBlockHash().ToString());
    3684           7 :             pindex = m_chainman.m_best_invalid;
    3685           7 :         } else {
    3686        1955 :             return;
    3687             :         }
    3688           7 :     }
    3689             : 
    3690         138 :     int nHeight = pindex->nHeight;
    3691             : 
    3692             :     // Remove the invalidity flag from this block and all its descendants.
    3693       32714 :     for (auto& [_, block_index] : m_blockman.m_block_index) {
    3694       31320 :         if (!block_index.IsValid() && block_index.GetAncestor(nHeight) == pindex) {
    3695        1318 :             block_index.nStatus &= ~BLOCK_FAILED_MASK;
    3696        1318 :             if (ignore_chainlocks) {
    3697           0 :                 block_index.nStatus &= ~BLOCK_CONFLICT_CHAINLOCK;
    3698           0 :             }
    3699        2636 :             m_blockman.m_dirty_blockindex.insert(&block_index);
    3700        1318 :             if (block_index.IsValid(BLOCK_VALID_TRANSACTIONS) && block_index.HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), &block_index)) {
    3701        1155 :                 if (ignore_chainlocks || !(block_index.nStatus & BLOCK_CONFLICT_CHAINLOCK)) {
    3702        2310 :                     setBlockIndexCandidates.insert(&block_index);
    3703        1155 :                 }
    3704        1155 :             }
    3705        1318 :             if (&block_index == m_chainman.m_best_invalid) {
    3706             :                 // Reset invalid block marker if it was pointing to one of those.
    3707         101 :                 m_chainman.m_best_invalid = nullptr;
    3708         101 :             }
    3709        2636 :             m_chainman.m_failed_blocks.erase(&block_index);
    3710        1318 :         }
    3711             :     }
    3712             : 
    3713             :     // Remove the invalidity flag from all ancestors too.
    3714       29442 :     while (pindex != nullptr) {
    3715       29304 :         if (pindex->nStatus & (BLOCK_FAILED_MASK | BLOCK_CONFLICT_CHAINLOCK)) {
    3716         617 :             pindex->nStatus &= ~BLOCK_FAILED_MASK;
    3717         617 :             if (ignore_chainlocks) {
    3718           0 :                 pindex->nStatus &= ~BLOCK_CONFLICT_CHAINLOCK;
    3719           0 :             }
    3720         617 :             m_blockman.m_dirty_blockindex.insert(pindex);
    3721         617 :             if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && pindex->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), pindex)) {
    3722         329 :                 if (ignore_chainlocks || !(pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK)) {
    3723         329 :                     setBlockIndexCandidates.insert(pindex);
    3724         329 :                 }
    3725         329 :             }
    3726         617 :             if (pindex == m_chainman.m_best_invalid) {
    3727             :                 // Reset invalid block marker if it was pointing to one of those.
    3728          14 :                 m_chainman.m_best_invalid = nullptr;
    3729          14 :             }
    3730         617 :             m_chainman.m_failed_blocks.erase(pindex);
    3731             :             // Mark all nearest BLOCK_FAILED_CHILD descendants (if any) as BLOCK_FAILED_VALID
    3732         617 :             auto itp = m_blockman.m_prev_block_index.equal_range(pindex->GetBlockHash());
    3733        1236 :             for (auto jt = itp.first; jt != itp.second; ++jt) {
    3734         619 :                 if (jt->second->nStatus & BLOCK_FAILED_CHILD) {
    3735           2 :                     jt->second->nStatus |= BLOCK_FAILED_VALID;
    3736           2 :                     m_chainman.m_failed_blocks.insert(jt->second);
    3737           2 :                     m_blockman.m_dirty_blockindex.insert(jt->second);
    3738           2 :                     setBlockIndexCandidates.erase(jt->second);
    3739           2 :                 }
    3740         619 :             }
    3741         617 :         }
    3742       29304 :         pindex = pindex->pprev;
    3743             :     }
    3744        2093 : }
    3745             : 
    3746             : /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
    3747      248574 : void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos)
    3748             : {
    3749      248574 :     AssertLockHeld(cs_main);
    3750      248574 :     pindexNew->nTx = block.vtx.size();
    3751      248574 :     pindexNew->nChainTx = 0;
    3752      248574 :     pindexNew->nFile = pos.nFile;
    3753      248574 :     pindexNew->nDataPos = pos.nPos;
    3754      248574 :     pindexNew->nUndoPos = 0;
    3755      248574 :     pindexNew->nStatus |= BLOCK_HAVE_DATA;
    3756      248574 :     pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
    3757      248574 :     m_blockman.m_dirty_blockindex.insert(pindexNew);
    3758             : 
    3759      248574 :     if (pindexNew->pprev == nullptr || pindexNew->pprev->HaveTxsDownloaded()) {
    3760             :         // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
    3761      241780 :         std::deque<CBlockIndex*> queue;
    3762      241780 :         queue.push_back(pindexNew);
    3763             : 
    3764             :         // Recursively process any descendant blocks that now may be eligible to be connected.
    3765      490346 :         while (!queue.empty()) {
    3766      248566 :             CBlockIndex *pindex = queue.front();
    3767      248566 :             queue.pop_front();
    3768      248566 :             pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
    3769      248566 :             pindex->nSequenceId = nBlockSequenceId++;
    3770      248566 :             if (m_chain.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, m_chain.Tip())) {
    3771      243845 :                 if (!(pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK)) {
    3772      243845 :                     setBlockIndexCandidates.insert(pindex);
    3773      243845 :                 }
    3774      243845 :             }
    3775      248566 :             std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = m_blockman.m_blocks_unlinked.equal_range(pindex);
    3776      255352 :             while (range.first != range.second) {
    3777        6786 :                 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
    3778        6786 :                 queue.push_back(it->second);
    3779        6786 :                 range.first++;
    3780        6786 :                 m_blockman.m_blocks_unlinked.erase(it);
    3781             :             }
    3782             :         }
    3783      241780 :     } else {
    3784        6794 :         if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
    3785        6794 :             m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
    3786        6794 :         }
    3787             :     }
    3788      248574 : }
    3789             : 
    3790      740960 : static bool CheckBlockHeader(const CBlockHeader& block, const uint256& hash, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
    3791             : {
    3792             :     // Check proof of work matches claimed amount
    3793      740960 :     if (fCheckPOW && !CheckProofOfWork(hash, block.nBits, consensusParams))
    3794           3 :         return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
    3795             : 
    3796             :     // Check DevNet
    3797      740969 :     if (!consensusParams.hashDevnetGenesisBlock.IsNull() &&
    3798          16 :             block.hashPrevBlock == consensusParams.hashGenesisBlock &&
    3799          12 :             hash != consensusParams.hashDevnetGenesisBlock) {
    3800           0 :         LogPrintf("ERROR: CheckBlockHeader(): wrong devnet genesis\n");
    3801           0 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "devnet-genesis");
    3802             :     }
    3803             : 
    3804      740957 :     return true;
    3805      740960 : }
    3806             : 
    3807     1041267 : bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot, const uint256* known_hash)
    3808             : {
    3809             :     // These are checks that are independent of context.
    3810             : 
    3811     1041267 :     auto start = Now<SteadyMicroseconds>();
    3812             : 
    3813             :     ASSERT_IF_DEBUG(!known_hash || *known_hash == block.GetHash());
    3814             : 
    3815     1041267 :     if (block.fChecked)
    3816      569309 :         return true;
    3817             : 
    3818             :     // Check that the header is valid (particularly PoW).  This is mostly
    3819             :     // redundant with the call in AcceptBlockHeader.
    3820      471958 :     const uint256 hash{known_hash ? *known_hash : block.GetHash()};
    3821      471958 :     if (!CheckBlockHeader(block, hash, state, consensusParams, fCheckPOW))
    3822           3 :         return false;
    3823             : 
    3824             :     // Check the merkle root.
    3825      471955 :     if (fCheckMerkleRoot) {
    3826             :         bool mutated;
    3827      296719 :         uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
    3828      296719 :         if (block.hashMerkleRoot != hashMerkleRoot2)
    3829          17 :             return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txnmrklroot", "hashMerkleRoot mismatch");
    3830             : 
    3831             :         // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
    3832             :         // of transactions in a block without affecting the merkle root of a block,
    3833             :         // while still invalidating it.
    3834      296702 :         if (mutated)
    3835         471 :             return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txns-duplicate", "duplicate transaction");
    3836      296231 :     }
    3837             : 
    3838             :     // All potential-corruption validation must be done before we do any
    3839             :     // transaction validation, as otherwise we may mark the header as invalid
    3840             :     // because we receive the wrong transactions for it.
    3841             : 
    3842             :     // Size limits (relaxed)
    3843      471467 :     if (block.vtx.empty() || block.vtx.size() > MaxBlockSize() || ::GetSerializeSize(block, PROTOCOL_VERSION) > MaxBlockSize())
    3844           3 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-length", "size limits failed");
    3845             : 
    3846             :     // First transaction must be coinbase, the rest must not be
    3847      471464 :     if (block.vtx.empty() || !block.vtx[0]->IsCoinBase())
    3848           5 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-missing", "first tx is not coinbase");
    3849      940835 :     for (unsigned int i = 1; i < block.vtx.size(); i++)
    3850      469380 :         if (block.vtx[i]->IsCoinBase())
    3851           4 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-multiple", "more than one coinbase");
    3852             : 
    3853             :     // Check transactions
    3854             :     // Must check for duplicate inputs (see CVE-2018-17144)
    3855     1410047 :     for (const auto& tx : block.vtx) {
    3856      940825 :         TxValidationState tx_state;
    3857      940825 :         if (!CheckTransaction(*tx, tx_state)) {
    3858             :             // CheckBlock() does context-free validation checks. The only
    3859             :             // possible failures are consensus failures.
    3860        2233 :             assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS);
    3861        4466 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
    3862        2233 :                                  strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), tx_state.GetDebugMessage()));
    3863             :         }
    3864      940825 :     }
    3865      469222 :     unsigned int nSigOps = 0;
    3866     1404947 :     for (const auto& tx : block.vtx)
    3867             :     {
    3868      935725 :         nSigOps += GetLegacySigOpCount(*tx);
    3869             :     }
    3870             :     // sigops limits (relaxed)
    3871      469222 :     if (nSigOps > MaxBlockSigOps())
    3872           3 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops", "out-of-bounds SigOpCount");
    3873             : 
    3874      469219 :     if (fCheckPOW && fCheckMerkleRoot)
    3875      293978 :         block.fChecked = true;
    3876             : 
    3877      469219 :     auto finish = Now<SteadyMicroseconds>();
    3878      469219 :     auto diff = finish - start;
    3879      469219 :     ::g_stats_client->timing("CheckBlock_us", count_microseconds(diff), 1.0f);
    3880             : 
    3881      469219 :     return true;
    3882     1041267 : }
    3883             : 
    3884             : /** Context-dependent validity checks.
    3885             :  *  By "context", we mean only the previous block headers, but not the UTXO
    3886             :  *  set; UTXO-related validity checks are done in ConnectBlock().
    3887             :  *  NOTE: This function is not currently invoked by ConnectBlock(), so we
    3888             :  *  should consider upgrade issues if we change which consensus rules are
    3889             :  *  enforced in this function (eg by adding a new consensus rule). See comment
    3890             :  *  in ConnectBlock().
    3891             :  *  Note that -reindex-chainstate skips the validation that happens here!
    3892             :  */
    3893      356623 : static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
    3894             : {
    3895      356623 :     AssertLockHeld(::cs_main);
    3896      356623 :     assert(pindexPrev != nullptr);
    3897      356623 :     const int nHeight = pindexPrev->nHeight + 1;
    3898             : 
    3899             :     // Check proof of work
    3900      356623 :     if (chainman.GetParams().NetworkIDString() == CBaseChainParams::MAIN && nHeight <= 68589){
    3901             :         // architecture issues with DGW v1 and v2)
    3902         144 :         unsigned int nBitsNext = GetNextWorkRequired(pindexPrev, &block, chainman.GetConsensus());
    3903         144 :         double n1 = ConvertBitsToDouble(block.nBits);
    3904         144 :         double n2 = ConvertBitsToDouble(nBitsNext);
    3905             : 
    3906         144 :         if (abs(n1-n2) > n1*0.5) {
    3907           0 :             LogPrintf("ERROR: %s : incorrect proof of work (DGW pre-fork) - %f %f %f at %d\n", __func__, abs(n1-n2), n1, n2, nHeight);
    3908           0 :             return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits");
    3909             :         }
    3910         144 :     } else {
    3911      356479 :         if (block.nBits != GetNextWorkRequired(pindexPrev, &block, chainman.GetConsensus())) {
    3912           5 :             return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", strprintf("incorrect proof of work at %d", nHeight));
    3913             :         }
    3914             :     }
    3915             : 
    3916             :     // Check against checkpoints
    3917      356618 :     if (fCheckpointsEnabled) {
    3918             :         // Don't accept any forks from the main chain prior to last checkpoint.
    3919             :         // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
    3920             :         // BlockIndex().
    3921      356608 :         const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
    3922      356608 :         if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
    3923           2 :             LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
    3924           2 :             return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
    3925             :         }
    3926      356606 :     }
    3927             : 
    3928             :     // Check timestamp against prev
    3929      356616 :     if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
    3930          13 :         return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", strprintf("block's timestamp is too early %d %d", block.GetBlockTime(), pindexPrev->GetMedianTimePast()));
    3931             : 
    3932             :     // Check timestamp
    3933      356603 :     if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
    3934          13 :         return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", strprintf("block timestamp too far in the future %d %d", block.GetBlockTime(), nAdjustedTime + 2 * 60 * 60));
    3935             : 
    3936             :     // Reject blocks with outdated version
    3937      357104 :     if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_HEIGHTINCB)) ||
    3938      357603 :         (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_DERSIG)) ||
    3939      357091 :         (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_CLTV))) {
    3940        2045 :             return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
    3941        2045 :                                  strprintf("rejected nVersion=0x%08x block", block.nVersion));
    3942             :     }
    3943             : 
    3944      356577 :     return true;
    3945      356617 : }
    3946             : 
    3947             : /** NOTE: This function is not currently invoked by ConnectBlock(), so we
    3948             :  *  should consider upgrade issues if we change which consensus rules are
    3949             :  *  enforced in this function (eg by adding a new consensus rule). See comment
    3950             :  *  in ConnectBlock().
    3951             :  *  Note that -reindex-chainstate skips the validation that happens here!
    3952             :  */
    3953      335231 : static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
    3954             : {
    3955             :     // TODO: validate - why do we need this cs_main ?
    3956      335231 :     AssertLockHeld(::cs_main);
    3957      335231 :     const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
    3958             : 
    3959             :     // Enforce BIP113 (Median Time Past).
    3960      335231 :     bool enforce_locktime_median_time_past{false};
    3961      335231 :     if (DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
    3962      331778 :         assert(pindexPrev != nullptr);
    3963      331778 :         enforce_locktime_median_time_past = true;
    3964      331778 :     }
    3965             : 
    3966      335231 :     const int64_t nLockTimeCutoff{enforce_locktime_median_time_past ?
    3967      331778 :                                       pindexPrev->GetMedianTimePast() :
    3968        3453 :                                       block.GetBlockTime()};
    3969             : 
    3970      335231 :     bool fDIP0001Active_context = DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_DIP0001);
    3971      335231 :     bool fDIP0003Active_context = DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
    3972             : 
    3973             :     // Size limits
    3974      335231 :     unsigned int nMaxBlockSize = MaxBlockSize(fDIP0001Active_context);
    3975      335231 :     if (block.vtx.empty() || block.vtx.size() > nMaxBlockSize || ::GetSerializeSize(block, PROTOCOL_VERSION) > nMaxBlockSize)
    3976           3 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-length", "size limits failed");
    3977             : 
    3978             :     // Check that all transactions are finalized and not over-sized
    3979             :     // Also count sigops
    3980      335228 :     unsigned int nSigOps = 0;
    3981     1027519 :     for (const auto& tx : block.vtx) {
    3982      692307 :         if (!IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
    3983          16 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal", "non-final transaction");
    3984             :         }
    3985      692291 :         TxValidationState tx_state;
    3986      692291 :         if (!ContextualCheckTransaction(*tx, tx_state, chainman.GetConsensus(), pindexPrev)) {
    3987             :             // ContextCheckTransaction() does validation checks than only should
    3988             :             // fails as consensus failures.
    3989           0 :             assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS);
    3990           0 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
    3991           0 :                                  strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), tx_state.GetDebugMessage()));
    3992             :         }
    3993      692291 :         nSigOps += GetLegacySigOpCount(*tx);
    3994      692291 :     }
    3995             : 
    3996             :     // Check sigops
    3997      335212 :     if (nSigOps > MaxBlockSigOps(fDIP0001Active_context))
    3998          19 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops", "out-of-bounds SigOpCount");
    3999             : 
    4000             :     // Enforce rule that the coinbase starts with serialized block height
    4001             :     // After DIP3/DIP4 activation, we don't enforce the height in the input script anymore.
    4002             :     // The CbTx special transaction payload will then contain the height, which is checked in CheckCbTx
    4003      335193 :     if (DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), Consensus::DEPLOYMENT_HEIGHTINCB) && !fDIP0003Active_context)
    4004             :     {
    4005      168371 :         CScript expect = CScript() << nHeight;
    4006      336739 :         if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
    4007      168368 :             !std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) {
    4008           3 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-height", "block height mismatch in coinbase");
    4009             :         }
    4010      168371 :     }
    4011             : 
    4012      335190 :     if (fDIP0003Active_context) {
    4013      166618 :         if (block.vtx[0]->nType != TRANSACTION_COINBASE) {
    4014           0 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-type", "coinbase is not a CbTx");
    4015             :         }
    4016      166618 :     }
    4017             : 
    4018      335190 :     return true;
    4019      335231 : }
    4020             : 
    4021      606187 : bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex, const uint256& hash)
    4022             : {
    4023      606187 :     AssertLockHeld(cs_main);
    4024             : 
    4025             :     ASSERT_IF_DEBUG(hash == block.GetHash());
    4026             : 
    4027             :     // TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES
    4028      606187 :     BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
    4029      606187 :     if (hash != GetConsensus().hashGenesisBlock) {
    4030      606117 :         if (miSelf != m_blockman.m_block_index.end()) {
    4031             :             // Block header is already known.
    4032      337115 :             CBlockIndex* pindex = &(miSelf->second);
    4033      337115 :             if (ppindex)
    4034      337115 :                 *ppindex = pindex;
    4035      337115 :             if (pindex->nStatus & BLOCK_FAILED_MASK) {
    4036         449 :                 LogPrint(BCLog::VALIDATION, "%s: block %s is marked invalid\n", __func__, hash.ToString());
    4037         449 :                 return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, "duplicate");
    4038             :             }
    4039      336666 :             if (pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK) {
    4040           5 :                 LogPrintf("ERROR: %s: block %s is marked conflicting\n", __func__, hash.ToString());
    4041           5 :                 return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "duplicate");
    4042             :             }
    4043      336661 :             return true;
    4044             :         }
    4045             : 
    4046      269002 :         if (!CheckBlockHeader(block, hash, state, GetConsensus())) {
    4047           0 :             LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
    4048           0 :             return false;
    4049             :         }
    4050             : 
    4051             :         // Get prev block index
    4052      269002 :         CBlockIndex* pindexPrev = nullptr;
    4053      269002 :         BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)};
    4054      269002 :         if (mi == m_blockman.m_block_index.end()) {
    4055           6 :             LogPrint(BCLog::VALIDATION, "header %s has prev block not found: %s\n", hash.ToString(), block.hashPrevBlock.ToString());
    4056           6 :             return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");
    4057             :         }
    4058      268996 :         pindexPrev = &((*mi).second);
    4059      268996 :         assert(pindexPrev);
    4060             : 
    4061      268996 :         if (pindexPrev->nStatus & BLOCK_FAILED_MASK) {
    4062          11 :             LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString());
    4063          11 :             return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
    4064             :         }
    4065             : 
    4066      268985 :         if (pindexPrev->nStatus & BLOCK_CONFLICT_CHAINLOCK) {
    4067             :             // it's ok-ish, the other node is probably missing the latest chainlock
    4068           3 :             LogPrint(BCLog::VALIDATION, "%s: prev block %s conflicts with chainlock\n", __func__, block.hashPrevBlock.ToString());
    4069           3 :             return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-prevblk-chainlock");
    4070             :         }
    4071             : 
    4072      268982 :         if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, GetAdjustedTime())) {
    4073          34 :             LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
    4074          34 :             return false;
    4075             :         }
    4076             : 
    4077             :         /* Determine if this block descends from any block which has been found
    4078             :          * invalid (m_failed_blocks), then mark pindexPrev and any blocks between
    4079             :          * them as failed. For example:
    4080             :          *
    4081             :          *                D3
    4082             :          *              /
    4083             :          *      B2 - C2
    4084             :          *    /         \
    4085             :          *  A             D2 - E2 - F2
    4086             :          *    \
    4087             :          *      B1 - C1 - D1 - E1
    4088             :          *
    4089             :          * In the case that we attempted to reorg from E1 to F2, only to find
    4090             :          * C2 to be invalid, we would mark D2, E2, and F2 as BLOCK_FAILED_CHILD
    4091             :          * but NOT D3 (it was not in any of our candidate sets at the time).
    4092             :          *
    4093             :          * In any case D3 will also be marked as BLOCK_FAILED_CHILD at restart
    4094             :          * in LoadBlockIndex.
    4095             :          */
    4096      268948 :         if (!pindexPrev->IsValid(BLOCK_VALID_SCRIPTS)) {
    4097             :             // The above does not mean "invalid": it checks if the previous block
    4098             :             // hasn't been validated up to BLOCK_VALID_SCRIPTS. This is a performance
    4099             :             // optimization, in the common case of adding a new block to the tip,
    4100             :             // we don't need to iterate over the failed blocks list.
    4101      246651 :             for (const CBlockIndex* failedit : m_failed_blocks) {
    4102      155259 :                 if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) {
    4103           2 :                     assert(failedit->nStatus & BLOCK_FAILED_VALID);
    4104           2 :                     CBlockIndex* invalid_walk = pindexPrev;
    4105           4 :                     while (invalid_walk != failedit) {
    4106           2 :                         invalid_walk->nStatus |= BLOCK_FAILED_CHILD;
    4107           2 :                         m_blockman.m_dirty_blockindex.insert(invalid_walk);
    4108           2 :                         invalid_walk = invalid_walk->pprev;
    4109             :                     }
    4110           2 :                     LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString());
    4111           2 :                     return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
    4112             :                 }
    4113             :             }
    4114       91392 :         }
    4115             : 
    4116      268946 :         if (ActiveChainstate().m_chain_helper->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
    4117           6 :             if (miSelf == m_blockman.m_block_index.end()) {
    4118           6 :                 m_blockman.AddToBlockIndex(block, hash, m_best_header, BLOCK_CONFLICT_CHAINLOCK);
    4119           6 :             }
    4120           6 :             LogPrintf("ERROR: %s: header %s conflicts with chainlock\n", __func__, hash.ToString());
    4121           6 :             return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock");
    4122             :         }
    4123      268940 :     }
    4124      269010 :     CBlockIndex* pindex{m_blockman.AddToBlockIndex(block, hash, m_best_header)};
    4125             : 
    4126      269010 :     if (ppindex)
    4127      269010 :         *ppindex = pindex;
    4128             : 
    4129             :     // Since this is the earliest point at which we have determined that a
    4130             :     // header is both new and valid, log here.
    4131             :     //
    4132             :     // These messages are valuable for detecting potential selfish mining behavior;
    4133             :     // if multiple displacing headers are seen near simultaneously across many
    4134             :     // nodes in the network, this might be an indication of selfish mining. Having
    4135             :     // this log by default when not in IBD ensures broad availability of this data
    4136             :     // in case investigation is merited.
    4137      269010 :     const auto msg = strprintf(
    4138      269010 :         "Saw new header hash=%s height=%d", hash.ToString(), pindex->nHeight);
    4139             : 
    4140      269010 :     if (ActiveChainstate().IsInitialBlockDownload()) {
    4141       24551 :         LogPrintLevel(BCLog::VALIDATION, BCLog::Level::Debug, "%s\n", msg);
    4142       24551 :     } else {
    4143      244459 :         LogPrintf("%s\n", msg);
    4144             :     }
    4145             : 
    4146             :     // Notify external listeners about accepted block header
    4147      269010 :     GetMainSignals().AcceptedBlockHeader(pindex);
    4148      269010 :     return true;
    4149      606187 : }
    4150             : 
    4151             : // Exposed wrapper for AcceptBlockHeader
    4152      224057 : bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CBlockIndex** ppindex)
    4153             : {
    4154      224057 :     AssertLockNotHeld(cs_main);
    4155             :     {
    4156      224057 :         LOCK(cs_main);
    4157      568340 :         for (const CBlockHeader& header : headers) {
    4158      344585 :             CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
    4159      344585 :             bool accepted{AcceptBlockHeader(header, state, &pindex, header.GetHash())};
    4160      344585 :             ActiveChainstate().CheckBlockIndex();
    4161             : 
    4162      344585 :             if (!accepted) {
    4163         302 :                 return false;
    4164             :             }
    4165      344283 :             if (ppindex) {
    4166      343467 :                 *ppindex = pindex;
    4167      343467 :             }
    4168             :         }
    4169      224057 :     }
    4170      223755 :     if (NotifyHeaderTip(ActiveChainstate())) {
    4171      117950 :         if (ActiveChainstate().IsInitialBlockDownload() && ppindex && *ppindex) {
    4172         200 :             const CBlockIndex& last_accepted{**ppindex};
    4173         200 :             const int64_t blocks_left{(GetTime() - last_accepted.GetBlockTime()) / GetConsensus().nPowTargetSpacing};
    4174         200 :             const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
    4175         200 :             LogPrintf("Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
    4176         200 :         }
    4177      117950 :     }
    4178      223755 :     return true;
    4179      224057 : }
    4180             : 
    4181             : /** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
    4182      261602 : bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, const uint256* known_hash)
    4183             : {
    4184      261602 :     auto start = Now<SteadyMicroseconds>();
    4185             : 
    4186      261602 :     const CBlock& block = *pblock;
    4187             : 
    4188      261602 :     if (fNewBlock) *fNewBlock = false;
    4189      261602 :     AssertLockHeld(cs_main);
    4190             : 
    4191      261602 :     CBlockIndex *pindexDummy = nullptr;
    4192      261602 :     CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
    4193             : 
    4194             :     // If the caller supplies a pre-computed hash, verify it in debug builds.
    4195             :     // In release builds a wrong hash is still caught: AcceptBlockHeader calls
    4196             :     // CheckBlockHeader which runs CheckProofOfWork against the header's nBits.
    4197             :     ASSERT_IF_DEBUG(!known_hash || *known_hash == block.GetHash());
    4198             : 
    4199      261602 :     const uint256 hash{known_hash ? *known_hash : block.GetHash()};
    4200      261602 :     bool accepted_header{m_chainman.AcceptBlockHeader(block, state, &pindex, hash)};
    4201      261602 :     CheckBlockIndex();
    4202             : 
    4203      261602 :     if (!accepted_header)
    4204         214 :         return false;
    4205             : 
    4206             :     // Try to process all requested blocks that we don't have, but only
    4207             :     // process an unrequested block if it's new and has enough work to
    4208             :     // advance our tip, and isn't too many blocks ahead.
    4209      261388 :     bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
    4210      261388 :     bool fHasMoreOrSameWork = (m_chain.Tip() ? pindex->nChainWork >= m_chain.Tip()->nChainWork : true);
    4211             :     // Blocks that are too out-of-order needlessly limit the effectiveness of
    4212             :     // pruning, because pruning will not delete block files that contain any
    4213             :     // blocks which are too close in height to the tip.  Apply this test
    4214             :     // regardless of whether pruning is enabled; it should generally be safe to
    4215             :     // not process unrequested blocks.
    4216      261388 :     bool fTooFarAhead{pindex->nHeight > m_chain.Height() + int(MIN_BLOCKS_TO_KEEP)};
    4217             : 
    4218             :     // TODO: Decouple this function from the block download logic by removing fRequested
    4219             :     // This requires some new chain data structure to efficiently look up if a
    4220             :     // block is in a chain leading to a candidate for best tip, despite not
    4221             :     // being such a candidate itself.
    4222             :     // Note that this would break the getblockfrompeer RPC
    4223             : 
    4224             :     // TODO: deal better with return value and error conditions for duplicate
    4225             :     // and unrequested blocks.
    4226      261388 :     if (fAlreadyHave) return true;
    4227      250889 :     if (!fRequested) {  // If we didn't ask for it:
    4228        4371 :         if (pindex->nTx != 0) return true;    // This is a previously-processed block that was pruned
    4229        4371 :         if (!fHasMoreOrSameWork) return true; // Don't process less-work chains
    4230        1095 :         if (fTooFarAhead) return true;        // Block height is too high
    4231             : 
    4232             :         // Protect against DoS attacks from low-work chains.
    4233             :         // If our tip is behind, a peer could try to send us
    4234             :         // low-work blocks on a fake chain that we would never
    4235             :         // request; don't process these.
    4236        1093 :         if (pindex->nChainWork < nMinimumChainWork) return true;
    4237        1091 :     }
    4238             : 
    4239      247609 :     if (!CheckBlock(block, state, m_params.GetConsensus(), true, true, &hash) ||
    4240      247609 :         !ContextualCheckBlock(block, state, m_chainman, pindex->pprev)) {
    4241          38 :         if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
    4242          38 :             pindex->nStatus |= BLOCK_FAILED_VALID;
    4243          38 :             m_blockman.m_dirty_blockindex.insert(pindex);
    4244          38 :         }
    4245          38 :         return error("%s: %s", __func__, state.ToString());
    4246             :     }
    4247             : 
    4248             :     // Header is valid/has work, merkle tree is good...RELAY NOW
    4249             :     // (but if it does not build on our best tip, let the SendMessages loop relay it)
    4250      247571 :     if (!IsInitialBlockDownload() && m_chain.Tip() == pindex->pprev)
    4251      224672 :         GetMainSignals().NewPoWValidBlock(pindex, pblock);
    4252             : 
    4253             :     // Write block to history file
    4254      247571 :     if (fNewBlock) *fNewBlock = true;
    4255             :     try {
    4256      247571 :         FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, pindex->nHeight, m_chain, dbp)};
    4257      247571 :         if (blockPos.IsNull()) {
    4258           0 :             state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
    4259           0 :             return false;
    4260             :         }
    4261      247571 :         ReceivedBlockTransactions(block, pindex, blockPos);
    4262      247571 :     } catch (const std::runtime_error& e) {
    4263           0 :         return AbortNode(state, std::string("System error: ") + e.what());
    4264           0 :     }
    4265             : 
    4266      247571 :     if (CanFlushToDisk()) {
    4267      247567 :         FlushStateToDisk(state, FlushStateMode::NONE);
    4268      247567 :     }
    4269             : 
    4270      247571 :     CheckBlockIndex();
    4271             : 
    4272      247571 :     auto finish = Now<SteadyMicroseconds>();
    4273      247571 :     auto diff = finish - start;
    4274      247571 :     ::g_stats_client->timing("AcceptBlock_us", count_microseconds(diff), 1.0f);
    4275             : 
    4276      247571 :     return true;
    4277      261602 : }
    4278             : 
    4279      254028 : bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
    4280             : {
    4281      254028 :     AssertLockNotHeld(cs_main);
    4282             : 
    4283             :     {
    4284      254028 :         CBlockIndex *pindex = nullptr;
    4285      254028 :         if (new_block) *new_block = false;
    4286      254028 :         BlockValidationState state;
    4287             : 
    4288             :         // CheckBlock() does not support multi-threaded block validation because CBlock::fChecked can cause data race.
    4289             :         // Therefore, the following critical section must include the CheckBlock() call as well.
    4290      254028 :         LOCK(cs_main);
    4291             : 
    4292             :         // Skipping AcceptBlock() for CheckBlock() failures means that we will never mark a block as invalid if
    4293             :         // CheckBlock() fails.  This is protective against consensus failure if there are any unknown forms of block
    4294             :         // malleability that cause CheckBlock() to fail; see e.g. CVE-2012-2459 and
    4295             :         // https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html.  Because CheckBlock() is
    4296             :         // not very expensive, the anti-DoS benefits of caching failure (of a definitely-invalid block) are not substantial.
    4297      254028 :         bool ret = CheckBlock(*block, state, GetConsensus());
    4298      254028 :         if (ret) {
    4299             :             // Store to disk
    4300      251300 :             ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
    4301      251300 :         }
    4302      254028 :         if (!ret) {
    4303        2980 :             GetMainSignals().BlockChecked(*block, state);
    4304        2980 :             return error("%s: AcceptBlock FAILED: %s", __func__, state.ToString());
    4305             :         }
    4306      254028 :     }
    4307             : 
    4308      251048 :     NotifyHeaderTip(ActiveChainstate());
    4309             : 
    4310      251048 :     BlockValidationState state; // Only used to report errors, not invalidity - ignore it
    4311      251048 :     if (!ActiveChainstate().ActivateBestChain(state, block))
    4312           2 :         return error("%s: ActivateBestChain failed: %s", __func__, state.ToString());
    4313             : 
    4314      251046 :     LogPrintf("%s : ACCEPTED\n", __func__);
    4315      251046 :     return true;
    4316      254028 : }
    4317             : 
    4318       46988 : MempoolAcceptResult ChainstateManager::ProcessTransaction(const CTransactionRef& tx, bool test_accept, bool bypass_limits)
    4319             : {
    4320       46988 :     CChainState& active_chainstate = ActiveChainstate();
    4321       46988 :     if (!active_chainstate.GetMempool()) {
    4322           0 :         TxValidationState state;
    4323           0 :         state.Invalid(TxValidationResult::TX_NO_MEMPOOL, "no-mempool");
    4324           0 :         return MempoolAcceptResult::Failure(state);
    4325           0 :     }
    4326       46988 :     auto result = AcceptToMemoryPool(active_chainstate, tx, GetTime(), bypass_limits, test_accept);
    4327       46988 :     active_chainstate.GetMempool()->check(active_chainstate.CoinsTip(), active_chainstate.m_chain.Height() + 1);
    4328       46988 :     return result;
    4329       93976 : }
    4330             : 
    4331       87635 : bool TestBlockValidity(BlockValidationState& state,
    4332             :                        const chainlock::Chainlocks& chainlocks,
    4333             :                        CEvoDB& evoDb,
    4334             :                        const CChainParams& chainparams,
    4335             :                        CChainState& chainstate,
    4336             :                        const CBlock& block,
    4337             :                        CBlockIndex* pindexPrev,
    4338             :                        bool fCheckPOW,
    4339             :                        bool fCheckMerkleRoot)
    4340             : {
    4341       87635 :     AssertLockHeld(cs_main);
    4342       87635 :     assert(pindexPrev && pindexPrev == chainstate.m_chain.Tip());
    4343             : 
    4344             :     // TODO: instead restoring bls_legacy_scheme better to keep it unchanged
    4345             :     // Moreover, current implementation is working incorrect if current function
    4346             :     // will return value too early due to error: old value won't be restored
    4347       87635 :     auto bls_legacy_scheme = bls::bls_legacy_scheme.load();
    4348             : 
    4349       87635 :     uint256 hash = block.GetHash();
    4350       87635 :     if (chainlocks.HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
    4351           0 :         LogPrintf("ERROR: %s: conflicting with chainlock\n", __func__);
    4352           0 :         return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-chainlock");
    4353             :     }
    4354             : 
    4355       87635 :     CCoinsViewCache viewNew(&chainstate.CoinsTip());
    4356       87635 :     uint256 block_hash(block.GetHash());
    4357       87635 :     CBlockIndex indexDummy(block);
    4358       87635 :     indexDummy.pprev = pindexPrev;
    4359       87635 :     indexDummy.nHeight = pindexPrev->nHeight + 1;
    4360       87635 :     indexDummy.phashBlock = &block_hash;
    4361             : 
    4362             :     // begin tx and let it rollback
    4363       87635 :     auto dbTx = evoDb.BeginTransaction();
    4364             : 
    4365             :     // NOTE: CheckBlockHeader is called by CheckBlock
    4366       87635 :     if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev, GetAdjustedTime()))
    4367           6 :         return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
    4368       87629 :     if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
    4369           7 :         return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
    4370       87622 :     if (!ContextualCheckBlock(block, state, chainstate.m_chainman, pindexPrev))
    4371           3 :         return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
    4372       87619 :     if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true))
    4373           7 :         return false;
    4374             : 
    4375       87612 :     assert(state.IsValid());
    4376             : 
    4377             :     // we could switch to another scheme while testing, switch back to the original one
    4378       87612 :     if (bls_legacy_scheme != bls::bls_legacy_scheme.load()) {
    4379         439 :         bls::bls_legacy_scheme.store(bls_legacy_scheme);
    4380         439 :         LogPrintf("%s: bls_legacy_scheme=%d\n", __func__, bls::bls_legacy_scheme.load());
    4381         439 :     }
    4382             : 
    4383       87612 :     return true;
    4384       87635 : }
    4385             : 
    4386             : /* This function is called from the RPC code for pruneblockchain */
    4387           0 : void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight)
    4388             : {
    4389           0 :     BlockValidationState state;
    4390           0 :     if (!active_chainstate.FlushStateToDisk(state, FlushStateMode::NONE, nManualPruneHeight)) {
    4391           0 :         LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
    4392           0 :     }
    4393           0 : }
    4394             : 
    4395        2831 : void CChainState::LoadMempool(const ArgsManager& args)
    4396             : {
    4397        2831 :     if (!m_mempool) return;
    4398        2831 :     if (args.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
    4399        2777 :         ::LoadMempool(*m_mempool, *this);
    4400        2777 :     }
    4401        2831 :     m_mempool->SetIsLoaded(!ShutdownRequested());
    4402        2831 : }
    4403             : 
    4404        1978 : bool CChainState::LoadChainTip()
    4405             : {
    4406        1978 :     AssertLockHeld(cs_main);
    4407        1978 :     const CCoinsViewCache& coins_cache = CoinsTip();
    4408        1978 :     assert(!coins_cache.GetBestBlock().IsNull()); // Never called when the coins view is empty
    4409        1978 :     const CBlockIndex* tip = m_chain.Tip();
    4410             : 
    4411        1978 :     if (tip && tip->GetBlockHash() == coins_cache.GetBestBlock()) {
    4412           2 :         return true;
    4413             :     }
    4414             : 
    4415             :     // Load pointer to end of best chain
    4416        1976 :     CBlockIndex* pindex = m_blockman.LookupBlockIndex(coins_cache.GetBestBlock());
    4417        1976 :     if (!pindex) {
    4418           0 :         return false;
    4419             :     }
    4420        1976 :     m_chain.SetTip(*pindex);
    4421        1976 :     PruneBlockIndexCandidates();
    4422             : 
    4423        1976 :     tip = m_chain.Tip();
    4424        1976 :     LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
    4425             :               tip->GetBlockHash().ToString(),
    4426             :               m_chain.Height(),
    4427             :               FormatISO8601DateTime(tip->GetBlockTime()),
    4428             :               GuessVerificationProgress(m_params.TxData(), tip));
    4429        1976 :     return true;
    4430        1978 : }
    4431             : 
    4432        3954 : CVerifyDB::CVerifyDB()
    4433        1977 : {
    4434        1977 :     uiInterface.ShowProgress(_("Verifying blocks…").translated, 0, false);
    4435        3954 : }
    4436             : 
    4437        3954 : CVerifyDB::~CVerifyDB()
    4438        1977 : {
    4439        1977 :     uiInterface.ShowProgress("", 100, false);
    4440        3954 : }
    4441             : 
    4442        1977 : bool CVerifyDB::VerifyDB(
    4443             :     CChainState& chainstate,
    4444             :     const Consensus::Params& consensus_params,
    4445             :     CCoinsView& coinsview,
    4446             :     CEvoDB& evoDb,
    4447             :     int nCheckLevel, int nCheckDepth)
    4448             : {
    4449        1977 :     AssertLockHeld(cs_main);
    4450             : 
    4451        1977 :     if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) {
    4452         254 :         return true;
    4453             :     }
    4454             : 
    4455             :     // begin tx and let it rollback
    4456        1723 :     auto dbTx = evoDb.BeginTransaction();
    4457             : 
    4458             :     // Verify blocks in the best chain
    4459        1723 :     if (nCheckDepth <= 0 || nCheckDepth > chainstate.m_chain.Height()) {
    4460        1723 :         nCheckDepth = chainstate.m_chain.Height();
    4461          56 :     }
    4462          56 :     nCheckLevel = std::max(0, std::min(4, nCheckLevel));
    4463        1723 :     LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
    4464        1723 :     CCoinsViewCache coins(&coinsview);
    4465             :     CBlockIndex* pindex;
    4466        1723 :     CBlockIndex* pindexFailure = nullptr;
    4467        1723 :     int nGoodTransactions = 0;
    4468        1723 :     BlockValidationState state;
    4469        1723 :     int reportDone = 0;
    4470        1723 :     bool skipped_l3_checks{false};
    4471        1723 :     LogPrintf("Verification progress: 0%%\n");
    4472             : 
    4473        1723 :     const bool is_snapshot_cs{chainstate.m_from_snapshot_blockhash};
    4474             : 
    4475       13684 :     for (pindex = chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
    4476       13628 :         const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
    4477       13628 :         if (reportDone < percentageDone / 10) {
    4478             :             // report every 10% step
    4479       10019 :             LogPrintf("Verification progress: %d%%\n", percentageDone);
    4480       10019 :             reportDone = percentageDone / 10;
    4481       10019 :         }
    4482       13628 :         uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
    4483       13628 :         if (pindex->nHeight <= chainstate.m_chain.Height() - nCheckDepth) {
    4484        1657 :             break;
    4485             :         }
    4486       11971 :         if ((fPruneMode || is_snapshot_cs) && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
    4487             :             // If pruning or running under an assumeutxo snapshot, only go
    4488             :             // back as far as we have data.
    4489           0 :             LogPrintf("VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->nHeight);
    4490           0 :             break;
    4491             :         }
    4492       11971 :         CBlock block;
    4493             :         // check level 0: read from disk
    4494       11971 :         if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
    4495           2 :             return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
    4496             :         }
    4497             :         // check level 1: verify block validity
    4498       11969 :         if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params)) {
    4499           0 :             return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
    4500           0 :                          pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
    4501             :         }
    4502             :         // check level 2: verify undo validity
    4503       11969 :         if (nCheckLevel >= 2 && pindex) {
    4504       11945 :             CBlockUndo undo;
    4505       11945 :             if (!pindex->GetUndoPos().IsNull()) {
    4506       11945 :                 if (!UndoReadFromDisk(undo, pindex)) {
    4507           2 :                     return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
    4508             :                 }
    4509       11943 :             }
    4510       11945 :         }
    4511             :         // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
    4512       11967 :         size_t curr_coins_usage = coins.DynamicMemoryUsage() + chainstate.CoinsTip().DynamicMemoryUsage();
    4513             : 
    4514       11967 :         if (nCheckLevel >= 3) {
    4515       11943 :             if (curr_coins_usage <= chainstate.m_coinstip_cache_size_bytes) {
    4516       11943 :                 assert(coins.GetBestBlock() == pindex->GetBlockHash());
    4517       11943 :                 DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
    4518       11941 :                 if (res == DISCONNECT_FAILED) {
    4519           0 :                     return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
    4520             :                 }
    4521       11941 :                 if (res == DISCONNECT_UNCLEAN) {
    4522           0 :                     nGoodTransactions = 0;
    4523           0 :                     pindexFailure = pindex;
    4524           0 :                 } else {
    4525       11941 :                     nGoodTransactions += block.vtx.size();
    4526             :                 }
    4527       11941 :             } else {
    4528           0 :                 skipped_l3_checks = true;
    4529             :             }
    4530       11941 :         }
    4531       11965 :         if (ShutdownRequested()) return true;
    4532       11971 :     }
    4533        1713 :     if (pindexFailure) {
    4534           0 :         return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
    4535             :     }
    4536        1713 :     if (skipped_l3_checks) {
    4537           0 :         LogPrintf("Skipped verification of level >=3 (insufficient database cache size). Consider increasing -dbcache.\n");
    4538           0 :     }
    4539             :     // store block count as we move pindex at check level >= 4
    4540        1713 :     int block_count = chainstate.m_chain.Height() - pindex->nHeight;
    4541             : 
    4542             :     // check level 4: try reconnecting blocks
    4543        1713 :     if (nCheckLevel >= 4 && !skipped_l3_checks) {
    4544         895 :         while (pindex != chainstate.m_chain.Tip()) {
    4545         890 :             const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
    4546         890 :             if (reportDone < percentageDone / 10) {
    4547             :                 // report every 10% step
    4548          21 :                 LogPrintf("Verification progress: %d%%\n", percentageDone);
    4549          21 :                 reportDone = percentageDone / 10;
    4550          21 :             }
    4551         890 :             uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
    4552         890 :             pindex = chainstate.m_chain.Next(pindex);
    4553         890 :             CBlock block;
    4554         890 :             if (!ReadBlockFromDisk(block, pindex, consensus_params))
    4555           0 :                 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
    4556         890 :             if (!chainstate.ConnectBlock(block, state, pindex, coins))
    4557           0 :                 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
    4558         890 :             if (ShutdownRequested()) return true;
    4559         890 :         }
    4560           5 :     }
    4561             : 
    4562        1713 :     LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
    4563             : 
    4564        1713 :     return true;
    4565        5313 : }
    4566             : 
    4567             : /** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
    4568           0 : bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs)
    4569             : {
    4570           0 :     AssertLockHeld(cs_main);
    4571             : 
    4572           0 :     assert(m_chain_helper);
    4573             : 
    4574             :     // TODO: merge with ConnectBlock
    4575           0 :     CBlock block;
    4576           0 :     if (!ReadBlockFromDisk(block, pindex, m_params.GetConsensus())) {
    4577           0 :         return error("RollforwardBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
    4578             :     }
    4579             : 
    4580             :     // MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
    4581           0 :     BlockValidationState state;
    4582           0 :     std::optional<MNListUpdates> mnlist_updates_opt{std::nullopt};
    4583           0 :     if (!m_chain_helper->special_tx->ProcessSpecialTxsInBlock(block, pindex, inputs, false /*fJustCheck*/, false /*fScriptChecks*/, state, mnlist_updates_opt)) {
    4584           0 :         return error("RollforwardBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
    4585           0 :             pindex->GetBlockHash().ToString(), state.ToString());
    4586             :     }
    4587             : 
    4588           0 :     for (size_t i = 0; i < block.vtx.size(); i++) {
    4589           0 :         const CTransactionRef& tx = block.vtx[i];
    4590             : 
    4591           0 :         if (!tx->IsCoinBase()) {
    4592           0 :             for (const CTxIn &txin : tx->vin) {
    4593           0 :                 inputs.SpendCoin(txin.prevout);
    4594             :             }
    4595           0 :         }
    4596             :         // Pass check = true as every addition may be an overwrite.
    4597           0 :         AddCoins(inputs, *tx, pindex->nHeight, true);
    4598           0 :     }
    4599             : 
    4600           0 :     return true;
    4601           0 : }
    4602             : 
    4603        3049 : bool CChainState::ReplayBlocks()
    4604             : {
    4605        3049 :     LOCK(cs_main);
    4606             : 
    4607        3049 :     CCoinsView& db = this->CoinsDB();
    4608        3049 :     CCoinsViewCache cache(&db);
    4609             : 
    4610        3049 :     std::vector<uint256> hashHeads = db.GetHeadBlocks();
    4611        3049 :     if (hashHeads.empty()) return true; // We're already in a consistent state.
    4612           0 :     if (hashHeads.size() != 2) return error("ReplayBlocks(): unknown inconsistent state");
    4613             : 
    4614           0 :     uiInterface.ShowProgress(_("Replaying blocks…").translated, 0, false);
    4615           0 :     LogPrintf("Replaying blocks\n");
    4616             : 
    4617           0 :     const CBlockIndex* pindexOld = nullptr;  // Old tip during the interrupted flush.
    4618             :     const CBlockIndex* pindexNew;            // New tip during the interrupted flush.
    4619           0 :     const CBlockIndex* pindexFork = nullptr; // Latest block common to both the old and the new tip.
    4620             : 
    4621           0 :     if (m_blockman.m_block_index.count(hashHeads[0]) == 0) {
    4622           0 :         return error("ReplayBlocks(): reorganization to unknown block requested");
    4623             :     }
    4624           0 :     pindexNew = &(m_blockman.m_block_index[hashHeads[0]]);
    4625             : 
    4626           0 :     if (!hashHeads[1].IsNull()) { // The old tip is allowed to be 0, indicating it's the first flush.
    4627           0 :         if (m_blockman.m_block_index.count(hashHeads[1]) == 0) {
    4628           0 :             return error("ReplayBlocks(): reorganization from unknown block requested");
    4629             :         }
    4630           0 :         pindexOld = &(m_blockman.m_block_index[hashHeads[1]]);
    4631           0 :         pindexFork = LastCommonAncestor(pindexOld, pindexNew);
    4632           0 :         assert(pindexFork != nullptr);
    4633           0 :         const bool fDIP0003Active = DeploymentActiveAt(*pindexOld, m_params.GetConsensus(), Consensus::DEPLOYMENT_DIP0003);
    4634           0 :         if (fDIP0003Active && !m_evoDb.VerifyBestBlock(pindexOld->GetBlockHash())) {
    4635           0 :             return error("ReplayBlocks(DASH): Found EvoDB inconsistency");
    4636             :         }
    4637           0 :     }
    4638             : 
    4639           0 :     auto dbTx = m_evoDb.BeginTransaction();
    4640             : 
    4641             :     // Rollback along the old branch.
    4642           0 :     while (pindexOld != pindexFork) {
    4643           0 :         if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
    4644           0 :             CBlock block;
    4645           0 :             if (!ReadBlockFromDisk(block, pindexOld, m_params.GetConsensus())) {
    4646           0 :                 return error("ReplayBlocks(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
    4647             :             }
    4648           0 :             LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
    4649           0 :             DisconnectResult res = DisconnectBlock(block, pindexOld, cache);
    4650           0 :             if (res == DISCONNECT_FAILED) {
    4651           0 :                 return error("ReplayBlocks(): DisconnectBlock failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
    4652             :             }
    4653             :             // If DISCONNECT_UNCLEAN is returned, it means a non-existing UTXO was deleted, or an existing UTXO was
    4654             :             // overwritten. It corresponds to cases where the block-to-be-disconnect never had all its operations
    4655             :             // applied to the UTXO set. However, as both writing a UTXO and deleting a UTXO are idempotent operations,
    4656             :             // the result is still a version of the UTXO set with the effects of that block undone.
    4657           0 :         }
    4658           0 :         pindexOld = pindexOld->pprev;
    4659             :     }
    4660             : 
    4661             :     // Roll forward from the forking point to the new tip.
    4662           0 :     int nForkHeight = pindexFork ? pindexFork->nHeight : 0;
    4663           0 :     for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; ++nHeight) {
    4664           0 :         const CBlockIndex& pindex{*Assert(pindexNew->GetAncestor(nHeight))};
    4665             : 
    4666           0 :         LogPrintf("Rolling forward %s (%i)\n", pindex.GetBlockHash().ToString(), nHeight);
    4667           0 :         uiInterface.ShowProgress(_("Replaying blocks…").translated, (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false);
    4668           0 :         if (!RollforwardBlock(&pindex, cache)) return false;
    4669           0 :     }
    4670             : 
    4671           0 :     cache.SetBestBlock(pindexNew->GetBlockHash());
    4672           0 :     m_evoDb.WriteBestBlock(pindexNew->GetBlockHash());
    4673           0 :     bool flushed = cache.Flush();
    4674           0 :     assert(flushed);
    4675           0 :     dbTx->Commit();
    4676           0 :     uiInterface.ShowProgress("", 100, false);
    4677           0 :     return true;
    4678        3049 : }
    4679             : 
    4680           3 : void CChainState::UnloadBlockIndex()
    4681             : {
    4682           3 :     AssertLockHeld(::cs_main);
    4683           3 :     nBlockSequenceId = 1;
    4684           3 :     setBlockIndexCandidates.clear();
    4685           3 : }
    4686             : 
    4687        3059 : bool ChainstateManager::LoadBlockIndex()
    4688             : {
    4689        3059 :     AssertLockHeld(cs_main);
    4690             :     // Load block index from databases
    4691        3059 :     bool needs_init = fReindex;
    4692        3059 :     if (!fReindex) {
    4693        2994 :         bool ret{m_blockman.LoadBlockIndexDB()};
    4694        2994 :         if (!ret) return false;
    4695             : 
    4696        2990 :         std::vector<CBlockIndex*> vSortedByHeight{m_blockman.GetAllBlockIndices()};
    4697        2990 :         std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
    4698             :                   CBlockIndexHeightOnlyComparator());
    4699             : 
    4700             :         // Find start of assumed-valid region.
    4701        2990 :         int first_assumed_valid_height = std::numeric_limits<int>::max();
    4702             : 
    4703      326470 :         for (const CBlockIndex* block : vSortedByHeight) {
    4704      323481 :             if (block->IsAssumedValid()) {
    4705           1 :                 auto chainstates = GetAll();
    4706             : 
    4707             :                 // If we encounter an assumed-valid block index entry, ensure that we have
    4708             :                 // one chainstate that tolerates assumed-valid entries and another that does
    4709             :                 // not (i.e. the background validation chainstate), since assumed-valid
    4710             :                 // entries should always be pending validation by a fully-validated chainstate.
    4711           3 :                 auto any_chain = [&](auto fnc) { return std::any_of(chainstates.cbegin(), chainstates.cend(), fnc); };
    4712           3 :                 assert(any_chain([](auto chainstate) { return chainstate->reliesOnAssumedValid(); }));
    4713           2 :                 assert(any_chain([](auto chainstate) { return !chainstate->reliesOnAssumedValid(); }));
    4714             : 
    4715           1 :                 first_assumed_valid_height = block->nHeight;
    4716             :                 break;
    4717           1 :             }
    4718             :         }
    4719             : 
    4720      326150 :         for (CBlockIndex* pindex : vSortedByHeight) {
    4721      323162 :             if (ShutdownRequested()) return false;
    4722      323160 :             if (pindex->IsAssumedValid() ||
    4723      323140 :                     (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) &&
    4724      322302 :                      (pindex->HaveTxsDownloaded() || pindex->pprev == nullptr))) {
    4725             : 
    4726             :                 // Fill each chainstate's block candidate set. Only add assumed-valid
    4727             :                 // blocks to the tip candidate set if the chainstate is allowed to rely on
    4728             :                 // assumed-valid blocks.
    4729             :                 //
    4730             :                 // If all setBlockIndexCandidates contained the assumed-valid blocks, the
    4731             :                 // background chainstate's ActivateBestChain() call would add assumed-valid
    4732             :                 // blocks to the chain (based on how FindMostWorkChain() works). Obviously
    4733             :                 // we don't want this since the purpose of the background validation chain
    4734             :                 // is to validate assued-valid blocks.
    4735             :                 //
    4736             :                 // Note: This is considering all blocks whose height is greater or equal to
    4737             :                 // the first assumed-valid block to be assumed-valid blocks, and excluding
    4738             :                 // them from the background chainstate's setBlockIndexCandidates set. This
    4739             :                 // does mean that some blocks which are not technically assumed-valid
    4740             :                 // (later blocks on a fork beginning before the first assumed-valid block)
    4741             :                 // might not get added to the background chainstate, but this is ok,
    4742             :                 // because they will still be attached to the active chainstate if they
    4743             :                 // actually contain more work.
    4744             :                 //
    4745             :                 // Instead of this height-based approach, an earlier attempt was made at
    4746             :                 // detecting "holistically" whether the block index under consideration
    4747             :                 // relied on an assumed-valid ancestor, but this proved to be too slow to
    4748             :                 // be practical.
    4749      644745 :                 for (CChainState* chainstate : GetAll()) {
    4750      322423 :                     if (chainstate->reliesOnAssumedValid() ||
    4751      322322 :                             pindex->nHeight < first_assumed_valid_height) {
    4752      322342 :                         chainstate->setBlockIndexCandidates.insert(pindex);
    4753      322342 :                     }
    4754             :                 }
    4755      322322 :             }
    4756      323160 :             if (pindex->nStatus & BLOCK_FAILED_MASK && (!m_best_invalid || pindex->nChainWork > m_best_invalid->nChainWork)) {
    4757         230 :                 m_best_invalid = pindex;
    4758         230 :             }
    4759      646014 :             if (pindex->IsValid(BLOCK_VALID_TREE) && (m_best_header == nullptr || CBlockIndexWorkComparator()(m_best_header, pindex)))
    4760      322391 :                 m_best_header = pindex;
    4761             :         }
    4762             : 
    4763        2988 :         needs_init = m_blockman.m_block_index.empty();
    4764        2990 :     }
    4765             : 
    4766        3053 :     if (needs_init) {
    4767             :         // Everything here is for *new* reindex/DBs. Thus, though
    4768             :         // LoadBlockIndexDB may have set fReindex if we shut down
    4769             :         // mid-reindex previously, we don't check fReindex and
    4770             :         // instead only check it prior to LoadBlockIndexDB to set
    4771             :         // needs_init.
    4772             : 
    4773        1065 :         LogPrintf("Initializing databases...\n");
    4774        1065 :     }
    4775        3053 :     return true;
    4776        3059 : }
    4777             : 
    4778        1003 : bool CChainState::AddGenesisBlock(const CBlock& block, BlockValidationState& state)
    4779             : {
    4780        1003 :     FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, 0, m_chain, nullptr)};
    4781        1003 :     if (blockPos.IsNull()) {
    4782           0 :         return error("%s: writing genesis block to disk failed (%s)", __func__, state.ToString());
    4783             :     }
    4784        1003 :     CBlockIndex* pindex = m_blockman.AddToBlockIndex(block, block.GetHash(), m_chainman.m_best_header);
    4785        1003 :     ReceivedBlockTransactions(block, pindex, blockPos);
    4786        1003 :     return true;
    4787        1003 : }
    4788             : 
    4789        3055 : bool CChainState::LoadGenesisBlock()
    4790             : {
    4791        3055 :     LOCK(cs_main);
    4792             : 
    4793             :     // Check whether we're already initialized by checking for genesis in
    4794             :     // m_blockman.m_block_index. Note that we can't use m_chain here, since it is
    4795             :     // set based on the coins db, not the block index db, which is the only
    4796             :     // thing loaded at this point.
    4797        3055 :     if (m_blockman.m_block_index.count(m_params.GenesisBlock().GetHash()))
    4798        2052 :         return true;
    4799             : 
    4800             :     try {
    4801        1003 :         BlockValidationState state;
    4802             : 
    4803        1003 :         if (!AddGenesisBlock(m_params.GenesisBlock(), state))
    4804           0 :             return false;
    4805             : 
    4806        1003 :         if (m_params.NetworkIDString() == CBaseChainParams::DEVNET) {
    4807             :             // We can't continue if devnet genesis block is invalid
    4808           4 :             std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(
    4809           4 :                     m_params.DevNetGenesisBlock());
    4810           4 :             bool fCheckBlock = CheckBlock(*shared_pblock, state, m_params.GetConsensus());
    4811           4 :             assert(fCheckBlock);
    4812           4 :             if (!AcceptBlock(shared_pblock, state, nullptr, true, nullptr, nullptr))
    4813           0 :                 return false;
    4814           4 :         }
    4815        1003 :     } catch (const std::runtime_error &e) {
    4816           0 :         return error("%s: failed to initialize block database: %s", __func__, e.what());
    4817           0 :     }
    4818             : 
    4819        1003 :     return true;
    4820        3055 : }
    4821             : 
    4822          67 : void CChainState::LoadExternalBlockFile(
    4823             :     FILE* fileIn,
    4824             :     FlatFilePos* dbp,
    4825             :     std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent)
    4826             : {
    4827          67 :     AssertLockNotHeld(m_chainstate_mutex);
    4828             : 
    4829             :     // Either both should be specified (-reindex), or neither (-loadblock).
    4830          67 :     assert(!dbp == !blocks_with_unknown_parent);
    4831             : 
    4832          67 :     const auto start{SteadyClock::now()};
    4833             : 
    4834          67 :     int nLoaded = 0;
    4835             :     try {
    4836          67 :         unsigned int nMaxBlockSize = MaxBlockSize();
    4837             :         // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
    4838          67 :         CBufferedFile blkdat(fileIn, 2*nMaxBlockSize, nMaxBlockSize+8, SER_DISK, CLIENT_VERSION);
    4839             :         // nRewind indicates where to resume scanning in case something goes wrong,
    4840             :         // such as a block fails to deserialize.
    4841          67 :         uint64_t nRewind = blkdat.GetPos();
    4842       10364 :         while (!blkdat.eof()) {
    4843       10362 :             if (ShutdownRequested()) return;
    4844             : 
    4845       10362 :             blkdat.SetPos(nRewind);
    4846       10362 :             nRewind++; // start one byte further next time, in case of failure
    4847       10362 :             blkdat.SetLimit(); // remove former limit
    4848       10362 :             unsigned int nSize = 0;
    4849             :             try {
    4850             :                 // locate a header
    4851             :                 unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
    4852       10362 :                 blkdat.FindByte(m_params.MessageStart()[0]);
    4853       10297 :                 nRewind = blkdat.GetPos() + 1;
    4854       10297 :                 blkdat >> buf;
    4855       10297 :                 if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
    4856           0 :                     continue;
    4857             :                 }
    4858             :                 // read size
    4859       10297 :                 blkdat >> nSize;
    4860       10297 :                 if (nSize < 80 || nSize > nMaxBlockSize)
    4861           0 :                     continue;
    4862       10362 :             } catch (const std::exception&) {
    4863             :                 // no valid block header found; don't complain
    4864             :                 // (this happens at the end of every blk.dat file)
    4865             :                 break;
    4866          65 :             }
    4867             :             try {
    4868             :                 // read block header
    4869       10297 :                 const uint64_t nBlockPos{blkdat.GetPos()};
    4870       10297 :                 if (dbp)
    4871       10095 :                     dbp->nPos = nBlockPos;
    4872       10297 :                 blkdat.SetLimit(nBlockPos + nSize);
    4873       10297 :                 CBlockHeader header;
    4874       10297 :                 blkdat >> header;
    4875       10297 :                 const uint256 hash{header.GetHash()};
    4876             :                 // Skip the rest of this block (this may read from disk into memory); position to the marker before the
    4877             :                 // next block, but it's still possible to rewind to the start of the current block (without a disk read).
    4878       10297 :                 nRewind = nBlockPos + nSize;
    4879       10297 :                 blkdat.SkipTo(nRewind);
    4880             : 
    4881       10297 :                 std::shared_ptr<CBlock> pblock{}; // needs to remain available after the cs_main lock is released to avoid duplicate reads from disk
    4882             : 
    4883             :                 {
    4884       10297 :                     LOCK(cs_main);
    4885             :                     // detect out of order blocks, and store them for later
    4886       10297 :                     if (hash != m_params.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(header.hashPrevBlock)) {
    4887          45 :                         LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
    4888             :                                  header.hashPrevBlock.ToString());
    4889          45 :                         if (dbp && blocks_with_unknown_parent) {
    4890          45 :                             blocks_with_unknown_parent->emplace(header.hashPrevBlock, *dbp);
    4891          45 :                         }
    4892          45 :                         continue;
    4893             :                     }
    4894             : 
    4895             :                     // process in case the block isn't known yet
    4896       10252 :                     const CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
    4897       10252 :                     if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
    4898             :                         // This block can be processed immediately; rewind to its start, read and deserialize it.
    4899       10250 :                         blkdat.SetPos(nBlockPos);
    4900       10250 :                         pblock = std::make_shared<CBlock>();
    4901       10250 :                         blkdat >> *pblock;
    4902       10250 :                         nRewind = blkdat.GetPos();
    4903             : 
    4904       10250 :                         BlockValidationState state;
    4905       10250 :                         if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr, &hash)) {
    4906       10250 :                             nLoaded++;
    4907       10250 :                         }
    4908       10250 :                         if (state.IsError()) {
    4909           0 :                             break;
    4910             :                         }
    4911       10252 :                     } else if (hash != m_params.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
    4912           0 :                         LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
    4913           0 :                     }
    4914       10297 :                 }
    4915             : 
    4916             :                 // Activate the genesis block so normal node progress can continue
    4917       10252 :                 if (hash == m_params.GetConsensus().hashGenesisBlock) {
    4918          67 :                     BlockValidationState state;
    4919          67 :                     if (!ActivateBestChain(state, nullptr)) {
    4920           0 :                         break;
    4921             :                     }
    4922          67 :                 }
    4923             : 
    4924       10252 :                 if (fPruneMode && !fReindex && pblock) {
    4925             :                     // must update the tip for pruning to work while importing with -loadblock.
    4926             :                     // this is a tradeoff to conserve disk space at the expense of time
    4927             :                     // spent updating the tip to be able to prune.
    4928             :                     // otherwise, ActivateBestChain won't be called by the import process
    4929             :                     // until after all of the block files are loaded. ActivateBestChain can be
    4930             :                     // called by concurrent network message processing. but, that is not
    4931             :                     // reliable for the purpose of pruning while importing.
    4932           0 :                     BlockValidationState state;
    4933           0 :                     if (!ActivateBestChain(state, pblock)) {
    4934           0 :                         LogPrint(BCLog::REINDEX, "failed to activate chain (%s)\n", state.ToString());
    4935           0 :                         break;
    4936             :                     }
    4937           0 :                 }
    4938             : 
    4939       10252 :                 NotifyHeaderTip(*this);
    4940             : 
    4941       10252 :                 if (!blocks_with_unknown_parent) continue;
    4942             : 
    4943             :                 // Recursively process earlier encountered successors of this block
    4944       10050 :                 std::deque<uint256> queue;
    4945       10050 :                 queue.push_back(hash);
    4946       20145 :                 while (!queue.empty()) {
    4947       10095 :                     uint256 head = queue.front();
    4948       10095 :                     queue.pop_front();
    4949       10095 :                     auto range = blocks_with_unknown_parent->equal_range(head);
    4950       10140 :                     while (range.first != range.second) {
    4951          45 :                         std::multimap<uint256, FlatFilePos>::iterator it = range.first;
    4952          45 :                         std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
    4953          45 :                         if (auto opt_hash{ReadBlockFromDisk(*pblockrecursive, it->second, m_params.GetConsensus())}) {
    4954          45 :                             const uint256& blockhash = *opt_hash;
    4955          45 :                             LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, blockhash.ToString(),
    4956             :                                     head.ToString());
    4957          45 :                             LOCK(cs_main);
    4958          45 :                             BlockValidationState dummy;
    4959          45 :                             if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr, &blockhash)) {
    4960          45 :                                 nLoaded++;
    4961          45 :                                 queue.push_back(blockhash);
    4962          45 :                             }
    4963          45 :                         }
    4964          45 :                         range.first++;
    4965          45 :                         blocks_with_unknown_parent->erase(it);
    4966          45 :                         NotifyHeaderTip(*this);
    4967          45 :                     }
    4968             :                 }
    4969       10297 :             } catch (const std::exception& e) {
    4970             :                 // historical bugs added extra data to the block files that does not deserialize cleanly.
    4971             :                 // commonly this data is between readable blocks, but it does not really matter. such data is not fatal to the import process.
    4972             :                 // the code that reads the block files deals with invalid data by simply ignoring it.
    4973             :                 // it continues to search for the next {4 byte magic message start bytes + 4 byte length + block} that does deserialize cleanly
    4974             :                 // and passes all of the other block validation checks dealing with POW and the merkle root, etc...
    4975             :                 // we merely note with this informational log message when unexpected data is encountered.
    4976             :                 // we could also be experiencing a storage system read error, or a read of a previous bad write. these are possible, but
    4977             :                 // less likely scenarios. we don't have enough information to tell a difference here.
    4978             :                 // the reindex process is not the place to attempt to clean and/or compact the block files. if so desired, a studious node operator
    4979             :                 // may use knowledge of the fact that the block files are not entirely pristine in order to prepare a set of pristine, and
    4980             :                 // perhaps ordered, block files for later reindexing.
    4981           0 :                 LogPrint(BCLog::REINDEX, "%s: unexpected data at file offset 0x%x - %s. continuing\n", __func__, (nRewind - 1), e.what());
    4982           0 :             }
    4983             :         }
    4984          67 :     } catch (const std::runtime_error& e) {
    4985           0 :         AbortNode(std::string("System error: ") + e.what());
    4986           0 :     }
    4987          67 :     LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
    4988         132 : }
    4989             : 
    4990     1080455 : void CChainState::CheckBlockIndex()
    4991             : {
    4992     1080455 :     if (!fCheckBlockIndex) {
    4993       24364 :         return;
    4994             :     }
    4995             : 
    4996     1056091 :     LOCK(cs_main);
    4997             : 
    4998             :     // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
    4999             :     // so we have the genesis block in m_blockman.m_block_index but no active chain. (A few of the
    5000             :     // tests when iterating the block tree require that m_chain has been initialized.)
    5001     1056091 :     if (m_chain.Height() < 0) {
    5002         130 :         assert(m_blockman.m_block_index.size() <= 1);
    5003         130 :         return;
    5004             :     }
    5005             : 
    5006             :     // Build forward-pointing map of the entire block tree.
    5007     1055961 :     std::multimap<CBlockIndex*,CBlockIndex*> forward;
    5008   336798067 :     for (auto& [_, block_index] : m_blockman.m_block_index) {
    5009   671484212 :         forward.emplace(block_index.pprev, &block_index);
    5010             :     }
    5011             : 
    5012     1055961 :     assert(forward.size() == m_blockman.m_block_index.size());
    5013             : 
    5014     1055961 :     std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr);
    5015     1055961 :     CBlockIndex *pindex = rangeGenesis.first->second;
    5016     1055961 :     rangeGenesis.first++;
    5017     1055961 :     assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr.
    5018             : 
    5019             :     // Iterate over the entire block tree, using depth-first search.
    5020             :     // Along the way, remember whether there are blocks on the path from genesis
    5021             :     // block being explored which are the first to have certain properties.
    5022     1055961 :     size_t nNodes = 0;
    5023     1055961 :     int nHeight = 0;
    5024     1055961 :     CBlockIndex* pindexFirstInvalid = nullptr; // Oldest ancestor of pindex which is invalid.
    5025     1055961 :     CBlockIndex* pindexFirstConflicing = nullptr; // Oldest ancestor of pindex which has BLOCK_CONFLICT_CHAINLOCK.
    5026     1055961 :     CBlockIndex* pindexFirstMissing = nullptr; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
    5027     1055961 :     CBlockIndex* pindexFirstNeverProcessed = nullptr; // Oldest ancestor of pindex for which nTx == 0.
    5028     1055961 :     CBlockIndex* pindexFirstNotTreeValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
    5029     1055961 :     CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
    5030     1055961 :     CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
    5031     1055961 :     CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
    5032   336798067 :     while (pindex != nullptr) {
    5033   335742106 :         nNodes++;
    5034   335742106 :         if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
    5035   335742106 :         if (pindexFirstConflicing == nullptr && pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK) pindexFirstConflicing = pindex;
    5036             :         // Assumed-valid index entries will not have data since we haven't downloaded the
    5037             :         // full block yet.
    5038   335742106 :         if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA) && !pindex->IsAssumedValid()) {
    5039     1155833 :             pindexFirstMissing = pindex;
    5040     1155833 :         }
    5041   335742106 :         if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
    5042   335742106 :         if (pindex->pprev != nullptr && pindexFirstNotTreeValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
    5043             : 
    5044   335742106 :         if (pindex->pprev != nullptr && !pindex->IsAssumedValid()) {
    5045             :             // Skip validity flag checks for BLOCK_ASSUMED_VALID index entries, since these
    5046             :             // *_VALID_MASK flags will not be present for index entries we are temporarily assuming
    5047             :             // valid.
    5048   334686145 :             if (pindexFirstNotTransactionsValid == nullptr &&
    5049   272074320 :                     (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) {
    5050     1155833 :                 pindexFirstNotTransactionsValid = pindex;
    5051     1155833 :             }
    5052             : 
    5053   334686145 :             if (pindexFirstNotChainValid == nullptr &&
    5054   266212076 :                     (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) {
    5055     2110307 :                 pindexFirstNotChainValid = pindex;
    5056     2110307 :             }
    5057             : 
    5058   334686145 :             if (pindexFirstNotScriptsValid == nullptr &&
    5059   266212076 :                     (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) {
    5060     2110307 :                 pindexFirstNotScriptsValid = pindex;
    5061     2110307 :             }
    5062   334686145 :         }
    5063             : 
    5064             :         // Begin: actual consistency checks.
    5065   335742106 :         if (pindex->pprev == nullptr) {
    5066             :             // Genesis block checks.
    5067     1055961 :             assert(pindex->GetBlockHash() == m_params.GetConsensus().hashGenesisBlock); // Genesis block's hash must match.
    5068     1055961 :             assert(pindex == m_chain.Genesis()); // The current active chain's genesis block must be this block.
    5069     1055961 :         }
    5070   335742106 :         if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock)
    5071             :         // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
    5072             :         // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
    5073             :         // Unless these indexes are assumed valid and pending block download on a
    5074             :         // background chainstate.
    5075   335742106 :         if (!m_blockman.m_have_pruned && !pindex->IsAssumedValid()) {
    5076             :             // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
    5077   335742106 :             assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
    5078   335742106 :             assert(pindexFirstMissing == pindexFirstNeverProcessed);
    5079   335742106 :         } else {
    5080             :             // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
    5081           0 :             if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
    5082             :         }
    5083   335742106 :         if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
    5084   335742106 :         if (pindex->IsAssumedValid()) {
    5085             :             // Assumed-valid blocks should have some nTx value.
    5086           0 :             assert(pindex->nTx > 0);
    5087             :             // Assumed-valid blocks should connect to the main chain.
    5088           0 :             assert((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE);
    5089           0 :         } else {
    5090             :             // Otherwise there should only be an nTx value if we have
    5091             :             // actually seen a block's transactions.
    5092   335742106 :             assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
    5093             :         }
    5094             :         // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to HaveTxsDownloaded().
    5095   335742106 :         assert((pindexFirstNeverProcessed == nullptr) == pindex->HaveTxsDownloaded());
    5096   335742106 :         assert((pindexFirstNotTransactionsValid == nullptr) == pindex->HaveTxsDownloaded());
    5097   335742106 :         assert(pindex->nHeight == nHeight); // nHeight must be consistent.
    5098   335742106 :         assert(pindex->pprev == nullptr || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
    5099   335742106 :         assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
    5100   335742106 :         assert(pindexFirstNotTreeValid == nullptr); // All m_blockman.m_block_index entries must at least be TREE valid
    5101   335742106 :         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid
    5102   335742106 :         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid
    5103   335742106 :         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid
    5104   335742106 :         if (pindexFirstInvalid == nullptr) {
    5105             :             // Checks for not-invalid blocks.
    5106   327929204 :             assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
    5107   327929204 :         }
    5108   335742106 :         if (pindexFirstConflicing == nullptr) {
    5109             :             // Checks for not-conflciting blocks.
    5110   335738541 :             assert((pindex->nStatus & BLOCK_CONFLICT_CHAINLOCK) == 0); // The conflicting mask cannot be set for blocks without conflicting parents.
    5111   335738541 :         }
    5112   335742106 :         if (!CBlockIndexWorkComparator()(pindex, m_chain.Tip()) && pindexFirstNeverProcessed == nullptr) {
    5113     6343007 :             if (pindexFirstInvalid == nullptr && pindexFirstConflicing == nullptr) {
    5114     3199279 :                 const bool is_active = this == &m_chainman.ActiveChainstate();
    5115             : 
    5116             :                 // If this block sorts at least as good as the current tip and
    5117             :                 // is valid and we have all data for its parents, it must be in
    5118             :                 // setBlockIndexCandidates.  m_chain.Tip() must also be there
    5119             :                 // even if some data has been pruned.
    5120             :                 //
    5121             :                 // Don't perform this check for the background chainstate since
    5122             :                 // its setBlockIndexCandidates shouldn't have some entries (i.e. those past the
    5123             :                 // snapshot block) which do exist in the block index for the active chainstate.
    5124     3199279 :                 if (is_active && (pindexFirstMissing == nullptr || pindex == m_chain.Tip())) {
    5125     3199272 :                     assert(setBlockIndexCandidates.count(pindex));
    5126     3199272 :                 }
    5127             :                 // If some parent is missing, then it could be that this block was in
    5128             :                 // setBlockIndexCandidates but had to be removed because of the missing data.
    5129             :                 // In this case it must be in m_blocks_unlinked -- see test below.
    5130     3199279 :             }
    5131     6343007 :         } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
    5132   329399099 :             assert(setBlockIndexCandidates.count(pindex) == 0);
    5133             :         }
    5134             :         // Check whether this block is in m_blocks_unlinked.
    5135   335742106 :         std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = m_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
    5136   335742106 :         bool foundInUnlinked = false;
    5137   335743010 :         while (rangeUnlinked.first != rangeUnlinked.second) {
    5138    21981368 :             assert(rangeUnlinked.first->first == pindex->pprev);
    5139    21981368 :             if (rangeUnlinked.first->second == pindex) {
    5140    21980464 :                 foundInUnlinked = true;
    5141    21980464 :                 break;
    5142             :             }
    5143         904 :             rangeUnlinked.first++;
    5144             :         }
    5145   335742106 :         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != nullptr && pindexFirstInvalid == nullptr) {
    5146             :             // If this block has block data available, some parent was never received, and has no invalid parents, it must be in m_blocks_unlinked.
    5147    21980464 :             assert(foundInUnlinked);
    5148    21980464 :         }
    5149   335742106 :         if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in m_blocks_unlinked if we don't HAVE_DATA
    5150   335742106 :         if (pindexFirstMissing == nullptr) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in m_blocks_unlinked.
    5151   335742106 :         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == nullptr && pindexFirstMissing != nullptr) {
    5152             :             // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
    5153           0 :             assert(m_blockman.m_have_pruned); // We must have pruned.
    5154             :             // This block may have entered m_blocks_unlinked if:
    5155             :             //  - it has a descendant that at some point had more work than the
    5156             :             //    tip, and
    5157             :             //  - we tried switching to that descendant but were missing
    5158             :             //    data for some intermediate block between m_chain and the
    5159             :             //    tip.
    5160             :             // So if this block is itself better than m_chain.Tip() and it wasn't in
    5161             :             // setBlockIndexCandidates, then it must be in m_blocks_unlinked.
    5162           0 :             if (!CBlockIndexWorkComparator()(pindex, m_chain.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
    5163           0 :                 if (pindexFirstInvalid == nullptr) {
    5164           0 :                     assert(foundInUnlinked);
    5165           0 :                 }
    5166           0 :             }
    5167           0 :         }
    5168             :         // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
    5169             :         // End: actual consistency checks.
    5170             : 
    5171             :         // Try descending into the first subnode.
    5172   335742106 :         std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
    5173   335742106 :         if (range.first != range.second) {
    5174             :             // A subnode was found.
    5175   333037925 :             pindex = range.first->second;
    5176   333037925 :             nHeight++;
    5177   333037925 :             continue;
    5178             :         }
    5179             :         // This is a leaf node.
    5180             :         // Move upwards until we reach a node of which we have not yet visited the last child.
    5181   336798067 :         while (pindex) {
    5182             :             // We are going to either move to a parent or a sibling of pindex.
    5183             :             // If pindex was the first with a certain property, unset the corresponding variable.
    5184   335742106 :             if (pindex == pindexFirstInvalid) pindexFirstInvalid = nullptr;
    5185   335742106 :             if (pindex == pindexFirstConflicing) pindexFirstConflicing = nullptr;
    5186   335742106 :             if (pindex == pindexFirstMissing) pindexFirstMissing = nullptr;
    5187   335742106 :             if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = nullptr;
    5188   335742106 :             if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = nullptr;
    5189   335742106 :             if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr;
    5190   335742106 :             if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr;
    5191   335742106 :             if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr;
    5192             :             // Find our parent.
    5193   335742106 :             CBlockIndex* pindexPar = pindex->pprev;
    5194             :             // Find which child we just visited.
    5195   335742106 :             std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
    5196   340712515 :             while (rangePar.first->second != pindex) {
    5197     4970409 :                 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
    5198     4970409 :                 rangePar.first++;
    5199             :             }
    5200             :             // Proceed to the next one.
    5201   335742106 :             rangePar.first++;
    5202   335742106 :             if (rangePar.first != rangePar.second) {
    5203             :                 // Move to the sibling.
    5204     1648220 :                 pindex = rangePar.first->second;
    5205     1648220 :                 break;
    5206             :             } else {
    5207             :                 // Move up further.
    5208   334093886 :                 pindex = pindexPar;
    5209   334093886 :                 nHeight--;
    5210   334093886 :                 continue;
    5211             :             }
    5212             :         }
    5213             :     }
    5214             : 
    5215             :     // Check that we actually traversed the entire map.
    5216     1055961 :     assert(nNodes == forward.size());
    5217     1080455 : }
    5218             : 
    5219        3119 : std::string CChainState::ToString()
    5220             : {
    5221        3119 :     AssertLockHeld(::cs_main);
    5222        3119 :     CBlockIndex* tip = m_chain.Tip();
    5223        3119 :     return strprintf("Chainstate [%s] @ height %d (%s)",
    5224        3119 :                      m_from_snapshot_blockhash ? "snapshot" : "ibd",
    5225        3119 :                      tip ? tip->nHeight : -1, tip ? tip->GetBlockHash().ToString() : "null");
    5226           0 : }
    5227             : 
    5228          23 : bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
    5229             : {
    5230          23 :     AssertLockHeld(::cs_main);
    5231          23 :     if (coinstip_size == m_coinstip_cache_size_bytes &&
    5232           0 :             coinsdb_size == m_coinsdb_cache_size_bytes) {
    5233             :         // Cache sizes are unchanged, no need to continue.
    5234           0 :         return true;
    5235             :     }
    5236          23 :     size_t old_coinstip_size = m_coinstip_cache_size_bytes;
    5237          23 :     m_coinstip_cache_size_bytes = coinstip_size;
    5238          23 :     m_coinsdb_cache_size_bytes = coinsdb_size;
    5239          23 :     CoinsDB().ResizeCache(coinsdb_size);
    5240             : 
    5241          23 :     LogPrintf("[%s] resized coinsdb cache to %.1f MiB\n",
    5242             :         this->ToString(), coinsdb_size * (1.0 / 1024 / 1024));
    5243          23 :     LogPrintf("[%s] resized coinstip cache to %.1f MiB\n",
    5244             :         this->ToString(), coinstip_size * (1.0 / 1024 / 1024));
    5245             : 
    5246          23 :     BlockValidationState state;
    5247             :     bool ret;
    5248             : 
    5249          23 :     if (coinstip_size > old_coinstip_size) {
    5250             :         // Likely no need to flush if cache sizes have grown.
    5251           9 :         ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
    5252           9 :     } else {
    5253             :         // Otherwise, flush state to disk and deallocate the in-memory coins map.
    5254          14 :         ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
    5255             :     }
    5256          23 :     return ret;
    5257          23 : }
    5258             : 
    5259             : static const uint64_t MEMPOOL_DUMP_VERSION = 1;
    5260             : 
    5261        2777 : bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mockable_fopen_function)
    5262             : {
    5263        2777 :     int64_t nExpiryTimeout = gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
    5264        2777 :     FILE* filestr{mockable_fopen_function(gArgs.GetDataDirNet() / "mempool.dat", "rb")};
    5265        2777 :     AutoFile file{filestr};
    5266        2777 :     if (file.IsNull()) {
    5267        1526 :         LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n");
    5268        1526 :         return false;
    5269             :     }
    5270             : 
    5271        1251 :     int64_t count = 0;
    5272        1251 :     int64_t expired = 0;
    5273        1251 :     int64_t failed = 0;
    5274        1251 :     int64_t already_there = 0;
    5275        1251 :     int64_t unbroadcast = 0;
    5276        1251 :     int64_t nNow = GetTime();
    5277             : 
    5278             :     try {
    5279             :         uint64_t version;
    5280        1251 :         file >> version;
    5281        1251 :         if (version != MEMPOOL_DUMP_VERSION) {
    5282           0 :             return false;
    5283             :         }
    5284             :         uint64_t total_txns_to_load;
    5285        1251 :         file >> total_txns_to_load;
    5286        1251 :         uint64_t txns_tried = 0;
    5287        1251 :         LogInfo("Loading %u mempool transactions from disk...\n", total_txns_to_load);
    5288        1251 :         int next_tenth_to_report = 0;
    5289        1632 :         while (txns_tried < total_txns_to_load) {
    5290         381 :             const int percentage_done(100.0 * txns_tried / total_txns_to_load);
    5291         381 :             if (next_tenth_to_report < percentage_done / 10) {
    5292         183 :                 LogInfo("Progress loading mempool transactions from disk: %d%% (tried %u, %u remaining)\n",
    5293             :                         percentage_done, txns_tried, total_txns_to_load - txns_tried);
    5294         183 :                 next_tenth_to_report = percentage_done / 10;
    5295         183 :             }
    5296         381 :             ++txns_tried;
    5297             : 
    5298         381 :             CTransactionRef tx;
    5299             :             int64_t nTime;
    5300             :             int64_t nFeeDelta;
    5301         381 :             file >> tx;
    5302         381 :             file >> nTime;
    5303         381 :             file >> nFeeDelta;
    5304             : 
    5305         381 :             CAmount amountdelta = nFeeDelta;
    5306         381 :             if (amountdelta) {
    5307          35 :                 pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
    5308          35 :             }
    5309         381 :             if (nTime > nNow - nExpiryTimeout) {
    5310         381 :                 LOCK(cs_main);
    5311         381 :                 const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false);
    5312         381 :                 if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) {
    5313         343 :                     ++count;
    5314         343 :                 } else {
    5315             :                     // mempool may contain the transaction already, e.g. from
    5316             :                     // wallet(s) having loaded it while we were processing
    5317             :                     // mempool transactions; consider these as valid, instead of
    5318             :                     // failed, but mark them as 'already there'
    5319          38 :                     if (pool.exists(tx->GetHash())) {
    5320           4 :                         ++already_there;
    5321           4 :                     } else {
    5322          34 :                         ++failed;
    5323             :                     }
    5324             :                 }
    5325         381 :             } else {
    5326           0 :                 ++expired;
    5327             :             }
    5328         381 :             if (ShutdownRequested())
    5329           0 :                 return false;
    5330         381 :         }
    5331        1251 :         std::map<uint256, CAmount> mapDeltas;
    5332        1251 :         file >> mapDeltas;
    5333             : 
    5334        1259 :         for (const auto& i : mapDeltas) {
    5335           8 :             pool.PrioritiseTransaction(i.first, i.second);
    5336             :         }
    5337             : 
    5338        1251 :         std::set<uint256> unbroadcast_txids;
    5339        1251 :         file >> unbroadcast_txids;
    5340        1251 :         unbroadcast = unbroadcast_txids.size();
    5341        1461 :         for (const auto& txid : unbroadcast_txids) {
    5342             :             // Ensure transactions were accepted to mempool then add to
    5343             :             // unbroadcast set.
    5344         210 :             if (pool.get(txid) != nullptr) pool.AddUnbroadcastTx(txid);
    5345             :         }
    5346             : 
    5347        1251 :     } catch (const std::exception& e) {
    5348           0 :         LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
    5349           0 :         return false;
    5350           0 :     }
    5351             : 
    5352        1251 :     LogPrintf("Imported mempool transactions from disk: %i succeeded, %i failed, %i expired, %i already there, %i waiting for initial broadcast\n", count, failed, expired, already_there, unbroadcast);
    5353        1251 :     return true;
    5354        2777 : }
    5355             : 
    5356        2775 : bool DumpMempool(const CTxMemPool& pool, FopenFn mockable_fopen_function, bool skip_file_commit)
    5357             : {
    5358        2775 :     int64_t start = GetTimeMicros();
    5359             : 
    5360        2775 :     std::map<uint256, CAmount> mapDeltas;
    5361        2775 :     std::vector<TxMempoolInfo> vinfo;
    5362        2775 :     std::set<uint256> unbroadcast_txids;
    5363             : 
    5364        2775 :     static Mutex dump_mutex;
    5365        2775 :     LOCK(dump_mutex);
    5366             : 
    5367             :     {
    5368        2775 :         LOCK(pool.cs);
    5369        2890 :         for (const auto &i : pool.mapDeltas) {
    5370         115 :             mapDeltas[i.first] = i.second;
    5371             :         }
    5372        2775 :         vinfo = pool.infoAll();
    5373        2775 :         unbroadcast_txids = pool.GetUnbroadcastTxs();
    5374        2775 :     }
    5375             : 
    5376        2775 :     int64_t mid = GetTimeMicros();
    5377             : 
    5378             :     try {
    5379        2775 :         FILE* filestr{mockable_fopen_function(gArgs.GetDataDirNet() / "mempool.dat.new", "wb")};
    5380        2775 :         if (!filestr) {
    5381           2 :             return false;
    5382             :         }
    5383             : 
    5384        2773 :         AutoFile file{filestr};
    5385             : 
    5386        2773 :         uint64_t version = MEMPOOL_DUMP_VERSION;
    5387        2773 :         file << version;
    5388             : 
    5389        2773 :         file << (uint64_t)vinfo.size();
    5390        4844 :         for (const auto& i : vinfo) {
    5391        2071 :             file << *(i.tx);
    5392        2071 :             file << int64_t{count_seconds(i.m_time)};
    5393        2071 :             file << int64_t{i.nFeeDelta};
    5394        2071 :             mapDeltas.erase(i.tx->GetHash());
    5395             :         }
    5396             : 
    5397        2773 :         file << mapDeltas;
    5398             : 
    5399        2773 :         LogPrintf("Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
    5400        2773 :         file << unbroadcast_txids;
    5401             : 
    5402        2773 :         if (!skip_file_commit && !FileCommit(file.Get()))
    5403           0 :             throw std::runtime_error("FileCommit failed");
    5404        2773 :         file.fclose();
    5405        2773 :         if (!RenameOver(gArgs.GetDataDirNet() / "mempool.dat.new", gArgs.GetDataDirNet() / "mempool.dat")) {
    5406           0 :             throw std::runtime_error("Rename failed");
    5407             :         }
    5408        2773 :         int64_t last = GetTimeMicros();
    5409        2773 :         LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*MICRO, (last-mid)*MICRO);
    5410        2773 :     } catch (const std::exception& e) {
    5411           0 :         LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
    5412           0 :         return false;
    5413           0 :     }
    5414        2773 :     return true;
    5415        2775 : }
    5416             : 
    5417             : //! Guess how far we are in the verification process at the given block index
    5418             : //! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
    5419      425730 : double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
    5420      425730 :     if (pindex == nullptr)
    5421           1 :         return 0.0;
    5422             : 
    5423      425729 :     int64_t nNow = time(nullptr);
    5424             : 
    5425             :     double fTxTotal;
    5426             : 
    5427      425729 :     if (pindex->nChainTx <= data.nTxCount) {
    5428         214 :         fTxTotal = data.nTxCount + (nNow - data.nTime) * data.dTxRate;
    5429         214 :     } else {
    5430      425515 :         fTxTotal = pindex->nChainTx + (nNow - pindex->GetBlockTime()) * data.dTxRate;
    5431             :     }
    5432             : 
    5433      425729 :     return std::min<double>(pindex->nChainTx / fTxTotal, 1.0);
    5434      425730 : }
    5435             : 
    5436          15 : std::optional<uint256> ChainstateManager::SnapshotBlockhash() const {
    5437          15 :     LOCK(::cs_main);  // for m_active_chainstate access
    5438          15 :     if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
    5439             :         // If a snapshot chainstate exists, it will always be our active.
    5440           4 :         return m_active_chainstate->m_from_snapshot_blockhash;
    5441             :     }
    5442          11 :     return std::nullopt;
    5443          15 : }
    5444             : 
    5445      337058 : std::vector<CChainState*> ChainstateManager::GetAll()
    5446             : {
    5447      337058 :     LOCK(::cs_main);
    5448      337058 :     std::vector<CChainState*> out;
    5449             : 
    5450      337058 :     if (!IsSnapshotValidated() && m_ibd_chainstate) {
    5451      337058 :         out.push_back(m_ibd_chainstate.get());
    5452      337058 :     }
    5453             : 
    5454      337058 :     if (m_snapshot_chainstate) {
    5455         108 :         out.push_back(m_snapshot_chainstate.get());
    5456         108 :     }
    5457             : 
    5458      337058 :     return out;
    5459      337058 : }
    5460             : 
    5461        3069 : CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool,
    5462             :                                                      CEvoDB& evoDb,
    5463             :                                                      const std::unique_ptr<CChainstateHelper>& chain_helper,
    5464             :                                                      const std::optional<uint256>& snapshot_blockhash)
    5465             : {
    5466        3069 :     AssertLockHeld(::cs_main);
    5467        3069 :     bool is_snapshot = snapshot_blockhash.has_value();
    5468        3069 :     std::unique_ptr<CChainState>& to_modify =
    5469        3069 :         is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
    5470             : 
    5471        3069 :     if (to_modify) {
    5472           0 :         throw std::logic_error("should not be overwriting a chainstate");
    5473             :     }
    5474             : 
    5475        3069 :     to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, snapshot_blockhash));
    5476             : 
    5477             :     // Snapshot chainstates and initial IBD chaintates always become active.
    5478        3069 :     if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
    5479        3069 :         LogPrintf("Switching active chainstate to %s\n", to_modify->ToString());
    5480        3069 :         m_active_chainstate = to_modify.get();
    5481        3069 :     } else {
    5482           0 :         throw std::logic_error("unexpected chainstate activation");
    5483             :     }
    5484             : 
    5485        3069 :     return *to_modify;
    5486           0 : }
    5487             : 
    5488          15 : const AssumeutxoData* ExpectedAssumeutxo(
    5489             :     const int height, const CChainParams& chainparams)
    5490             : {
    5491          15 :     const MapAssumeutxo& valid_assumeutxos_map = chainparams.Assumeutxo();
    5492          15 :     const auto assumeutxo_found = valid_assumeutxos_map.find(height);
    5493             : 
    5494          15 :     if (assumeutxo_found != valid_assumeutxos_map.end()) {
    5495           8 :         return &assumeutxo_found->second;
    5496             :     }
    5497           7 :     return nullptr;
    5498          15 : }
    5499             : 
    5500           9 : bool ChainstateManager::ActivateSnapshot(
    5501             :         AutoFile& coins_file,
    5502             :         const SnapshotMetadata& metadata,
    5503             :         bool in_memory)
    5504             : {
    5505           9 :     uint256 base_blockhash = metadata.m_base_blockhash;
    5506             : 
    5507           9 :     if (this->SnapshotBlockhash()) {
    5508           1 :         LogPrintf("[snapshot] can't activate a snapshot-based chainstate more than once\n");
    5509           1 :         return false;
    5510             :     }
    5511             : 
    5512           8 :     int64_t current_coinsdb_cache_size{0};
    5513           8 :     int64_t current_coinstip_cache_size{0};
    5514             : 
    5515             :     // Cache percentages to allocate to each chainstate.
    5516             :     //
    5517             :     // These particular percentages don't matter so much since they will only be
    5518             :     // relevant during snapshot activation; caches are rebalanced at the conclusion of
    5519             :     // this function. We want to give (essentially) all available cache capacity to the
    5520             :     // snapshot to aid the bulk load later in this function.
    5521             :     static constexpr double IBD_CACHE_PERC = 0.01;
    5522             :     static constexpr double SNAPSHOT_CACHE_PERC = 0.99;
    5523             : 
    5524             :     {
    5525           8 :         LOCK(::cs_main);
    5526             :         // Resize the coins caches to ensure we're not exceeding memory limits.
    5527             :         //
    5528             :         // Allocate the majority of the cache to the incoming snapshot chainstate, since
    5529             :         // (optimistically) getting to its tip will be the top priority. We'll need to call
    5530             :         // `MaybeRebalanceCaches()` once we're done with this function to ensure
    5531             :         // the right allocation (including the possibility that no snapshot was activated
    5532             :         // and that we should restore the active chainstate caches to their original size).
    5533             :         //
    5534           8 :         current_coinsdb_cache_size = this->ActiveChainstate().m_coinsdb_cache_size_bytes;
    5535           8 :         current_coinstip_cache_size = this->ActiveChainstate().m_coinstip_cache_size_bytes;
    5536             : 
    5537             :         // Temporarily resize the active coins cache to make room for the newly-created
    5538             :         // snapshot chain.
    5539           8 :         this->ActiveChainstate().ResizeCoinsCaches(
    5540           8 :             static_cast<size_t>(current_coinstip_cache_size * IBD_CACHE_PERC),
    5541           8 :             static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
    5542           8 :     }
    5543             : 
    5544          16 :     auto snapshot_chainstate = WITH_LOCK(::cs_main, return std::make_unique<CChainState>(
    5545             :             /*mempool=*/ nullptr, m_blockman, *this,
    5546             :             this->ActiveChainstate().m_evoDb,
    5547             :             this->ActiveChainstate().m_chain_helper,
    5548             :             base_blockhash
    5549             :         )
    5550             :     );
    5551             : 
    5552             :     {
    5553           8 :         LOCK(::cs_main);
    5554           8 :         snapshot_chainstate->InitCoinsDB(
    5555           8 :             static_cast<size_t>(current_coinsdb_cache_size * SNAPSHOT_CACHE_PERC),
    5556           8 :             in_memory, false, "chainstate");
    5557          16 :         snapshot_chainstate->InitCoinsCache(
    5558           8 :             static_cast<size_t>(current_coinstip_cache_size * SNAPSHOT_CACHE_PERC));
    5559           8 :     }
    5560             : 
    5561           8 :     const bool snapshot_ok = this->PopulateAndValidateSnapshot(
    5562           8 :         *snapshot_chainstate, coins_file, metadata);
    5563             : 
    5564           8 :     if (!snapshot_ok) {
    5565          12 :         WITH_LOCK(::cs_main, this->MaybeRebalanceCaches());
    5566           6 :         return false;
    5567             :     }
    5568             : 
    5569             :     {
    5570           2 :         LOCK(::cs_main);
    5571           2 :         assert(!m_snapshot_chainstate);
    5572           2 :         m_snapshot_chainstate.swap(snapshot_chainstate);
    5573           2 :         const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
    5574           2 :         assert(chaintip_loaded);
    5575             : 
    5576           2 :         m_active_chainstate = m_snapshot_chainstate.get();
    5577             : 
    5578           2 :         LogPrintf("[snapshot] successfully activated snapshot %s\n", base_blockhash.ToString());
    5579           2 :         LogPrintf("[snapshot] (%.2f MB)\n",
    5580             :             m_snapshot_chainstate->CoinsTip().DynamicMemoryUsage() / (1000 * 1000));
    5581             : 
    5582           2 :         this->MaybeRebalanceCaches();
    5583           2 :     }
    5584           2 :     return true;
    5585           9 : }
    5586             : 
    5587           3 : static void FlushSnapshotToDisk(CCoinsViewCache& coins_cache, bool snapshot_loaded)
    5588             : {
    5589           3 :     LOG_TIME_MILLIS_WITH_CATEGORY_MSG_ONCE(
    5590             :         strprintf("%s (%.2f MB)",
    5591             :                   snapshot_loaded ? "saving snapshot chainstate" : "flushing coins cache",
    5592             :                   coins_cache.DynamicMemoryUsage() / (1000 * 1000)),
    5593             :         BCLog::LogFlags::ALL);
    5594             : 
    5595           3 :     coins_cache.Flush();
    5596           3 : }
    5597             : 
    5598           8 : bool ChainstateManager::PopulateAndValidateSnapshot(
    5599             :     CChainState& snapshot_chainstate,
    5600             :     AutoFile& coins_file,
    5601             :     const SnapshotMetadata& metadata)
    5602             : {
    5603             :     // It's okay to release cs_main before we're done using `coins_cache` because we know
    5604             :     // that nothing else will be referencing the newly created snapshot_chainstate yet.
    5605          16 :     CCoinsViewCache& coins_cache = WITH_LOCK(::cs_main, return snapshot_chainstate.CoinsTip());
    5606             : 
    5607           8 :     uint256 base_blockhash = metadata.m_base_blockhash;
    5608             : 
    5609          16 :     CBlockIndex* snapshot_start_block = WITH_LOCK(::cs_main, return m_blockman.LookupBlockIndex(base_blockhash));
    5610             : 
    5611           8 :     if (!snapshot_start_block) {
    5612             :         // Needed for ComputeUTXOStats and ExpectedAssumeutxo to determine the
    5613             :         // height and to avoid a crash when base_blockhash.IsNull()
    5614           2 :         LogPrintf("[snapshot] Did not find snapshot start blockheader %s\n",
    5615             :                   base_blockhash.ToString());
    5616           2 :         return false;
    5617             :     }
    5618             : 
    5619           6 :     int base_height = snapshot_start_block->nHeight;
    5620           6 :     auto maybe_au_data = ExpectedAssumeutxo(base_height, GetParams());
    5621             : 
    5622           6 :     if (!maybe_au_data) {
    5623           1 :         LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
    5624             :                   "(%d) - refusing to load snapshot\n", base_height);
    5625           1 :         return false;
    5626             :     }
    5627             : 
    5628           5 :     const AssumeutxoData& au_data = *maybe_au_data;
    5629             : 
    5630           5 :     COutPoint outpoint;
    5631           5 :     Coin coin;
    5632           5 :     const uint64_t coins_count = metadata.m_coins_count;
    5633           5 :     uint64_t coins_left = metadata.m_coins_count;
    5634             : 
    5635           5 :     LogPrintf("[snapshot] loading coins from snapshot %s\n", base_blockhash.ToString());
    5636           5 :     int64_t coins_processed{0};
    5637             : 
    5638         553 :     while (coins_left > 0) {
    5639             :         try {
    5640         549 :             coins_file >> outpoint;
    5641         548 :             coins_file >> coin;
    5642         549 :         } catch (const std::ios_base::failure&) {
    5643           1 :             LogPrintf("[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n",
    5644             :                       coins_count - coins_left);
    5645           1 :             return false;
    5646           1 :         }
    5647         548 :         if (coin.nHeight > base_height ||
    5648         548 :             outpoint.n >= std::numeric_limits<decltype(outpoint.n)>::max() // Avoid integer wrap-around in coinstats.cpp:ApplyHash
    5649             :         ) {
    5650           0 :             LogPrintf("[snapshot] bad snapshot data after deserializing %d coins\n",
    5651             :                       coins_count - coins_left);
    5652           0 :             return false;
    5653             :         }
    5654             : 
    5655         548 :         coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin));
    5656             : 
    5657         548 :         --coins_left;
    5658         548 :         ++coins_processed;
    5659             : 
    5660         548 :         if (coins_processed % 1000000 == 0) {
    5661           0 :             LogPrintf("[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n",
    5662             :                 coins_processed,
    5663             :                 static_cast<float>(coins_processed) * 100 / static_cast<float>(coins_count),
    5664             :                 coins_cache.DynamicMemoryUsage() / (1000 * 1000));
    5665           0 :         }
    5666             : 
    5667             :         // Batch write and flush (if we need to) every so often.
    5668             :         //
    5669             :         // If our average Coin size is roughly 41 bytes, checking every 120,000 coins
    5670             :         // means <5MB of memory imprecision.
    5671         548 :         if (coins_processed % 120000 == 0) {
    5672           0 :             if (ShutdownRequested()) {
    5673           0 :                 return false;
    5674             :             }
    5675             : 
    5676           0 :             const auto snapshot_cache_state = WITH_LOCK(::cs_main,
    5677             :                 return snapshot_chainstate.GetCoinsCacheSizeState());
    5678             : 
    5679           0 :             if (snapshot_cache_state >= CoinsCacheSizeState::CRITICAL) {
    5680             :                 // This is a hack - we don't know what the actual best block is, but that
    5681             :                 // doesn't matter for the purposes of flushing the cache here. We'll set this
    5682             :                 // to its correct value (`base_blockhash`) below after the coins are loaded.
    5683           0 :                 coins_cache.SetBestBlock(GetRandHash());
    5684             : 
    5685             :                 // No need to acquire cs_main since this chainstate isn't being used yet.
    5686           0 :                 FlushSnapshotToDisk(coins_cache, /*snapshot_loaded=*/false);
    5687           0 :             }
    5688           0 :         }
    5689             :     }
    5690             : 
    5691             :     // Important that we set this. This and the coins_cache accesses above are
    5692             :     // sort of a layer violation, but either we reach into the innards of
    5693             :     // CCoinsViewCache here or we have to invert some of the CChainState to
    5694             :     // embed them in a snapshot-activation-specific CCoinsViewCache bulk load
    5695             :     // method.
    5696           4 :     coins_cache.SetBestBlock(base_blockhash);
    5697             : 
    5698           4 :     bool out_of_coins{false};
    5699             :     try {
    5700           4 :         coins_file >> outpoint;
    5701           4 :     } catch (const std::ios_base::failure&) {
    5702             :         // We expect an exception since we should be out of coins.
    5703           3 :         out_of_coins = true;
    5704           3 :     }
    5705           4 :     if (!out_of_coins) {
    5706           1 :         LogPrintf("[snapshot] bad snapshot - coins left over after deserializing %d coins\n",
    5707             :             coins_count);
    5708           1 :         return false;
    5709             :     }
    5710             : 
    5711           3 :     LogPrintf("[snapshot] loaded %d (%.2f MB) coins from snapshot %s\n",
    5712             :         coins_count,
    5713             :         coins_cache.DynamicMemoryUsage() / (1000 * 1000),
    5714             :         base_blockhash.ToString());
    5715             : 
    5716             :     // No need to acquire cs_main since this chainstate isn't being used yet.
    5717           3 :     FlushSnapshotToDisk(coins_cache, /*snapshot_loaded=*/true);
    5718             : 
    5719           3 :     assert(coins_cache.GetBestBlock() == base_blockhash);
    5720             : 
    5721         332 :     auto breakpoint_fnc = [] { /* TODO insert breakpoint here? */ };
    5722             : 
    5723             :     // As above, okay to immediately release cs_main here since no other context knows
    5724             :     // about the snapshot_chainstate.
    5725           6 :     CCoinsViewDB* snapshot_coinsdb = WITH_LOCK(::cs_main, return &snapshot_chainstate.CoinsDB());
    5726             : 
    5727           3 :     const std::optional<CCoinsStats> maybe_stats = ComputeUTXOStats(CoinStatsHashType::HASH_SERIALIZED, snapshot_coinsdb, m_blockman, breakpoint_fnc);
    5728           3 :     if (!maybe_stats.has_value()) {
    5729           0 :         LogPrintf("[snapshot] failed to generate coins stats\n");
    5730           0 :         return false;
    5731             :     }
    5732             : 
    5733             :     // Assert that the deserialized chainstate contents match the expected assumeutxo value.
    5734           3 :     if (AssumeutxoHash{maybe_stats->hashSerialized} != au_data.hash_serialized) {
    5735           1 :         LogPrintf("[snapshot] bad snapshot content hash: expected %s, got %s\n",
    5736             :             au_data.hash_serialized.ToString(), maybe_stats->hashSerialized.ToString());
    5737           1 :         return false;
    5738             :     }
    5739             : 
    5740           2 :     snapshot_chainstate.m_chain.SetTip(*snapshot_start_block);
    5741             : 
    5742             :     // The remainder of this function requires modifying data protected by cs_main.
    5743           2 :     LOCK(::cs_main);
    5744             : 
    5745             :     // Fake various pieces of CBlockIndex state:
    5746           2 :     CBlockIndex* index = nullptr;
    5747             : 
    5748             :     // Don't make any modifications to the genesis block.
    5749             :     // This is especially important because we don't want to erroneously
    5750             :     // apply BLOCK_ASSUMED_VALID to genesis, which would happen if we didn't skip
    5751             :     // it here (since it apparently isn't BLOCK_VALID_SCRIPTS).
    5752           2 :     constexpr int AFTER_GENESIS_START{1};
    5753             : 
    5754         222 :     for (int i = AFTER_GENESIS_START; i <= snapshot_chainstate.m_chain.Height(); ++i) {
    5755         220 :         index = snapshot_chainstate.m_chain[i];
    5756             : 
    5757             :         // Fake nTx so that LoadBlockIndex() loads assumed-valid CBlockIndex
    5758             :         // entries (among other things)
    5759         220 :         if (!index->nTx) {
    5760           0 :             index->nTx = 1;
    5761           0 :         }
    5762             :         // Fake nChainTx so that GuessVerificationProgress reports accurately
    5763         220 :         index->nChainTx = index->pprev->nChainTx + index->nTx;
    5764             : 
    5765             :         // Mark unvalidated block index entries beneath the snapshot base block as assumed-valid.
    5766         220 :         if (!index->IsValid(BLOCK_VALID_SCRIPTS)) {
    5767             :             // This flag will be removed once the block is fully validated by a
    5768             :             // background chainstate.
    5769           0 :             index->nStatus |= BLOCK_ASSUMED_VALID;
    5770           0 :         }
    5771             : 
    5772         220 :         m_blockman.m_dirty_blockindex.insert(index);
    5773             :         // Changes to the block index will be flushed to disk after this call
    5774             :         // returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
    5775             :         // called, since we've added a snapshot chainstate and therefore will
    5776             :         // have to downsize the IBD chainstate, which will result in a call to
    5777             :         // `FlushStateToDisk(ALWAYS)`.
    5778         220 :     }
    5779             : 
    5780           2 :     assert(index);
    5781           2 :     index->nChainTx = au_data.nChainTx;
    5782           2 :     snapshot_chainstate.setBlockIndexCandidates.insert(snapshot_start_block);
    5783             : 
    5784           2 :     LogPrintf("[snapshot] validated snapshot (%.2f MB)\n",
    5785             :         coins_cache.DynamicMemoryUsage() / (1000 * 1000));
    5786           2 :     return true;
    5787          12 : }
    5788             : 
    5789    14472306 : CChainState& ChainstateManager::ActiveChainstate() const
    5790             : {
    5791    14472306 :     LOCK(::cs_main);
    5792    14472306 :     assert(m_active_chainstate);
    5793    14472306 :     return *m_active_chainstate;
    5794    14472306 : }
    5795             : 
    5796         289 : bool ChainstateManager::IsSnapshotActive() const
    5797             : {
    5798         289 :     LOCK(::cs_main);
    5799         289 :     return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
    5800         289 : }
    5801             : 
    5802     3692530 : bool ChainstateManager::IsQuorumTypeEnabled(const Consensus::LLMQType llmqType,
    5803             :                                             gsl::not_null<const CBlockIndex*> pindexPrev,
    5804             :                                             std::optional<bool> optDIP0024IsActive,
    5805             :                                             std::optional<bool> optHaveDIP0024Quorums) const
    5806             : {
    5807     3692530 :     constexpr int TESTNET_LLMQ_25_67_ACTIVATION_HEIGHT = 847000;
    5808             : 
    5809     3692530 :     const bool fDIP0024IsActive{optDIP0024IsActive.value_or(
    5810     3692530 :         DeploymentActiveAfter(pindexPrev, GetConsensus(), Consensus::DEPLOYMENT_DIP0024))};
    5811     3692530 :     const bool fHaveDIP0024Quorums{
    5812     3692530 :         optHaveDIP0024Quorums.value_or(pindexPrev->nHeight >= GetConsensus().DIP0024QuorumsHeight)};
    5813     3692530 :     switch (llmqType) {
    5814             :     case Consensus::LLMQType::LLMQ_DEVNET:
    5815           0 :         return true;
    5816             :     case Consensus::LLMQType::LLMQ_50_60:
    5817           1 :         return !fDIP0024IsActive || !fHaveDIP0024Quorums || m_chainparams.NetworkIDString() == CBaseChainParams::TESTNET ||
    5818           0 :                m_chainparams.NetworkIDString() == CBaseChainParams::DEVNET;
    5819             :     case Consensus::LLMQType::LLMQ_TEST_INSTANTSEND:
    5820      620764 :         return !fDIP0024IsActive || !fHaveDIP0024Quorums ||
    5821      581519 :                m_chainparams.GetConsensus().llmqTypeDIP0024InstantSend == Consensus::LLMQType::LLMQ_TEST_INSTANTSEND;
    5822             :     case Consensus::LLMQType::LLMQ_TEST:
    5823             :     case Consensus::LLMQType::LLMQ_TEST_PLATFORM:
    5824             :     case Consensus::LLMQType::LLMQ_400_60:
    5825             :     case Consensus::LLMQType::LLMQ_400_85:
    5826             :     case Consensus::LLMQType::LLMQ_DEVNET_PLATFORM:
    5827     1670396 :         return true;
    5828             : 
    5829             :     case Consensus::LLMQType::LLMQ_TEST_V17: {
    5830      603204 :         return DeploymentActiveAfter(pindexPrev, /*chainman=*/*this, Consensus::DEPLOYMENT_TESTDUMMY);
    5831             :     }
    5832             :     case Consensus::LLMQType::LLMQ_100_67:
    5833           4 :         return DeploymentActiveAfter(pindexPrev, GetConsensus(), Consensus::DEPLOYMENT_DIP0020);
    5834             : 
    5835             :     case Consensus::LLMQType::LLMQ_60_75:
    5836             :     case Consensus::LLMQType::LLMQ_DEVNET_DIP0024:
    5837             :     case Consensus::LLMQType::LLMQ_TEST_DIP0024: {
    5838      798161 :         return fDIP0024IsActive;
    5839             :     }
    5840             :     // TODO: remove it in case of testnet reset
    5841             :     case Consensus::LLMQType::LLMQ_25_67:
    5842           0 :         return pindexPrev->nHeight >= TESTNET_LLMQ_25_67_ACTIVATION_HEIGHT;
    5843             : 
    5844             :     default:
    5845           0 :         throw std::runtime_error(strprintf("%s: Unknown LLMQ type %d", __func__, std23::to_underlying(llmqType)));
    5846             :     }
    5847             : 
    5848             :     // Something wrong with conditions above, they are not consistent
    5849             :     assert(false);
    5850     3692530 : }
    5851             : 
    5852          10 : void ChainstateManager::MaybeRebalanceCaches()
    5853             : {
    5854          10 :     AssertLockHeld(::cs_main);
    5855          10 :     if (m_ibd_chainstate && !m_snapshot_chainstate) {
    5856             :         // Allocate everything to the IBD chainstate. This will always happen
    5857             :         // when we are not using a snapshot
    5858           7 :         m_ibd_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
    5859           7 :     }
    5860           3 :     else if (m_snapshot_chainstate && !m_ibd_chainstate) {
    5861           0 :         LogPrintf("[snapshot] allocating all cache to the snapshot chainstate\n");
    5862             :         // Allocate everything to the snapshot chainstate.
    5863           0 :         m_snapshot_chainstate->ResizeCoinsCaches(m_total_coinstip_cache, m_total_coinsdb_cache);
    5864           0 :     }
    5865           3 :     else if (m_ibd_chainstate && m_snapshot_chainstate) {
    5866             :         // If both chainstates exist, determine who needs more cache based on IBD status.
    5867             :         //
    5868             :         // Note: shrink caches first so that we don't inadvertently overwhelm available memory.
    5869           3 :         if (m_snapshot_chainstate->IsInitialBlockDownload()) {
    5870           2 :             m_ibd_chainstate->ResizeCoinsCaches(
    5871           1 :                 m_total_coinstip_cache * 0.05, m_total_coinsdb_cache * 0.05);
    5872           2 :             m_snapshot_chainstate->ResizeCoinsCaches(
    5873           1 :                 m_total_coinstip_cache * 0.95, m_total_coinsdb_cache * 0.95);
    5874           1 :         } else {
    5875           4 :             m_snapshot_chainstate->ResizeCoinsCaches(
    5876           2 :                 m_total_coinstip_cache * 0.05, m_total_coinsdb_cache * 0.05);
    5877           4 :             m_ibd_chainstate->ResizeCoinsCaches(
    5878           2 :                 m_total_coinstip_cache * 0.95, m_total_coinsdb_cache * 0.95);
    5879             :         }
    5880           3 :     }
    5881          10 : }
    5882             : 
    5883        6138 : ChainstateManager::~ChainstateManager()
    5884        3069 : {
    5885        3069 :     LOCK(::cs_main);
    5886             : 
    5887        3069 :     m_versionbitscache.Clear();
    5888        6138 : }
    5889             : 
    5890      341665 : bool IsBIP30Repeat(const CBlockIndex& block_index)
    5891             : {
    5892      683330 :     return (block_index.nHeight==91842 && block_index.GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
    5893      341665 :            (block_index.nHeight==91880 && block_index.GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"));
    5894             : }
    5895             : 
    5896        1121 : bool IsBIP30Unspendable(const CBlockIndex& block_index)
    5897             : {
    5898        2242 :     return (block_index.nHeight==91722 && block_index.GetBlockHash() == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) ||
    5899        1121 :            (block_index.nHeight==91812 && block_index.GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"));
    5900             : }

Generated by: LCOV version 1.16