LCOV - code coverage report
Current view: top level - src/kernel - mempool_entry.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 50 61 82.0 %
Date: 2023-09-26 12:08:55 Functions: 26 32 81.2 %

          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       10268 :     bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const
      43             :     {
      44       10268 :         return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
      45             :     }
      46             :     template <typename T>
      47       10244 :     bool operator()(const T& a, const T& b) const
      48             :     {
      49       10244 :         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        2211 : 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             :     const CTransactionRef tx;
      75             :     mutable Parents m_parents;
      76             :     mutable Children m_children;
      77             :     const CAmount nFee;             //!< Cached to avoid expensive parent-transaction lookups
      78             :     const int32_t nTxWeight;         //!< ... and avoid recomputing tx weight (also used for GetTxSize())
      79             :     const size_t nUsageSize;        //!< ... and total memory usage
      80             :     const int64_t nTime;            //!< Local time when entering the mempool
      81             :     const uint64_t entry_sequence;  //!< Sequence number used to determine whether this transaction is too recent for relay
      82             :     const unsigned int entryHeight; //!< Chain height when entering the mempool
      83             :     const bool spendsCoinbase;      //!< keep track of transactions that spend a coinbase
      84             :     const int64_t sigOpCost;        //!< Total sigop cost
      85             :     CAmount m_modified_fee;         //!< Used for determining the priority of the transaction for mining in a block
      86             :     LockPoints lockPoints;          //!< Track the height and time at which tx was final
      87             : 
      88             :     // Information about descendants of this transaction that are in the
      89             :     // mempool; if we remove this transaction we must remove all of these
      90             :     // descendants as well.
      91        5047 :     int64_t m_count_with_descendants{1}; //!< number of descendant transactions
      92             :     // Using int64_t instead of int32_t to avoid signed integer overflow issues.
      93             :     int64_t nSizeWithDescendants;      //!< ... and size
      94             :     CAmount nModFeesWithDescendants;   //!< ... and total fees (all including us)
      95             : 
      96             :     // Analogous statistics for ancestor transactions
      97        5047 :     int64_t m_count_with_ancestors{1};
      98             :     // Using int64_t instead of int32_t to avoid signed integer overflow issues.
      99             :     int64_t nSizeWithAncestors;
     100             :     CAmount nModFeesWithAncestors;
     101             :     int64_t nSigOpCostWithAncestors;
     102             : 
     103             : public:
     104       15141 :     CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
     105             :                     int64_t time, unsigned int entry_height, uint64_t entry_sequence,
     106             :                     bool spends_coinbase,
     107             :                     int64_t sigops_cost, LockPoints lp)
     108        5047 :         : tx{tx},
     109        5047 :           nFee{fee},
     110        5047 :           nTxWeight{GetTransactionWeight(*tx)},
     111        5047 :           nUsageSize{RecursiveDynamicUsage(tx)},
     112        5047 :           nTime{time},
     113        5047 :           entry_sequence{entry_sequence},
     114        5047 :           entryHeight{entry_height},
     115        5047 :           spendsCoinbase{spends_coinbase},
     116        5047 :           sigOpCost{sigops_cost},
     117        5047 :           m_modified_fee{nFee},
     118        5047 :           lockPoints{lp},
     119        5047 :           nSizeWithDescendants{GetTxSize()},
     120        5047 :           nModFeesWithDescendants{nFee},
     121        5047 :           nSizeWithAncestors{GetTxSize()},
     122        5047 :           nModFeesWithAncestors{nFee},
     123       10094 :           nSigOpCostWithAncestors{sigOpCost} {}
     124             : 
     125      141907 :     const CTransaction& GetTx() const { return *this->tx; }
     126       34353 :     CTransactionRef GetSharedTx() const { return this->tx; }
     127       15229 :     const CAmount& GetFee() const { return nFee; }
     128       63867 :     int32_t GetTxSize() const
     129             :     {
     130       63867 :         return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
     131             :     }
     132         815 :     int32_t GetTxWeight() const { return nTxWeight; }
     133        9407 :     std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
     134           0 :     unsigned int GetHeight() const { return entryHeight; }
     135           0 :     uint64_t GetSequence() const { return entry_sequence; }
     136        4318 :     int64_t GetSigOpCost() const { return sigOpCost; }
     137       29457 :     CAmount GetModifiedFee() const { return m_modified_fee; }
     138        6324 :     size_t DynamicMemoryUsage() const { return nUsageSize; }
     139           0 :     const LockPoints& GetLockPoints() const { return lockPoints; }
     140             : 
     141             :     // Adjusts the descendant state.
     142             :     void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount);
     143             :     // Adjusts the ancestor state
     144             :     void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps);
     145             :     // Updates the modified fees with descendants/ancestors.
     146         466 :     void UpdateModifiedFee(CAmount fee_diff)
     147             :     {
     148         466 :         nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff);
     149         466 :         nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff);
     150         466 :         m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
     151         466 :     }
     152             : 
     153             :     // Update the LockPoints after a reorg
     154           0 :     void UpdateLockPoints(const LockPoints& lp)
     155             :     {
     156           0 :         lockPoints = lp;
     157           0 :     }
     158             : 
     159        1899 :     uint64_t GetCountWithDescendants() const { return m_count_with_descendants; }
     160        9155 :     int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
     161        4996 :     CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
     162             : 
     163           0 :     bool GetSpendsCoinbase() const { return spendsCoinbase; }
     164             : 
     165        9031 :     uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; }
     166        8748 :     int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
     167        8748 :     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
     168        3934 :     int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
     169             : 
     170       16809 :     const Parents& GetMemPoolParentsConst() const { return m_parents; }
     171       13341 :     const Children& GetMemPoolChildrenConst() const { return m_children; }
     172         348 :     Parents& GetMemPoolParents() const { return m_parents; }
     173         692 :     Children& GetMemPoolChildren() const { return m_children; }
     174             : 
     175             :     mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes
     176             :     mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
     177             : };
     178             : 
     179             : #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H

Generated by: LCOV version 1.14