Skip to content

Commit 94b39ce

Browse files
committed
refactor: Change m_tx_inventory_to_send from std::set<GenTxid> to std::set<Wtxid>
Simplifies `m_tx_inventory_to_send` a bit by making it a set of Wtxids. Wtxid relay is prevalent throughout the network, so the complexity of dealing with a GenTxid in this data structure isn't necessary. For peers that aren't wtxid relay, the txid is now retrieved from our mempool entry when the inv is constructed.
1 parent a9819b0 commit 94b39ce

File tree

3 files changed

+35
-32
lines changed

3 files changed

+35
-32
lines changed

src/net_processing.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,11 @@ struct Peer {
298298
* us or we have announced to the peer. We use this to avoid announcing
299299
* the same (w)txid to a peer that already has the transaction. */
300300
CRollingBloomFilter m_tx_inventory_known_filter GUARDED_BY(m_tx_inventory_mutex){50000, 0.000001};
301-
/** Set of transaction ids we still have to announce (txid for
302-
* non-wtxid-relay peers, wtxid for wtxid-relay peers). We use the
303-
* mempool to sort transactions in dependency order before relay, so
304-
* this does not have to be sorted. */
305-
std::set<GenTxid> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
301+
/** Set of wtxids we still have to announce. For non-wtxid-relay peers,
302+
* we retrieve the txid from the corresponding mempool transaction when
303+
* constructing the `inv` message. We use the mempool to sort transactions
304+
* in dependency order before relay, so this does not have to be sorted. */
305+
std::set<Wtxid> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
306306
/** Whether the peer has requested us to send our complete mempool. Only
307307
* permitted if the peer has NetPermissionFlags::Mempool or we advertise
308308
* NODE_BLOOM. See BIP35. */
@@ -2166,9 +2166,9 @@ void PeerManagerImpl::RelayTransaction(const Txid& txid, const Wtxid& wtxid)
21662166
// in the announcement.
21672167
if (tx_relay->m_next_inv_send_time == 0s) continue;
21682168

2169-
const auto gtxid{peer.m_wtxid_relay ? GenTxid{wtxid} : GenTxid{txid}};
2170-
if (!tx_relay->m_tx_inventory_known_filter.contains(gtxid.ToUint256())) {
2171-
tx_relay->m_tx_inventory_to_send.insert(gtxid);
2169+
const uint256& hash{peer.m_wtxid_relay ? wtxid.ToUint256() : txid.ToUint256()};
2170+
if (!tx_relay->m_tx_inventory_known_filter.contains(hash)) {
2171+
tx_relay->m_tx_inventory_to_send.insert(wtxid);
21722172
}
21732173
}
21742174
}
@@ -5439,7 +5439,7 @@ class CompareInvMempoolOrder
54395439
public:
54405440
explicit CompareInvMempoolOrder(CTxMemPool* mempool) : m_mempool{mempool} {}
54415441

5442-
bool operator()(std::set<GenTxid>::iterator a, std::set<GenTxid>::iterator b)
5442+
bool operator()(std::set<Wtxid>::iterator a, std::set<Wtxid>::iterator b)
54435443
{
54445444
/* As std::make_heap produces a max-heap, we want the entries with the
54455445
* fewest ancestors/highest fee to sort later. */
@@ -5755,13 +5755,12 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57555755
LOCK(tx_relay->m_bloom_filter_mutex);
57565756

57575757
for (const auto& txinfo : vtxinfo) {
5758-
CInv inv{
5759-
peer->m_wtxid_relay ? MSG_WTX : MSG_TX,
5760-
peer->m_wtxid_relay ?
5761-
txinfo.tx->GetWitnessHash().ToUint256() :
5762-
txinfo.tx->GetHash().ToUint256(),
5763-
};
5764-
tx_relay->m_tx_inventory_to_send.erase(ToGenTxid(inv));
5758+
const Txid& txid{txinfo.tx->GetHash()};
5759+
const Wtxid& wtxid{txinfo.tx->GetWitnessHash()};
5760+
const auto inv = peer->m_wtxid_relay ?
5761+
CInv{MSG_WTX, wtxid.ToUint256()} :
5762+
CInv{MSG_TX, txid.ToUint256()};
5763+
tx_relay->m_tx_inventory_to_send.erase(wtxid);
57655764

57665765
// Don't send transactions that peers will not put into their mempool
57675766
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
@@ -5782,9 +5781,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57825781
// Determine transactions to relay
57835782
if (fSendTrickle) {
57845783
// Produce a vector with all candidates for sending
5785-
std::vector<std::set<GenTxid>::iterator> vInvTx;
5784+
std::vector<std::set<Wtxid>::iterator> vInvTx;
57865785
vInvTx.reserve(tx_relay->m_tx_inventory_to_send.size());
5787-
for (std::set<GenTxid>::iterator it = tx_relay->m_tx_inventory_to_send.begin(); it != tx_relay->m_tx_inventory_to_send.end(); it++) {
5786+
for (std::set<Wtxid>::iterator it = tx_relay->m_tx_inventory_to_send.begin(); it != tx_relay->m_tx_inventory_to_send.end(); it++) {
57885787
vInvTx.push_back(it);
57895788
}
57905789
const CFeeRate filterrate{tx_relay->m_fee_filter_received.load()};
@@ -5801,22 +5800,26 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58015800
while (!vInvTx.empty() && nRelayedTransactions < broadcast_max) {
58025801
// Fetch the top element from the heap
58035802
std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
5804-
std::set<GenTxid>::iterator it = vInvTx.back();
5803+
std::set<Wtxid>::iterator it = vInvTx.back();
58055804
vInvTx.pop_back();
5806-
GenTxid hash = *it;
5807-
Assume(peer->m_wtxid_relay == hash.IsWtxid());
5808-
CInv inv(peer->m_wtxid_relay ? MSG_WTX : MSG_TX, hash.ToUint256());
5805+
auto wtxid = *it;
58095806
// Remove it from the to-be-sent set
58105807
tx_relay->m_tx_inventory_to_send.erase(it);
5811-
// Check if not in the filter already
5812-
if (tx_relay->m_tx_inventory_known_filter.contains(hash.ToUint256())) {
5813-
continue;
5814-
}
58155808
// Not in the mempool anymore? don't bother sending it.
5816-
auto txinfo{std::visit([&](const auto& id) { return m_mempool.info(id); }, hash)};
5809+
auto txinfo = m_mempool.info(wtxid);
58175810
if (!txinfo.tx) {
58185811
continue;
58195812
}
5813+
// `TxRelay::m_tx_inventory_known_filter` contains either txids or wtxids
5814+
// depending on whether our peer supports wtxid-relay. Therefore, first
5815+
// construct the inv and then use its hash for the filter check.
5816+
const auto inv = peer->m_wtxid_relay ?
5817+
CInv{MSG_WTX, wtxid.ToUint256()} :
5818+
CInv{MSG_TX, txinfo.tx->GetHash().ToUint256()};
5819+
// Check if not in the filter already
5820+
if (tx_relay->m_tx_inventory_known_filter.contains(inv.hash)) {
5821+
continue;
5822+
}
58205823
// Peer told you to not send transactions at that feerate? Don't bother sending it.
58215824
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
58225825
continue;
@@ -5829,7 +5832,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58295832
MakeAndPushMessage(*pto, NetMsgType::INV, vInv);
58305833
vInv.clear();
58315834
}
5832-
tx_relay->m_tx_inventory_known_filter.insert(hash.ToUint256());
5835+
tx_relay->m_tx_inventory_known_filter.insert(inv.hash);
58335836
}
58345837

58355838
// Ensure we'll respond to GETDATA requests for anything we've just announced

src/txmempool.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,17 +794,17 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
794794
assert(innerUsage == cachedInnerUsage);
795795
}
796796

797-
bool CTxMemPool::CompareDepthAndScore(const GenTxid& hasha, const GenTxid& hashb) const
797+
bool CTxMemPool::CompareDepthAndScore(const Wtxid& hasha, const Wtxid& hashb) const
798798
{
799799
/* Return `true` if hasha should be considered sooner than hashb. Namely when:
800800
* a is not in the mempool, but b is
801801
* both are in the mempool and a has fewer ancestors than b
802802
* both are in the mempool and a has a higher score than b
803803
*/
804804
LOCK(cs);
805-
auto j{std::visit([&](const auto& id) EXCLUSIVE_LOCKS_REQUIRED(cs) { return GetIter(id); }, hashb)};
805+
auto j{GetIter(hashb)};
806806
if (!j.has_value()) return false;
807-
auto i{std::visit([&](const auto& id) EXCLUSIVE_LOCKS_REQUIRED(cs) { return GetIter(id); }, hasha)};
807+
auto i{GetIter(hasha)};
808808
if (!i.has_value()) return true;
809809
uint64_t counta = i.value()->GetCountWithAncestors();
810810
uint64_t countb = j.value()->GetCountWithAncestors();

src/txmempool.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ class CTxMemPool
448448
void removeConflicts(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
449449
void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);
450450

451-
bool CompareDepthAndScore(const GenTxid& hasha, const GenTxid& hashb) const;
451+
bool CompareDepthAndScore(const Wtxid& hasha, const Wtxid& hashb) const;
452452
bool isSpent(const COutPoint& outpoint) const;
453453
unsigned int GetTransactionsUpdated() const;
454454
void AddTransactionsUpdated(unsigned int n);

0 commit comments

Comments
 (0)