LCOV - code coverage report
Current view: top level - src - txmempool.h (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 83.2 % 119 99
Test Date: 2026-03-01 04:36:14 Functions: 87.0 % 23 20
Branches: 43.6 % 172 75

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2                 :             : // Copyright (c) 2009-present The Bitcoin Core developers
       3                 :             : // Distributed under the MIT software license, see the accompanying
       4                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5                 :             : 
       6                 :             : #ifndef BITCOIN_TXMEMPOOL_H
       7                 :             : #define BITCOIN_TXMEMPOOL_H
       8                 :             : 
       9                 :             : #include <coins.h>
      10                 :             : #include <consensus/amount.h>
      11                 :             : #include <indirectmap.h>
      12                 :             : #include <kernel/cs_main.h>
      13                 :             : #include <kernel/mempool_entry.h>          // IWYU pragma: export
      14                 :             : #include <kernel/mempool_limits.h>         // IWYU pragma: export
      15                 :             : #include <kernel/mempool_options.h>        // IWYU pragma: export
      16                 :             : #include <kernel/mempool_removal_reason.h> // IWYU pragma: export
      17                 :             : #include <policy/feerate.h>
      18                 :             : #include <policy/packages.h>
      19                 :             : #include <primitives/transaction.h>
      20                 :             : #include <primitives/transaction_identifier.h>
      21                 :             : #include <sync.h>
      22                 :             : #include <txgraph.h>
      23                 :             : #include <util/feefrac.h>
      24                 :             : #include <util/hasher.h>
      25                 :             : #include <util/result.h>
      26                 :             : 
      27                 :             : #include <boost/multi_index/hashed_index.hpp>
      28                 :             : #include <boost/multi_index/identity.hpp>
      29                 :             : #include <boost/multi_index/indexed_by.hpp>
      30                 :             : #include <boost/multi_index/ordered_index.hpp>
      31                 :             : #include <boost/multi_index/sequenced_index.hpp>
      32                 :             : #include <boost/multi_index/tag.hpp>
      33                 :             : #include <boost/multi_index_container.hpp>
      34                 :             : 
      35                 :             : #include <atomic>
      36                 :             : #include <map>
      37                 :             : #include <optional>
      38                 :             : #include <set>
      39                 :             : #include <string>
      40                 :             : #include <string_view>
      41                 :             : #include <utility>
      42                 :             : #include <vector>
      43                 :             : 
      44                 :             : class CChain;
      45                 :             : class ValidationSignals;
      46                 :             : 
      47                 :             : struct bilingual_str;
      48                 :             : 
      49                 :             : /** Fake height value used in Coin to signify they are only in the memory pool (since 0.8) */
      50                 :             : static const uint32_t MEMPOOL_HEIGHT = 0x7FFFFFFF;
      51                 :             : 
      52                 :             : /** How much linearization cost required for TxGraph clusters to have
      53                 :             :  * "acceptable" quality, if they cannot be optimally linearized with less cost. */
      54                 :             : static constexpr uint64_t ACCEPTABLE_COST = 75'000;
      55                 :             : 
      56                 :             : /** How much work we ask TxGraph to do after a mempool change occurs (either
      57                 :             :  * due to a changeset being applied, a new block being found, or a reorg). */
      58                 :             : static constexpr uint64_t POST_CHANGE_COST = 5 * ACCEPTABLE_COST;
      59                 :             : 
      60                 :             : /**
      61                 :             :  * Test whether the LockPoints height and time are still valid on the current chain
      62                 :             :  */
      63                 :             : bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
      64                 :             : 
      65                 :             : // extracts a transaction hash from CTxMemPoolEntry or CTransactionRef
      66                 :             : struct mempoolentry_txid
      67                 :             : {
      68                 :             :     typedef Txid result_type;
      69                 :    75730871 :     result_type operator() (const CTxMemPoolEntry &entry) const
      70                 :             :     {
      71 [ +  + ][ -  +  :    75730871 :         return entry.GetTx().GetHash();
             +  +  -  - ]
      72                 :             :     }
      73                 :             : 
      74                 :             :     result_type operator() (const CTransactionRef& tx) const
      75                 :             :     {
      76                 :             :         return tx->GetHash();
      77                 :             :     }
      78                 :             : };
      79                 :             : 
      80                 :             : // extracts a transaction witness-hash from CTxMemPoolEntry or CTransactionRef
      81                 :             : struct mempoolentry_wtxid
      82                 :             : {
      83                 :             :     typedef Wtxid result_type;
      84                 :     9898221 :     result_type operator() (const CTxMemPoolEntry &entry) const
      85                 :             :     {
      86         [ +  + ]:     9898221 :         return entry.GetTx().GetWitnessHash();
           [ -  +  +  + ]
      87                 :             :     }
      88                 :             : 
      89                 :             :     result_type operator() (const CTransactionRef& tx) const
      90                 :             :     {
      91                 :             :         return tx->GetWitnessHash();
      92                 :             :     }
      93                 :             : };
      94                 :             : 
      95                 :             : class CompareTxMemPoolEntryByEntryTime
      96                 :             : {
      97                 :             : public:
      98                 :    17014541 :     bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
      99                 :             :     {
     100                 :    17014541 :         return a.GetTime() < b.GetTime();
     101                 :             :     }
     102                 :             : };
     103                 :             : 
     104                 :             : // Multi_index tag names
     105                 :             : struct entry_time {};
     106                 :             : struct index_by_wtxid {};
     107                 :             : 
     108                 :             : /**
     109                 :             :  * Information about a mempool transaction.
     110                 :             :  */
     111 [ #  # ][ +  -  :   139182459 : struct TxMempoolInfo
             +  -  -  - ]
           [ -  -  -  -  
             -  +  -  - ]
           [ -  -  -  -  
          -  -  -  -  -  
                +  -  - ]
     112                 :             : {
     113                 :             :     /** The transaction itself */
     114                 :             :     CTransactionRef tx;
     115                 :             : 
     116                 :             :     /** Time the transaction entered the mempool. */
     117                 :             :     std::chrono::seconds m_time;
     118                 :             : 
     119                 :             :     /** Fee of the transaction. */
     120                 :             :     CAmount fee;
     121                 :             : 
     122                 :             :     /** Virtual size of the transaction. */
     123                 :             :     int32_t vsize;
     124                 :             : 
     125                 :             :     /** The fee delta. */
     126                 :             :     int64_t nFeeDelta;
     127                 :             : };
     128                 :             : 
     129                 :             : /**
     130                 :             :  * CTxMemPool stores valid-according-to-the-current-best-chain transactions
     131                 :             :  * that may be included in the next block.
     132                 :             :  *
     133                 :             :  * Transactions are added when they are seen on the network (or created by the
     134                 :             :  * local node), but not all transactions seen are added to the pool. For
     135                 :             :  * example, the following new transactions will not be added to the mempool:
     136                 :             :  * - a transaction which doesn't meet the minimum fee requirements.
     137                 :             :  * - a new transaction that double-spends an input of a transaction already in
     138                 :             :  * the pool where the new transaction does not meet the Replace-By-Fee
     139                 :             :  * requirements as defined in doc/policy/mempool-replacements.md.
     140                 :             :  * - a non-standard transaction.
     141                 :             :  *
     142                 :             :  * TxGraph (CTxMemPool::m_txgraph) provides an abstraction layer for separating
     143                 :             :  * the transaction graph parts of the mempool from the rest of the
     144                 :             :  * Bitcoin-specific logic. Specifically, TxGraph handles (for each transaction)
     145                 :             :  * managing the in-mempool parents and children, and has knowledge of the fee
     146                 :             :  * and size of every transaction. It uses this to partition the mempool into
     147                 :             :  * connected clusters, and it implements (among other things):
     148                 :             :  *  - limits on the size of a cluster (in both number of transactions
     149                 :             :  *    and total weight)
     150                 :             :  *  - sorting the mempool optimally for block inclusion, taking into account
     151                 :             :  *    dependencies
     152                 :             :  *  - selecting transactions for removal due to cluster size limit violations
     153                 :             :  *    after a reorg.
     154                 :             :  * See txgraph.h and txgraph.cpp for more details.
     155                 :             :  *
     156                 :             :  * CTxMemPool itself handles the Bitcoin-specific parts of mempool
     157                 :             :  * transactions; it stores the full transaction inside CTxMemPoolEntry, along
     158                 :             :  * with other consensus-specific fields (such as whether a transaction spends a
     159                 :             :  * coinbase, or the LockPoints for transaction finality). And it provides
     160                 :             :  * interfaces to the rest of the codebase, such as:
     161                 :             :  *  - to validation for replace-by-fee calculations and cluster size limits
     162                 :             :  *    when evaluating unconfirmed transactions
     163                 :             :  *  - to validation for evicting transactions due to expiry or the mempool size
     164                 :             :  *    limit being hit
     165                 :             :  *  - to validation for updating the mempool to be consistent with the best
     166                 :             :  *    chain after a new block is connected or after a reorg.
     167                 :             :  *  - to net_processing for ordering transactions that are to-be-announced to
     168                 :             :  *    other peers
     169                 :             :  *  - to RPC code for inspecting the mempool
     170                 :             :  *
     171                 :             :  * (Many of these interfaces are just wrappers around corresponding TxGraph
     172                 :             :  * functions.)
     173                 :             :  *
     174                 :             :  * Within CTxMemPool, the mempool entries are stored in a boost::multi_index
     175                 :             :  * mapTx, which sorts the mempool on 3 criteria:
     176                 :             :  * - transaction hash (txid)
     177                 :             :  * - witness-transaction hash (wtxid)
     178                 :             :  * - time in mempool
     179                 :             :  *
     180                 :             :  * We also maintain a map from COutPoint to the (in-mempool) transaction that
     181                 :             :  * spends it (mapNextTx). This allows us to recover from a reorg and find
     182                 :             :  * transactions in the mempool that conflict with transactions that are
     183                 :             :  * confirmed in a block.
     184                 :             :  *
     185                 :             :  */
     186                 :             : class CTxMemPool
     187                 :             : {
     188                 :             : protected:
     189                 :             :     std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
     190                 :             : 
     191                 :             :     uint64_t totalTxSize GUARDED_BY(cs){0};      //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
     192                 :             :     CAmount m_total_fee GUARDED_BY(cs){0};       //!< sum of all mempool tx's fees (NOT modified fee)
     193                 :             :     uint64_t cachedInnerUsage GUARDED_BY(cs){0}; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
     194                 :             : 
     195                 :             :     mutable int64_t lastRollingFeeUpdate GUARDED_BY(cs){GetTime()};
     196                 :             :     mutable bool blockSinceLastRollingFeeBump GUARDED_BY(cs){false};
     197                 :             :     mutable double rollingMinimumFeeRate GUARDED_BY(cs){0}; //!< minimum fee to get into the pool, decreases exponentially
     198                 :             : 
     199                 :             :     // In-memory counter for external mempool tracking purposes.
     200                 :             :     // This number is incremented once every time a transaction
     201                 :             :     // is added or removed from the mempool for any reason.
     202                 :             :     mutable uint64_t m_sequence_number GUARDED_BY(cs){1};
     203                 :             : 
     204                 :             :     void trackPackageRemoved(const CFeeRate& rate) EXCLUSIVE_LOCKS_REQUIRED(cs);
     205                 :             : 
     206                 :             :     bool m_load_tried GUARDED_BY(cs){false};
     207                 :             : 
     208                 :             :     CFeeRate GetMinFee(size_t sizelimit) const;
     209                 :             : 
     210                 :             : public:
     211                 :             : 
     212                 :             :     static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12; // public only for testing
     213                 :             : 
     214                 :             :     struct CTxMemPoolEntry_Indices final : boost::multi_index::indexed_by<
     215                 :             :             // sorted by txid
     216                 :             :             boost::multi_index::hashed_unique<mempoolentry_txid, SaltedTxidHasher>,
     217                 :             :             // sorted by wtxid
     218                 :             :             boost::multi_index::hashed_unique<
     219                 :             :                 boost::multi_index::tag<index_by_wtxid>,
     220                 :             :                 mempoolentry_wtxid,
     221                 :             :                 SaltedWtxidHasher
     222                 :             :             >,
     223                 :             :             // sorted by entry time
     224                 :             :             boost::multi_index::ordered_non_unique<
     225                 :             :                 boost::multi_index::tag<entry_time>,
     226                 :             :                 boost::multi_index::identity<CTxMemPoolEntry>,
     227                 :             :                 CompareTxMemPoolEntryByEntryTime
     228                 :             :             >
     229                 :             :         >
     230                 :             :         {};
     231                 :             :     typedef boost::multi_index_container<
     232                 :             :         CTxMemPoolEntry,
     233                 :             :         CTxMemPoolEntry_Indices
     234                 :             :     > indexed_transaction_set;
     235                 :             : 
     236                 :             :     /**
     237                 :             :      * This mutex needs to be locked when accessing `mapTx` or other members
     238                 :             :      * that are guarded by it.
     239                 :             :      *
     240                 :             :      * @par Consistency guarantees
     241                 :             :      * By design, it is guaranteed that:
     242                 :             :      * 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool
     243                 :             :      *    that is consistent with current chain tip (`ActiveChain()` and
     244                 :             :      *    `CoinsTip()`) and is fully populated. Fully populated means that if the
     245                 :             :      *    current active chain is missing transactions that were present in a
     246                 :             :      *    previously active chain, all the missing transactions will have been
     247                 :             :      *    re-added to the mempool and should be present if they meet size and
     248                 :             :      *    consistency constraints.
     249                 :             :      * 2. Locking `mempool.cs` without `cs_main` will give a view of a mempool
     250                 :             :      *    consistent with some chain that was active since `cs_main` was last
     251                 :             :      *    locked, and that is fully populated as described above. It is ok for
     252                 :             :      *    code that only needs to query or remove transactions from the mempool
     253                 :             :      *    to lock just `mempool.cs` without `cs_main`.
     254                 :             :      *
     255                 :             :      * To provide these guarantees, it is necessary to lock both `cs_main` and
     256                 :             :      * `mempool.cs` whenever adding transactions to the mempool and whenever
     257                 :             :      * changing the chain tip. It's necessary to keep both mutexes locked until
     258                 :             :      * the mempool is consistent with the new chain tip and fully populated.
     259                 :             :      */
     260                 :             :     mutable RecursiveMutex cs;
     261                 :             :     std::unique_ptr<TxGraph> m_txgraph GUARDED_BY(cs);
     262                 :             :     mutable std::unique_ptr<TxGraph::BlockBuilder> m_builder GUARDED_BY(cs);
     263                 :             :     indexed_transaction_set mapTx GUARDED_BY(cs);
     264                 :             : 
     265                 :             :     using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator;
     266                 :             :     std::vector<std::pair<Wtxid, txiter>> txns_randomized GUARDED_BY(cs); //!< All transactions in mapTx with their wtxids, in arbitrary order
     267                 :             : 
     268                 :             :     typedef std::set<txiter, CompareIteratorByHash> setEntries;
     269                 :             : 
     270                 :             :     using Limits = kernel::MemPoolLimits;
     271                 :             : 
     272                 :             :     std::tuple<size_t, size_t, CAmount> CalculateAncestorData(const CTxMemPoolEntry& entry) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     273                 :             :     std::tuple<size_t, size_t, CAmount> CalculateDescendantData(const CTxMemPoolEntry& entry) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     274                 :             :     int64_t GetDescendantCount(txiter it) const { LOCK(cs); return m_txgraph->GetDescendants(*it, TxGraph::Level::MAIN).size(); }
     275   [ -  +  +  - ]:       20397 :     int64_t GetDescendantCount(const CTxMemPoolEntry &e) const { LOCK(cs); return m_txgraph->GetDescendants(e, TxGraph::Level::MAIN).size(); }
     276   [ -  +  +  - ]:       24272 :     int64_t GetAncestorCount(const CTxMemPoolEntry &e) const { LOCK(cs); return m_txgraph->GetAncestors(e, TxGraph::Level::MAIN).size(); }
     277                 :             :     std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> GetChildren(const CTxMemPoolEntry &entry) const;
     278                 :             :     std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> GetParents(const CTxMemPoolEntry &entry) const;
     279                 :             : 
     280                 :             : private:
     281                 :             :     std::vector<indexed_transaction_set::const_iterator> GetSortedScoreWithTopology() const EXCLUSIVE_LOCKS_REQUIRED(cs);
     282                 :             : 
     283                 :             :     /**
     284                 :             :      * Track locally submitted transactions to periodically retry initial broadcast.
     285                 :             :      */
     286                 :             :     std::set<Txid> m_unbroadcast_txids GUARDED_BY(cs);
     287                 :             : 
     288                 :    34827392 :     static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
     289                 :             :     {
     290   [ +  -  +  -  :    69654784 :         return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
                   -  - ]
     291                 :             :     }
     292                 :             : 
     293                 :             :     // Helper to remove all transactions that conflict with a given
     294                 :             :     // transaction (used for transactions appearing in a block).
     295                 :             :     void removeConflicts(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
     296                 :             : 
     297                 :             : public:
     298                 :             :     indirectmap<COutPoint, txiter> mapNextTx GUARDED_BY(cs);
     299                 :             :     std::map<Txid, CAmount> mapDeltas GUARDED_BY(cs);
     300                 :             : 
     301                 :             :     using Options = kernel::MemPoolOptions;
     302                 :             : 
     303                 :             :     const Options m_opts;
     304                 :             : 
     305                 :             :     /** Create a new CTxMemPool.
     306                 :             :      * Sanity checks will be off by default for performance, because otherwise
     307                 :             :      * accepting transactions becomes O(N^2) where N is the number of transactions
     308                 :             :      * in the pool.
     309                 :             :      */
     310                 :             :     explicit CTxMemPool(Options opts, bilingual_str& error);
     311                 :             : 
     312                 :             :     /**
     313                 :             :      * If sanity-checking is turned on, check makes sure the pool is
     314                 :             :      * consistent (does not contain two transactions that spend the same inputs,
     315                 :             :      * all inputs are in the mapNextTx array). If sanity-checking is turned off,
     316                 :             :      * check does nothing.
     317                 :             :      */
     318                 :             :     void check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     319                 :             : 
     320                 :             :     /**
     321                 :             :      * Remove a transaction from the mempool along with any descendants.
     322                 :             :      * If the transaction is not already in the mempool, find any descendants
     323                 :             :      * and remove them.
     324                 :             :      */
     325                 :             :     void removeRecursive(const CTransaction& tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
     326                 :             :     /** After reorg, filter the entries that would no longer be valid in the next block, and update
     327                 :             :      * the entries' cached LockPoints if needed.  The mempool does not have any knowledge of
     328                 :             :      * consensus rules. It just applies the callable function and removes the ones for which it
     329                 :             :      * returns true.
     330                 :             :      * @param[in]   filter_final_and_mature   Predicate that checks the relevant validation rules
     331                 :             :      *                                        and updates an entry's LockPoints.
     332                 :             :      * */
     333                 :             :     void removeForReorg(CChain& chain, std::function<bool(txiter)> filter_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
     334                 :             :     void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);
     335                 :             : 
     336                 :             :     bool CompareMiningScoreWithTopology(const Wtxid& hasha, const Wtxid& hashb) const;
     337                 :             :     bool isSpent(const COutPoint& outpoint) const;
     338                 :             :     unsigned int GetTransactionsUpdated() const;
     339                 :             :     void AddTransactionsUpdated(unsigned int n);
     340                 :             :     /**
     341                 :             :      * Check that none of this transactions inputs are in the mempool, and thus
     342                 :             :      * the tx is not dependent on other mempool transactions to be included in a block.
     343                 :             :      */
     344                 :             :     bool HasNoInputsOf(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     345                 :             : 
     346                 :             :     /** Affect CreateNewBlock prioritisation of transactions */
     347                 :             :     void PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta);
     348                 :             :     void ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     349                 :             :     void ClearPrioritisation(const Txid& hash) EXCLUSIVE_LOCKS_REQUIRED(cs);
     350                 :             : 
     351                 :             :     struct delta_info {
     352                 :             :         /** Whether this transaction is in the mempool. */
     353                 :             :         const bool in_mempool;
     354                 :             :         /** The fee delta added using PrioritiseTransaction(). */
     355                 :             :         const CAmount delta;
     356                 :             :         /** The modified fee (base fee + delta) of this entry. Only present if in_mempool=true. */
     357                 :             :         std::optional<CAmount> modified_fee;
     358                 :             :         /** The prioritised transaction's txid. */
     359                 :             :         const Txid txid;
     360                 :             :     };
     361                 :             :     /** Return a vector of all entries in mapDeltas with their corresponding delta_info. */
     362                 :             :     std::vector<delta_info> GetPrioritisedTransactions() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
     363                 :             : 
     364                 :             :     /** Get the transaction in the pool that spends the same prevout */
     365                 :             :     const CTransaction* GetConflictTx(const COutPoint& prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     366                 :             : 
     367                 :             :     /** Returns an iterator to the given hash, if found */
     368                 :             :     std::optional<txiter> GetIter(const Txid& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     369                 :             :     std::optional<txiter> GetIter(const Wtxid& wtxid) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     370                 :             : 
     371                 :             :     /** Translate a set of hashes into a set of pool iterators to avoid repeated lookups.
     372                 :             :      * Does not require that all of the hashes correspond to actual transactions in the mempool,
     373                 :             :      * only returns the ones that exist. */
     374                 :             :     setEntries GetIterSet(const std::set<Txid>& hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     375                 :             : 
     376                 :             :     /** Translate a list of hashes into a list of mempool iterators to avoid repeated lookups.
     377                 :             :      * The nth element in txids becomes the nth element in the returned vector. If any of the txids
     378                 :             :      * don't actually exist in the mempool, returns an empty vector. */
     379                 :             :     std::vector<txiter> GetIterVec(const std::vector<Txid>& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     380                 :             : 
     381                 :             :     /** UpdateTransactionsFromBlock is called when adding transactions from a
     382                 :             :      * disconnected block back to the mempool, new mempool entries may have
     383                 :             :      * children in the mempool (which is generally not the case when otherwise
     384                 :             :      * adding transactions).
     385                 :             :      *  @post updated descendant state for descendants of each transaction in
     386                 :             :      *        vHashesToUpdate (excluding any child transactions present in
     387                 :             :      *        vHashesToUpdate, which are already accounted for). Updated state
     388                 :             :      *        includes add fee/size information for such descendants to the
     389                 :             :      *        parent and updated ancestor state to include the parent.
     390                 :             :      *
     391                 :             :      * @param[in] vHashesToUpdate          The set of txids from the
     392                 :             :      *     disconnected block that have been accepted back into the mempool.
     393                 :             :      */
     394                 :             :     void UpdateTransactionsFromBlock(const std::vector<Txid>& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
     395                 :             : 
     396                 :             :     std::vector<FeePerWeight> GetFeerateDiagram() const EXCLUSIVE_LOCKS_REQUIRED(cs);
     397                 :           0 :     FeePerWeight GetMainChunkFeerate(const CTxMemPoolEntry& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs) {
     398                 :           0 :         return m_txgraph->GetMainChunkFeerate(tx);
     399                 :             :     }
     400                 :           0 :     std::vector<const CTxMemPoolEntry*> GetCluster(Txid txid) const EXCLUSIVE_LOCKS_REQUIRED(cs) {
     401                 :           0 :         auto tx = GetIter(txid);
     402         [ #  # ]:           0 :         if (!tx) return {};
     403                 :           0 :         auto cluster = m_txgraph->GetCluster(**tx, TxGraph::Level::MAIN);
     404                 :           0 :         std::vector<const CTxMemPoolEntry*> ret;
     405   [ #  #  #  # ]:           0 :         ret.reserve(cluster.size());
     406         [ #  # ]:           0 :         for (const auto& tx : cluster) {
     407         [ #  # ]:           0 :             ret.emplace_back(static_cast<const CTxMemPoolEntry*>(tx));
     408                 :             :         }
     409                 :           0 :         return ret;
     410                 :           0 :     }
     411                 :             : 
     412                 :             : 
     413                 :      416676 :     size_t GetUniqueClusterCount(const setEntries& iters_conflicting) const EXCLUSIVE_LOCKS_REQUIRED(cs) {
     414                 :      416676 :         std::vector<const TxGraph::Ref *> entries;
     415         [ +  - ]:      416676 :         entries.reserve(iters_conflicting.size());
     416         [ +  + ]:      982788 :         for (auto it : iters_conflicting) {
     417         [ +  - ]:      566112 :             entries.emplace_back(&*it);
     418                 :             :         }
     419         [ -  + ]:      416676 :         Assume(!m_txgraph->IsOversized(TxGraph::Level::MAIN));
     420         [ -  + ]:      416676 :         return m_txgraph->CountDistinctClusters(entries, TxGraph::Level::MAIN);
     421                 :      416676 :     }
     422                 :             : 
     423                 :             :     /**
     424                 :             :      * Calculate all in-mempool ancestors of entry (not including the tx itself)
     425                 :             :      *
     426                 :             :      * @param[in]   entry               CTxMemPoolEntry of which all in-mempool ancestors are calculated
     427                 :             :      *
     428                 :             :      * @return all in-mempool ancestors
     429                 :             :      */
     430                 :             :     setEntries CalculateMemPoolAncestors(const CTxMemPoolEntry& entry) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     431                 :             : 
     432                 :             :     bool HasDescendants(const Txid& txid) const;
     433                 :             : 
     434                 :             :     /** Collect the entire cluster of connected transactions for each transaction in txids.
     435                 :             :      * All txids must correspond to transaction entries in the mempool, otherwise this returns an
     436                 :             :      * empty vector. This call will also exit early and return an empty vector if it collects 500 or
     437                 :             :      * more transactions as a DoS protection. */
     438                 :             :     std::vector<txiter> GatherClusters(const std::vector<Txid>& txids) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     439                 :             : 
     440                 :             :     /** Populate setDescendants with all in-mempool descendants of given transaction.
     441                 :             :      *  Assumes that setDescendants includes all in-mempool descendants of anything
     442                 :             :      *  already in it.  */
     443                 :             :     void CalculateDescendants(txiter it, setEntries& setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     444                 :             :     CTxMemPool::txiter CalculateDescendants(const CTxMemPoolEntry& entry, setEntries& setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs);
     445                 :             : 
     446                 :             :     /** The minimum fee to get into the mempool, which may itself not be enough
     447                 :             :      *  for larger-sized transactions.
     448                 :             :      *  The m_incremental_relay_feerate policy variable is used to bound the time it
     449                 :             :      *  takes the fee rate to go back down all the way to 0. When the feerate
     450                 :             :      *  would otherwise be half of this, it is set to 0 instead.
     451                 :             :      */
     452                 :     1946774 :     CFeeRate GetMinFee() const {
     453         [ +  - ]:     1946774 :         return GetMinFee(m_opts.max_size_bytes);
     454                 :             :     }
     455                 :             : 
     456                 :             :     /** Remove transactions from the mempool until its dynamic size is <= sizelimit.
     457                 :             :       *  pvNoSpendsRemaining, if set, will be populated with the list of outpoints
     458                 :             :       *  which are not in mempool which no longer have any spends in this mempool.
     459                 :             :       */
     460                 :             :     void TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
     461                 :             : 
     462                 :             :     /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */
     463                 :             :     int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
     464                 :             : 
     465                 :             :     /**
     466                 :             :      * Calculate the ancestor and cluster count for the given transaction.
     467                 :             :      * The counts include the transaction itself.
     468                 :             :      * When ancestors is non-zero (ie, the transaction itself is in the mempool),
     469                 :             :      * ancestorsize and ancestorfees will also be set to the appropriate values.
     470                 :             :      */
     471                 :             :     void GetTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& cluster_count, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) const;
     472                 :             : 
     473                 :             :     /**
     474                 :             :      * @returns true if an initial attempt to load the persisted mempool was made, regardless of
     475                 :             :      *          whether the attempt was successful or not
     476                 :             :      */
     477                 :             :     bool GetLoadTried() const;
     478                 :             : 
     479                 :             :     /**
     480                 :             :      * Set whether or not an initial attempt to load the persisted mempool was made (regardless
     481                 :             :      * of whether the attempt was successful or not)
     482                 :             :      */
     483                 :             :     void SetLoadTried(bool load_tried);
     484                 :             : 
     485                 :        7495 :     unsigned long size() const
     486                 :             :     {
     487                 :        7495 :         LOCK(cs);
     488         [ +  - ]:        7495 :         return mapTx.size();
     489                 :        7495 :     }
     490                 :             : 
     491                 :           1 :     uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
     492                 :             :     {
     493                 :           1 :         AssertLockHeld(cs);
     494         [ +  - ]:           1 :         return totalTxSize;
     495                 :             :     }
     496                 :             : 
     497                 :       45561 :     CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
     498                 :             :     {
     499                 :       45561 :         AssertLockHeld(cs);
     500         [ +  - ]:       45561 :         return m_total_fee;
     501                 :             :     }
     502                 :             : 
     503                 :     7527742 :     bool exists(const Txid& txid) const
     504                 :             :     {
     505                 :     7527742 :         LOCK(cs);
     506         [ +  - ]:     7527742 :         return (mapTx.count(txid) != 0);
     507                 :     7527742 :     }
     508                 :             : 
     509                 :     3767267 :     bool exists(const Wtxid& wtxid) const
     510                 :             :     {
     511                 :     3767267 :         LOCK(cs);
     512         [ +  - ]:     3767267 :         return (mapTx.get<index_by_wtxid>().count(wtxid) != 0);
     513                 :     3767267 :     }
     514                 :             : 
     515                 :             :     const CTxMemPoolEntry* GetEntry(const Txid& txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs);
     516                 :             : 
     517                 :             :     CTransactionRef get(const Txid& hash) const;
     518                 :             : 
     519                 :             :     template <TxidOrWtxid T>
     520                 :       81897 :     TxMempoolInfo info(const T& id) const
     521                 :             :     {
     522                 :       81897 :         LOCK(cs);
     523         [ +  - ]:       81897 :         auto i{GetIter(id)};
     524   [ +  -  +  - ]:       81897 :         return i.has_value() ? GetInfo(*i) : TxMempoolInfo{};
     525                 :       81897 :     }
     526                 :             : 
     527                 :             :     /** Returns info for a transaction if its entry_sequence < last_sequence */
     528                 :             :     template <TxidOrWtxid T>
     529                 :       36685 :     TxMempoolInfo info_for_relay(const T& id, uint64_t last_sequence) const
     530                 :             :     {
     531                 :       36685 :         LOCK(cs);
     532         [ +  - ]:       36685 :         auto i{GetIter(id)};
     533   [ -  +  -  -  :       36685 :         return (i.has_value() && i.value()->GetSequence() < last_sequence) ? GetInfo(*i) : TxMempoolInfo{};
                   -  - ]
     534                 :       36685 :     }
     535                 :             : 
     536                 :             :     std::vector<CTxMemPoolEntryRef> entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs);
     537                 :             :     std::vector<TxMempoolInfo> infoAll() const;
     538                 :             : 
     539                 :             :     size_t DynamicMemoryUsage() const;
     540                 :             : 
     541                 :             :     /** Adds a transaction to the unbroadcast set */
     542                 :           0 :     void AddUnbroadcastTx(const Txid& txid)
     543                 :             :     {
     544                 :           0 :         LOCK(cs);
     545                 :             :         // Sanity check the transaction is in the mempool & insert into
     546                 :             :         // unbroadcast set.
     547   [ #  #  #  #  :           0 :         if (exists(txid)) m_unbroadcast_txids.insert(txid);
                   #  # ]
     548                 :           0 :     };
     549                 :             : 
     550                 :             :     bool CheckPolicyLimits(const CTransactionRef& tx);
     551                 :             : 
     552                 :             :     /** Removes a transaction from the unbroadcast set */
     553                 :             :     void RemoveUnbroadcastTx(const Txid& txid, bool unchecked = false);
     554                 :             : 
     555                 :             :     /** Returns transactions in unbroadcast set */
     556                 :        2215 :     std::set<Txid> GetUnbroadcastTxs() const
     557                 :             :     {
     558                 :        2215 :         LOCK(cs);
     559   [ +  -  +  - ]:        2215 :         return m_unbroadcast_txids;
     560                 :        2215 :     }
     561                 :             : 
     562                 :             :     /** Returns whether a txid is in the unbroadcast set */
     563                 :           0 :     bool IsUnbroadcastTx(const Txid& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
     564                 :             :     {
     565                 :           0 :         AssertLockHeld(cs);
     566                 :           0 :         return m_unbroadcast_txids.contains(txid);
     567                 :             :     }
     568                 :             : 
     569                 :             :     /** Guards this internal counter for external reporting */
     570                 :      510370 :     uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs) {
     571   [ +  +  #  # ]:      510370 :         return m_sequence_number++;
           [ +  -  +  - ]
     572                 :             :     }
     573                 :             : 
     574                 :     1370056 :     uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs) {
     575         [ +  - ]:     1370056 :         return m_sequence_number;
     576                 :             :     }
     577                 :             : 
     578                 :             : private:
     579                 :             :     /** Remove a set of transactions from the mempool.
     580                 :             :      *  If a transaction is in this set, then all in-mempool descendants must
     581                 :             :      *  also be in the set, unless this transaction is being removed for being
     582                 :             :      *  in a block.
     583                 :             :      */
     584                 :             :     void RemoveStaged(setEntries& stage, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
     585                 :             : 
     586                 :             :     /* Helper for the public removeRecursive() */
     587                 :             :     void removeRecursive(txiter to_remove, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
     588                 :             : 
     589                 :             :     /* Removal from the mempool also triggers removal of the entry's Ref from txgraph. */
     590                 :             :     void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
     591                 :             : public:
     592                 :             :     /*
     593                 :             :      * CTxMemPool::ChangeSet:
     594                 :             :      *
     595                 :             :      * This class is used for all mempool additions and associated removals (eg
     596                 :             :      * due to rbf). Removals that don't need to be evaluated for acceptance,
     597                 :             :      * such as removing transactions that appear in a block, or due to reorg,
     598                 :             :      * or removals related to mempool limiting or expiry do not need to use
     599                 :             :      * this.
     600                 :             :      *
     601                 :             :      * Callers can interleave calls to StageAddition()/StageRemoval(), and
     602                 :             :      * removals may be invoked in any order, but additions must be done in a
     603                 :             :      * topological order in the case of transaction packages (ie, parents must
     604                 :             :      * be added before children).
     605                 :             :      *
     606                 :             :      * CalculateChunksForRBF() can be used to calculate the feerate diagram of
     607                 :             :      * the proposed set of new transactions and compare with the existing
     608                 :             :      * mempool.
     609                 :             :      *
     610                 :             :      * CalculateMemPoolAncestors() calculates the in-mempool (not including
     611                 :             :      * what is in the change set itself) ancestors of a given transaction.
     612                 :             :      *
     613                 :             :      * Apply() will apply the removals and additions that are staged into the
     614                 :             :      * mempool.
     615                 :             :      *
     616                 :             :      * Only one changeset may exist at a time. While a changeset is
     617                 :             :      * outstanding, no removals or additions may be made directly to the
     618                 :             :      * mempool.
     619                 :             :      */
     620                 :             :     class ChangeSet {
     621                 :             :     public:
     622                 :     3544631 :         explicit ChangeSet(CTxMemPool* pool) : m_pool(pool) { m_pool->m_txgraph->StartStaging(); }
     623                 :     3544631 :         ~ChangeSet() EXCLUSIVE_LOCKS_REQUIRED(m_pool->cs) {
     624                 :     3544631 :             AssertLockHeld(m_pool->cs);
     625         [ +  + ]:     3544631 :             if (m_pool->m_txgraph->HaveStaging()) {
     626                 :     2159693 :                 m_pool->m_txgraph->AbortStaging();
     627                 :             :             }
     628                 :     3544631 :             m_pool->m_have_changeset = false;
     629                 :     3544631 :         }
     630                 :             : 
     631                 :             :         ChangeSet(const ChangeSet&) = delete;
     632                 :             :         ChangeSet& operator=(const ChangeSet&) = delete;
     633                 :             : 
     634                 :             :         using TxHandle = CTxMemPool::txiter;
     635                 :             : 
     636                 :             :         TxHandle StageAddition(const CTransactionRef& tx, CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp);
     637                 :             : 
     638                 :             :         void StageRemoval(CTxMemPool::txiter it);
     639                 :             : 
     640         [ +  + ]:      383568 :         const CTxMemPool::setEntries& GetRemovals() const { return m_to_remove; }
     641                 :             : 
     642                 :             :         /** Check if any cluster limits are exceeded. Returns true if pass, false if fail. */
     643                 :             :         bool CheckMemPoolPolicyLimits();
     644                 :             : 
     645                 :       56303 :         CTxMemPool::setEntries CalculateMemPoolAncestors(TxHandle tx)
     646                 :             :         {
     647                 :             :             // Look up transaction in our cache first
     648                 :       56303 :             auto it = m_ancestors.find(tx);
     649         [ -  + ]:       56303 :             if (it != m_ancestors.end()) return it->second;
     650                 :             : 
     651                 :             :             // If not found, try to have the mempool calculate it, and cache
     652                 :             :             // for later.
     653                 :       56303 :             LOCK(m_pool->cs);
     654         [ +  - ]:       56303 :             auto ret = m_pool->CalculateMemPoolAncestors(*tx);
     655         [ +  - ]:       56303 :             m_ancestors.try_emplace(tx, ret);
     656                 :       56303 :             return ret;
     657         [ +  - ]:      112606 :         }
     658                 :             : 
     659                 :        2649 :         std::vector<CTransactionRef> GetAddedTxns() const {
     660                 :        2649 :             std::vector<CTransactionRef> ret;
     661   [ -  +  +  - ]:        2649 :             ret.reserve(m_entry_vec.size());
     662         [ +  + ]:        7947 :             for (const auto& entry : m_entry_vec) {
     663   [ +  -  +  - ]:       15894 :                 ret.emplace_back(entry->GetSharedTx());
     664                 :             :             }
     665                 :        2649 :             return ret;
     666                 :           0 :         }
     667                 :             : 
     668                 :             :         /**
     669                 :             :          * Calculate the sorted chunks for the old and new mempool relating to the
     670                 :             :          * clusters that would be affected by a potential replacement transaction.
     671                 :             :          *
     672                 :             :          * @return old and new diagram pair respectively, or an error string if the conflicts don't match a calculable topology
     673                 :             :          */
     674                 :             :         util::Result<std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>>> CalculateChunksForRBF();
     675                 :             : 
     676   [ -  +  +  +  :       56441 :         size_t GetTxCount() const { return m_entry_vec.size(); }
             -  +  +  - ]
     677   [ +  -  +  - ]:       51143 :         const CTransaction& GetAddedTxn(size_t index) const { return m_entry_vec.at(index)->GetTx(); }
     678                 :             : 
     679                 :             :         void Apply() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     680                 :             : 
     681                 :             :     private:
     682                 :             :         void ProcessDependencies();
     683                 :             : 
     684                 :             :         CTxMemPool* m_pool;
     685                 :             :         CTxMemPool::indexed_transaction_set m_to_add;
     686                 :             :         std::vector<CTxMemPool::txiter> m_entry_vec; // track the added transactions' insertion order
     687                 :             :         // map from the m_to_add index to the ancestors for the transaction
     688                 :             :         std::map<CTxMemPool::txiter, CTxMemPool::setEntries, CompareIteratorByHash> m_ancestors;
     689                 :             :         CTxMemPool::setEntries m_to_remove;
     690                 :             :         bool m_dependencies_processed{false};
     691                 :             : 
     692                 :             :         friend class CTxMemPool;
     693                 :             :     };
     694                 :             : 
     695                 :     3544631 :     std::unique_ptr<ChangeSet> GetChangeSet() EXCLUSIVE_LOCKS_REQUIRED(cs) {
     696         [ -  + ]:     3544631 :         Assume(!m_have_changeset);
     697                 :     3544631 :         m_have_changeset = true;
     698                 :     3544631 :         return std::make_unique<ChangeSet>(this);
     699                 :             :     }
     700                 :             : 
     701                 :             :     bool m_have_changeset GUARDED_BY(cs){false};
     702                 :             : 
     703                 :             :     friend class CTxMemPool::ChangeSet;
     704                 :             : 
     705                 :             : private:
     706                 :             :     // Apply the given changeset to the mempool, by removing transactions in
     707                 :             :     // the to_remove set and adding transactions in the to_add set.
     708                 :             :     void Apply(CTxMemPool::ChangeSet* changeset) EXCLUSIVE_LOCKS_REQUIRED(cs);
     709                 :             : 
     710                 :             :     // addNewTransaction must update state for all ancestors of a given transaction,
     711                 :             :     // to track size/count of descendant transactions.  First version of
     712                 :             :     // addNewTransaction can be used to have it call CalculateMemPoolAncestors(), and
     713                 :             :     // then invoke the second version.
     714                 :             :     // Note that addNewTransaction is ONLY called (via Apply()) from ATMP
     715                 :             :     // outside of tests and any other callers may break wallet's in-mempool
     716                 :             :     // tracking (due to lack of CValidationInterface::TransactionAddedToMempool
     717                 :             :     // callbacks).
     718                 :             :     void addNewTransaction(CTxMemPool::txiter it) EXCLUSIVE_LOCKS_REQUIRED(cs);
     719                 :             : public:
     720         [ -  + ]:      246661 :     void StartBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs) { assert(!m_builder); m_builder = m_txgraph->GetBlockBuilder(); }
     721                 :      482235 :     FeePerWeight GetBlockBuilderChunk(std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef>& entries) const EXCLUSIVE_LOCKS_REQUIRED(cs)
     722                 :             :     {
     723         [ -  + ]:      482235 :         if (!m_builder) { return {}; }
     724                 :             : 
     725                 :      482235 :         auto res = m_builder->GetCurrentChunk();
     726         [ +  + ]:      482235 :         if (!res) { return {}; }
     727                 :             : 
     728         [ +  - ]:      236452 :         auto [chunk_entries, chunk_feerate] = *res;
     729         [ +  + ]:      526781 :         for (TxGraph::Ref* ref : chunk_entries) {
     730         [ +  - ]:      290329 :             entries.emplace_back(static_cast<const CTxMemPoolEntry&>(*ref));
     731                 :             :         }
     732                 :      236452 :         return chunk_feerate;
     733                 :      718687 :     }
     734                 :      223912 :     void IncludeBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs) { m_builder->Include(); }
     735                 :       11662 :     void SkipBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs) { m_builder->Skip(); }
     736         [ +  - ]:      246661 :     void StopBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs) { m_builder.reset(); }
     737                 :             : };
     738                 :             : 
     739                 :             : /**
     740                 :             :  * CCoinsView that brings transactions from a mempool into view.
     741                 :             :  * It does not check for spendings by memory pool transactions.
     742                 :             :  * Instead, it provides access to all Coins which are either unspent in the
     743                 :             :  * base CCoinsView, are outputs from any mempool transaction, or are
     744                 :             :  * tracked temporarily to allow transaction dependencies in package validation.
     745                 :             :  * This allows transaction replacement to work as expected, as you want to
     746                 :             :  * have all inputs "available" to check signatures, and any cycles in the
     747                 :             :  * dependency graph are checked directly in AcceptToMemoryPool.
     748                 :             :  * It also allows you to sign a double-spend directly in
     749                 :             :  * signrawtransactionwithkey and signrawtransactionwithwallet,
     750                 :             :  * as long as the conflicting transaction is not yet confirmed.
     751                 :             :  */
     752                 :             : class CCoinsViewMemPool : public CCoinsViewBacked
     753                 :             : {
     754                 :             :     /**
     755                 :             :     * Coins made available by transactions being validated. Tracking these allows for package
     756                 :             :     * validation, since we can access transaction outputs without submitting them to mempool.
     757                 :             :     */
     758                 :             :     std::unordered_map<COutPoint, Coin, SaltedOutpointHasher> m_temp_added;
     759                 :             : 
     760                 :             :     /**
     761                 :             :      * Set of all coins that have been fetched from mempool or created using PackageAddTransaction
     762                 :             :      * (not base). Used to track the origin of a coin, see GetNonBaseCoins().
     763                 :             :      */
     764                 :             :     mutable std::unordered_set<COutPoint, SaltedOutpointHasher> m_non_base_coins;
     765                 :             : protected:
     766                 :             :     const CTxMemPool& mempool;
     767                 :             : 
     768                 :             : public:
     769                 :             :     CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn);
     770                 :             :     /** GetCoin, returning whether it exists and is not spent. Also updates m_non_base_coins if the
     771                 :             :      * coin is not fetched from base. */
     772                 :             :     std::optional<Coin> GetCoin(const COutPoint& outpoint) const override;
     773                 :             :     /** Add the coins created by this transaction. These coins are only temporarily stored in
     774                 :             :      * m_temp_added and cannot be flushed to the back end. Only used for package validation. */
     775                 :             :     void PackageAddTransaction(const CTransactionRef& tx);
     776                 :             :     /** Get all coins in m_non_base_coins. */
     777                 :     3841767 :     const std::unordered_set<COutPoint, SaltedOutpointHasher>& GetNonBaseCoins() const { return m_non_base_coins; }
     778                 :             :     /** Clear m_temp_added and m_non_base_coins. */
     779                 :             :     void Reset();
     780                 :             : };
     781                 :             : #endif // BITCOIN_TXMEMPOOL_H
        

Generated by: LCOV version 2.0-1