From 2bce4c525d51b8ecbc923a43632ef8a724426453 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 17:15:05 +0100 Subject: [PATCH] Cargo: bump jsonrpc version to 0.17 It now finally accepts an option as argument. --- Cargo.lock | 4 +-- Cargo.toml | 2 +- src/bitcoin/d/mod.rs | 80 +++++++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2934881e..02b8fc58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,9 +235,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jsonrpc" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efde8d2422fb79ed56db1d3aea8fa5b583351d15a26770cdee2f88813dd702" +checksum = "a26d9104d516092f092d97448787505881fdb6518293b2d6500bf9c180c839dd" dependencies = [ "base64", "minreq", diff --git a/Cargo.toml b/Cargo.toml index 1b56beed..cd63dd83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ backtrace = "0.3" rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] } # To talk to bitcoind -jsonrpc = { version = "0.16", features = ["minreq_http"], default-features = false } +jsonrpc = { version = "0.17", features = ["minreq_http"], default-features = false } # Used for daemonization libc = { version = "0.2", optional = true } diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index e356f3e8..41e7fe1e 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -213,11 +213,12 @@ pub struct BitcoinD { macro_rules! params { ($($param:expr),* $(,)?) => { - [ + // FIXME: is there a way to avoid the allocation of an unnecessary Box? + Some(&*arg(Json::Array(vec![ $( - arg($param), + $param, )* - ] + ]))) }; } @@ -312,7 +313,7 @@ impl BitcoinD { } fn check_client(&self, client: &Client) -> Result<(), BitcoindError> { - if let Err(e) = self.make_request(client, "echo", &[]) { + if let Err(e) = self.make_request(client, "echo", None) { if e.is_warming_up() { log::info!("bitcoind is warming up. Retrying connection sanity check in 1 second."); thread::sleep(Duration::from_secs(1)); @@ -388,7 +389,7 @@ impl BitcoinD { &self, client: &Client, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, retry: bool, ) -> Result { let req = client.build_request(method, params); @@ -403,7 +404,7 @@ impl BitcoinD { &self, client: &Client, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request_inner(client, method, params, true) } @@ -413,7 +414,7 @@ impl BitcoinD { fn make_noreply_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result<(), BitcoindError> { match self.make_request_inner(&self.sendonly_client, method, params, false) { Ok(_) => Ok(()), @@ -431,12 +432,16 @@ impl BitcoinD { fn make_fallible_node_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request(&self.node_client, method, params) } - fn make_node_request(&self, method: &str, params: &[Box]) -> Json { + fn make_node_request( + &self, + method: &str, + params: Option<&serde_json::value::RawValue>, + ) -> Json { self.make_request(&self.node_client, method, params) .expect("We must not fail to make a request for more than a minute") } @@ -444,7 +449,7 @@ impl BitcoinD { fn make_wallet_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Json { self.make_request(&self.watchonly_client, method, params) .expect("We must not fail to make a request for more than a minute") @@ -453,20 +458,20 @@ impl BitcoinD { fn make_faillible_wallet_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request(&self.watchonly_client, method, params) } fn get_bitcoind_version(&self) -> u64 { - self.make_node_request("getnetworkinfo", &[]) + self.make_node_request("getnetworkinfo", None) .get("version") .and_then(Json::as_u64) .expect("Missing or invalid 'version' in 'getnetworkinfo' result?") } fn get_network_bip70(&self) -> String { - self.make_node_request("getblockchaininfo", &[]) + self.make_node_request("getblockchaininfo", None) .get("chain") .and_then(Json::as_str) .expect("Missing or invalid 'chain' in 'getblockchaininfo' result?") @@ -474,7 +479,7 @@ impl BitcoinD { } fn list_wallets(&self) -> Vec { - self.make_node_request("listwallets", &[]) + self.make_node_request("listwallets", None) .as_array() .expect("API break, 'listwallets' didn't return an array.") .iter() @@ -517,7 +522,7 @@ impl BitcoinD { } fn unload_wallet(&self, wallet_path: String) -> Option { - let res = self.make_node_request("unloadwallet", ¶ms!(Json::String(wallet_path),)); + let res = self.make_node_request("unloadwallet", params!(Json::String(wallet_path),)); self.warning_from_res(&res) } @@ -527,7 +532,7 @@ impl BitcoinD { let res = self .make_fallible_node_request( "createwallet", - ¶ms!( + params!( Json::String(wallet_path), Json::Bool(true), // watchonly Json::Bool(true), // blank @@ -562,7 +567,7 @@ impl BitcoinD { }) .collect(); - let res = self.make_wallet_request("importdescriptors", ¶ms!(Json::Array(descriptors))); + let res = self.make_wallet_request("importdescriptors", params!(Json::Array(descriptors))); let all_succeeded = res .as_array() .map(|results| { @@ -579,7 +584,7 @@ impl BitcoinD { } fn list_descriptors(&self) -> Vec { - self.make_wallet_request("listdescriptors", &[]) + self.make_wallet_request("listdescriptors", None) .get("descriptors") .and_then(Json::as_array) .expect("Missing or invalid 'descriptors' field in 'listdescriptors' response") @@ -660,7 +665,7 @@ impl BitcoinD { } let res = self.make_fallible_node_request( "loadwallet", - ¶ms!(Json::String(self.watchonly_wallet_path.clone()),), + params!(Json::String(self.watchonly_wallet_path.clone()),), ); match res { Err(BitcoindError::Server(jsonrpc::Error::Rpc(ref e))) => { @@ -753,7 +758,7 @@ impl BitcoinD { } fn block_chain_info(&self) -> Json { - self.make_node_request("getblockchaininfo", &[]) + self.make_node_request("getblockchaininfo", None) } pub fn sync_progress(&self) -> SyncProgress { @@ -800,7 +805,7 @@ impl BitcoinD { pub fn get_block_hash(&self, height: i32) -> Option { Some( - self.make_fallible_node_request("getblockhash", ¶ms!(Json::Number(height.into()),)) + self.make_fallible_node_request("getblockhash", params!(Json::Number(height.into()),)) .ok()? .as_str() .and_then(|s| bitcoin::BlockHash::from_str(s).ok()) @@ -811,7 +816,7 @@ impl BitcoinD { pub fn list_since_block(&self, block_hash: &bitcoin::BlockHash) -> LSBlockRes { self.make_wallet_request( "listsinceblock", - ¶ms!( + params!( Json::String(block_hash.to_string()), Json::Number(1.into()), // Default for min_confirmations for the returned Json::Bool(true), // Whether to include watchonly @@ -826,7 +831,7 @@ impl BitcoinD { // TODO: Maybe assert we got a -5 error, and not any other kind of error? self.make_faillible_wallet_request( "gettransaction", - ¶ms!(Json::String(txid.to_string())), + params!(Json::String(txid.to_string())), ) .ok() .map(|res| res.into()) @@ -837,7 +842,7 @@ impl BitcoinD { // The result of gettxout is empty if the outpoint is spent. self.make_node_request( "gettxout", - ¶ms!( + params!( Json::String(op.txid.to_string()), Json::Number(op.vout.into()) ), @@ -857,7 +862,7 @@ impl BitcoinD { // unconfirmed, just use the tip. let req = self.make_wallet_request( "gettransaction", - ¶ms!(Json::String(spent_outpoint.txid.to_string())), + params!(Json::String(spent_outpoint.txid.to_string())), ); let list_since_height = match req.get("blockheight").and_then(Json::as_i64) { Some(h) => h as i32, @@ -865,7 +870,7 @@ impl BitcoinD { }; let block_hash = if let Ok(res) = self.make_fallible_node_request( "getblockhash", - ¶ms!(Json::Number((list_since_height - 1).into())), + params!(Json::Number((list_since_height - 1).into())), ) { res.as_str() .expect("'getblockhash' result isn't a string") @@ -880,7 +885,7 @@ impl BitcoinD { // TODO: merge this with the existing list_since_block method. let lsb_res = self.make_wallet_request( "listsinceblock", - ¶ms!( + params!( Json::String(block_hash), Json::Number(1.into()), // Default for min_confirmations for the returned Json::Bool(true), // Whether to include watchonly @@ -915,7 +920,7 @@ impl BitcoinD { let gettx_res = self.make_wallet_request( "gettransaction", - ¶ms!( + params!( Json::String(spending_txid.to_string()), Json::Bool(true), // watchonly Json::Bool(true) // verbose @@ -968,7 +973,7 @@ impl BitcoinD { pub fn get_block_stats(&self, blockhash: bitcoin::BlockHash) -> Option { let res = match self.make_fallible_node_request( "getblockheader", - ¶ms!(Json::String(blockhash.to_string()),), + params!(Json::String(blockhash.to_string()),), ) { Ok(res) => res, Err(e) => { @@ -1016,7 +1021,7 @@ impl BitcoinD { pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> { self.make_fallible_node_request( "sendrawtransaction", - ¶ms!(bitcoin::consensus::encode::serialize_hex(tx)), + params!(bitcoin::consensus::encode::serialize_hex(tx).into()), )?; Ok(()) } @@ -1084,10 +1089,9 @@ impl BitcoinD { const NUM_RETRIES: usize = 10; let mut i = 0; loop { - if let Err(e) = self.make_noreply_request( - "importdescriptors", - ¶ms!(Json::Array(desc_json.clone())), - ) { + if let Err(e) = self + .make_noreply_request("importdescriptors", params!(Json::Array(desc_json.clone()))) + { log::error!( "Error when calling 'importdescriptors' for rescanning: {}", e @@ -1108,7 +1112,7 @@ impl BitcoinD { /// Get the progress of the ongoing rescan, if there is any. pub fn rescan_progress(&self) -> Option { - self.make_wallet_request("getwalletinfo", &[]) + self.make_wallet_request("getwalletinfo", None) .get("scanning") // If no rescan is ongoing, it will fail cause it would be 'false' .and_then(Json::as_object) @@ -1135,7 +1139,7 @@ impl BitcoinD { /// Returns `None` if it is not in the mempool. pub fn mempool_entry(&self, txid: &bitcoin::Txid) -> Option { match self - .make_fallible_node_request("getmempoolentry", ¶ms!(Json::String(txid.to_string()))) + .make_fallible_node_request("getmempoolentry", params!(Json::String(txid.to_string()))) { Ok(json) => Some(MempoolEntry::from(json)), Err(BitcoindError::Server(jsonrpc::Error::Rpc(jsonrpc::error::RpcError { @@ -1157,7 +1161,7 @@ impl BitcoinD { .iter() .map(|op| serde_json::json!({"txid": op.txid.to_string(), "vout": op.vout})) .collect(); - self.make_node_request("gettxspendingprevout", ¶ms!(prevouts)) + self.make_node_request("gettxspendingprevout", params!(prevouts)) .as_array() .expect("Always returns an array") .iter() @@ -1173,7 +1177,7 @@ impl BitcoinD { /// Stop bitcoind. pub fn stop(&self) { - self.make_node_request("stop", &[]); + self.make_node_request("stop", None); } }