fix(rpc): detect mid-session disconnects and stop blocking the UI thread
The connection state machine never tore down on a lost connection: refresh-loop RPC errors were swallowed, rpc_->isConnected() stayed true after a daemon crash/restart/socket drop, and the UI showed stale balances with no reconnect. Several operations also ran synchronous curl straight from ImGui handlers. - Add handleLostConnection(): after N consecutive cycles where BOTH core RPCs fail (warmup excluded, so no reconnect loop), disconnect so update()'s reconnect branch re-enters tryConnect(). - Move banPeer/unbanPeer/clearBans and key export/import onto the worker thread (import requests a rescan that could freeze the UI for the curl timeout). - Run the block-info dialog's two chained RPCs on the worker thread (+ guard the getblockhash result type). - Detect daemon warmup via the JSON-RPC -28 code (new RpcError carrying the code; message text preserved so 401/warmup string-matching is unaffected), and widen CONNECTTIMEOUT to 10s for remote/TLS hosts (2s localhost). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -574,6 +574,9 @@ private:
|
||||
bool encryption_state_prefetched_ = false; // suppress duplicate getwalletinfo on connect
|
||||
bool rescan_status_poll_in_progress_ = false;
|
||||
bool opid_poll_in_progress_ = false;
|
||||
// Consecutive Core-refresh cycles where BOTH core RPCs failed → likely a dead
|
||||
// connection. After kCoreFailuresBeforeDisconnect, tear down and reconnect.
|
||||
int consecutive_core_failures_ = 0;
|
||||
|
||||
// Pending z_sendmany operation tracking
|
||||
bool send_progress_active_ = false;
|
||||
@@ -692,6 +695,10 @@ private:
|
||||
void tryConnect();
|
||||
void onConnected();
|
||||
void onDisconnected(const std::string& reason);
|
||||
// Tear down a connection that died mid-session (daemon crash / restart / dropped
|
||||
// socket) so update()'s reconnect branch re-enters tryConnect(). Unlike onDisconnected
|
||||
// alone, this also rpc_->disconnect()s so rpc_->isConnected() actually flips to false.
|
||||
void handleLostConnection(const std::string& reason);
|
||||
void applyDefaultBanlist();
|
||||
|
||||
// Private methods - data refresh
|
||||
|
||||
Reference in New Issue
Block a user