5#ifndef BITCOIN_PRIVATE_BROADCAST_H
6#define BITCOIN_PRIVATE_BROADCAST_H
16#include <unordered_map>
74 std::vector<PeerSendInfo>
peers;
196 bool disconnected{
false};
229 return static_cast<size_t>(tx->GetWitnessHash().ToUint256().GetUint64(0));
236 return a->GetWitnessHash() == b->GetWitnessHash();
261 bool IsPending(
const TxSendStatus& status)
const;
267 std::unordered_map<CTransactionRef, TxSendStatus, CTransactionRefHash, CTransactionRefComp>
A combination of a network address (CNetAddr) and a (TCP) port.
Store a list of transactions to be broadcast privately.
static Priority DerivePriority(const std::vector< SendStatus > &sent_to)
Derive the sending priority of a transaction.
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...
AddResult Add(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a transaction to the storage, or reset an exhausted transaction so it can be broadcast again.
std::vector< TxBroadcastInfo > GetBroadcastInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get stats about all transactions currently being privately broadcast.
bool MarkResolved(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Mark a transaction as resolved because it was received back from the network or is no longer acceptab...
AddResult
Outcome of Add().
@ QueueFull
Rejected: the queue is already at MAX_TRANSACTIONS.
@ AlreadyPresent
The transaction was already present with send attempts remaining; no change.
@ Added
The transaction was newly added or reset after exhausting its send attempts.
const size_t m_max_transactions
Cap on the number of simultaneously tracked transactions (see Add()).
PrivateBroadcast(size_t max_transactions=MAX_TRANSACTIONS, size_t max_send_attempts=MAX_SEND_ATTEMPTS)
bool HavePendingTransactions() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if there are transactions with send attempts remaining.
static constexpr auto STALE_DURATION
If a transaction is not received back from the network for this duration after it is broadcast,...
std::optional< size_t > Remove(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Forget a transaction.
void NodeDisconnected(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Mark a connection finished.
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.
bool IsPending(const TxSendStatus &status) const
bool TryGrantRetry(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Grant one additional send attempt if the transaction is unresolved, all planned sends have been picke...
static constexpr size_t MAX_TRANSACTIONS
Maximum number of transactions tracked simultaneously.
std::optional< TxAndSendStatusForNode > GetSendStatusByNode(const NodeId &nodeid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex)
Find which transaction we sent to a given node (marked by PickTxForSend()).
const size_t m_max_send_attempts
Cap on the number of send attempts per transaction (see PickTxForSend()).
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().
static constexpr size_t MAX_SEND_ATTEMPTS
Maximum number of send attempts for a transaction. Once this limit is reached, the transaction remain...
std::vector< CTransactionRef > GetStale() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the transactions that have not been broadcast recently and have send attempts remaining.
std::unordered_map< CTransactionRef, TxSendStatus, CTransactionRefHash, CTransactionRefComp > m_transactions GUARDED_BY(m_mutex)
static constexpr size_t INITIAL_CONNECTION_COUNT
Number of connections to make for initial broadcast.
static constexpr auto INITIAL_STALE_DURATION
If a transaction is not sent to any peer for this duration, then we consider it stale / for rebroadca...
std::shared_ptr< const CTransaction > CTransactionRef
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::time_point< NodeClock > time_point
bool operator()(const CTransactionRef &a, const CTransactionRef &b) const
size_t operator()(const CTransactionRef &tx) const
std::optional< NodeClock::time_point > received
NodeClock::time_point sent
Cumulative stats from all the send attempts for a transaction. Used to prioritize transactions.
size_t num_picked
Number of times the transaction was picked for sending.
auto operator<=>(const Priority &other) const
NodeClock::time_point last_confirmed
The most recent time when the transaction was confirmed.
size_t num_confirmed
Number of nodes that have confirmed reception of a transaction (by PONG).
NodeClock::time_point last_picked
The most recent time when the transaction was picked for sending.
Status of a transaction sent to a given node.
SendStatus(const NodeId &nodeid, const CService &address, const NodeClock::time_point &picked)
std::optional< NodeClock::time_point > confirmed
When was the transaction reception confirmed by the node (by PONG).
const NodeId nodeid
Node to which the transaction will be sent (or was sent).
const NodeClock::time_point picked
When was the transaction picked for sending to the node.
const CService address
Address of the node.
A pair of a transaction and a sent status for a given node. Convenience return type of GetSendStatusB...
const CTransactionRef & tx
std::vector< PeerSendInfo > peers
size_t attempts_remaining
Number of additional send attempts allowed for this transaction (0 if exhausted).
NodeClock::time_point time_added
std::vector< SendStatus > send_statuses
bool resolved
Whether the transaction no longer needs to be retried.
NodeClock::time_point time_added
size_t planned_sends
Total number of sends granted, including initial count.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.