Ensure CNode::addrKnown immediately takes little memory when we disconnect the node

This commit is contained in:
Duke
2023-03-17 00:21:00 -04:00
parent c1baab7b8a
commit 63ad87f69b
3 changed files with 29 additions and 9 deletions

View File

@@ -7132,7 +7132,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
addr.nTime = nNow - 5 * 24 * 60 * 60; addr.nTime = nNow - 5 * 24 * 60 * 60;
pfrom->AddAddressKnown(addr); pfrom->AddAddressIfNotAlreadyKnown(addr);
++num_proc; ++num_proc;
bool fReachable = IsReachable(addr); bool fReachable = IsReachable(addr);
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
@@ -7988,9 +7989,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
vAddr.reserve(pto->vAddrToSend.size()); vAddr.reserve(pto->vAddrToSend.size());
BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
{ {
if (!pto->addrKnown.contains(addr.GetKey())) if (pto->AddAddressIfNotAlreadyKnown(addr))
{ {
pto->addrKnown.insert(addr.GetKey());
vAddr.push_back(addr); vAddr.push_back(addr);
if (vAddr.size() >= MAX_ADDR_TO_SEND) if (vAddr.size() >= MAX_ADDR_TO_SEND)

View File

@@ -556,6 +556,10 @@ void CNode::CloseSocketDisconnect()
CloseSocket(hSocket); CloseSocket(hSocket);
} }
} }
{
LOCK(cs_addrKnown);
addrKnown.reset();
}
// in case this fails, we'll empty the recv buffer when the CNode is deleted // in case this fails, we'll empty the recv buffer when the CNode is deleted
TRY_LOCK(cs_vRecvMsg, lockRecv); TRY_LOCK(cs_vRecvMsg, lockRecv);

View File

@@ -432,6 +432,8 @@ public:
CCriticalSection cs_filter; CCriticalSection cs_filter;
CBloomFilter* pfilter; CBloomFilter* pfilter;
int nRefCount; int nRefCount;
CRollingBloomFilter addrKnown;
mutable CCriticalSection cs_addrKnown;
NodeId id; NodeId id;
/** /**
@@ -478,7 +480,6 @@ public:
// flood relay // flood relay
std::vector<CAddress> vAddrToSend; std::vector<CAddress> vAddrToSend;
CRollingBloomFilter addrKnown;
bool fGetAddr; bool fGetAddr;
std::set<uint256> setKnown; std::set<uint256> setKnown;
@@ -561,11 +562,25 @@ public:
nRefCount--; nRefCount--;
} }
bool AddAddressIfNotAlreadyKnown(const CAddress& addr)
void AddAddressKnown(const CAddress& _addr)
{ {
addrKnown.insert(_addr.GetKey()); LOCK(cs_addrKnown);
// Avoid adding to addrKnown after it has been reset in CloseSocketDisconnect.
if (fDisconnect) {
return false;
}
if (!addrKnown.contains(addr.GetKey())) {
addrKnown.insert(addr.GetKey());
return true;
} else {
return false;
}
}
bool IsAddressKnown(const CAddress& addr) const
{
LOCK(cs_addrKnown);
return addrKnown.contains(addr.GetKey());
} }
void PushAddress(const CAddress& _addr) void PushAddress(const CAddress& _addr)
@@ -578,7 +593,8 @@ public:
// Known checking here is only to save space from duplicates. // Known checking here is only to save space from duplicates.
// SendMessages will filter it again for knowns that were added // SendMessages will filter it again for knowns that were added
// after addresses were pushed. // after addresses were pushed.
if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey()) && addr_format_supported) { if (_addr.IsValid() && !IsAddressKnown(addr) && addr_format_supported) {
if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) { if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr; vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr;
} else { } else {