@@ -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+
50375057void 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