LCOV - code coverage report
Current view: top level - src/kernel - mempool_entry.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 71 71
Test Date: 2024-11-04 05:10:19 Functions: 100.0 % 7 7
Branches: 46.0 % 526 242

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2009-2022 The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #ifndef BITCOIN_KERNEL_MEMPOOL_ENTRY_H
       6                 :             : #define BITCOIN_KERNEL_MEMPOOL_ENTRY_H
       7                 :             : 
       8                 :             : #include <consensus/amount.h>
       9                 :             : #include <consensus/validation.h>
      10                 :             : #include <core_memusage.h>
      11                 :             : #include <policy/policy.h>
      12                 :             : #include <policy/settings.h>
      13                 :             : #include <primitives/transaction.h>
      14                 :             : #include <util/epochguard.h>
      15                 :             : #include <util/overflow.h>
      16                 :             : 
      17                 :             : #include <chrono>
      18                 :             : #include <functional>
      19                 :             : #include <memory>
      20                 :             : #include <set>
      21                 :             : #include <stddef.h>
      22                 :             : #include <stdint.h>
      23                 :             : 
      24                 :             : class CBlockIndex;
      25                 :             : 
      26                 :             : struct LockPoints {
      27                 :             :     // Will be set to the blockchain height and median time past
      28                 :             :     // values that would be necessary to satisfy all relative locktime
      29                 :             :     // constraints (BIP68) of this tx given our view of block chain history
      30                 :             :     int height{0};
      31                 :             :     int64_t time{0};
      32                 :             :     // As long as the current chain descends from the highest height block
      33                 :             :     // containing one of the inputs used in the calculation, then the cached
      34                 :             :     // values are still valid even after a reorg.
      35                 :             :     CBlockIndex* maxInputBlock{nullptr};
      36                 :             : };
      37                 :             : 
      38                 :             : struct CompareIteratorByHash {
      39                 :             :     // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T>
      40                 :             :     // (e.g. a wrapped CTxMemPoolEntry&)
      41                 :             :     template <typename T>
      42                 :     7711121 :     bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const
      43                 :             :     {
      44                 :     7711121 :         return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
      45                 :             :     }
      46                 :             :     template <typename T>
      47                 :    58375108 :     bool operator()(const T& a, const T& b) const
      48                 :             :     {
      49                 :    58375108 :         return a->GetTx().GetHash() < b->GetTx().GetHash();
      50                 :             :     }
      51                 :             : };
      52                 :             : 
      53                 :             : /** \class CTxMemPoolEntry
      54                 :             :  *
      55                 :             :  * CTxMemPoolEntry stores data about the corresponding transaction, as well
      56                 :             :  * as data about all in-mempool transactions that depend on the transaction
      57                 :             :  * ("descendant" transactions).
      58                 :             :  *
      59                 :             :  * When a new entry is added to the mempool, we update the descendant state
      60                 :             :  * (m_count_with_descendants, nSizeWithDescendants, and nModFeesWithDescendants) for
      61                 :             :  * all ancestors of the newly added transaction.
      62                 :             :  *
      63                 :             :  */
      64                 :             : 
      65                 :             : class CTxMemPoolEntry
      66                 :             : {
      67                 :             : public:
      68                 :             :     typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef;
      69                 :             :     // two aliases, should the types ever diverge
      70                 :             :     typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Parents;
      71                 :             :     typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Children;
      72                 :             : 
      73                 :             : private:
      74   [ +  -  +  -  :       98836 :     CTxMemPoolEntry(const CTxMemPoolEntry&) = default;
             +  -  -  - ]
      75                 :             :     struct ExplicitCopyTag {
      76                 :             :         explicit ExplicitCopyTag() = default;
      77                 :             :     };
      78                 :             : 
      79                 :             :     const CTransactionRef tx;
      80                 :             :     mutable Parents m_parents;
      81                 :             :     mutable Children m_children;
      82                 :             :     const CAmount nFee;             //!< Cached to avoid expensive parent-transaction lookups
      83                 :             :     const int32_t nTxWeight;         //!< ... and avoid recomputing tx weight (also used for GetTxSize())
      84                 :             :     const size_t nUsageSize;        //!< ... and total memory usage
      85                 :             :     const int64_t nTime;            //!< Local time when entering the mempool
      86                 :             :     const uint64_t entry_sequence;  //!< Sequence number used to determine whether this transaction is too recent for relay
      87                 :             :     const unsigned int entryHeight; //!< Chain height when entering the mempool
      88                 :             :     const bool spendsCoinbase;      //!< keep track of transactions that spend a coinbase
      89                 :             :     const int64_t sigOpCost;        //!< Total sigop cost
      90                 :             :     CAmount m_modified_fee;         //!< Used for determining the priority of the transaction for mining in a block
      91                 :             :     mutable LockPoints lockPoints;  //!< Track the height and time at which tx was final
      92                 :             : 
      93                 :             :     // Information about descendants of this transaction that are in the
      94                 :             :     // mempool; if we remove this transaction we must remove all of these
      95                 :             :     // descendants as well.
      96                 :             :     int64_t m_count_with_descendants{1}; //!< number of descendant transactions
      97                 :             :     // Using int64_t instead of int32_t to avoid signed integer overflow issues.
      98                 :             :     int64_t nSizeWithDescendants;      //!< ... and size
      99                 :             :     CAmount nModFeesWithDescendants;   //!< ... and total fees (all including us)
     100                 :             : 
     101                 :             :     // Analogous statistics for ancestor transactions
     102                 :             :     int64_t m_count_with_ancestors{1};
     103                 :             :     // Using int64_t instead of int32_t to avoid signed integer overflow issues.
     104                 :             :     int64_t nSizeWithAncestors;
     105                 :             :     CAmount nModFeesWithAncestors;
     106                 :             :     int64_t nSigOpCostWithAncestors;
     107                 :             : 
     108                 :             : public:
     109                 :       60255 :     CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
     110                 :             :                     int64_t time, unsigned int entry_height, uint64_t entry_sequence,
     111                 :             :                     bool spends_coinbase,
     112                 :             :                     int64_t sigops_cost, LockPoints lp)
     113   [ +  -  -  - ]:       60255 :         : tx{tx},
     114                 :       60255 :           nFee{fee},
     115                 :       60255 :           nTxWeight{GetTransactionWeight(*tx)},
     116                 :       60255 :           nUsageSize{RecursiveDynamicUsage(tx)},
     117                 :       60255 :           nTime{time},
     118                 :       60255 :           entry_sequence{entry_sequence},
     119                 :       60255 :           entryHeight{entry_height},
     120                 :       60255 :           spendsCoinbase{spends_coinbase},
     121                 :       60255 :           sigOpCost{sigops_cost},
     122                 :       60255 :           m_modified_fee{nFee},
     123                 :       60255 :           lockPoints{lp},
     124                 :      120510 :           nSizeWithDescendants{GetTxSize()},
     125                 :       60255 :           nModFeesWithDescendants{nFee},
     126                 :      120510 :           nSizeWithAncestors{GetTxSize()},
     127                 :       60255 :           nModFeesWithAncestors{nFee},
     128   [ +  -  +  - ]:      120510 :           nSigOpCostWithAncestors{sigOpCost} {}
     129                 :             : 
     130         [ +  - ]:       49418 :     CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
     131                 :             :     CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
     132                 :             :     CTxMemPoolEntry(CTxMemPoolEntry&&) = delete;
     133                 :             :     CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete;
     134                 :             : 
     135                 :             :     static constexpr ExplicitCopyTag ExplicitCopy{};
     136                 :             : 
     137   [ +  +  +  +  :   107741584 :     const CTransaction& GetTx() const { return *this->tx; }
                   +  + ]
           [ +  +  +  + ]
           [ -  -  -  -  
             +  -  +  - ]
           [ -  -  -  -  
          +  -  +  -  +  
           - ][ -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  -  
          +  -  -  +  +  
          -  -  +  +  -  
          +  +  +  +  -  
          -  -  -  +  -  
          +  -  +  -  +  
          +  -  +  +  +  
          +  -  +  -  -  
                -  -  - ]
     138   [ +  -  +  -  :      789452 :     CTransactionRef GetSharedTx() const { return this->tx; }
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
           [ +  -  +  - ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
           -  +  - ][ #  
          #  #  #  #  #  
                   #  # ]
     139 [ +  - ][ +  -  :       56184 :     const CAmount& GetFee() const { return nFee; }
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     140                 :   263274552 :     int32_t GetTxSize() const
     141                 :             :     {
     142                 :   263274552 :         return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
     143                 :             :     }
     144         [ +  - ]:       14885 :     int32_t GetTxWeight() const { return nTxWeight; }
     145   [ +  +  +  - ]:    16460289 :     std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
     146         [ +  - ]:       47515 :     unsigned int GetHeight() const { return entryHeight; }
     147         [ +  + ]:       11535 :     uint64_t GetSequence() const { return entry_sequence; }
     148         [ +  - ]:     8473126 :     int64_t GetSigOpCost() const { return sigOpCost; }
     149 [ +  - ][ +  -  :    55414568 :     CAmount GetModifiedFee() const { return m_modified_fee; }
             +  -  +  - ]
           [ +  -  +  -  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     150                 :     6905533 :     size_t DynamicMemoryUsage() const { return nUsageSize; }
     151         [ +  - ]:        1752 :     const LockPoints& GetLockPoints() const { return lockPoints; }
     152                 :             : 
     153                 :             :     // Adjusts the descendant state.
     154                 :             :     void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount);
     155                 :             :     // Adjusts the ancestor state
     156                 :             :     void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps);
     157                 :             :     // Updates the modified fees with descendants/ancestors.
     158                 :         283 :     void UpdateModifiedFee(CAmount fee_diff)
     159                 :             :     {
     160                 :         283 :         nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff);
     161                 :         283 :         nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff);
     162                 :         283 :         m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
     163                 :         283 :     }
     164                 :             : 
     165                 :             :     // Update the LockPoints after a reorg
     166                 :         163 :     void UpdateLockPoints(const LockPoints& lp) const
     167                 :             :     {
     168                 :         163 :         lockPoints = lp;
     169                 :             :     }
     170                 :             : 
     171 [ +  + ][ +  +  :     1681835 :     uint64_t GetCountWithDescendants() const { return m_count_with_descendants; }
          +  -  +  +  +  
                +  +  + ]
     172   [ +  -  +  + ]:    42006619 :     int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
                 [ #  # ]
     173         [ +  - ]:    33566387 :     CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
     174                 :             : 
     175         [ +  + ]:         876 :     bool GetSpendsCoinbase() const { return spendsCoinbase; }
     176                 :             : 
     177 [ +  + ][ +  +  :    83094904 :     uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; }
          +  -  +  +  +  
          +  +  +  +  +  
             -  +  +  - ]
           [ #  #  #  #  
                   #  # ]
     178   [ +  -  +  +  :     6934100 :     int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
                   +  - ]
           [ -  +  -  + ]
                 [ #  # ]
     179 [ +  - ][ +  -  :    12366490 :     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
             +  +  +  - ]
           [ +  +  -  + ]
     180   [ +  -  +  +  :     6847260 :     int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
           +  - ][ -  + ]
     181                 :             : 
     182   [ +  +  +  +  :    15454260 :     const Parents& GetMemPoolParentsConst() const { return m_parents; }
             +  +  -  + ]
                 [ #  # ]
     183         [ +  + ]:    14902295 :     const Children& GetMemPoolChildrenConst() const { return m_children; }
           [ +  +  -  + ]
     184         [ +  - ]:       11505 :     Parents& GetMemPoolParents() const { return m_parents; }
     185         [ +  - ]:       11505 :     Children& GetMemPoolChildren() const { return m_children; }
     186                 :             : 
     187                 :             :     mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
     188                 :             :     mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
     189                 :             : };
     190                 :             : 
     191                 :             : using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
     192                 :             : 
     193                 :      702396 : struct TransactionInfo {
     194                 :             :     const CTransactionRef m_tx;
     195                 :             :     /* The fee the transaction paid */
     196                 :             :     const CAmount m_fee;
     197                 :             :     /**
     198                 :             :      * The virtual transaction size.
     199                 :             :      *
     200                 :             :      * This is a policy field which considers the sigop cost of the
     201                 :             :      * transaction as well as its weight, and reinterprets it as bytes.
     202                 :             :      *
     203                 :             :      * It is the primary metric by which the mining algorithm selects
     204                 :             :      * transactions.
     205                 :             :      */
     206                 :             :     const int64_t m_virtual_transaction_size;
     207                 :             :     /* The block height the transaction entered the mempool */
     208                 :             :     const unsigned int txHeight;
     209                 :             : 
     210                 :       89495 :     TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
     211                 :      178990 :         : m_tx{tx},
     212                 :       89495 :           m_fee{fee},
     213                 :       89495 :           m_virtual_transaction_size{vsize},
     214                 :       89495 :           txHeight{height} {}
     215                 :             : };
     216                 :             : 
     217   [ -  -  #  # ]:      731884 : struct RemovedMempoolTransactionInfo {
           [ -  -  +  - ]
     218                 :             :     TransactionInfo info;
     219                 :       43052 :     explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
     220   [ +  -  +  -  :      172208 :         : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
             +  -  +  - ]
     221                 :             : };
     222                 :             : 
     223   [ +  -  -  -  :      185772 : struct NewMempoolTransactionInfo {
             #  #  #  # ]
           [ +  -  -  -  
             +  -  -  - ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
             -  -  -  - ]
     224                 :             :     TransactionInfo info;
     225                 :             :     /*
     226                 :             :      * This boolean indicates whether the transaction was added
     227                 :             :      * without enforcing mempool fee limits.
     228                 :             :      */
     229                 :             :     const bool m_mempool_limit_bypassed;
     230                 :             :     /* This boolean indicates whether the transaction is part of a package. */
     231                 :             :     const bool m_submitted_in_package;
     232                 :             :     /*
     233                 :             :      * This boolean indicates whether the blockchain is up to date when the
     234                 :             :      * transaction is added to the mempool.
     235                 :             :      */
     236                 :             :     const bool m_chainstate_is_current;
     237                 :             :     /* Indicates whether the transaction has unconfirmed parents. */
     238                 :             :     const bool m_has_no_mempool_parents;
     239                 :             : 
     240                 :       46443 :     explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
     241                 :             :                                        const int64_t vsize, const unsigned int height,
     242                 :             :                                        const bool mempool_limit_bypassed, const bool submitted_in_package,
     243                 :             :                                        const bool chainstate_is_current,
     244                 :             :                                        const bool has_no_mempool_parents)
     245   [ +  -  +  - ]:       46443 :         : info{tx, fee, vsize, height},
           [ +  -  +  -  
                   +  - ]
     246                 :       46443 :           m_mempool_limit_bypassed{mempool_limit_bypassed},
     247                 :       46443 :           m_submitted_in_package{submitted_in_package},
     248                 :       46443 :           m_chainstate_is_current{chainstate_is_current},
     249   [ +  -  +  - ]:       46443 :           m_has_no_mempool_parents{has_no_mempool_parents} {}
           [ +  -  +  -  
                   +  - ]
     250                 :             : };
     251                 :             : 
     252                 :             : #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
        

Generated by: LCOV version 2.0-1