From a868d0c61a652d7a4167b4d18686e9a1c448e75c Mon Sep 17 00:00:00 2001 From: feafel Date: Mon, 12 Oct 2026 18:20:50 +0700 Subject: [PATCH] fix(thread): answer commands with missing/unknown wallet id instead of 500 When the wallet id was absent or unknown, the loop logged and continued without answering the oneshot, so send_cmd reported 'wallet thread is dead' (HTTP 500) - indistinguishable from a dead server and an invitation to retry-storm. Reply InvalidFingerprint (HTTP 400, the id is the master fingerprint) on every variant via an exhaustive helper. --- src/wallet/wallet_thread.rs | 107 ++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/wallet/wallet_thread.rs b/src/wallet/wallet_thread.rs index 41c98ae..031ab78 100644 --- a/src/wallet/wallet_thread.rs +++ b/src/wallet/wallet_thread.rs @@ -302,6 +302,7 @@ impl WalletThread { Some(id) => id, None => { log::error!("Command {} requires a wallet ID", cmd); + respond_wallet_missing(cmd); continue; } }; @@ -311,6 +312,7 @@ impl WalletThread { handle_wallet_cmd(wallet_state, id.clone(), cmd); } else { log::warn!("Wallet not found: {id}"); + respond_wallet_missing(cmd); } } } @@ -318,6 +320,111 @@ impl WalletThread { } } +/// Answer a command whose wallet id is missing or unknown instead of dropping +/// the response: otherwise the caller's oneshot closes and `send_cmd` reports +/// "wallet thread is dead" (HTTP 500), indistinguishable from a dead server +/// and an invitation to retry-storm. The wallet id is the master fingerprint, +/// so an unknown one is reported as an invalid fingerprint (HTTP 400). +fn respond_wallet_missing(cmd: WalletCmd) { + let err = rgb_lib::Error::InvalidFingerprint; + match cmd { + WalletCmd::Refresh {} => {} + WalletCmd::RefreshWallet { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::DropWallet { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Stop { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::WalletInfo { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Backup { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Address { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Assets { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Transfers { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::FailTransfer { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::TransfersByAsset { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::TransfersByRecipient { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Transactions { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::ListUnspends { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::AssetInfo { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::BtcBalance { resp } => { + let _ = resp.send(Err(err)); + } + WalletCmd::TokenBalance { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::Receive { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::IssueNiaToken { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::IssueIfaToken { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::InflateBegin { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::InflateEnd { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::CreateUtxoBegin { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::CreateUtxoEnd { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::SendBegin { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::SendEnd { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::BurnBegin { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::BurnEnd { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::GetConsignment { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::SendBtcBegin { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::SendBtcEnd { resp, .. } => { + let _ = resp.send(Err(err)); + } + WalletCmd::AddReadOnlyWallet { resp, .. } => { + let _ = resp.send(Err(err)); + } + } +} + fn handle_wallet_cmd(wallet_state: Arc>, id: String, cmd: WalletCmd) { log::debug!("handle cmd: wid={}, cmd={}", id, cmd); match cmd {