refactor(audit): batch 8 — share the post-encrypt daemon-restart block
Extract App::restartDaemonAfterEncryption(taskName, announceRestartStatus) from the two verbatim copies in encryptWalletWithPassphrase and processDeferredEncryption. The two differed only in the async task name and whether they set connection_status_ = "restarting_after_encryption" first (the immediate encrypt path does; the deferred path does not) — both parameterized. The 20x100ms settle loop, cancel/shutdown guards, and stop/startEmbeddedDaemon sequence are preserved exactly. Deliberately NOT done: the audit's "decrypt 5-deep callback pyramid" finding. On inspection the nesting is load-bearing, not gratuitous — WalletSecurityWorkflow is unsynchronized main-thread-only state, and each step's worker->MainCb bounce is what keeps its mutations on the main thread (the UI reads snapshot()/importActive() every frame); collapsing the pipeline onto one worker/async task would race the UI, and the final restart+import stage requires an AsyncTaskManager::Token that worker_->post can't supply. Left byte-for-byte intact. Full-node + Lite build clean; ctest 1/1 (incl. WalletSecurity controller tests); hygiene clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -395,6 +395,12 @@ public:
|
|||||||
|
|
||||||
// Wallet encryption helpers
|
// Wallet encryption helpers
|
||||||
void encryptWalletWithPassphrase(const std::string& passphrase);
|
void encryptWalletWithPassphrase(const std::string& passphrase);
|
||||||
|
// Post-encrypt daemon restart: the daemon shuts itself down after
|
||||||
|
// encryptwallet, so restart it off the main thread. Shared by the
|
||||||
|
// immediate and deferred encryption continuations. When
|
||||||
|
// announceRestartStatus is true, connection_status_ is updated first so
|
||||||
|
// the loading overlay explains the restart.
|
||||||
|
void restartDaemonAfterEncryption(const char* taskName, bool announceRestartStatus);
|
||||||
void unlockWallet(const std::string& passphrase, int timeout);
|
void unlockWallet(const std::string& passphrase, int timeout);
|
||||||
void lockWallet();
|
void lockWallet();
|
||||||
void changePassphrase(const std::string& oldPass, const std::string& newPass);
|
void changePassphrase(const std::string& oldPass, const std::string& newPass);
|
||||||
|
|||||||
@@ -230,6 +230,34 @@ private:
|
|||||||
// Wallet encryption helpers
|
// Wallet encryption helpers
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
|
// The daemon shuts itself down after encryptwallet. Restart the embedded
|
||||||
|
// daemon off the main thread (to avoid stalling the UI), or ask the user to
|
||||||
|
// restart an external daemon. Shared by encryptWalletWithPassphrase() and
|
||||||
|
// processDeferredEncryption(); must be called on the main thread.
|
||||||
|
void App::restartDaemonAfterEncryption(const char* taskName, bool announceRestartStatus) {
|
||||||
|
if (isUsingEmbeddedDaemon()) {
|
||||||
|
if (announceRestartStatus) {
|
||||||
|
// Update connection_status_ so the loading overlay explains why
|
||||||
|
// the daemon is restarting.
|
||||||
|
connection_status_ = TR("restarting_after_encryption");
|
||||||
|
}
|
||||||
|
// Give daemon a moment to shut down, then restart
|
||||||
|
// (do this off the main thread to avoid stalling the UI)
|
||||||
|
async_tasks_.submit(taskName, [this](const util::AsyncTaskManager::Token& token) {
|
||||||
|
for (int i = 0; i < 20 && !token.cancelled() && !shutting_down_; ++i)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
if (token.cancelled() || shutting_down_) return;
|
||||||
|
stopEmbeddedDaemon();
|
||||||
|
if (token.cancelled() || shutting_down_) return;
|
||||||
|
startEmbeddedDaemon();
|
||||||
|
// tryConnect will be called by the update loop
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui::Notifications::instance().warning(
|
||||||
|
"Please restart your daemon for encryption to take effect.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void App::encryptWalletWithPassphrase(const std::string& passphrase) {
|
void App::encryptWalletWithPassphrase(const std::string& passphrase) {
|
||||||
if (!rpc_ || !rpc_->isConnected()) return;
|
if (!rpc_ || !rpc_->isConnected()) return;
|
||||||
encrypt_in_progress_ = true;
|
encrypt_in_progress_ = true;
|
||||||
@@ -267,23 +295,8 @@ void App::encryptWalletWithPassphrase(const std::string& passphrase) {
|
|||||||
// The daemon shuts itself down after encryptwallet.
|
// The daemon shuts itself down after encryptwallet.
|
||||||
// Update connection_status_ so the loading overlay
|
// Update connection_status_ so the loading overlay
|
||||||
// explains why the daemon is restarting.
|
// explains why the daemon is restarting.
|
||||||
if (isUsingEmbeddedDaemon()) {
|
restartDaemonAfterEncryption("encrypt-daemon-restart",
|
||||||
connection_status_ = TR("restarting_after_encryption");
|
/*announceRestartStatus=*/true);
|
||||||
// Give daemon a moment to shut down, then restart
|
|
||||||
// (do this off the main thread to avoid stalling the UI)
|
|
||||||
async_tasks_.submit("encrypt-daemon-restart", [this](const util::AsyncTaskManager::Token& token) {
|
|
||||||
for (int i = 0; i < 20 && !token.cancelled() && !shutting_down_; ++i)
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
if (token.cancelled() || shutting_down_) return;
|
|
||||||
stopEmbeddedDaemon();
|
|
||||||
if (token.cancelled() || shutting_down_) return;
|
|
||||||
startEmbeddedDaemon();
|
|
||||||
// tryConnect will be called by the update loop
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ui::Notifications::instance().warning(
|
|
||||||
"Please restart your daemon for encryption to take effect.");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
std::string err = result.error;
|
std::string err = result.error;
|
||||||
@@ -366,20 +379,8 @@ void App::processDeferredEncryption() {
|
|||||||
wallet_security_.clearDeferredEncryption();
|
wallet_security_.clearDeferredEncryption();
|
||||||
|
|
||||||
// Restart daemon (it shuts itself down after encryptwallet)
|
// Restart daemon (it shuts itself down after encryptwallet)
|
||||||
if (isUsingEmbeddedDaemon()) {
|
restartDaemonAfterEncryption("deferred-encrypt-daemon-restart",
|
||||||
async_tasks_.submit("deferred-encrypt-daemon-restart", [this](const util::AsyncTaskManager::Token& token) {
|
/*announceRestartStatus=*/false);
|
||||||
for (int i = 0; i < 20 && !token.cancelled() && !shutting_down_; ++i)
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
if (token.cancelled() || shutting_down_) return;
|
|
||||||
stopEmbeddedDaemon();
|
|
||||||
if (token.cancelled() || shutting_down_) return;
|
|
||||||
startEmbeddedDaemon();
|
|
||||||
// tryConnect will be called by the update loop
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ui::Notifications::instance().warning(
|
|
||||||
"Please restart your daemon for encryption to take effect.");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
std::string err = result.error;
|
std::string err = result.error;
|
||||||
|
|||||||
Reference in New Issue
Block a user