txdownloadman.h
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 struct PackageToValidate { 58 Package m_txns; 59 std::vector<NodeId> m_senders; 60 /** Construct a 1-parent-1-child package. */ 61 explicit PackageToValidate(const CTransactionRef& parent, 62 const CTransactionRef& child, 63 NodeId parent_sender, 64 NodeId child_sender) : 65 m_txns{parent, child}, 66 m_senders{parent_sender, child_sender} 67 {} 68 69 // Move ctor 70 PackageToValidate(PackageToValidate&& other) : m_txns{std::move(other.m_txns)}, m_senders{std::move(other.m_senders)} {} 71 // Copy ctor 72 PackageToValidate(const PackageToValidate& other) = default; 73 74 // Move assignment 75 PackageToValidate& operator=(PackageToValidate&& other) { 76 this->m_txns = std::move(other.m_txns); 77 this->m_senders = std::move(other.m_senders); 78 return *this; 79 } 80 81 std::string ToString() const { 82 Assume(m_txns.size() == 2); 83 return strprintf("parent %s (wtxid=%s, sender=%d) + child %s (wtxid=%s, sender=%d)", 84 m_txns.front()->GetHash().ToString(), 85 m_txns.front()->GetWitnessHash().ToString(), 86 m_senders.front(), 87 m_txns.back()->GetHash().ToString(), 88 m_txns.back()->GetWitnessHash().ToString(), 89 m_senders.back()); 90 } 91 }; 92 struct RejectedTxTodo 93 { 94 bool m_should_add_extra_compact_tx; 95 std::vector<Txid> 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 * Returns true if this was a dropped inv (p2p_inv=true and we already have the tx), false otherwise. */ 140 bool AddTxAnnouncement(NodeId peer, const GenTxid& gtxid, std::chrono::microseconds now); 141 142 /** Get getdata requests to send. */ 143 std::vector<GenTxid> GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time); 144 145 /** Should be called when a notfound for a tx has been received. */ 146 void ReceivedNotFound(NodeId nodeid, const std::vector<uint256>& txhashes); 147 148 /** Respond to successful transaction submission to mempool */ 149 void MempoolAcceptedTx(const CTransactionRef& tx); 150 151 /** Respond to transaction rejected from mempool */ 152 RejectedTxTodo MempoolRejectedTx(const CTransactionRef& ptx, const TxValidationState& state, NodeId nodeid, bool first_time_failure); 153 154 /** Respond to package rejected from mempool */ 155 void MempoolRejectedPackage(const Package& package); 156 157 /** Marks a tx as ReceivedResponse in txrequest and checks whether AlreadyHaveTx. 158 * Return a bool indicating whether this tx should be validated. If false, optionally, a 159 * PackageToValidate. */ 160 std::pair<bool, std::optional<PackageToValidate>> ReceivedTx(NodeId nodeid, const CTransactionRef& ptx); 161 162 /** Whether there are any orphans to reconsider for this peer. */ 163 bool HaveMoreWork(NodeId nodeid) const; 164 165 /** Returns next orphan tx to consider, or nullptr if none exist. */ 166 CTransactionRef GetTxToReconsider(NodeId nodeid); 167 168 /** Check that all data structures are empty. */ 169 void CheckIsEmpty() const; 170 171 /** Check that all data structures that track per-peer information have nothing for this peer. */ 172 void CheckIsEmpty(NodeId nodeid) const; 173 174 /** Wrapper for TxOrphanage::GetOrphanTransactions */ 175 std::vector<TxOrphanage::OrphanTxBase> GetOrphanTransactions() const; 176 }; 177 } // namespace node 178 #endif // BITCOIN_NODE_TXDOWNLOADMAN_H