Respond to getheaders if we have sufficient chainwork

Previously, we would check to see if we were in IBD and ignore getheaders
requests accordingly. However, the IBD criteria -- an optimization mostly
targeted at behavior when we have peers serving us many blocks we need to
download -- is difficult to reason about in edge-case scenarios, such as if the
network were to go a long time without any blocks found and nodes getting
restarted during that time.

To make things simpler to reason about, just use nMinimumChainWork as our
anti-DoS threshold; as long as our chain has that much work, it should be fine
to respond to a peer asking for our headers (and this should allow such a peer
to request blocks from us if needed).
This commit is contained in:
Suhas Daftuar
2022-01-26 18:29:56 -05:00
parent d0bf9bb6a5
commit ef6dbe6863

View File

@@ -3189,9 +3189,23 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
if (fImporting || fReindex) {
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d while importing/reindexing\n", pfrom.GetId());
return;
}
LOCK(cs_main);
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !pfrom.HasPermission(NetPermissionFlags::Download)) {
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.GetId());
// Note that if we were to be on a chain that forks from the checkpointed
// chain, then serving those headers to a peer that has seen the
// checkpointed chain would cause that peer to disconnect us. Requiring
// that our chainwork exceed nMinimumChainWork is a protection against
// being fed a bogus chain when we started up for the first time and
// getting partitioned off the honest network for serving that chain to
// others.
if (m_chainman.ActiveTip() == nullptr ||
(m_chainman.ActiveTip()->nChainWork < nMinimumChainWork && !pfrom.HasPermission(NetPermissionFlags::Download))) {
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because active chain has too little work\n", pfrom.GetId());
return;
}