From dc45e7d904b5f8b28eae0f0e230af24f59126030 Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 7 Jul 2026 08:08:34 +0200 Subject: [PATCH] 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) --- src/main.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 3f79c13eb..5dc93c611 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6890,7 +6890,15 @@ void static ProcessGetData(CNode* pfrom) CBlock block; 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 {