diff --git a/src/txrequest.cpp b/src/txrequest.cpp index 96ea716481c..ca68a998680 100644 --- a/src/txrequest.cpp +++ b/src/txrequest.cpp @@ -574,6 +574,23 @@ public: } } + std::vector GetCandidatePeers(const CTransactionRef& tx) const + { + // Search by txid and, if the tx has a witness, wtxid + std::vector hashes{tx->GetHash().ToUint256()}; + if (tx->HasWitness()) hashes.emplace_back(tx->GetWitnessHash().ToUint256()); + + std::vector result_peers; + for (const uint256& txhash : hashes) { + auto it = m_index.get().lower_bound(ByTxHashView{txhash, State::CANDIDATE_DELAYED, 0}); + while (it != m_index.get().end() && it->m_txhash == txhash && it->GetState() != State::COMPLETED) { + result_peers.push_back(it->m_peer); + ++it; + } + } + return result_peers; + } + void ReceivedInv(NodeId peer, const GenTxid& gtxid, bool preferred, std::chrono::microseconds reqtime) { @@ -721,6 +738,7 @@ size_t TxRequestTracker::CountInFlight(NodeId peer) const { return m_impl->Count size_t TxRequestTracker::CountCandidates(NodeId peer) const { return m_impl->CountCandidates(peer); } size_t TxRequestTracker::Count(NodeId peer) const { return m_impl->Count(peer); } size_t TxRequestTracker::Size() const { return m_impl->Size(); } +std::vector TxRequestTracker::GetCandidatePeers(const CTransactionRef& tx) const { return m_impl->GetCandidatePeers(tx); } void TxRequestTracker::SanityCheck() const { m_impl->SanityCheck(); } void TxRequestTracker::PostGetRequestableSanityCheck(std::chrono::microseconds now) const diff --git a/src/txrequest.h b/src/txrequest.h index cd3042c87e5..95a1e9e7f6b 100644 --- a/src/txrequest.h +++ b/src/txrequest.h @@ -195,6 +195,9 @@ public: /** Count how many announcements are being tracked in total across all peers and transaction hashes. */ size_t Size() const; + /** For some tx return all peers with non-COMPLETED announcements for its txid or wtxid. The resulting vector may contain duplicate NodeIds. */ + std::vector GetCandidatePeers(const CTransactionRef& tx) const; + /** Access to the internal priority computation (testing only) */ uint64_t ComputePriority(const uint256& txhash, NodeId peer, bool preferred) const;