aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2016-04-08 16:26:41 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2016-04-21 00:33:56 +0200
commited7068302c7490e8061cb3a558a0f83a465beeea (patch)
tree99d5a18d6912a7cdefd9874f65508f0a0c95f497 /src
parentdc13dcd2bec2613a1cd5e0395b09b449d176146f (diff)
downloadbitcoin-ed7068302c7490e8061cb3a558a0f83a465beeea.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp74
-rw-r--r--src/net.cpp1
-rw-r--r--src/net.h2
3 files changed, 49 insertions, 28 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 61d9301f8f..282c8cdb66 100644
--- a/src/main.cpp
+++ b/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);
}
}
diff --git a/src/net.cpp b/src/net.cpp
index f294e4c667..6b305ebae4 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -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;
diff --git a/src/net.h b/src/net.h
index a95fa79e7e..26acf59e60 100644
--- a/src/net.h
+++ b/src/net.h
@@ -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.