From 89bd21018a55a59fdd56ac3f60b2536b1f88c740 Mon Sep 17 00:00:00 2001 From: DanS Date: Fri, 5 Jun 2026 16:11:58 -0500 Subject: [PATCH] fix(lite): don't run the full-node RPC loop in lite; drive isConnected() from the wallet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Runtime monitoring of ObsidianDragonLite (WSLg) showed the full-node RPC connect state machine running in the lite build — `tryConnect()` fired every ~5s and failed ("Couldn't connect to server / no daemon"). It's called unconditionally from the main loop with no lite guard. Worse than noise: `state_.connected` (App::isConnected()) was therefore ALWAYS false in lite, and it gates the wallet UI — receive_tab disables the new-address button + shows "not connected", send_tab disables send, transactions_tab shows not-connected. So the M3/M4 GUI wiring was effectively unreachable: a lite user could never generate an address or send, even with an open, synced wallet. Fix: - tryConnect() no-ops in lite builds (isLiteBuild()), so no RPC attempts. - App::update() derives state_.connected from lite_wallet_->walletOpen() each frame — a non-blocking proxy for "lite backend operational" (a wallet opens only after a successful backend init against the lite server). This enables the wallet UI once a wallet is open. Full-node is unaffected (both branches are runtime-gated: isLiteBuild() is false and lite_wallet_ is null there). Verified by re-running the app: RPC connection attempts dropped from 7/30s to 0; clean launch (GL 4.2) + clean shutdown; tests pass. Co-Authored-By: Claude Opus 4.8 --- src/app.cpp | 6 ++++++ src/app_network.cpp | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app.cpp b/src/app.cpp index d8bcaa5..7552aeb 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -403,6 +403,12 @@ void App::update() // Apply any lite-wallet refresh the controller's background worker produced (main thread). if (lite_wallet_) { + // Lite has no RPC daemon (tryConnect() is a no-op in lite builds), so derive the app's + // "online" state — which gates the wallet UI via isConnected() — from the lite wallet. + // A wallet is open only after a successful backend init against the lite server, so this + // is a non-blocking proxy for "lite backend operational". + state_.connected = lite_wallet_->walletOpen(); + wallet::LiteWalletAppRefreshModel liteModel; if (lite_wallet_->takeRefreshedModel(liteModel)) { wallet::applyLiteRefreshModelToWalletState(liteModel, state_); diff --git a/src/app_network.cpp b/src/app_network.cpp index 60ed328..8330535 100644 --- a/src/app_network.cpp +++ b/src/app_network.cpp @@ -164,8 +164,13 @@ static WarmupText translateWarmup(const std::string& raw) void App::tryConnect() { + // Lite builds have no full node / RPC daemon, so never run the RPC connection state machine + // (it would just fail every tick). The lite controller drives the wallet; "online" status is + // derived from it each frame in App::update(), which also gates the wallet UI (isConnected()). + if (isLiteBuild()) return; + if (connection_in_progress_) return; - + static int connect_attempt = 0; ++connect_attempt;