Skip to content

Commit 3d0fca1

Browse files
committed
Merge bitcoin/bitcoin#26355: p2p: Handle IsContinuationOfLowWorkHeadersSync return value correctly when new headers sync is started
7ad15d1 [net processing] Handle IsContinuationOfLowWorkHeadersSync return value correctly when new headers sync is started (dergoegge) Pull request description: This PR fixes a bug in the headers sync logic that enables submitting headers to a nodes block index that don't lead to a chain that surpasses our DoS limit. The issue is that we ignore the return value on [the first `IsContinuationOfLowWorkHeadersSync` call after a new headers sync is started](https://github.com/bitcoin/bitcoin/blob/fabc0310480b49e159a15d494525c5aa15072cba/src/net_processing.cpp#L2553-L2568), which leads to us passing headers to [`ProcessNewBlockHeaders`](https://github.com/bitcoin/bitcoin/blob/fabc0310480b49e159a15d494525c5aa15072cba/src/net_processing.cpp#L2856) when that initial `IsContinuationOfLowWorkHeadersSync` call returns `false`. One easy way (maybe the only?) to trigger this is by sending 2000 headers where the last header has a different `nBits` value than the prior headers (which fails the pre-sync logic [here](https://github.com/bitcoin/bitcoin/blob/fabc0310480b49e159a15d494525c5aa15072cba/src/headerssync.cpp#L189)). Those 2000 headers will be passed to `ProcessNewBlockHeaders`. I haven't included a test here so far because we can't test this without changing the default value for `CRegTestParams::consensus.fPowAllowMinDifficultyBlocks` or doing some more involved refactoring. ACKs for top commit: sipa: ACK 7ad15d1 glozow: ACK 7ad15d1 Tree-SHA512: 9aabb8bf3700401e79863d0accda0befd2a83c4d469a53f97d827e51139e2f826aee08cdfbc8866b311b153f61fdac9b7aa515fcfa2a21c5e2812c2bf3c03664
2 parents 3db23fd + 7ad15d1 commit 3d0fca1

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/net_processing.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,14 +2565,22 @@ bool PeerManagerImpl::TryLowWorkHeadersSync(Peer& peer, CNode& pfrom, const CBlo
25652565

25662566
// Now a HeadersSyncState object for tracking this synchronization is created,
25672567
// process the headers using it as normal.
2568-
return IsContinuationOfLowWorkHeadersSync(peer, pfrom, headers);
2568+
if (!IsContinuationOfLowWorkHeadersSync(peer, pfrom, headers)) {
2569+
// Something went wrong, reset the headers sync.
2570+
peer.m_headers_sync.reset(nullptr);
2571+
LOCK(m_headers_presync_mutex);
2572+
m_headers_presync_stats.erase(peer.m_id);
2573+
}
25692574
} else {
25702575
LogPrint(BCLog::NET, "Ignoring low-work chain (height=%u) from peer=%d\n", chain_start_header->nHeight + headers.size(), pfrom.GetId());
2571-
// Since this is a low-work headers chain, no further processing is required.
2572-
headers = {};
2573-
return true;
25742576
}
2577+
2578+
// The peer has not yet given us a chain that meets our work threshold,
2579+
// so we want to prevent further processing of the headers in any case.
2580+
headers = {};
2581+
return true;
25752582
}
2583+
25762584
return false;
25772585
}
25782586

0 commit comments

Comments
 (0)