@@ -388,6 +388,9 @@ struct Peer {
388
388
* reorgs) **/
389
389
std::unique_ptr<HeadersSyncState> m_headers_sync PT_GUARDED_BY (m_headers_sync_mutex) GUARDED_BY(m_headers_sync_mutex) {};
390
390
391
+ /* * Whether we've sent our peer a sendheaders message. **/
392
+ std::atomic<bool > m_sent_sendheaders{false };
393
+
391
394
explicit Peer (NodeId id, ServiceFlags our_services)
392
395
: m_id{id}
393
396
, m_our_services{our_services}
@@ -682,6 +685,9 @@ class PeerManagerImpl final : public PeerManager
682
685
/* * Send `addr` messages on a regular schedule. */
683
686
void MaybeSendAddr (CNode& node, Peer& peer, std::chrono::microseconds current_time);
684
687
688
+ /* * Send a single `sendheaders` message, after we have completed headers sync with a peer. */
689
+ void MaybeSendSendHeaders (CNode& node, Peer& peer);
690
+
685
691
/* * Relay (gossip) an address to a few randomly chosen nodes.
686
692
*
687
693
* @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,
3295
3301
pfrom.ConnectionTypeAsString ());
3296
3302
}
3297
3303
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
- }
3305
3304
if (pfrom.GetCommonVersion () >= SHORT_IDS_BLOCKS_VERSION) {
3306
3305
// Tell our peer we are willing to provide version 2 cmpctblocks.
3307
3306
// However, we do not request new block announcements using
@@ -5034,6 +5033,27 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
5034
5033
}
5035
5034
}
5036
5035
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
+
5037
5057
void PeerManagerImpl::MaybeSendFeefilter (CNode& pto, Peer& peer, std::chrono::microseconds current_time)
5038
5058
{
5039
5059
if (m_ignore_incoming_txs) return ;
@@ -5155,6 +5175,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5155
5175
5156
5176
MaybeSendAddr (*pto, *peer, current_time);
5157
5177
5178
+ MaybeSendSendHeaders (*pto, *peer);
5179
+
5158
5180
{
5159
5181
LOCK (cs_main);
5160
5182
0 commit comments