Skip to content

Commit 935d488

Browse files
committed
[net processing] Refactor MaybeSendAddr()
Changes to make MaybeSendAddr simpler and easier to maintain/update: - assert invariant that node.vAddrToSend.size() can never exceed MAX_ADDR_TO_SEND - erase known addresses from vAddrToSend in one pass - no check for (vAddr.size() >= MAX_ADDR_TO_SEND) during iteration, since vAddr can never exceed MAX_ADDR_TO_SEND.
1 parent 01a79ff commit 935d488

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

src/net_processing.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <util/system.h>
3434
#include <validation.h>
3535

36+
#include <algorithm>
3637
#include <memory>
3738
#include <optional>
3839
#include <typeinfo>
@@ -4148,8 +4149,6 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, std::chrono::microseconds curre
41484149

41494150
assert(node.m_addr_known);
41504151

4151-
const CNetMsgMaker msgMaker(node.GetCommonVersion());
4152-
41534152
LOCK(node.m_addr_send_times_mutex);
41544153
// Periodically advertise our local address to the peer.
41554154
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
@@ -4174,8 +4173,25 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, std::chrono::microseconds curre
41744173
if (current_time <= node.m_next_addr_send) return;
41754174

41764175
node.m_next_addr_send = PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
4177-
std::vector<CAddress> vAddr;
4178-
vAddr.reserve(node.vAddrToSend.size());
4176+
4177+
if (!Assume(node.vAddrToSend.size() <= MAX_ADDR_TO_SEND)) {
4178+
// Should be impossible since we always check size before adding to
4179+
// vAddrToSend. Recover by trimming the vector.
4180+
node.vAddrToSend.resize(MAX_ADDR_TO_SEND);
4181+
}
4182+
4183+
// Remove addr records that the peer already knows about, and add new
4184+
// addrs to the m_addr_known filter on the same pass.
4185+
auto addr_already_known = [&node](const CAddress& addr) {
4186+
bool ret = node.m_addr_known->contains(addr.GetKey());
4187+
if (!ret) node.m_addr_known->insert(addr.GetKey());
4188+
return ret;
4189+
};
4190+
node.vAddrToSend.erase(std::remove_if(node.vAddrToSend.begin(), node.vAddrToSend.end(), addr_already_known),
4191+
node.vAddrToSend.end());
4192+
4193+
// No addr messages to send
4194+
if (node.vAddrToSend.empty()) return;
41794195

41804196
const char* msg_type;
41814197
int make_flags;
@@ -4186,27 +4202,13 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, std::chrono::microseconds curre
41864202
msg_type = NetMsgType::ADDR;
41874203
make_flags = 0;
41884204
}
4189-
4190-
for (const CAddress& addr : node.vAddrToSend)
4191-
{
4192-
if (!node.m_addr_known->contains(addr.GetKey()))
4193-
{
4194-
node.m_addr_known->insert(addr.GetKey());
4195-
vAddr.push_back(addr);
4196-
// receiver rejects addr messages larger than MAX_ADDR_TO_SEND
4197-
if (vAddr.size() >= MAX_ADDR_TO_SEND)
4198-
{
4199-
m_connman.PushMessage(&node, msgMaker.Make(make_flags, msg_type, vAddr));
4200-
vAddr.clear();
4201-
}
4202-
}
4203-
}
4205+
m_connman.PushMessage(&node, CNetMsgMaker(node.GetCommonVersion()).Make(make_flags, msg_type, node.vAddrToSend));
42044206
node.vAddrToSend.clear();
4205-
if (!vAddr.empty())
4206-
m_connman.PushMessage(&node, msgMaker.Make(make_flags, msg_type, vAddr));
4207+
42074208
// we only send the big addr message once
4208-
if (node.vAddrToSend.capacity() > 40)
4209+
if (node.vAddrToSend.capacity() > 40) {
42094210
node.vAddrToSend.shrink_to_fit();
4211+
}
42104212
}
42114213

42124214
namespace {

0 commit comments

Comments
 (0)