Skip to content

Commit fba37b7

Browse files
committed
Move enough-headers check up, rejecting excess headers when received.
1 parent 394e59d commit fba37b7

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

src/net_processing.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,28 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
20072007
return;
20082008
}
20092009

2010+
// If we are already too far ahead of where we want to be on headers, discard
2011+
// the received headers. We can still get ahead by up to a single maximum-sized
2012+
// headers message here, but never further, so that's fine.
2013+
if (pindexBestHeader) {
2014+
uint64_t headers_ahead = pindexBestHeader->nHeight - m_chainman.ActiveHeight();
2015+
bool too_far_ahead = fTrimHeaders && (headers_ahead >= nHeaderDownloadBuffer);
2016+
if (too_far_ahead) {
2017+
LogPrint(BCLog::NET, "Discarding received headers and pausing header sync from peer=%d, because we are too far ahead of block sync (%d > %d, %d new headers received)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight(), nCount);
2018+
LOCK(cs_main);
2019+
CNodeState *nodestate = State(pfrom.GetId());
2020+
if (nodestate->fSyncStarted) {
2021+
// Cancel sync from this node, so we don't penalize it later.
2022+
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
2023+
// if we still need to sync headers.
2024+
nSyncStarted--;
2025+
nodestate->fSyncStarted = false;
2026+
nodestate->m_headers_sync_timeout = 0us;
2027+
}
2028+
return;
2029+
}
2030+
}
2031+
20102032
bool received_new_header = false;
20112033
const CBlockIndex *pindexLast = nullptr;
20122034
{
@@ -2084,17 +2106,11 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
20842106
nodestate->m_last_block_announcement = GetTime();
20852107
}
20862108

2087-
uint64_t headers_ahead = pindexLast->nHeight - m_chainman.ActiveHeight();
2088-
bool got_enough_headers = fTrimHeaders && (headers_ahead >= nHeaderDownloadBuffer);
2089-
20902109
// If a peer gives us as many headers as possible, this is implicitly a signal that the
20912110
// peer has more headers to send us. In Bitcoin Core, the node always asks for more
2092-
// headers at this point. Our logic is slightly more complex, because:
2093-
// (1) There is an apparent bug in the Bitcoin Core state machine here, where we can
2094-
// end up downloading headers from lots of peers at the same time by accident, which we
2095-
// work around rather than truly fix;
2096-
// (2) For various reasons we may want to avoid letting the header downloads get "too
2097-
// far ahead" of block downloads, so we may pause syncing for that reasons.
2111+
// headers at this point. Our logic is slightly more complex, to work around an apparent
2112+
// bug in the Bitcoin Core state machine, where we can end up downloading headers from
2113+
/// lots of peers at the same time by accident.
20982114
if (nCount == MAX_HEADERS_RESULTS) {
20992115
if (all_duplicate && !nodestate->fSyncStarted) {
21002116
// In this case two things are true:
@@ -2106,18 +2122,6 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
21062122
// In this case the right thing to do is simply stop syncing headers from this
21072123
// peer; it's redundant. Here we do nothing; since we don't ask the peer for
21082124
// more headers, it will stop sending them.
2109-
} else if (got_enough_headers) {
2110-
// If we're trying to save memory on headers, and we've already got plenty of headers,
2111-
// pause until we're ready for more.
2112-
LogPrint(BCLog::NET, "Pausing header sync from peer=%d, because the last one was too far ahead of block sync (%d >> %d)\n", pfrom.GetId(), pindexLast->nHeight, m_chainman.ActiveHeight());
2113-
if (nodestate->fSyncStarted) {
2114-
// Cancel sync from this node, so we don't penalize it later.
2115-
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
2116-
// if we still need to sync headers.
2117-
nSyncStarted--;
2118-
nodestate->fSyncStarted = false;
2119-
nodestate->m_headers_sync_timeout = 0us;
2120-
}
21212125
} else {
21222126
// TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or pindexBestHeader, continue
21232127
// from there instead.

0 commit comments

Comments
 (0)