Skip to content

Commit 83c6a0c

Browse files
committed
Reduce spurious messages during headers sync
Delay sending SENDHEADERS (BIP 130) message until we know our peer's best header's chain has more than nMinimumChainWork. This reduces inadvertent headers messages received during initial headers sync due to block announcements, which throw off our sync algorithm.
1 parent ed6cddd commit 83c6a0c

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

src/net_processing.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ struct Peer {
388388
* reorgs) **/
389389
std::unique_ptr<HeadersSyncState> m_headers_sync PT_GUARDED_BY(m_headers_sync_mutex) GUARDED_BY(m_headers_sync_mutex) {};
390390

391+
/** Whether we've sent our peer a sendheaders message. **/
392+
std::atomic<bool> m_sent_sendheaders{false};
393+
391394
explicit Peer(NodeId id, ServiceFlags our_services)
392395
: m_id{id}
393396
, m_our_services{our_services}
@@ -682,6 +685,9 @@ class PeerManagerImpl final : public PeerManager
682685
/** Send `addr` messages on a regular schedule. */
683686
void MaybeSendAddr(CNode& node, Peer& peer, std::chrono::microseconds current_time);
684687

688+
/** Send a single `sendheaders` message, after we have completed headers sync with a peer. */
689+
void MaybeSendSendHeaders(CNode& node, Peer& peer);
690+
685691
/** Relay (gossip) an address to a few randomly chosen nodes.
686692
*
687693
* @param[in] originator The id of the peer that sent us the address. We don't want to relay it back.
@@ -3295,13 +3301,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32953301
pfrom.ConnectionTypeAsString());
32963302
}
32973303

3298-
if (pfrom.GetCommonVersion() >= SENDHEADERS_VERSION) {
3299-
// Tell our peer we prefer to receive headers rather than inv's
3300-
// We send this to non-NODE NETWORK peers as well, because even
3301-
// non-NODE NETWORK peers can announce blocks (such as pruning
3302-
// nodes)
3303-
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDHEADERS));
3304-
}
33053304
if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) {
33063305
// Tell our peer we are willing to provide version 2 cmpctblocks.
33073306
// However, we do not request new block announcements using
@@ -5034,6 +5033,27 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
50345033
}
50355034
}
50365035

5036+
void PeerManagerImpl::MaybeSendSendHeaders(CNode& node, Peer& peer)
5037+
{
5038+
// Delay sending SENDHEADERS (BIP 130) until we're done with an
5039+
// initial-headers-sync with this peer. Receiving headers announcements for
5040+
// new blocks while trying to sync their headers chain is problematic,
5041+
// because of the state tracking done.
5042+
if (!peer.m_sent_sendheaders && node.GetCommonVersion() >= SENDHEADERS_VERSION) {
5043+
LOCK(cs_main);
5044+
CNodeState &state = *State(node.GetId());
5045+
if (state.pindexBestKnownBlock != nullptr &&
5046+
state.pindexBestKnownBlock->nChainWork > nMinimumChainWork) {
5047+
// Tell our peer we prefer to receive headers rather than inv's
5048+
// We send this to non-NODE NETWORK peers as well, because even
5049+
// non-NODE NETWORK peers can announce blocks (such as pruning
5050+
// nodes)
5051+
m_connman.PushMessage(&node, CNetMsgMaker(node.GetCommonVersion()).Make(NetMsgType::SENDHEADERS));
5052+
peer.m_sent_sendheaders = true;
5053+
}
5054+
}
5055+
}
5056+
50375057
void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::microseconds current_time)
50385058
{
50395059
if (m_ignore_incoming_txs) return;
@@ -5155,6 +5175,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
51555175

51565176
MaybeSendAddr(*pto, *peer, current_time);
51575177

5178+
MaybeSendSendHeaders(*pto, *peer);
5179+
51585180
{
51595181
LOCK(cs_main);
51605182

0 commit comments

Comments
 (0)