Skip to content

Commit d81cff3

Browse files
gavinandresensipa
authored andcommitted
Replace mruset setAddrKnown with CRollingBloomFilter addrKnown
Use a probabilistic bloom filter to keep track of which addresses we think we have given our peers, instead of a list. This uses much less memory, at the cost of sometimes failing to relay an address to a peer-- worst case if the bloom filter happens to be as full as it gets, 1-in-1,000. Measured memory usage of a full mruset setAddrKnown: 650Kbytes Constant memory usage of CRollingBloomFilter addrKnown: 37Kbytes. This will also help heap fragmentation, because the 37K of storage is allocated when a CNode is created (when a connection to a peer is established) and then there is no per-item-remembered memory allocation. I plan on testing by restarting a full node with an empty peers.dat, running a while with -debug=addrman and -debug=net, and making sure that the 'addr' message traffic out is reasonable. (suggestions for better tests welcome)
1 parent 69a5f8b commit d81cff3

File tree

3 files changed

+9
-9
lines changed

3 files changed

+9
-9
lines changed

src/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,7 +3995,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
39953995
{
39963996
LOCK(cs_vNodes);
39973997
// Use deterministic randomness to send to the same nodes for 24 hours
3998-
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
3998+
// at a time so the addrKnowns of the chosen nodes prevent repeats
39993999
static uint256 hashSalt;
40004000
if (hashSalt.IsNull())
40014001
hashSalt = GetRandHash();
@@ -4779,9 +4779,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
47794779
LOCK(cs_vNodes);
47804780
BOOST_FOREACH(CNode* pnode, vNodes)
47814781
{
4782-
// Periodically clear setAddrKnown to allow refresh broadcasts
4782+
// Periodically clear addrKnown to allow refresh broadcasts
47834783
if (nLastRebroadcast)
4784-
pnode->setAddrKnown.clear();
4784+
pnode->addrKnown.clear();
47854785

47864786
// Rebroadcast our address
47874787
AdvertizeLocal(pnode);
@@ -4799,9 +4799,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
47994799
vAddr.reserve(pto->vAddrToSend.size());
48004800
BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
48014801
{
4802-
// returns true if wasn't already contained in the set
4803-
if (pto->setAddrKnown.insert(addr).second)
4802+
if (!pto->addrKnown.contains(addr.GetKey()))
48044803
{
4804+
pto->addrKnown.insert(addr.GetKey());
48054805
vAddr.push_back(addr);
48064806
// receiver rejects addr messages larger than 1000
48074807
if (vAddr.size() >= 1000)

src/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ bool CAddrDB::Read(CAddrMan& addr)
19051905
unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
19061906
unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
19071907

1908-
CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
1908+
CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001, insecure_rand())
19091909
{
19101910
nServices = 0;
19111911
hSocket = hSocketIn;

src/net.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ class CNode
300300

301301
// flood relay
302302
std::vector<CAddress> vAddrToSend;
303-
mruset<CAddress> setAddrKnown;
303+
CRollingBloomFilter addrKnown;
304304
bool fGetAddr;
305305
std::set<uint256> setKnown;
306306

@@ -380,15 +380,15 @@ class CNode
380380

381381
void AddAddressKnown(const CAddress& addr)
382382
{
383-
setAddrKnown.insert(addr);
383+
addrKnown.insert(addr.GetKey());
384384
}
385385

386386
void PushAddress(const CAddress& addr)
387387
{
388388
// Known checking here is only to save space from duplicates.
389389
// SendMessages will filter it again for knowns that were added
390390
// after addresses were pushed.
391-
if (addr.IsValid() && !setAddrKnown.count(addr)) {
391+
if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) {
392392
if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
393393
vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
394394
} else {

0 commit comments

Comments
 (0)