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 : : #include <util/transaction_identifier.h>
12 : :
13 : : #include <cstdint>
14 : : #include <memory>
15 : :
16 : : class CBlock;
17 : : class CRollingBloomFilter;
18 : : class CTxMemPool;
19 : : class GenTxid;
20 : : class TxRequestTracker;
21 : : namespace node {
22 : : class TxDownloadManagerImpl;
23 : :
24 : : /** Maximum number of in-flight transaction requests from a peer. It is not a hard limit, but the threshold at which
25 : : * point the OVERLOADED_PEER_TX_DELAY kicks in. */
26 : : static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100;
27 : : /** Maximum number of transactions to consider for requesting, per peer. It provides a reasonable DoS limit to
28 : : * per-peer memory usage spent on announcements, while covering peers continuously sending INVs at the maximum
29 : : * rate (by our own policy, see INVENTORY_BROADCAST_PER_SECOND) for several minutes, while not receiving
30 : : * the actual transaction (from any peer) in response to requests for them. */
31 : : static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 5000;
32 : : /** How long to delay requesting transactions via txids, if we have wtxid-relaying peers */
33 : : static constexpr auto TXID_RELAY_DELAY{2s};
34 : : /** How long to delay requesting transactions from non-preferred peers */
35 : : static constexpr auto NONPREF_PEER_TX_DELAY{2s};
36 : : /** How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT). */
37 : : static constexpr auto OVERLOADED_PEER_TX_DELAY{2s};
38 : : /** How long to wait before downloading a transaction from an additional peer */
39 : : static constexpr auto GETDATA_TX_INTERVAL{60s};
40 : : struct TxDownloadOptions {
41 : : /** Read-only reference to mempool. */
42 : : const CTxMemPool& m_mempool;
43 : : /** RNG provided by caller. */
44 : : FastRandomContext& m_rng;
45 : : /** Maximum number of transactions allowed in orphanage. */
46 : : const uint32_t m_max_orphan_txs;
47 : : /** Instantiate TxRequestTracker as deterministic (used for tests). */
48 : : bool m_deterministic_txrequest{false};
49 : : };
50 : : struct TxDownloadConnectionInfo {
51 : : /** Whether this peer is preferred for transaction download. */
52 : : const bool m_preferred;
53 : : /** Whether this peer has Relay permissions. */
54 : : const bool m_relay_permissions;
55 : : /** Whether this peer supports wtxid relay. */
56 : : const bool m_wtxid_relay;
57 : : };
58 : 97 : struct PackageToValidate {
59 : : Package m_txns;
60 : : std::vector<NodeId> m_senders;
61 : : /** Construct a 1-parent-1-child package. */
62 : 25 : explicit PackageToValidate(const CTransactionRef& parent,
63 : : const CTransactionRef& child,
64 : : NodeId parent_sender,
65 : 25 : NodeId child_sender) :
66 [ + + + - : 75 : m_txns{parent, child},
- - - - ]
67 [ + - ]: 25 : m_senders{parent_sender, child_sender}
68 [ + - + - : 100 : {}
+ - ]
69 : :
70 : : // Move ctor
71 : 61 : PackageToValidate(PackageToValidate&& other) : m_txns{std::move(other.m_txns)}, m_senders{std::move(other.m_senders)} {}
72 : : // Copy ctor
73 [ + - ]: 11 : PackageToValidate(const PackageToValidate& other) = default;
74 : :
75 : : // Move assignment
76 : 0 : PackageToValidate& operator=(PackageToValidate&& other) {
77 : 0 : this->m_txns = std::move(other.m_txns);
78 : 0 : this->m_senders = std::move(other.m_senders);
79 : 0 : return *this;
80 : : }
81 : :
82 : 25 : std::string ToString() const {
83 : 25 : Assume(m_txns.size() == 2);
84 : 25 : return strprintf("parent %s (wtxid=%s, sender=%d) + child %s (wtxid=%s, sender=%d)",
85 : 25 : m_txns.front()->GetHash().ToString(),
86 [ + - + - ]: 50 : m_txns.front()->GetWitnessHash().ToString(),
87 : 25 : m_senders.front(),
88 [ + - ]: 50 : m_txns.back()->GetHash().ToString(),
89 [ + - ]: 25 : m_txns.back()->GetWitnessHash().ToString(),
90 [ + - ]: 75 : m_senders.back());
91 : : }
92 : : };
93 : : struct RejectedTxTodo
94 : : {
95 : : bool m_should_add_extra_compact_tx;
96 : : std::vector<Txid> m_unique_parents;
97 : : std::optional<PackageToValidate> m_package_to_validate;
98 : : };
99 : :
100 : :
101 : : /**
102 : : * Class responsible for deciding what transactions to request and, once
103 : : * downloaded, whether and how to validate them. It is also responsible for
104 : : * deciding what transaction packages to validate and how to resolve orphan
105 : : * transactions. Its data structures include TxRequestTracker for scheduling
106 : : * requests, rolling bloom filters for remembering transactions that have
107 : : * already been {accepted, rejected, confirmed}, an orphanage, and a registry of
108 : : * each peer's transaction relay-related information.
109 : : *
110 : : * Caller needs to interact with TxDownloadManager:
111 : : * - ValidationInterface callbacks.
112 : : * - When a potential transaction relay peer connects or disconnects.
113 : : * - When a transaction or package is accepted or rejected from mempool
114 : : * - When a inv, notfound, or tx message is received
115 : : * - To get instructions for which getdata messages to send
116 : : *
117 : : * This class is not thread-safe. Access must be synchronized using an
118 : : * external mutex.
119 : : */
120 : : class TxDownloadManager {
121 : : const std::unique_ptr<TxDownloadManagerImpl> m_impl;
122 : :
123 : : public:
124 : : explicit TxDownloadManager(const TxDownloadOptions& options);
125 : : ~TxDownloadManager();
126 : :
127 : : // Responses to chain events. TxDownloadManager is not an actual client of ValidationInterface, these are called through PeerManager.
128 : : void ActiveTipChange();
129 : : void BlockConnected(const std::shared_ptr<const CBlock>& pblock);
130 : : void BlockDisconnected();
131 : :
132 : : /** Creates a new PeerInfo. Saves the connection info to calculate tx announcement delays later. */
133 : : void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo& info);
134 : :
135 : : /** Deletes all txrequest announcements and orphans for a given peer. */
136 : : void DisconnectedPeer(NodeId nodeid);
137 : :
138 : : /** Consider adding this tx hash to txrequest. Should be called whenever a new inv has been received.
139 : : * Also called internally when a transaction is missing parents so that we can request them.
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);
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<GenTxid>& gtxids);
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
|