feat(fullnode): manage the daemon binary in Settings; stop auto-overwriting it
Previously the wallet re-extracted the bundled dragonxd on startup whenever the
installed binary's size differed from the bundle ("stale" overwrite), which could
replace a node a user had deliberately placed in dragonx/.
Now dragonx binaries (dragonxd/cli/tx) are auto-placed ONLY when missing — never
auto-overwritten on a size mismatch (needsParamsExtraction + extractEmbeddedResources).
Params/asmap keep their size-based refresh; a daemon dropped next to the wallet exe
still takes priority and is never touched.
Replacing the daemon is now an explicit action: Settings → "Daemon binary" reports the
installed binary's version (scanned from the file), size and modified date, compares it
to the version bundled in this build, and offers an "Install bundled daemon" button.
That stops the node, overwrites dragonxd/cli/tx with the bundled copies (waiting for the
process to release the file lock), and restarts — wallet/keys/chain data untouched.
Adds resources::{getInstalledDaemonInfo,getBundledDaemonInfo,reextractBundledDaemon}
(+ a version-string scanner) and App::reinstallBundledDaemon().
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
39
src/app.cpp
39
src/app.cpp
@@ -3035,6 +3035,45 @@ void App::repairWallet()
|
||||
});
|
||||
}
|
||||
|
||||
void App::reinstallBundledDaemon()
|
||||
{
|
||||
if (!supportsFullNodeLifecycleActions()) {
|
||||
ui::Notifications::instance().warning("Full-node lifecycle actions are unavailable in lite build");
|
||||
return;
|
||||
}
|
||||
if (!resources::getBundledDaemonInfo().available) {
|
||||
ui::Notifications::instance().warning("This build has no bundled daemon to install");
|
||||
return;
|
||||
}
|
||||
if (!daemon_controller_ || !isUsingEmbeddedDaemon()) {
|
||||
ui::Notifications::instance().warning("Reinstalling the daemon requires the embedded daemon");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOGF("[App] Reinstalling bundled daemon binary — stopping daemon first\n");
|
||||
ui::Notifications::instance().info("Installing bundled daemon — the node will stop, update, and restart...");
|
||||
|
||||
async_tasks_.submit("reinstall-daemon", [this](const util::AsyncTaskManager::Token& token) {
|
||||
AppDaemonLifecycleRuntime runtime(*this);
|
||||
daemon::AsyncLifecycleTaskContext ctx(token, shutting_down_);
|
||||
// Stop the daemon so its binary is no longer locked (Windows) / in use (ETXTBSY on Linux).
|
||||
runtime.stopDaemonWithPolicy();
|
||||
// Wait (bounded, ~12s) for the process to exit and release the binary before overwriting.
|
||||
for (int i = 0; i < 120 && daemon::EmbeddedDaemon::isRpcPortInUse()
|
||||
&& !ctx.cancelled() && !ctx.shuttingDown(); ++i) {
|
||||
ctx.sleepForMs(100);
|
||||
}
|
||||
// Overwrite the installed dragonx binaries (dragonxd/cli/tx) with the bundled ones.
|
||||
const bool ok = resources::reextractBundledDaemon();
|
||||
DEBUG_LOGF("[App] Reinstall bundled daemon: %s\n", ok ? "ok" : "FAILED");
|
||||
// Restart on the freshly-installed binary.
|
||||
runtime.resetOutputOffset();
|
||||
if (!ctx.cancelled() && !ctx.shuttingDown()) {
|
||||
runtime.startDaemon();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void App::deleteBlockchainData()
|
||||
{
|
||||
if (!supportsFullNodeLifecycleActions()) {
|
||||
|
||||
Reference in New Issue
Block a user