From 3a82c3a81d2c6f6a726395a8a2fbab462466f3e6 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 12 May 2023 10:57:23 +0200 Subject: [PATCH 1/2] bitcoind: do not assert presence of 'warning' field in unloadwallet response --- src/bitcoin/d/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index 4bd6e0c9..1a45b1ab 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -449,8 +449,7 @@ impl BitcoinD { pub fn unload_wallet(&self, wallet_path: String) -> Option { self.make_node_request("unloadwallet", ¶ms!(Json::String(wallet_path),)) .get("warning") - .expect("No 'warning' in 'unloadwallet' response?") - .as_str() + .and_then(Json::as_str) .and_then(|w| { if w.is_empty() { None From 0f07361d9b6a9d118360607479ef9f7e5d9278e1 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 12 May 2023 11:27:46 +0200 Subject: [PATCH 2/2] bitcoind: adapt the warning detection with interface breakage in v25 --- src/bitcoin/d/mod.rs | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index 1a45b1ab..e3ef8b3d 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -446,17 +446,38 @@ impl BitcoinD { .collect() } - pub fn unload_wallet(&self, wallet_path: String) -> Option { - self.make_node_request("unloadwallet", ¶ms!(Json::String(wallet_path),)) - .get("warning") - .and_then(Json::as_str) - .and_then(|w| { - if w.is_empty() { - None - } else { - Some(w.to_string()) + // Get a warning from the result of a wallet command. It was modified in v25 so it's a bit + // messy... + fn warning_from_res(&self, res: &Json) -> Option { + // In v24, it's a "warning" field. + if let Some(warning) = res.get("warning").and_then(Json::as_str) { + if !warning.is_empty() { + return Some(warning.to_string()); + } + } + + // In v25 it becomes a "warnings" field... + if let Some(warnings) = res.get("warnings").and_then(Json::as_array) { + // FIXME: don't drop the other warnings if there are more than one. + let first_actual_warning = warnings.iter().find_map(|w| { + if let Some(w) = w.as_str() { + if !w.is_empty() { + return Some(w); + } } - }) + None + }); + if let Some(warning) = first_actual_warning { + return Some(warning.to_string()); + } + } + + None + } + + pub fn unload_wallet(&self, wallet_path: String) -> Option { + let res = self.make_node_request("unloadwallet", ¶ms!(Json::String(wallet_path),)); + self.warning_from_res(&res) } fn create_wallet(&self, wallet_path: String) -> Result<(), String> { @@ -471,10 +492,8 @@ impl BitcoinD { ) .map_err(|e| e.to_string())?; - if let Some(warning) = res.get("warning").and_then(Json::as_str) { - if !warning.is_empty() { - return Err(warning.to_string()); - } + if let Some(warning) = self.warning_from_res(&res) { + return Err(warning); } if res.get("name").is_none() { return Err("Unknown error when create watchonly wallet".to_string());