fix(wallet-switch): cluster B — daemon-switch robustness
From the wallet-switching audit: - Revert on failure (HIGH): switchToWallet persisted active_wallet_file before confirming the new daemon started, so a missing/corrupt wallet wedged across restarts. The switch worker now confirms dragonxd survives a grace period; on failure it flags the main thread (processWalletSwitchRevert), which restores the previous wallet file + re-scopes the vault + re-arms reconnect (settings writes stay on the main thread). - Cross-guard concurrent lifecycle ops (HIGH): switchToWallet now refuses during a rescan/repair (state_.sync.rescanning) or seed migration; rescan/repair now refuse while daemon_restarting_; and restartDaemonAfterEncryption now sets daemon_restarting_ (which also fixes a latent reconnect-to-a-stopped-daemon race during the encryption restart). So the switch/adopt/restart/rescan/repair/ encryption ops are mutually exclusive. - Quit during switch (MED): beginShutdown now joins the "Switch wallet" task (like the adopt task) so quitting can't orphan a freshly-started dragonxd. - Reset the daemon crash count on switch (LOW) so a prior crash-wedge can't block reconnecting to the new wallet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -475,6 +475,8 @@ public:
|
||||
// (rescan only if it was never synced in this datadir). Per-wallet data follows automatically
|
||||
// via the identity-scoped caches (P1). No-op if that wallet is already active.
|
||||
void switchToWallet(const std::string& walletFile);
|
||||
// Main-thread continuation: if a wallet switch's daemon failed to start, revert active_wallet_file.
|
||||
void processWalletSwitchRevert();
|
||||
|
||||
// Wallet encryption helpers
|
||||
void encryptWalletWithPassphrase(const std::string& passphrase);
|
||||
@@ -729,6 +731,13 @@ private:
|
||||
// Daemon restart (e.g. after changing debug log categories)
|
||||
std::atomic<bool> daemon_restarting_{false};
|
||||
|
||||
// Wallet-switch failure recovery: the switch worker sets wallet_switch_failed_ when the new
|
||||
// wallet's daemon won't start/stay up; the main loop then reverts active_wallet_file to
|
||||
// wallet_switch_prev_file_ (settings writes stay on the main thread) so a broken wallet isn't
|
||||
// persisted across restarts. daemon_restarting_ stays set until the revert re-arms the reconnect.
|
||||
std::atomic<bool> wallet_switch_failed_{false};
|
||||
std::string wallet_switch_prev_file_;
|
||||
|
||||
// Set by the deleteBlockchainData worker (item count); the main loop surfaces a completion toast
|
||||
// and resets it to -1. Atomic because the worker thread writes it and the UI thread reads/clears it.
|
||||
std::atomic<int> pending_delete_result_{-1};
|
||||
|
||||
Reference in New Issue
Block a user