From 59d07fab64f02849ef4b7686e32ca8d2a0c84362 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Thu, 22 Jan 2026 11:35:00 +0000 Subject: [PATCH] fix: Flush buffers before renaming cache file (#2927) If clio shuts itself down due to exceeding graceful period when cache is saved and renamed but the buffers are not flushed, we may end up with a corrupted cache file. Clio will detect corruption and will not load corrupted cache file, but we could avoid it by explicitly flushing ofstream buffer. --- src/data/impl/LedgerCacheFile.cpp | 5 +++++ src/data/impl/OutputFile.cpp | 11 +++++++++++ src/data/impl/OutputFile.hpp | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/src/data/impl/LedgerCacheFile.cpp b/src/data/impl/LedgerCacheFile.cpp index 34f7b71d..a171e791 100644 --- a/src/data/impl/LedgerCacheFile.cpp +++ b/src/data/impl/LedgerCacheFile.cpp @@ -115,6 +115,11 @@ LedgerCacheFile::write(DataView dataView) auto const hash = file.hash(); file.write(hash.data(), decltype(hash)::bytes); + // flush internal buffer explicitly before renaming + if (auto const expectedSuccess = file.close(); not expectedSuccess.has_value()) { + return expectedSuccess; + } + try { std::filesystem::rename(newFilePath, path_); } catch (std::exception const& e) { diff --git a/src/data/impl/OutputFile.cpp b/src/data/impl/OutputFile.cpp index e7837979..5228133a 100644 --- a/src/data/impl/OutputFile.cpp +++ b/src/data/impl/OutputFile.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -59,4 +60,14 @@ OutputFile::hash() const return std::move(sum).finalize(); } +std::expected +OutputFile::close() +{ + file_.close(); + if (not file_) { + return std::unexpected{"Error closing cache file"}; + } + return {}; +} + } // namespace data::impl diff --git a/src/data/impl/OutputFile.hpp b/src/data/impl/OutputFile.hpp index f0e0c94f..480b85e3 100644 --- a/src/data/impl/OutputFile.hpp +++ b/src/data/impl/OutputFile.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -60,6 +61,9 @@ public: ripple::uint256 hash() const; + std::expected + close(); + private: void writeToFile(char const* data, size_t size);