From 6fdc4def4a96811a22127beece2173ebde7cc196 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 20 Apr 2016 07:05:23 +0000 Subject: [PATCH] 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. (cherry picked from commit b5599147533103efea896a1fc4ff51f2d3ad5808) --- src/main.cpp | 27 ++++++++++++++++++++++----- src/net.cpp | 11 +---------- src/net.h | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 150dd9148..c8a3e6632 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6258,10 +6258,13 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string vRecv >> nStartingHeight; pfrom->nStartingHeight = nStartingHeight; } - if (!vRecv.empty()) - vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message - else - pfrom->fRelayTxes = true; + { + LOCK(pfrom->cs_filter); + if (!vRecv.empty()) + vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message + else + pfrom->fRelayTxes = true; + } // Disconnect if we connected to ourself if (nNonce == nLocalHostNonce && nNonce > 1) @@ -7060,6 +7063,8 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string CBloomFilter filter; vRecv >> filter; + LOCK(pfrom->cs_filter); + if (!filter.IsWithinSizeConstraints()) { // There is no excuse for sending a too-large filter @@ -7068,7 +7073,6 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string } else { - LOCK(pfrom->cs_filter); delete pfrom->pfilter; pfrom->pfilter = new CBloomFilter(filter); pfrom->fRelayTxes = true; @@ -7439,6 +7443,12 @@ bool SendMessages(const Consensus::Params& params, CNode* pto) pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound); } + // Time to send but the peer has requested we not relay transactions. + if (fSendTrickle) { + LOCK(pto->cs_filter); + if (!pto->fRelayTxes) pto->setInventoryTxToSend.clear(); + } + // Respond to BIP35 mempool requests if (fSendTrickle && pto->fSendMempool) { std::vector vtxid; @@ -7485,6 +7495,7 @@ bool SendMessages(const Consensus::Params& params, CNode* pto) // No reason to drain out at many times the network's capacity, // especially since we have many peers and some will draw much shorter delays. unsigned int nRelayedTransactions = 0; + LOCK(pto->cs_filter); while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) { // Fetch the top element from the heap std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder); @@ -7497,6 +7508,12 @@ bool SendMessages(const Consensus::Params& params, CNode* pto) if (pto->filterInventoryKnown.contains(hash)) { continue; } + // Not in the mempool anymore? don't bother sending it. + if (pto->pfilter) { + CTransaction tx; + if (!mempool.lookup(hash, tx)) continue; + if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue; + } // Send vInv.push_back(CInv(MSG_TX, hash)); nRelayedTransactions++; diff --git a/src/net.cpp b/src/net.cpp index c2f07221d..c4407122f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2050,16 +2050,7 @@ void RelayTransaction(const CTransaction& tx) LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if(!pnode->fRelayTxes) - continue; - LOCK(pnode->cs_filter); - auto spanGuard = pnode->span.Enter(); - if (pnode->pfilter) - { - if (pnode->pfilter->IsRelevantAndUpdate(tx)) - pnode->PushInventory(inv); - } else - pnode->PushInventory(inv); + pnode->PushInventory(inv); } } diff --git a/src/net.h b/src/net.h index 461c789e9..46a205812 100644 --- a/src/net.h +++ b/src/net.h @@ -297,7 +297,7 @@ public: // a) it allows us to not relay tx invs before receiving the peer's version message // b) the peer may tell us in its version message that we should not relay tx invs // unless it loads a bloom filter. - bool fRelayTxes; + bool fRelayTxes; //protected by cs_filter bool fSentAddr; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter;