fix(lite): flush the wallet save on quit before _Exit
On quit the lite controller's destructor never runs, because main() ends the process with _Exit(). Any state the background refresh had scanned since the last save was lost: the destructor is where that final save would normally happen, and it was being skipped on the one path that always runs. - shutdown() now calls a new flushOnExit() that persists once on the way out, bounded to 4 s so the existing 15 s shutdown watchdog budget still holds. On timeout it abandons the save thread and lets _Exit follow. - It is a plain save through the same backend path, which writes a temp file and renames it into place. That cannot corrupt the wallet if it is cut off or abandoned, and it does not change the wallet file format - it only persists sooner on the quit path. - It reuses the destructor's guards and also skips when a wallet op is already in progress: shutdown() has already waited for ops to go idle, and a still-pending op holds the sync lock and issues its own save, so flushOnExit would only block the budget on a save that cannot take the lock. Tests cover a save on the open, synced, idle path (exactly once), a blocked save returning within the budget, and the retired and never-opened guards skipping the save. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7742,6 +7742,9 @@ void App::shutdown()
|
||||
// Lite: let an in-flight wallet op (e.g. Encrypt's save) finish. Bounded: the window is already hidden and
|
||||
// main.cpp has a 15 s watchdog. The backend writes tmp + rename, so being cut off never corrupts the wallet.
|
||||
if (lite_wallet_) lite_wallet_->waitWalletOpsIdle(std::chrono::milliseconds(2500));
|
||||
// Persist refresh-scanned state: ~LiteWalletController never runs on the _Exit path. Bounded (4 s) so the
|
||||
// 15 s watchdog budget holds; the save is tmp + rename, so an abandoned/cut-off save never corrupts.
|
||||
if (lite_wallet_) lite_wallet_->flushOnExit(std::chrono::milliseconds(4000));
|
||||
|
||||
// Full node: persist whatever a refresh changed since beginShutdown() (everything, on the direct-exit path),
|
||||
// then drain + join the history writer. Bounded like the settings flush: on a wedged disk the in-flight write
|
||||
|
||||
Reference in New Issue
Block a user