Skip to content

Commit b559914

Browse files
gmaxwellsipa
authored andcommitted
Move bloom and feerate filtering to just prior to tx sending.
This will avoid sending more pointless INVs around updates, and prevents using filter updates to timetag transactions. Also adds locking for fRelayTxes.
1 parent 4578215 commit b559914

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

src/main.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4557,12 +4557,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
45574557
vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
45584558
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
45594559
}
4560-
if (!vRecv.empty())
4560+
if (!vRecv.empty()) {
45614561
vRecv >> pfrom->nStartingHeight;
4562-
if (!vRecv.empty())
4563-
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
4564-
else
4565-
pfrom->fRelayTxes = true;
4562+
}
4563+
{
4564+
LOCK(pfrom->cs_filter);
4565+
if (!vRecv.empty())
4566+
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
4567+
else
4568+
pfrom->fRelayTxes = true;
4569+
}
45664570

45674571
// Disconnect if we connected to ourself
45684572
if (nNonce == nLocalHostNonce && nNonce > 1)
@@ -5325,12 +5329,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
53255329
CBloomFilter filter;
53265330
vRecv >> filter;
53275331

5332+
LOCK(pfrom->cs_filter);
5333+
53285334
if (!filter.IsWithinSizeConstraints())
53295335
// There is no excuse for sending a too-large filter
53305336
Misbehaving(pfrom->GetId(), 100);
53315337
else
53325338
{
5333-
LOCK(pfrom->cs_filter);
53345339
delete pfrom->pfilter;
53355340
pfrom->pfilter = new CBloomFilter(filter);
53365341
pfrom->pfilter->UpdateEmptyFull();
@@ -5798,6 +5803,12 @@ bool SendMessages(CNode* pto)
57985803
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
57995804
}
58005805

5806+
// Time to send but the peer has requested we not relay transactions.
5807+
if (fSendTrickle) {
5808+
LOCK(pto->cs_filter);
5809+
if (!pto->fRelayTxes) pto->setInventoryTxToSend.clear();
5810+
}
5811+
58015812
// Respond to BIP35 mempool requests
58025813
if (fSendTrickle && pto->fSendMempool) {
58035814
std::vector<uint256> vtxid;
@@ -5843,13 +5854,19 @@ bool SendMessages(CNode* pto)
58435854
for (std::set<uint256>::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) {
58445855
vInvTx.push_back(it);
58455856
}
5857+
CAmount filterrate = 0;
5858+
{
5859+
LOCK(pto->cs_feeFilter);
5860+
filterrate = pto->minFeeFilter;
5861+
}
58465862
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
58475863
// A heap is used so that not all items need sorting if only a few are being sent.
58485864
CompareInvMempoolOrder compareInvMempoolOrder(&mempool);
58495865
std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
58505866
// No reason to drain out at many times the network's capacity,
58515867
// especially since we have many peers and some will draw much shorter delays.
58525868
unsigned int nRelayedTransactions = 0;
5869+
LOCK(pto->cs_filter);
58535870
while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
58545871
// Fetch the top element from the heap
58555872
std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
@@ -5862,6 +5879,19 @@ bool SendMessages(CNode* pto)
58625879
if (pto->filterInventoryKnown.contains(hash)) {
58635880
continue;
58645881
}
5882+
// Not in the mempool anymore? don't bother sending it.
5883+
CFeeRate feeRate;
5884+
if (!mempool.lookupFeeRate(hash, feeRate)) {
5885+
continue;
5886+
}
5887+
if (filterrate && feeRate.GetFeePerK() < filterrate) {
5888+
continue;
5889+
}
5890+
if (pto->pfilter) {
5891+
CTransaction tx;
5892+
if (!mempool.lookup(hash, tx)) continue;
5893+
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
5894+
}
58655895
// Send
58665896
vInv.push_back(CInv(MSG_TX, hash));
58675897
nRelayedTransactions++;

src/net.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,20 +2071,7 @@ void RelayTransaction(const CTransaction& tx, CFeeRate feerate)
20712071
LOCK(cs_vNodes);
20722072
BOOST_FOREACH(CNode* pnode, vNodes)
20732073
{
2074-
if(!pnode->fRelayTxes)
2075-
continue;
2076-
{
2077-
LOCK(pnode->cs_feeFilter);
2078-
if (feerate.GetFeePerK() < pnode->minFeeFilter)
2079-
continue;
2080-
}
2081-
LOCK(pnode->cs_filter);
2082-
if (pnode->pfilter)
2083-
{
2084-
if (pnode->pfilter->IsRelevantAndUpdate(tx))
2085-
pnode->PushInventory(inv);
2086-
} else
2087-
pnode->PushInventory(inv);
2074+
pnode->PushInventory(inv);
20882075
}
20892076
}
20902077

src/net.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ class CNode
357357
// a) it allows us to not relay tx invs before receiving the peer's version message
358358
// b) the peer may tell us in its version message that we should not relay tx invs
359359
// unless it loads a bloom filter.
360-
bool fRelayTxes;
360+
bool fRelayTxes; //protected by cs_filter
361361
bool fSentAddr;
362362
CSemaphoreGrant grantOutbound;
363363
CCriticalSection cs_filter;

0 commit comments

Comments
 (0)