LCOV - code coverage report
Current view: top level - src/node - txdownloadman.h (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 33.3 % 21 7
Test Date: 2024-12-04 04:00:22 Functions: 25.0 % 4 1
Branches: 25.0 % 28 7

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2024 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_NODE_TXDOWNLOADMAN_H
       6                 :             : #define BITCOIN_NODE_TXDOWNLOADMAN_H
       7                 :             : 
       8                 :             : #include <net.h>
       9                 :             : #include <policy/packages.h>
      10                 :             : #include <txorphanage.h>
      11                 :             : 
      12                 :             : #include <cstdint>
      13                 :             : #include <memory>
      14                 :             : 
      15                 :             : class CBlock;
      16                 :             : class CRollingBloomFilter;
      17                 :             : class CTxMemPool;
      18                 :             : class GenTxid;
      19                 :             : class TxRequestTracker;
      20                 :             : namespace node {
      21                 :             : class TxDownloadManagerImpl;
      22                 :             : 
      23                 :             : /** Maximum number of in-flight transaction requests from a peer. It is not a hard limit, but the threshold at which
      24                 :             :  *  point the OVERLOADED_PEER_TX_DELAY kicks in. */
      25                 :             : static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100;
      26                 :             : /** Maximum number of transactions to consider for requesting, per peer. It provides a reasonable DoS limit to
      27                 :             :  *  per-peer memory usage spent on announcements, while covering peers continuously sending INVs at the maximum
      28                 :             :  *  rate (by our own policy, see INVENTORY_BROADCAST_PER_SECOND) for several minutes, while not receiving
      29                 :             :  *  the actual transaction (from any peer) in response to requests for them. */
      30                 :             : static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 5000;
      31                 :             : /** How long to delay requesting transactions via txids, if we have wtxid-relaying peers */
      32                 :             : static constexpr auto TXID_RELAY_DELAY{2s};
      33                 :             : /** How long to delay requesting transactions from non-preferred peers */
      34                 :             : static constexpr auto NONPREF_PEER_TX_DELAY{2s};
      35                 :             : /** How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT). */
      36                 :             : static constexpr auto OVERLOADED_PEER_TX_DELAY{2s};
      37                 :             : /** How long to wait before downloading a transaction from an additional peer */
      38                 :             : static constexpr auto GETDATA_TX_INTERVAL{60s};
      39                 :             : struct TxDownloadOptions {
      40                 :             :     /** Read-only reference to mempool. */
      41                 :             :     const CTxMemPool& m_mempool;
      42                 :             :     /** RNG provided by caller. */
      43                 :             :     FastRandomContext& m_rng;
      44                 :             :     /** Maximum number of transactions allowed in orphanage. */
      45                 :             :     const uint32_t m_max_orphan_txs;
      46                 :             :     /** Instantiate TxRequestTracker as deterministic (used for tests). */
      47                 :             :     bool m_deterministic_txrequest{false};
      48                 :             : };
      49                 :             : struct TxDownloadConnectionInfo {
      50                 :             :     /** Whether this peer is preferred for transaction download. */
      51                 :             :     const bool m_preferred;
      52                 :             :     /** Whether this peer has Relay permissions. */
      53                 :             :     const bool m_relay_permissions;
      54                 :             :     /** Whether this peer supports wtxid relay. */
      55                 :             :     const bool m_wtxid_relay;
      56                 :             : };
      57                 :          56 : struct PackageToValidate {
      58                 :             :     Package m_txns;
      59                 :             :     std::vector<NodeId> m_senders;
      60                 :             :     /** Construct a 1-parent-1-child package. */
      61                 :          14 :     explicit PackageToValidate(const CTransactionRef& parent,
      62                 :             :                                const CTransactionRef& child,
      63                 :             :                                NodeId parent_sender,
      64                 :          14 :                                NodeId child_sender) :
      65   [ +  +  +  -  :          42 :         m_txns{parent, child},
             -  -  -  - ]
      66         [ +  - ]:          14 :         m_senders{parent_sender, child_sender}
      67   [ +  -  +  -  :          56 :     {}
                   +  - ]
      68                 :             : 
      69                 :             :     // Move ctor
      70                 :          42 :     PackageToValidate(PackageToValidate&& other) : m_txns{std::move(other.m_txns)}, m_senders{std::move(other.m_senders)} {}
      71                 :             :     // Copy ctor
      72         [ #  # ]:           0 :     PackageToValidate(const PackageToValidate& other) = default;
      73                 :             : 
      74                 :             :     // Move assignment
      75                 :           0 :     PackageToValidate& operator=(PackageToValidate&& other) {
      76                 :           0 :         this->m_txns = std::move(other.m_txns);
      77                 :           0 :         this->m_senders = std::move(other.m_senders);
      78                 :           0 :         return *this;
      79                 :             :     }
      80                 :             : 
      81                 :           0 :     std::string ToString() const {
      82                 :           0 :         Assume(m_txns.size() == 2);
      83                 :           0 :         return strprintf("parent %s (wtxid=%s, sender=%d) + child %s (wtxid=%s, sender=%d)",
      84                 :           0 :                          m_txns.front()->GetHash().ToString(),
      85   [ #  #  #  # ]:           0 :                          m_txns.front()->GetWitnessHash().ToString(),
      86                 :           0 :                          m_senders.front(),
      87         [ #  # ]:           0 :                          m_txns.back()->GetHash().ToString(),
      88         [ #  # ]:           0 :                          m_txns.back()->GetWitnessHash().ToString(),
      89         [ #  # ]:           0 :                          m_senders.back());
      90                 :             :     }
      91                 :             : };
      92                 :             : struct RejectedTxTodo
      93                 :             : {
      94                 :             :     bool m_should_add_extra_compact_tx;
      95                 :             :     std::vector<uint256> m_unique_parents;
      96                 :             :     std::optional<PackageToValidate> m_package_to_validate;
      97                 :             : };
      98                 :             : 
      99                 :             : 
     100                 :             : /**
     101                 :             :  * Class responsible for deciding what transactions to request and, once
     102                 :             :  * downloaded, whether and how to validate them. It is also responsible for
     103                 :             :  * deciding what transaction packages to validate and how to resolve orphan
     104                 :             :  * transactions. Its data structures include TxRequestTracker for scheduling
     105                 :             :  * requests, rolling bloom filters for remembering transactions that have
     106                 :             :  * already been {accepted, rejected, confirmed}, an orphanage, and a registry of
     107                 :             :  * each peer's transaction relay-related information.
     108                 :             :  *
     109                 :             :  * Caller needs to interact with TxDownloadManager:
     110                 :             :  * - ValidationInterface callbacks.
     111                 :             :  * - When a potential transaction relay peer connects or disconnects.
     112                 :             :  * - When a transaction or package is accepted or rejected from mempool
     113                 :             :  * - When a inv, notfound, or tx message is received
     114                 :             :  * - To get instructions for which getdata messages to send
     115                 :             :  *
     116                 :             :  * This class is not thread-safe. Access must be synchronized using an
     117                 :             :  * external mutex.
     118                 :             :  */
     119                 :             : class TxDownloadManager {
     120                 :             :     const std::unique_ptr<TxDownloadManagerImpl> m_impl;
     121                 :             : 
     122                 :             : public:
     123                 :             :     explicit TxDownloadManager(const TxDownloadOptions& options);
     124                 :             :     ~TxDownloadManager();
     125                 :             : 
     126                 :             :     // Responses to chain events. TxDownloadManager is not an actual client of ValidationInterface, these are called through PeerManager.
     127                 :             :     void ActiveTipChange();
     128                 :             :     void BlockConnected(const std::shared_ptr<const CBlock>& pblock);
     129                 :             :     void BlockDisconnected();
     130                 :             : 
     131                 :             :     /** Creates a new PeerInfo. Saves the connection info to calculate tx announcement delays later. */
     132                 :             :     void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo& info);
     133                 :             : 
     134                 :             :     /** Deletes all txrequest announcements and orphans for a given peer. */
     135                 :             :     void DisconnectedPeer(NodeId nodeid);
     136                 :             : 
     137                 :             :     /** Consider adding this tx hash to txrequest. Should be called whenever a new inv has been received.
     138                 :             :      * Also called internally when a transaction is missing parents so that we can request them.
     139                 :             :      * @param[in] p2p_inv     When true, only add this announcement if we don't already have the tx.
     140                 :             :      * Returns true if this was a dropped inv (p2p_inv=true and we already have the tx), false otherwise. */
     141                 :             :     bool AddTxAnnouncement(NodeId peer, const GenTxid& gtxid, std::chrono::microseconds now, bool p2p_inv);
     142                 :             : 
     143                 :             :     /** Get getdata requests to send. */
     144                 :             :     std::vector<GenTxid> GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time);
     145                 :             : 
     146                 :             :     /** Should be called when a notfound for a tx has been received. */
     147                 :             :     void ReceivedNotFound(NodeId nodeid, const std::vector<uint256>& txhashes);
     148                 :             : 
     149                 :             :     /** Respond to successful transaction submission to mempool */
     150                 :             :     void MempoolAcceptedTx(const CTransactionRef& tx);
     151                 :             : 
     152                 :             :     /** Respond to transaction rejected from mempool */
     153                 :             :     RejectedTxTodo MempoolRejectedTx(const CTransactionRef& ptx, const TxValidationState& state, NodeId nodeid, bool first_time_failure);
     154                 :             : 
     155                 :             :     /** Respond to package rejected from mempool */
     156                 :             :     void MempoolRejectedPackage(const Package& package);
     157                 :             : 
     158                 :             :     /** Marks a tx as ReceivedResponse in txrequest and checks whether AlreadyHaveTx.
     159                 :             :      * Return a bool indicating whether this tx should be validated. If false, optionally, a
     160                 :             :      * PackageToValidate. */
     161                 :             :     std::pair<bool, std::optional<PackageToValidate>> ReceivedTx(NodeId nodeid, const CTransactionRef& ptx);
     162                 :             : 
     163                 :             :     /** Whether there are any orphans to reconsider for this peer. */
     164                 :             :     bool HaveMoreWork(NodeId nodeid) const;
     165                 :             : 
     166                 :             :     /** Returns next orphan tx to consider, or nullptr if none exist. */
     167                 :             :     CTransactionRef GetTxToReconsider(NodeId nodeid);
     168                 :             : 
     169                 :             :     /** Check that all data structures are empty. */
     170                 :             :     void CheckIsEmpty() const;
     171                 :             : 
     172                 :             :     /** Check that all data structures that track per-peer information have nothing for this peer. */
     173                 :             :     void CheckIsEmpty(NodeId nodeid) const;
     174                 :             : 
     175                 :             :     /** Wrapper for TxOrphanage::GetOrphanTransactions */
     176                 :             :     std::vector<TxOrphanage::OrphanTxBase> GetOrphanTransactions() const;
     177                 :             : };
     178                 :             : } // namespace node
     179                 :             : #endif // BITCOIN_NODE_TXDOWNLOADMAN_H
        

Generated by: LCOV version 2.0-1