11 #include <txmempool.h> 18 m_impl{std::make_unique<TxDownloadManagerImpl>(options)}
28 m_impl->BlockConnected(pblock);
32 m_impl->BlockDisconnected();
36 m_impl->ConnectedPeer(nodeid, info);
40 m_impl->DisconnectedPeer(nodeid);
44 return m_impl->AddTxAnnouncement(peer, gtxid, now);
48 return m_impl->GetRequestsToSend(nodeid, current_time);
52 m_impl->ReceivedNotFound(nodeid, txhashes);
56 m_impl->MempoolAcceptedTx(tx);
60 return m_impl->MempoolRejectedTx(ptx, state, nodeid, first_time_failure);
64 m_impl->MempoolRejectedPackage(package);
68 return m_impl->ReceivedTx(nodeid, ptx);
72 return m_impl->HaveMoreWork(nodeid);
76 return m_impl->GetTxToReconsider(nodeid);
84 m_impl->CheckIsEmpty(nodeid);
88 return m_impl->GetOrphanTransactions();
102 for (
const auto& ptx : pblock->vtx) {
104 if (ptx->HasWitness()) {
185 std::erase_if(unique_parents, [&](
const auto& txid){
191 if (unique_parents.empty()) {
209 const auto& info = it->second.m_connection_info;
239 const auto& info = peer_entry.m_connection_info;
243 if (!info.m_relay_permissions) {
251 std::chrono::seconds delay{0
s};
263 for (
const auto& parent_txid : unique_parents) {
272 std::vector<GenTxid> requests;
273 std::vector<std::pair<NodeId, GenTxid>> expired;
275 for (
const auto& entry : expired) {
276 LogDebug(
BCLog::NET,
"timeout of inflight %s %s from peer=%d\n", entry.second.IsWtxid() ?
"wtx" :
"tx",
277 entry.second.GetHash().ToString(), entry.first);
279 for (
const GenTxid& gtxid : requestable) {
282 gtxid.GetHash().ToString(), nodeid);
283 requests.emplace_back(gtxid);
296 for (
const auto& txhash : txhashes) {
305 const auto& parent_wtxid{ptx->GetWitnessHash()};
319 for (
const auto& child : cpfp_candidates_same_peer) {
320 Package maybe_cpfp_package{ptx, child};
343 std::vector<Txid> unique_parents;
344 unique_parents.reserve(tx.
vin.size());
350 std::sort(unique_parents.begin(), unique_parents.end());
351 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
353 return unique_parents;
361 bool add_extra_compact_tx{first_time_failure};
363 std::vector<Txid> unique_parents;
365 std::optional<node::PackageToValidate> package_to_validate;
371 bool fRejectedParents =
false;
380 std::optional<uint256> rejected_parent_reconsiderable;
381 for (
const uint256& parent_txid : unique_parents) {
383 fRejectedParents =
true;
389 if (rejected_parent_reconsiderable.has_value()) {
390 fRejectedParents =
true;
393 rejected_parent_reconsiderable = parent_txid;
396 if (!fRejectedParents) {
400 std::erase_if(unique_parents, [&](
const auto& txid){
403 const auto now{GetTime<std::chrono::microseconds>()};
404 const auto& wtxid = ptx->GetWitnessHash();
414 std::vector<NodeId> orphan_resolution_candidates{nodeid};
418 for (
const auto& nodeid : orphan_resolution_candidates) {
433 unique_parents.clear();
435 tx.GetHash().ToString(),
436 tx.GetWitnessHash().ToString());
450 add_extra_compact_tx =
false;
471 if (first_time_failure) {
475 ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString());
501 LogDebug(
BCLog::TXPACKAGES,
" removed orphan tx %s (wtxid=%s)\n", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString());
506 .m_unique_parents = std::move(unique_parents),
507 .m_package_to_validate = std::move(package_to_validate)
518 const uint256& txid = ptx->GetHash();
519 const uint256& wtxid = ptx->GetWitnessHash();
554 return {
false, std::nullopt};
565 return {
true, std::nullopt};
std::shared_ptr< const CTransaction > CTransactionRef
bool contains(Span< const unsigned char > vKey) const
void ReceivedResponse(NodeId peer, const uint256 &txhash)
Converts a CANDIDATE or REQUESTED announcement to a COMPLETED one.
CTransactionRef GetTxToReconsider(NodeId peer)
Extract a transaction from a peer's work set Returns nullptr if there are no transactions to work on...
int EraseTx(const Wtxid &wtxid)
Erase an orphan by wtxid.
static constexpr auto OVERLOADED_PEER_TX_DELAY
How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT).
bool AddAnnouncer(const Wtxid &wtxid, NodeId peer)
Add an additional announcer to an orphan if it exists.
unsigned int TotalOrphanUsage() const
Get the total usage (weight) of all orphans.
static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT
Maximum number of in-flight transaction requests from a peer.
static GenTxid Wtxid(const uint256 &hash)
void insert(Span< const unsigned char > vKey)
bool AddTxAnnouncement(NodeId peer, const GenTxid >xid, std::chrono::microseconds now)
Consider adding this tx hash to txrequest.
size_t Count(NodeId peer) const
Count how many announcements a peer has (REQUESTED, CANDIDATE, and COMPLETED combined).
static constexpr auto TXID_RELAY_DELAY
How long to delay requesting transactions via txids, if we have wtxid-relaying peers.
uint256 GetPackageHash(const std::vector< CTransactionRef > &transactions)
Get the hash of the concatenated wtxids of transactions, with wtxids treated as a little-endian numbe...
void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo &info)
Creates a new PeerInfo.
std::pair< bool, std::optional< PackageToValidate > > ReceivedTx(NodeId nodeid, const CTransactionRef &ptx)
bool MaybeAddOrphanResolutionCandidate(const std::vector< Txid > &unique_parents, const Wtxid &wtxid, NodeId nodeid, std::chrono::microseconds now)
If this peer is an orphan resolution candidate for this transaction, treat the unique_parents as anno...
bool exists(const GenTxid >xid) const
void GetCandidatePeers(const uint256 &txhash, std::vector< NodeId > &result_peers) const
For some txhash (txid or wtxid), finds all peers with non-COMPLETED announcements and appends them to...
std::vector< GenTxid > GetRequestable(NodeId peer, std::chrono::microseconds now, std::vector< std::pair< NodeId, GenTxid >> *expired=nullptr)
Find the txids to request now from peer.
void ReceivedInv(NodeId peer, const GenTxid >xid, bool preferred, std::chrono::microseconds reqtime)
Adds a new CANDIDATE announcement.
std::optional< PackageToValidate > Find1P1CPackage(const CTransactionRef &ptx, NodeId nodeid)
Look for a child of this transaction in the orphanage to form a 1-parent-1-child package, skipping any combinations that have already been tried.
size_t CountInFlight(NodeId peer) const
Count how many REQUESTED announcements a peer has.
CRollingBloomFilter & RecentConfirmedTransactionsFilter()
TxRequestTracker m_txrequest
Tracks candidates for requesting and downloading transaction data.
TxOrphanage m_orphanage
Manages unvalidated tx data (orphan transactions for which we are downloading ancestors).
CTransactionRef GetTxToReconsider(NodeId nodeid)
Returns next orphan tx to consider, or nullptr if none exist.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
transaction was missing some of its inputs
void MempoolAcceptedTx(const CTransactionRef &tx)
Respond to successful transaction submission to mempool.
RejectedTxTodo MempoolRejectedTx(const CTransactionRef &ptx, const TxValidationState &state, NodeId nodeid, bool first_time_failure)
void BlockConnected(const std::shared_ptr< const CBlock > &pblock)
void MempoolRejectedPackage(const Package &package)
std::vector< CTransactionRef > GetChildrenFromSamePeer(const CTransactionRef &parent, NodeId nodeid) const
Get all children that spend from this tx and were received from nodeid.
inputs (covered by txid) failed policy rules
void AddChildrenToWorkSet(const CTransaction &tx, FastRandomContext &rng)
Add any orphans that list a particular tx as a parent into the from peer's work set.
bool AddTxAnnouncement(NodeId peer, const GenTxid >xid, std::chrono::microseconds now)
Consider adding this tx hash to txrequest.
size_t Size() const
Count how many announcements are being tracked in total across all peers and transaction hashes...
const CTxMemPool & m_mempool
Read-only reference to mempool.
const std::vector< CTxIn > vin
bool HaveMoreWork(NodeId nodeid) const
Whether there are any orphans to reconsider for this peer.
void ReceivedNotFound(NodeId nodeid, const std::vector< uint256 > &txhashes)
Should be called when a notfound for a tx has been received.
std::pair< bool, std::optional< PackageToValidate > > ReceivedTx(NodeId nodeid, const CTransactionRef &ptx)
Marks a tx as ReceivedResponse in txrequest and checks whether AlreadyHaveTx.
RejectedTxTodo MempoolRejectedTx(const CTransactionRef &ptx, const TxValidationState &state, NodeId nodeid, bool first_time_failure)
Respond to transaction rejected from mempool.
FastRandomContext & m_rng
RNG provided by caller.
const bool m_wtxid_relay
Whether this peer supports wtxid relay.
const std::unique_ptr< TxDownloadManagerImpl > m_impl
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS
Maximum number of transactions to consider for requesting, per peer.
CTransactionRef GetTx(const Wtxid &wtxid) const
void DisconnectedPeer(NodeId peer)
Deletes all announcements for a given peer.
unsigned int UsageByPeer(NodeId peer) const
Total usage (weight) of orphans for which this peer is an announcer.
std::vector< Txid > GetUniqueParents(const CTransaction &tx)
Helper for getting deduplicated vector of Txids in vin.
void LimitOrphans(unsigned int max_orphans, FastRandomContext &rng)
Limit the orphanage to the given maximum.
void ReceivedNotFound(NodeId nodeid, const std::vector< uint256 > &txhashes)
Marks a tx as ReceivedResponse in txrequest.
void EraseForPeer(NodeId peer)
Maybe erase all orphans announced by a peer (eg, after that peer disconnects).
CRollingBloomFilter & RecentRejectsFilter()
std::vector< TxOrphanage::OrphanTxBase > GetOrphanTransactions() const
Wrapper for TxOrphanage::GetOrphanTransactions.
An input of a transaction.
std::map< NodeId, PeerInfo > m_peer_info
Information for all of the peers we may download transactions from.
static constexpr auto GETDATA_TX_INTERVAL
How long to wait before downloading a transaction from an additional peer.
TxDownloadManager(const TxDownloadOptions &options)
CRollingBloomFilter & RecentRejectsReconsiderableFilter()
std::string ToString() const
bool HaveMoreWork(NodeId nodeid)
void RequestedTx(NodeId peer, const uint256 &txhash, std::chrono::microseconds expiry)
Marks a transaction as requested, with a specified expiry.
std::string ToString() const
bool HaveTxFromPeer(const Wtxid &wtxid, NodeId peer) const
Check if a {tx, peer} exists in the orphanage.
bool m_should_add_extra_compact_tx
fails some policy, but might be acceptable if submitted in a (different) package
const uint32_t m_max_orphan_txs
Maximum number of transactions allowed in orphanage.
#define Assume(val)
Assume is the identity function.
bool HaveTxToReconsider(NodeId peer)
Does this peer have any work to do?
bool AddTx(const CTransactionRef &tx, NodeId peer)
Add a new orphan transaction.
Transaction is missing a witness.
std::vector< GenTxid > GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time)
Get getdata requests to send.
std::vector< OrphanTxBase > GetOrphanTransactions() const
void DisconnectedPeer(NodeId nodeid)
Deletes all txrequest announcements and orphans for a given peer.
std::vector< GenTxid > GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time)
Get getdata requests to send.
static constexpr auto NONPREF_PEER_TX_DELAY
How long to delay requesting transactions from non-preferred peers.
#define LogDebug(category,...)
static transaction_identifier FromUint256(const uint256 &id)
uint32_t m_num_wtxid_peers
Number of wtxid relay peers we have in m_peer_info.
void CheckIsEmpty() const
Check that all data structures are empty.
void MempoolAcceptedTx(const CTransactionRef &tx)
CTransactionRef GetTxToReconsider(NodeId nodeid)
size_t Size() const
Return how many entries exist in the orphange.
The basic transaction that is broadcasted on the network and contained in blocks. ...
void BlockConnected(const std::shared_ptr< const CBlock > &pblock)
void MempoolRejectedPackage(const Package &package)
Respond to package rejected from mempool.
std::vector< TxOrphanage::OrphanTxBase > GetOrphanTransactions() const
void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo &info)
void EraseForBlock(const CBlock &block)
Erase all orphans included in or invalidated by a new block.
bool AlreadyHaveTx(const GenTxid >xid, bool include_reconsiderable)
Check whether we already have this gtxid in:
void DisconnectedPeer(NodeId nodeid)
bool HaveTx(const Wtxid &wtxid) const
Check if we already have an orphan transaction (by wtxid only)
A generic txid reference (txid or wtxid).
static GenTxid Txid(const uint256 &hash)
void ForgetTxHash(const uint256 &txhash)
Deletes all announcements for a given txhash (both txid and wtxid ones).
const uint256 & GetHash() const LIFETIMEBOUND
transaction_identifier represents the two canonical transaction identifier types (txid, wtxid).