validation: In AcceptBlock, ignore flush result
What changed, and why it matters
This change fixes a subtle bug in how Bitcoin Core reports disk flush errors during block acceptance. Previously, if writing block data to disk failed (for example, because the disk was full during pruning), the error could be misreported to callers as 'this block is invalid.' That could trick other parts of the program or external logic into permanently rejecting a perfectly valid block. Now the disk-flush error is handled separately, and the node still shuts down safely on serious disk problems. The fix is defensive and prevents a non-validation failure from being misclassified as a consensus failure.
Treat as a low-to-moderate severity hardening fix. Review whether any downstream callers of AcceptBlock rely on state after flush errors, and ensure the internal fatal-error notification reliably shuts down the node on unrecoverable disk errors. No emergency deployment is indicated, but include in normal release cycle.
Security signals we found
Error-state confusion between disk flush and block validation
Potential for valid blocks to be rejected due to misattributed flush failures
Defensive hardening of error propagation in consensus-critical code path
No change to consensus rules or block validity logic
Evidence from the diff
In ChainstateManager::AcceptBlock, the code previously called ActiveChainstate().FlushStateToDisk(state, FlushStateMode::NONE) using the same BlockValidationState object that carried the block validation result. Because FlushStateToDisk can set state errors (e.g., out-of-disk during pruning), a caller inspecting ‘state’ could interpret a flush failure as a block validation failure. The patch introduces a separate BlockValidationState flush_state_ignore, ignores its return value, and lets FlushStateToDisk’s internal fatal-error path (AbortNode) handle unrecoverable errors. This is a correctness fix in error propagation, not a consensus change.
Changed components
src/validation.cppChainstateManager::AcceptBlockFlushStateToDisk error handlingInspect captured patch +8 / −1
diff --git a/src/validation.cpp b/src/validation.cpp
index 87cf646b..5341c604 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -4398,7 +4398,14 @@ bool ChainstateManager::AcceptBlock(const std::shared_ptr<const CBlock>& pblock,
// the block files may be pruned, so we can just call this on one
// chainstate (particularly if we haven't implemented pruning with
// background validation yet).
- ActiveChainstate().FlushStateToDisk(state, FlushStateMode::NONE);
+ //
+ // Flush errors (e.g. low disk space during pruning) are ignored, so that
+ // callers can't mistreat a flush failure as a block validation failure.
+ // The fatal error notification inside FlushStateToDisk still fires,
+ // so the node will shut down on unrecoverable flush errors regardless.
+ // For state a dummy value is used, and the return value is ignored.
+ BlockValidationState flush_state_ignore;
+ (void)ActiveChainstate().FlushStateToDisk(flush_state_ignore, FlushStateMode::NONE);
CheckBlockIndex();
Why this scored 57/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.