From 2e3b05ccdd32f0827f30d70e6329b981b129a4ce Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 25 Nov 2015 21:25:30 -0800 Subject: [PATCH] Replace setInventoryKnown with a rolling bloom filter. Mruset setInventoryKnown was reduced to a remarkably small 1000 entries as a side effect of sendbuffer size reductions in 2012. This removes setInventoryKnown filtering from merkleBlock responses because false positives there are especially unattractive and also because I'm not sure if there aren't race conditions around the relay pool that would cause some transactions there to be suppressed. (Also, ProcessGetData was accessing setInventoryKnown without taking the required lock.) --- src/main.cpp | 9 ++++----- src/net.cpp | 3 ++- src/net.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6f3359893e6bf..f90478033637c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5159,8 +5159,7 @@ void static ProcessGetData(CNode* pfrom) // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; for (PairType& pair : merkleBlock.vMatchedTxn) - if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) - pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); + pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -6398,7 +6397,7 @@ bool SendMessages(CNode* pto) vInv.reserve(pto->vInventoryToSend.size()); vInvWait.reserve(pto->vInventoryToSend.size()); for (const CInv& inv : pto->vInventoryToSend) { - if (pto->setInventoryKnown.count(inv)) + if (pto->setInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -6417,8 +6416,8 @@ bool SendMessages(CNode* pto) } } - // returns true if wasn't already contained in the set - if (pto->setInventoryKnown.insert(inv).second) { + if (!pto->setInventoryKnown.contains(inv.hash)) { + pto->setInventoryKnown.insert(inv.hash); vInv.push_back(inv); if (vInv.size() >= 1000) { pto->PushMessage(NetMsgType::INV, vInv); diff --git a/src/net.cpp b/src/net.cpp index 341bd52067490..35546ae264eda 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2319,7 +2319,7 @@ unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", 1 * 1000) CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(SendBufferSize() / 1000) + setInventoryKnown(50000, 0.000001) { nServices = NODE_NONE; nServicesExpected = NODE_NONE; @@ -2347,6 +2347,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nSendOffset = 0; hashContinue = UINT256_ZERO; nStartingHeight = -1; + setInventoryKnown.reset(); fGetAddr = false; nNextLocalAddrSend = 0; nNextAddrSend = 0; diff --git a/src/net.h b/src/net.h index a8d2334ad5894..ac67e77bca79a 100644 --- a/src/net.h +++ b/src/net.h @@ -387,7 +387,7 @@ class CNode int64_t nNextLocalAddrSend; // inventory based relay - mruset setInventoryKnown; + CRollingBloomFilter setInventoryKnown; std::vector vInventoryToSend; RecursiveMutex cs_inventory; std::multimap mapAskFor; @@ -487,7 +487,7 @@ class CNode { { LOCK(cs_inventory); - setInventoryKnown.insert(inv); + setInventoryKnown.insert(inv.hash); } } @@ -495,7 +495,7 @@ class CNode { { LOCK(cs_inventory); - if (!setInventoryKnown.count(inv)) + if (!setInventoryKnown.contains(inv.hash)) vInventoryToSend.push_back(inv); } }