Skip to content

Commit cb4fc6c

Browse files
committed
An adapted version of btc@ed7068302c7490e8061cb3a558a0f83a465beeea
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 9645775 commit cb4fc6c

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

src/net.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,6 +2438,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
24382438
hashContinue = UINT256_ZERO;
24392439
nStartingHeight = -1;
24402440
filterInventoryKnown.reset();
2441+
fSendMempool = false;
24412442
fGetAddr = false;
24422443
nNextLocalAddrSend = 0;
24432444
nNextAddrSend = 0;

src/net.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,8 @@ class CNode
623623
std::multimap<int64_t, CInv> mapAskFor;
624624
std::vector<uint256> vBlockRequested;
625625
int64_t nNextInvSend;
626+
// Used for BIP35 mempool sending, also protected by cs_inventory
627+
bool fSendMempool;
626628

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

src/net_processing.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,27 +1633,10 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
16331633

16341634

16351635
else if (strCommand == NetMsgType::MEMPOOL) {
1636-
LOCK2(cs_main, pfrom->cs_filter);
16371636

1638-
std::vector<uint256> vtxid;
1639-
mempool.queryHashes(vtxid);
1640-
std::vector<CInv> vInv;
1641-
for (uint256& hash : vtxid) {
1642-
CInv inv(MSG_TX, hash);
1643-
if (pfrom->pfilter) {
1644-
CTransaction tx;
1645-
bool fInMemPool = mempool.lookup(hash, tx);
1646-
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
1647-
if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
1648-
}
1649-
vInv.emplace_back(inv);
1650-
if (vInv.size() == MAX_INV_SZ) {
1651-
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::INV, vInv));
1652-
vInv.clear();
1653-
}
1654-
}
1655-
if (vInv.size() > 0)
1656-
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::INV, vInv));
1637+
// todo: limit mempool request with a bandwidth limit
1638+
LOCK(pfrom->cs_inventory);
1639+
pfrom->fSendMempool = true;
16571640
}
16581641

16591642

@@ -2104,13 +2087,42 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
21042087
}
21052088
pto->vInventoryTierTwoToSend.clear();
21062089

2107-
// Determine transactions to relay
2090+
// Check whether periodic send should happen
21082091
bool fSendTrickle = pto->fWhitelisted;
21092092
if (pto->nNextInvSend < nNow) {
21102093
fSendTrickle = true;
21112094
// Use half the delay for outbound peers, as there is less privacy concern for them.
21122095
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
21132096
}
2097+
2098+
// Respond to BIP35 mempool requests
2099+
if (fSendTrickle && pto->fSendMempool) {
2100+
std::vector<uint256> vtxid;
2101+
mempool.queryHashes(vtxid);
2102+
pto->fSendMempool = false;
2103+
// future: back port fee filter rate
2104+
LOCK(pto->cs_filter);
2105+
2106+
for (const uint256& hash : vtxid) {
2107+
CInv inv(MSG_TX, hash);
2108+
pto->setInventoryTxToSend.erase(hash);
2109+
// future: add fee filter check here..
2110+
if (pto->pfilter) {
2111+
CTransaction tx;
2112+
bool fInMemPool = mempool.lookup(hash, tx);
2113+
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
2114+
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
2115+
}
2116+
pto->filterInventoryKnown.insert(hash);
2117+
vInv.emplace_back(inv);
2118+
if (vInv.size() == MAX_INV_SZ) {
2119+
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2120+
vInv.clear();
2121+
}
2122+
}
2123+
}
2124+
2125+
// Determine transactions to relay
21142126
if (fSendTrickle) {
21152127
// Produce a vector with all candidates for sending
21162128
std::vector<std::set<uint256>::iterator> vInvTx;
@@ -2140,6 +2152,10 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
21402152
// Send
21412153
vInv.emplace_back(CInv(MSG_TX, hash));
21422154
nRelayedTransactions++;
2155+
if (vInv.size() == MAX_INV_SZ) {
2156+
connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2157+
vInv.clear();
2158+
}
21432159
pto->filterInventoryKnown.insert(hash);
21442160
}
21452161
}

0 commit comments

Comments
 (0)