mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 02:25:40 +01:00
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.
This commit is contained in:
parent
ed6cddd98e
commit
83c6a0c524
@ -388,6 +388,9 @@ struct Peer {
|
||||
* reorgs) **/
|
||||
std::unique_ptr<HeadersSyncState> m_headers_sync PT_GUARDED_BY(m_headers_sync_mutex) GUARDED_BY(m_headers_sync_mutex) {};
|
||||
|
||||
/** Whether we've sent our peer a sendheaders message. **/
|
||||
std::atomic<bool> m_sent_sendheaders{false};
|
||||
|
||||
explicit Peer(NodeId id, ServiceFlags our_services)
|
||||
: m_id{id}
|
||||
, m_our_services{our_services}
|
||||
@ -682,6 +685,9 @@ private:
|
||||
/** Send `addr` messages on a regular schedule. */
|
||||
void MaybeSendAddr(CNode& node, Peer& peer, std::chrono::microseconds current_time);
|
||||
|
||||
/** Send a single `sendheaders` message, after we have completed headers sync with a peer. */
|
||||
void MaybeSendSendHeaders(CNode& node, Peer& peer);
|
||||
|
||||
/** Relay (gossip) an address to a few randomly chosen nodes.
|
||||
*
|
||||
* @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,
|
||||
pfrom.ConnectionTypeAsString());
|
||||
}
|
||||
|
||||
if (pfrom.GetCommonVersion() >= SENDHEADERS_VERSION) {
|
||||
// Tell our peer we prefer to receive headers rather than inv's
|
||||
// We send this to non-NODE NETWORK peers as well, because even
|
||||
// non-NODE NETWORK peers can announce blocks (such as pruning
|
||||
// nodes)
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDHEADERS));
|
||||
}
|
||||
if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) {
|
||||
// Tell our peer we are willing to provide version 2 cmpctblocks.
|
||||
// However, we do not request new block announcements using
|
||||
@ -5034,6 +5033,27 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
|
||||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::MaybeSendSendHeaders(CNode& node, Peer& peer)
|
||||
{
|
||||
// Delay sending SENDHEADERS (BIP 130) until we're done with an
|
||||
// initial-headers-sync with this peer. Receiving headers announcements for
|
||||
// new blocks while trying to sync their headers chain is problematic,
|
||||
// because of the state tracking done.
|
||||
if (!peer.m_sent_sendheaders && node.GetCommonVersion() >= SENDHEADERS_VERSION) {
|
||||
LOCK(cs_main);
|
||||
CNodeState &state = *State(node.GetId());
|
||||
if (state.pindexBestKnownBlock != nullptr &&
|
||||
state.pindexBestKnownBlock->nChainWork > nMinimumChainWork) {
|
||||
// Tell our peer we prefer to receive headers rather than inv's
|
||||
// We send this to non-NODE NETWORK peers as well, because even
|
||||
// non-NODE NETWORK peers can announce blocks (such as pruning
|
||||
// nodes)
|
||||
m_connman.PushMessage(&node, CNetMsgMaker(node.GetCommonVersion()).Make(NetMsgType::SENDHEADERS));
|
||||
peer.m_sent_sendheaders = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::microseconds current_time)
|
||||
{
|
||||
if (m_ignore_incoming_txs) return;
|
||||
@ -5155,6 +5175,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
|
||||
MaybeSendAddr(*pto, *peer, current_time);
|
||||
|
||||
MaybeSendSendHeaders(*pto, *peer);
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user