Merge bitcoin/bitcoin#33553: validation: Improve warnings in case of chain corruption

4b47113698 validation: Reword CheckForkWarningConditions and call it also during IBD and at startup (Martin Zumsande)
2f51951d03 p2p: Add warning message when receiving headers for blocks cached as invalid (Martin Zumsande)

Pull request description:

  In case of corruption that leads to a block being marked as invalid that is seen as valid by the rest of the network, the user currently doesn't receive good error messages, but will often be stuck in an endless headers-sync loop with no explanation (#26391).

  This PR improves warnings in two ways:
  - When we receive a header that is already saved in our disk, but invalid, add a warning. This will happen repeatedly during the headerssync loop (see https://github.com/bitcoin/bitcoin/issues/26391#issuecomment-1291765534 on how to trigger it artificially).
  - Removes the IBD check from `CheckForkWarningConditions` and adds a call to the function during init (`LoadChainTip()`). The existing check was added in 55ed3f1475 a long time ago when we had more sophisticated fork detection that could lead to false positives during IBD, but that  logic was removed in fa62304c97 so that I don't see a reason to suppress the warning anymore.

  Fixes #26391 (We'll still do the endless looping, trying to find a peer with a headers that we can use, but will now repeatedly log warnings while doing so).

ACKs for top commit:
  glozow:
    ACK `git range-diff 6d2c8ea9dbd77c71051935b5ab59224487509559...4b4711369880369729893ba7baef11ba2a36cf4b`
  theStack:
    re-ACK 4b47113698
  sedited:
    ACK 4b47113698

Tree-SHA512: 78bc53606374636d616ee10fdce0324adcc9bcee2806a7e13c9471e4c02ef00925ce6daef303bc153b7fcf5a8528fb4263c875b71d2e965f7c4332304bc4d922
This commit is contained in:
merge-script
2025-12-09 08:25:17 -08:00
3 changed files with 15 additions and 9 deletions

View File

@@ -2955,6 +2955,13 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
state, &pindexLast)};
if (!processed) {
if (state.IsInvalid()) {
if (!pfrom.IsInboundConn() && state.GetResult() == BlockValidationResult::BLOCK_CACHED_INVALID) {
// Warn user if outgoing peers send us headers of blocks that we previously marked as invalid.
LogWarning("%s (received from peer=%i). "
"If this happens with all peers, consider database corruption (that -reindex may fix) "
"or a potential consensus incompatibility.",
state.GetDebugMessage(), pfrom.GetId());
}
MaybePunishNodeForBlock(pfrom.GetId(), state, via_compact_block, "invalid header received");
return;
}