aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2016-04-20 07:05:23 +0000
committerPieter Wuille <pieter.wuille@gmail.com>2016-04-21 00:33:56 +0200
commitb5599147533103efea896a1fc4ff51f2d3ad5808 (patch)
tree96273816a881746f3d0390d7e50e6466eb6f28c0 /src
parent4578215e7f787968c1d6478e6df75499bd36dd8d (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp42
-rw-r--r--src/net.cpp15
-rw-r--r--src/net.h2
3 files changed, 38 insertions, 21 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 282c8cdb66..b707de2e58 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4557,12 +4557,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
}
- if (!vRecv.empty())
+ if (!vRecv.empty()) {
vRecv >> pfrom->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)
@@ -5325,12 +5329,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBloomFilter filter;
vRecv >> filter;
+ LOCK(pfrom->cs_filter);
+
if (!filter.IsWithinSizeConstraints())
// There is no excuse for sending a too-large filter
Misbehaving(pfrom->GetId(), 100);
else
{
- LOCK(pfrom->cs_filter);
delete pfrom->pfilter;
pfrom->pfilter = new CBloomFilter(filter);
pfrom->pfilter->UpdateEmptyFull();
@@ -5798,6 +5803,12 @@ bool SendMessages(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<uint256> vtxid;
@@ -5843,6 +5854,11 @@ bool SendMessages(CNode* pto)
for (std::set<uint256>::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) {
vInvTx.push_back(it);
}
+ CAmount filterrate = 0;
+ {
+ LOCK(pto->cs_feeFilter);
+ filterrate = pto->minFeeFilter;
+ }
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
// A heap is used so that not all items need sorting if only a few are being sent.
CompareInvMempoolOrder compareInvMempoolOrder(&mempool);
@@ -5850,6 +5866,7 @@ bool SendMessages(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);
@@ -5862,6 +5879,19 @@ bool SendMessages(CNode* pto)
if (pto->filterInventoryKnown.contains(hash)) {
continue;
}
+ // Not in the mempool anymore? don't bother sending it.
+ CFeeRate feeRate;
+ if (!mempool.lookupFeeRate(hash, feeRate)) {
+ continue;
+ }
+ if (filterrate && feeRate.GetFeePerK() < filterrate) {
+ continue;
+ }
+ 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 6b305ebae4..ccc430f5c2 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2071,20 +2071,7 @@ void RelayTransaction(const CTransaction& tx, CFeeRate feerate)
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
- if(!pnode->fRelayTxes)
- continue;
- {
- LOCK(pnode->cs_feeFilter);
- if (feerate.GetFeePerK() < pnode->minFeeFilter)
- continue;
- }
- LOCK(pnode->cs_filter);
- 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 26acf59e60..b6ec7bf3e2 100644
--- a/src/net.h
+++ b/src/net.h
@@ -357,7 +357,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;