LCOV - code coverage report
Current view: top level - src/kernel - mempool_entry.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 79 0.0 %
Date: 2024-01-03 14:57:27 Functions: 0 44 0.0 %
Branches: 0 18 0.0 %

           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                 :          0 : 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                 :          0 :     int height{0};
      31                 :          0 :     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                 :          0 :     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                 :          0 :     bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const
      43                 :            :     {
      44                 :          0 :         return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
      45                 :            :     }
      46                 :            :     template <typename T>
      47                 :          0 :     bool operator()(const T& a, const T& b) const
      48                 :            :     {
      49                 :          0 :         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                 :          0 : 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 [ #  # ][ #  # ]:          0 :     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                 :          0 :     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                 :          0 :     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                 :          0 :     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                 :          0 :         : tx{tx},
     114                 :          0 :           nFee{fee},
     115         [ #  # ]:          0 :           nTxWeight{GetTransactionWeight(*tx)},
     116         [ #  # ]:          0 :           nUsageSize{RecursiveDynamicUsage(tx)},
     117                 :          0 :           nTime{time},
     118                 :          0 :           entry_sequence{entry_sequence},
     119                 :          0 :           entryHeight{entry_height},
     120                 :          0 :           spendsCoinbase{spends_coinbase},
     121                 :          0 :           sigOpCost{sigops_cost},
     122                 :          0 :           m_modified_fee{nFee},
     123                 :          0 :           lockPoints{lp},
     124         [ #  # ]:          0 :           nSizeWithDescendants{GetTxSize()},
     125                 :          0 :           nModFeesWithDescendants{nFee},
     126         [ #  # ]:          0 :           nSizeWithAncestors{GetTxSize()},
     127                 :          0 :           nModFeesWithAncestors{nFee},
     128                 :          0 :           nSigOpCostWithAncestors{sigOpCost} {}
     129                 :            : 
     130                 :          0 :     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                 :          0 :     const CTransaction& GetTx() const { return *this->tx; }
     138                 :          0 :     CTransactionRef GetSharedTx() const { return this->tx; }
     139                 :          0 :     const CAmount& GetFee() const { return nFee; }
     140                 :          0 :     int32_t GetTxSize() const
     141                 :            :     {
     142                 :          0 :         return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
     143                 :            :     }
     144                 :          0 :     int32_t GetTxWeight() const { return nTxWeight; }
     145                 :          0 :     std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
     146                 :          0 :     unsigned int GetHeight() const { return entryHeight; }
     147                 :          0 :     uint64_t GetSequence() const { return entry_sequence; }
     148                 :          0 :     int64_t GetSigOpCost() const { return sigOpCost; }
     149                 :          0 :     CAmount GetModifiedFee() const { return m_modified_fee; }
     150                 :          0 :     size_t DynamicMemoryUsage() const { return nUsageSize; }
     151                 :          0 :     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                 :          0 :     void UpdateModifiedFee(CAmount fee_diff)
     159                 :            :     {
     160                 :          0 :         nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff);
     161                 :          0 :         nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff);
     162                 :          0 :         m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
     163                 :          0 :     }
     164                 :            : 
     165                 :            :     // Update the LockPoints after a reorg
     166                 :          0 :     void UpdateLockPoints(const LockPoints& lp) const
     167                 :            :     {
     168                 :          0 :         lockPoints = lp;
     169                 :          0 :     }
     170                 :            : 
     171                 :          0 :     uint64_t GetCountWithDescendants() const { return m_count_with_descendants; }
     172                 :          0 :     int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
     173                 :          0 :     CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
     174                 :            : 
     175                 :          0 :     bool GetSpendsCoinbase() const { return spendsCoinbase; }
     176                 :            : 
     177                 :          0 :     uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; }
     178                 :          0 :     int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
     179                 :          0 :     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
     180                 :          0 :     int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
     181                 :            : 
     182                 :          0 :     const Parents& GetMemPoolParentsConst() const { return m_parents; }
     183                 :          0 :     const Children& GetMemPoolChildrenConst() const { return m_children; }
     184                 :          0 :     Parents& GetMemPoolParents() const { return m_parents; }
     185                 :          0 :     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                 :          0 : 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                 :          0 :     TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
     211                 :          0 :         : m_tx{tx},
     212                 :          0 :           m_fee{fee},
     213                 :          0 :           m_virtual_transaction_size{vsize},
     214                 :          0 :           txHeight{height} {}
     215                 :            : };
     216                 :            : 
     217                 :          0 : struct RemovedMempoolTransactionInfo {
     218                 :            :     TransactionInfo info;
     219                 :          0 :     explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
     220 [ #  # ][ #  # ]:          0 :         : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
                 [ #  # ]
     221                 :            : };
     222                 :            : 
     223                 :          0 : 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_from_disconnected_block;
     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                 :          0 :     explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
     241                 :            :                                        const int64_t vsize, const unsigned int height,
     242                 :            :                                        const bool from_disconnected_block, const bool submitted_in_package,
     243                 :            :                                        const bool chainstate_is_current,
     244                 :            :                                        const bool has_no_mempool_parents)
     245                 :          0 :         : info{tx, fee, vsize, height},
     246                 :          0 :           m_from_disconnected_block{from_disconnected_block},
     247                 :          0 :           m_submitted_in_package{submitted_in_package},
     248                 :          0 :           m_chainstate_is_current{chainstate_is_current},
     249                 :          0 :           m_has_no_mempool_parents{has_no_mempool_parents} {}
     250                 :            : };
     251                 :            : 
     252                 :            : #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H

Generated by: LCOV version 1.14