The goal of this PR is to establish that fatal blockstorage flush errors should be treated as errors at their call site.
Prior to this patch FlushBlockFile
may have failed without returning in Chainstate::FlushStateToDisk
, leading to a potential write from WriteBlockIndexDB
that may refer to a block that is not fully flushed to disk yet. By returning if either FlushUndoFile
or FlushBlockFile
fail, we ensure that no further write operations take place that may lead to an inconsistent database when crashing. Add [[nodiscard]]
annotations to them such that they are not ignored in future.
Functions that call either FlushUndoFile
or FlushBlockFile
, need to handle these extra abort cases properly. Since Chainstate::FlushStateToDisk
already produces an abort error in case of WriteBlockIndexDB
failing, no extra logic for functions calling Chainstate::FlushStateToDisk
is required.
Besides Chainstate::FlushStateToDisk
, FlushBlockFile
is also called by FindBlockPos
, while FlushUndoFile
is only called by FlushBlockFile
and WriteUndoDataForBlock
. For both these cases, the flush error is not further bubbled up. Instead, the error is logged and a comment is provided why bubbling up an error would be less desirable in these cases.
This pull request is part of a larger effort towards improving the shutdown / abort / fatal error handling in validation code. It is a first step towards implementing proper fatal error return type enforcement similar as proposed by theuni in this pull request comment. For ease of review of these critical changes, a first step would be checking that AbortNode
leads to early and error-conveying returns at its call site. Further work for enforcing returns when AbortNode
is called is done in #27862.