Skip to content

Commit

Permalink
[net processing] Extract addr send functionality into MaybeSendAddr()
Browse files Browse the repository at this point in the history
Summary:
Reviewer hint: review with

 `git diff --color-moved=dimmed-zebra --ignore-all-space`

This is a backport of [[bitcoin/bitcoin#21236 | core#21236]] [3/6]
bitcoin/bitcoin@ad71929

Depends on D10916

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10917
  • Loading branch information
jnewbery authored and PiRK committed Jan 28, 2022
1 parent 5ef11dc commit ff4da06
Showing 1 changed file with 73 additions and 68 deletions.
141 changes: 73 additions & 68 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ class PeerManagerImpl final : public PeerManager {
void MaybeSendPing(CNode &node_to, Peer &peer,
std::chrono::microseconds now);

/** Send `addr` messages on a regular schedule. */
void MaybeSendAddr(CNode *pto, std::chrono::microseconds current_time);

const CChainParams &m_chainparams;
CConnman &m_connman;
/**
Expand Down Expand Up @@ -5609,6 +5612,74 @@ void PeerManagerImpl::MaybeSendPing(CNode &node_to, Peer &peer,
}
}

void PeerManagerImpl::MaybeSendAddr(CNode *pto,
std::chrono::microseconds current_time) {
LOCK(pto->m_addr_send_times_mutex);
const CNetMsgMaker msgMaker(pto->GetCommonVersion());

if (pto->RelayAddrsWithConn() &&
!::ChainstateActive().IsInitialBlockDownload() &&
pto->m_next_local_addr_send < current_time) {
// If we've sent before, clear the bloom filter for the peer, so
// that our self-announcement will actually go out. This might
// be unnecessary if the bloom filter has already rolled over
// since our last self-announcement, but there is only a small
// bandwidth cost that we can incur by doing this (which happens
// once a day on average).
if (pto->m_next_local_addr_send != 0us) {
pto->m_addr_known->reset();
}
AdvertiseLocal(pto);
pto->m_next_local_addr_send =
PoissonNextSend(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
}

//
// Message: addr
//
if (pto->RelayAddrsWithConn() && pto->m_next_addr_send < current_time) {
pto->m_next_addr_send =
PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
std::vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
assert(pto->m_addr_known);

const char *msg_type;
int make_flags;
if (pto->m_wants_addrv2) {
msg_type = NetMsgType::ADDRV2;
make_flags = ADDRV2_FORMAT;
} else {
msg_type = NetMsgType::ADDR;
make_flags = 0;
}

for (const CAddress &addr : pto->vAddrToSend) {
if (!pto->m_addr_known->contains(addr.GetKey())) {
pto->m_addr_known->insert(addr.GetKey());
vAddr.push_back(addr);
// receiver rejects addr messages larger than
// MAX_ADDR_TO_SEND
if (vAddr.size() >= GetMaxAddrToSend()) {
m_connman.PushMessage(
pto, msgMaker.Make(make_flags, msg_type, vAddr));
vAddr.clear();
}
}
}
pto->vAddrToSend.clear();
if (!vAddr.empty()) {
m_connman.PushMessage(pto,
msgMaker.Make(make_flags, msg_type, vAddr));
}

// we only send the big addr message once
if (pto->vAddrToSend.capacity() > 40) {
pto->vAddrToSend.shrink_to_fit();
}
}
}

namespace {
class CompareInvMempoolOrder {
CTxMemPool *mp;
Expand Down Expand Up @@ -5660,79 +5731,13 @@ bool PeerManagerImpl::SendMessages(const Config &config, CNode *pto) {

bool fFetch;

MaybeSendAddr(pto, current_time);

{
LOCK(cs_main);

CNodeState &state = *State(pto->GetId());

// Address refresh broadcast
{
LOCK(pto->m_addr_send_times_mutex);
if (pto->RelayAddrsWithConn() &&
!::ChainstateActive().IsInitialBlockDownload() &&
pto->m_next_local_addr_send < current_time) {
// If we've sent before, clear the bloom filter for the peer, so
// that our self-announcement will actually go out. This might
// be unnecessary if the bloom filter has already rolled over
// since our last self-announcement, but there is only a small
// bandwidth cost that we can incur by doing this (which happens
// once a day on average).
if (pto->m_next_local_addr_send != 0us) {
pto->m_addr_known->reset();
}
AdvertiseLocal(pto);
pto->m_next_local_addr_send = PoissonNextSend(
current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
}

//
// Message: addr
//
if (pto->RelayAddrsWithConn() &&
pto->m_next_addr_send < current_time) {
pto->m_next_addr_send = PoissonNextSend(
current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
std::vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
assert(pto->m_addr_known);

const char *msg_type;
int make_flags;
if (pto->m_wants_addrv2) {
msg_type = NetMsgType::ADDRV2;
make_flags = ADDRV2_FORMAT;
} else {
msg_type = NetMsgType::ADDR;
make_flags = 0;
}

for (const CAddress &addr : pto->vAddrToSend) {
if (!pto->m_addr_known->contains(addr.GetKey())) {
pto->m_addr_known->insert(addr.GetKey());
vAddr.push_back(addr);
// receiver rejects addr messages larger than
// MAX_ADDR_TO_SEND
if (vAddr.size() >= GetMaxAddrToSend()) {
m_connman.PushMessage(
pto,
msgMaker.Make(make_flags, msg_type, vAddr));
vAddr.clear();
}
}
}
pto->vAddrToSend.clear();
if (!vAddr.empty()) {
m_connman.PushMessage(
pto, msgMaker.Make(make_flags, msg_type, vAddr));
}

// we only send the big addr message once
if (pto->vAddrToSend.capacity() > 40) {
pto->vAddrToSend.shrink_to_fit();
}
}
} // pto->m_addr_send_times_mutex

// Start block sync
if (pindexBestHeader == nullptr) {
pindexBestHeader = ::ChainActive().Tip();
Expand Down

0 comments on commit ff4da06

Please sign in to comment.