Harden ProcessGetData: log+disconnect instead of asserting on block-read failure

The legacy getdata block-serving path asserted whenever ReadBlockFromDisk failed for a block we had advertised (BLOCK_HAVE_DATA). A single transient I/O error or on-disk corruption, triggerable by any peer getdata, crashed the whole node (observed once during bulk-serve load testing on 176). Now log the failure and disconnect that peer so it can re-fetch from another node, matching the bulk GETBLOCKSTREAM serve path which already fails gracefully. Build-verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-07 08:08:34 +02:00
parent 1ed468e040
commit dc45e7d904

View File

@@ -6890,7 +6890,15 @@ void static ProcessGetData(CNode* pfrom)
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, (*mi).second,1)) if (!ReadBlockFromDisk(block, (*mi).second,1))
{ {
assert(!"cannot load block from disk"); // A block we advertised (BLOCK_HAVE_DATA) failed to load from disk: a transient
// I/O error or on-disk corruption. This previously asserted and crashed the whole
// node -- any peer getdata for such a block could take us down. Log and drop this
// peer instead; it can re-fetch from another node. (The bulk GETBLOCKSTREAM serve
// path already fails gracefully rather than asserting.)
LogPrintf("%s: ReadBlockFromDisk failed for block %s (peer=%i);"
" disconnecting peer instead of asserting\n",
__func__, inv.hash.ToString(), pfrom->GetId());
pfrom->fDisconnect = true;
} }
else else
{ {