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.
This commit is contained in:
parent
dc13dcd2be
commit
ed7068302c
3 changed files with 49 additions and 28 deletions
74
src/main.cpp
74
src/main.cpp
|
@ -5235,34 +5235,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
pfrom->fDisconnect = true;
|
||||
return true;
|
||||
}
|
||||
LOCK2(cs_main, pfrom->cs_filter);
|
||||
|
||||
std::vector<uint256> vtxid;
|
||||
mempool.queryHashes(vtxid);
|
||||
vector<CInv> vInv;
|
||||
BOOST_FOREACH(uint256& hash, vtxid) {
|
||||
CInv inv(MSG_TX, hash);
|
||||
if (pfrom->pfilter) {
|
||||
CTransaction tx;
|
||||
bool fInMemPool = mempool.lookup(hash, tx);
|
||||
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
|
||||
if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
|
||||
}
|
||||
if (pfrom->minFeeFilter) {
|
||||
CFeeRate feeRate;
|
||||
mempool.lookupFeeRate(hash, feeRate);
|
||||
LOCK(pfrom->cs_feeFilter);
|
||||
if (feeRate.GetFeePerK() < pfrom->minFeeFilter)
|
||||
continue;
|
||||
}
|
||||
vInv.push_back(inv);
|
||||
if (vInv.size() == MAX_INV_SZ) {
|
||||
pfrom->PushMessage(NetMsgType::INV, vInv);
|
||||
vInv.clear();
|
||||
}
|
||||
}
|
||||
if (vInv.size() > 0)
|
||||
pfrom->PushMessage(NetMsgType::INV, vInv);
|
||||
LOCK(pfrom->cs_inventory);
|
||||
pfrom->fSendMempool = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5815,13 +5790,52 @@ bool SendMessages(CNode* pto)
|
|||
}
|
||||
pto->vInventoryBlockToSend.clear();
|
||||
|
||||
// Determine transactions to relay
|
||||
// Check whether periodic sends should happen
|
||||
bool fSendTrickle = pto->fWhitelisted;
|
||||
if (pto->nNextInvSend < nNow) {
|
||||
fSendTrickle = true;
|
||||
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
||||
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
|
||||
}
|
||||
|
||||
// Respond to BIP35 mempool requests
|
||||
if (fSendTrickle && pto->fSendMempool) {
|
||||
std::vector<uint256> vtxid;
|
||||
mempool.queryHashes(vtxid);
|
||||
pto->fSendMempool = false;
|
||||
CAmount filterrate = 0;
|
||||
{
|
||||
LOCK(pto->cs_feeFilter);
|
||||
filterrate = pto->minFeeFilter;
|
||||
}
|
||||
|
||||
LOCK(pto->cs_filter);
|
||||
|
||||
BOOST_FOREACH(const uint256& hash, vtxid) {
|
||||
CInv inv(MSG_TX, hash);
|
||||
pto->setInventoryTxToSend.erase(hash);
|
||||
if (filterrate) {
|
||||
CFeeRate feeRate;
|
||||
mempool.lookupFeeRate(hash, feeRate);
|
||||
if (feeRate.GetFeePerK() < filterrate)
|
||||
continue;
|
||||
}
|
||||
if (pto->pfilter) {
|
||||
CTransaction tx;
|
||||
bool fInMemPool = mempool.lookup(hash, tx);
|
||||
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
|
||||
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
|
||||
}
|
||||
pto->filterInventoryKnown.insert(hash);
|
||||
vInv.push_back(inv);
|
||||
if (vInv.size() == MAX_INV_SZ) {
|
||||
pto->PushMessage(NetMsgType::INV, vInv);
|
||||
vInv.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine transactions to relay
|
||||
if (fSendTrickle) {
|
||||
// Produce a vector with all candidates for sending
|
||||
vector<std::set<uint256>::iterator> vInvTx;
|
||||
|
@ -5851,6 +5865,10 @@ bool SendMessages(CNode* pto)
|
|||
// Send
|
||||
vInv.push_back(CInv(MSG_TX, hash));
|
||||
nRelayedTransactions++;
|
||||
if (vInv.size() == MAX_INV_SZ) {
|
||||
pto->PushMessage(NetMsgType::INV, vInv);
|
||||
vInv.clear();
|
||||
}
|
||||
pto->filterInventoryKnown.insert(hash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2370,6 +2370,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
|
|||
hashContinue = uint256();
|
||||
nStartingHeight = -1;
|
||||
filterInventoryKnown.reset();
|
||||
fSendMempool = false;
|
||||
fGetAddr = false;
|
||||
nNextLocalAddrSend = 0;
|
||||
nNextAddrSend = 0;
|
||||
|
|
|
@ -411,6 +411,8 @@ public:
|
|||
// Used for headers announcements - unfiltered blocks to relay
|
||||
// Also protected by cs_inventory
|
||||
std::vector<uint256> vBlockHashesToAnnounce;
|
||||
// Used for BIP35 mempool sending, also protected by cs_inventory
|
||||
bool fSendMempool;
|
||||
|
||||
// Ping time measurement:
|
||||
// The pong reply we're expecting, or 0 if no pong expected.
|
||||
|
|
Loading…
Reference in a new issue