Skip to content

Commit 66a5885

Browse files
committed
Handle mempool requests in send loop, subject to trickle
By eliminating queued entries from the mempool response and responding only at trickle time, this makes the mempool no longer leak transaction arrival order information (as the mempool itself is also sorted)-- at least no more than relay itself leaks it.
1 parent cb9c551 commit 66a5885

File tree

3 files changed

+49
-28
lines changed

3 files changed

+49
-28
lines changed

src/main.cpp

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5235,34 +5235,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
52355235
pfrom->fDisconnect = true;
52365236
return true;
52375237
}
5238-
LOCK2(cs_main, pfrom->cs_filter);
52395238

5240-
std::vector<uint256> vtxid;
5241-
mempool.queryHashes(vtxid);
5242-
vector<CInv> vInv;
5243-
BOOST_FOREACH(uint256& hash, vtxid) {
5244-
CInv inv(MSG_TX, hash);
5245-
if (pfrom->pfilter) {
5246-
CTransaction tx;
5247-
bool fInMemPool = mempool.lookup(hash, tx);
5248-
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
5249-
if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
5250-
}
5251-
if (pfrom->minFeeFilter) {
5252-
CFeeRate feeRate;
5253-
mempool.lookupFeeRate(hash, feeRate);
5254-
LOCK(pfrom->cs_feeFilter);
5255-
if (feeRate.GetFeePerK() < pfrom->minFeeFilter)
5256-
continue;
5257-
}
5258-
vInv.push_back(inv);
5259-
if (vInv.size() == MAX_INV_SZ) {
5260-
pfrom->PushMessage(NetMsgType::INV, vInv);
5261-
vInv.clear();
5262-
}
5263-
}
5264-
if (vInv.size() > 0)
5265-
pfrom->PushMessage(NetMsgType::INV, vInv);
5239+
LOCK(pfrom->cs_inventory);
5240+
pfrom->fSendMempool = true;
52665241
}
52675242

52685243

@@ -5811,13 +5786,52 @@ bool SendMessages(CNode* pto)
58115786
}
58125787
pto->vInventoryBlockToSend.clear();
58135788

5814-
// Determine transactions to relay
5789+
// Check whether periodic sends should happen
58155790
bool fSendTrickle = pto->fWhitelisted;
58165791
if (pto->nNextInvSend < nNow) {
58175792
fSendTrickle = true;
58185793
// Use half the delay for outbound peers, as there is less privacy concern for them.
58195794
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
58205795
}
5796+
5797+
// Respond to BIP35 mempool requests
5798+
if (fSendTrickle && pto->fSendMempool) {
5799+
std::vector<uint256> vtxid;
5800+
mempool.queryHashes(vtxid);
5801+
pto->fSendMempool = false;
5802+
CAmount filterrate = 0;
5803+
{
5804+
LOCK(pto->cs_feeFilter);
5805+
filterrate = pto->minFeeFilter;
5806+
}
5807+
5808+
LOCK(pto->cs_filter);
5809+
5810+
BOOST_FOREACH(const uint256& hash, vtxid) {
5811+
CInv inv(MSG_TX, hash);
5812+
pto->setInventoryTxToSend.erase(hash);
5813+
if (filterrate) {
5814+
CFeeRate feeRate;
5815+
mempool.lookupFeeRate(hash, feeRate);
5816+
if (feeRate.GetFeePerK() < filterrate)
5817+
continue;
5818+
}
5819+
if (pto->pfilter) {
5820+
CTransaction tx;
5821+
bool fInMemPool = mempool.lookup(hash, tx);
5822+
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
5823+
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
5824+
}
5825+
pto->filterInventoryKnown.insert(hash);
5826+
vInv.push_back(inv);
5827+
if (vInv.size() == MAX_INV_SZ) {
5828+
pto->PushMessage(NetMsgType::INV, vInv);
5829+
vInv.clear();
5830+
}
5831+
}
5832+
}
5833+
5834+
// Determine transactions to relay
58215835
if (fSendTrickle) {
58225836
// Produce a vector with all candidates for sending
58235837
vector<std::set<uint256>::iterator> vInvTx;
@@ -5847,6 +5861,10 @@ bool SendMessages(CNode* pto)
58475861
// Send
58485862
vInv.push_back(CInv(MSG_TX, hash));
58495863
nRelayedTransactions++;
5864+
if (vInv.size() == MAX_INV_SZ) {
5865+
pto->PushMessage(NetMsgType::INV, vInv);
5866+
vInv.clear();
5867+
}
58505868
pto->filterInventoryKnown.insert(hash);
58515869
}
58525870
}

src/net.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,6 +2370,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
23702370
hashContinue = uint256();
23712371
nStartingHeight = -1;
23722372
filterInventoryKnown.reset();
2373+
fSendMempool = false;
23732374
fGetAddr = false;
23742375
nNextLocalAddrSend = 0;
23752376
nNextAddrSend = 0;

src/net.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ class CNode
411411
// Used for headers announcements - unfiltered blocks to relay
412412
// Also protected by cs_inventory
413413
std::vector<uint256> vBlockHashesToAnnounce;
414+
// Used for BIP35 mempool sending, also protected by cs_inventory
415+
bool fSendMempool;
414416

415417
// Ping time measurement:
416418
// The pong reply we're expecting, or 0 if no pong expected.

0 commit comments

Comments
 (0)