Bitcoin Core  31.0.0
P2P Digital Currency
private_broadcast.h
Go to the documentation of this file.
1 // Copyright (c) 2023-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://opensource.org/license/mit/.
4 
5 #ifndef BITCOIN_PRIVATE_BROADCAST_H
6 #define BITCOIN_PRIVATE_BROADCAST_H
7 
8 #include <net.h>
11 #include <sync.h>
12 #include <threadsafety.h>
13 #include <util/time.h>
14 
15 #include <optional>
16 #include <tuple>
17 #include <unordered_map>
18 #include <vector>
19 
31 {
32 public:
33  struct PeerSendInfo {
36  std::optional<NodeClock::time_point> received;
37  };
38 
39  struct TxBroadcastInfo {
41  std::vector<PeerSendInfo> peers;
42  };
43 
50  bool Add(const CTransactionRef& tx)
52 
60  std::optional<size_t> Remove(const CTransactionRef& tx)
62 
72  std::optional<CTransactionRef> PickTxForSend(const NodeId& will_send_to_nodeid, const CService& will_send_to_address)
74 
80  std::optional<CTransactionRef> GetTxForNode(const NodeId& nodeid)
82 
88  void NodeConfirmedReception(const NodeId& nodeid)
90 
96  bool DidNodeConfirmReception(const NodeId& nodeid)
98 
104 
108  std::vector<CTransactionRef> GetStale() const
110 
114  std::vector<TxBroadcastInfo> GetBroadcastInfo() const
116 
117 private:
119  struct SendStatus {
120  const NodeId nodeid;
123  std::optional<NodeClock::time_point> confirmed;
124 
125  SendStatus(const NodeId& nodeid, const CService& address, const NodeClock::time_point& picked) : nodeid{nodeid}, address{address}, picked{picked} {}
126  };
127 
129  struct Priority {
130  size_t num_picked{0};
132  size_t num_confirmed{0};
134 
135  auto operator<=>(const Priority& other) const
136  {
137  // Invert `other` and `this` in the comparison because smaller num_picked, num_confirmed or
138  // earlier times mean greater priority. In other words, if this.num_picked < other.num_picked
139  // then this > other.
140  return std::tie(other.num_picked, other.num_confirmed, other.last_picked, other.last_confirmed) <=>
142  }
143  };
144 
149  };
150 
151  // No need for salted hasher because we are going to store just a bunch of locally originating transactions.
152 
154  size_t operator()(const CTransactionRef& tx) const
155  {
156  return static_cast<size_t>(tx->GetWitnessHash().ToUint256().GetUint64(0));
157  }
158  };
159 
161  bool operator()(const CTransactionRef& a, const CTransactionRef& b) const
162  {
163  return a->GetWitnessHash() == b->GetWitnessHash(); // If wtxid equals, then txid also equals.
164  }
165  };
166 
171  static Priority DerivePriority(const std::vector<SendStatus>& sent_to);
172 
178  std::optional<TxAndSendStatusForNode> GetSendStatusByNode(const NodeId& nodeid)
180 
181  mutable Mutex m_mutex;
182  std::unordered_map<CTransactionRef, std::vector<SendStatus>, CTransactionRefHash, CTransactionRefComp>
183  m_transactions GUARDED_BY(m_mutex);
184 };
185 
186 #endif // BITCOIN_PRIVATE_BROADCAST_H
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
A pair of a transaction and a sent status for a given node. Convenience return type of GetSendStatusB...
std::chrono::time_point< NodeClock > time_point
Definition: time.h:19
void NodeConfirmedReception(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Mark that the node has confirmed reception of the transaction we sent it by responding with PONG to o...
std::optional< size_t > Remove(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Forget a transaction.
size_t operator()(const CTransactionRef &tx) const
Definition: common.h:29
std::vector< TxBroadcastInfo > GetBroadcastInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get stats about all transactions currently being privately broadcast.
const NodeClock::time_point picked
Address of the node.
std::optional< NodeClock::time_point > received
std::optional< CTransactionRef > GetTxForNode(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the transaction that was picked for sending to a given node by PickTxForSend().
std::unordered_map< CTransactionRef, std::vector< SendStatus >, CTransactionRefHash, CTransactionRefComp > m_transactions GUARDED_BY(m_mutex)
bool HavePendingTransactions() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if there are transactions that need to be broadcast.
std::optional< TxAndSendStatusForNode > GetSendStatusByNode(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex)
Find which transaction we sent to a given node (marked by PickTxForSend()).
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:529
Status of a transaction sent to a given node.
std::optional< CTransactionRef > PickTxForSend(const NodeId &will_send_to_nodeid, const CService &will_send_to_address) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Pick the transaction with the fewest send attempts, and confirmations, and oldest send/confirm times...
NodeClock::time_point last_picked
The most recent time when the transaction was picked for sending.
static Priority DerivePriority(const std::vector< SendStatus > &sent_to)
Derive the sending priority of a transaction.
int64_t NodeId
Definition: net.h:103
Cumulative stats from all the send attempts for a transaction. Used to prioritize transactions...
const CService address
Node to which the transaction will be sent (or was sent).
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
SendStatus(const NodeId &nodeid, const CService &address, const NodeClock::time_point &picked)
std::vector< PeerSendInfo > peers
bool DidNodeConfirmReception(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if the node has confirmed reception of the transaction.
size_t num_confirmed
Number of nodes that have confirmed reception of a transaction (by PONG).
std::vector< CTransactionRef > GetStale() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the transactions that have not been broadcast recently.
bool Add(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a transaction to the storage.
size_t num_picked
Number of times the transaction was picked for sending.
std::optional< NodeClock::time_point > confirmed
When was the transaction reception confirmed by the node (by PONG).
Store a list of transactions to be broadcast privately.
bool operator()(const CTransactionRef &a, const CTransactionRef &b) const
NodeClock::time_point last_confirmed
The most recent time when the transaction was confirmed.