Cargo: bump jsonrpc version to 0.17

It now finally accepts an option as argument.
This commit is contained in:
Antoine Poinsot 2024-01-03 17:15:05 +01:00
parent 65c9e389bb
commit 2bce4c525d
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
3 changed files with 45 additions and 41 deletions

4
Cargo.lock generated
View File

@ -235,9 +235,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "jsonrpc" name = "jsonrpc"
version = "0.16.0" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34efde8d2422fb79ed56db1d3aea8fa5b583351d15a26770cdee2f88813dd702" checksum = "a26d9104d516092f092d97448787505881fdb6518293b2d6500bf9c180c839dd"
dependencies = [ dependencies = [
"base64", "base64",
"minreq", "minreq",

View File

@ -53,7 +53,7 @@ backtrace = "0.3"
rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] } rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] }
# To talk to bitcoind # 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 # Used for daemonization
libc = { version = "0.2", optional = true } libc = { version = "0.2", optional = true }

View File

@ -213,11 +213,12 @@ pub struct BitcoinD {
macro_rules! params { macro_rules! params {
($($param:expr),* $(,)?) => { ($($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> { 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() { if e.is_warming_up() {
log::info!("bitcoind is warming up. Retrying connection sanity check in 1 second."); log::info!("bitcoind is warming up. Retrying connection sanity check in 1 second.");
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
@ -388,7 +389,7 @@ impl BitcoinD {
&self, &self,
client: &Client, client: &Client,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
retry: bool, retry: bool,
) -> Result<Json, BitcoindError> { ) -> Result<Json, BitcoindError> {
let req = client.build_request(method, params); let req = client.build_request(method, params);
@ -403,7 +404,7 @@ impl BitcoinD {
&self, &self,
client: &Client, client: &Client,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> { ) -> Result<Json, BitcoindError> {
self.make_request_inner(client, method, params, true) self.make_request_inner(client, method, params, true)
} }
@ -413,7 +414,7 @@ impl BitcoinD {
fn make_noreply_request( fn make_noreply_request(
&self, &self,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
) -> Result<(), BitcoindError> { ) -> Result<(), BitcoindError> {
match self.make_request_inner(&self.sendonly_client, method, params, false) { match self.make_request_inner(&self.sendonly_client, method, params, false) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
@ -431,12 +432,16 @@ impl BitcoinD {
fn make_fallible_node_request( fn make_fallible_node_request(
&self, &self,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> { ) -> Result<Json, BitcoindError> {
self.make_request(&self.node_client, method, params) self.make_request(&self.node_client, method, params)
} }
fn make_node_request(&self, method: &str, params: &[Box<serde_json::value::RawValue>]) -> Json { fn make_node_request(
&self,
method: &str,
params: Option<&serde_json::value::RawValue>,
) -> Json {
self.make_request(&self.node_client, method, params) self.make_request(&self.node_client, method, params)
.expect("We must not fail to make a request for more than a minute") .expect("We must not fail to make a request for more than a minute")
} }
@ -444,7 +449,7 @@ impl BitcoinD {
fn make_wallet_request( fn make_wallet_request(
&self, &self,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
) -> Json { ) -> Json {
self.make_request(&self.watchonly_client, method, params) self.make_request(&self.watchonly_client, method, params)
.expect("We must not fail to make a request for more than a minute") .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( fn make_faillible_wallet_request(
&self, &self,
method: &str, method: &str,
params: &[Box<serde_json::value::RawValue>], params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> { ) -> Result<Json, BitcoindError> {
self.make_request(&self.watchonly_client, method, params) self.make_request(&self.watchonly_client, method, params)
} }
fn get_bitcoind_version(&self) -> u64 { fn get_bitcoind_version(&self) -> u64 {
self.make_node_request("getnetworkinfo", &[]) self.make_node_request("getnetworkinfo", None)
.get("version") .get("version")
.and_then(Json::as_u64) .and_then(Json::as_u64)
.expect("Missing or invalid 'version' in 'getnetworkinfo' result?") .expect("Missing or invalid 'version' in 'getnetworkinfo' result?")
} }
fn get_network_bip70(&self) -> String { fn get_network_bip70(&self) -> String {
self.make_node_request("getblockchaininfo", &[]) self.make_node_request("getblockchaininfo", None)
.get("chain") .get("chain")
.and_then(Json::as_str) .and_then(Json::as_str)
.expect("Missing or invalid 'chain' in 'getblockchaininfo' result?") .expect("Missing or invalid 'chain' in 'getblockchaininfo' result?")
@ -474,7 +479,7 @@ impl BitcoinD {
} }
fn list_wallets(&self) -> Vec<String> { fn list_wallets(&self) -> Vec<String> {
self.make_node_request("listwallets", &[]) self.make_node_request("listwallets", None)
.as_array() .as_array()
.expect("API break, 'listwallets' didn't return an array.") .expect("API break, 'listwallets' didn't return an array.")
.iter() .iter()
@ -517,7 +522,7 @@ impl BitcoinD {
} }
fn unload_wallet(&self, wallet_path: String) -> Option<String> { fn unload_wallet(&self, wallet_path: String) -> Option<String> {
let res = self.make_node_request("unloadwallet", &params!(Json::String(wallet_path),)); let res = self.make_node_request("unloadwallet", params!(Json::String(wallet_path),));
self.warning_from_res(&res) self.warning_from_res(&res)
} }
@ -527,7 +532,7 @@ impl BitcoinD {
let res = self let res = self
.make_fallible_node_request( .make_fallible_node_request(
"createwallet", "createwallet",
&params!( params!(
Json::String(wallet_path), Json::String(wallet_path),
Json::Bool(true), // watchonly Json::Bool(true), // watchonly
Json::Bool(true), // blank Json::Bool(true), // blank
@ -562,7 +567,7 @@ impl BitcoinD {
}) })
.collect(); .collect();
let res = self.make_wallet_request("importdescriptors", &params!(Json::Array(descriptors))); let res = self.make_wallet_request("importdescriptors", params!(Json::Array(descriptors)));
let all_succeeded = res let all_succeeded = res
.as_array() .as_array()
.map(|results| { .map(|results| {
@ -579,7 +584,7 @@ impl BitcoinD {
} }
fn list_descriptors(&self) -> Vec<ListDescEntry> { fn list_descriptors(&self) -> Vec<ListDescEntry> {
self.make_wallet_request("listdescriptors", &[]) self.make_wallet_request("listdescriptors", None)
.get("descriptors") .get("descriptors")
.and_then(Json::as_array) .and_then(Json::as_array)
.expect("Missing or invalid 'descriptors' field in 'listdescriptors' response") .expect("Missing or invalid 'descriptors' field in 'listdescriptors' response")
@ -660,7 +665,7 @@ impl BitcoinD {
} }
let res = self.make_fallible_node_request( let res = self.make_fallible_node_request(
"loadwallet", "loadwallet",
&params!(Json::String(self.watchonly_wallet_path.clone()),), params!(Json::String(self.watchonly_wallet_path.clone()),),
); );
match res { match res {
Err(BitcoindError::Server(jsonrpc::Error::Rpc(ref e))) => { Err(BitcoindError::Server(jsonrpc::Error::Rpc(ref e))) => {
@ -753,7 +758,7 @@ impl BitcoinD {
} }
fn block_chain_info(&self) -> Json { fn block_chain_info(&self) -> Json {
self.make_node_request("getblockchaininfo", &[]) self.make_node_request("getblockchaininfo", None)
} }
pub fn sync_progress(&self) -> SyncProgress { pub fn sync_progress(&self) -> SyncProgress {
@ -800,7 +805,7 @@ impl BitcoinD {
pub fn get_block_hash(&self, height: i32) -> Option<bitcoin::BlockHash> { pub fn get_block_hash(&self, height: i32) -> Option<bitcoin::BlockHash> {
Some( Some(
self.make_fallible_node_request("getblockhash", &params!(Json::Number(height.into()),)) self.make_fallible_node_request("getblockhash", params!(Json::Number(height.into()),))
.ok()? .ok()?
.as_str() .as_str()
.and_then(|s| bitcoin::BlockHash::from_str(s).ok()) .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 { pub fn list_since_block(&self, block_hash: &bitcoin::BlockHash) -> LSBlockRes {
self.make_wallet_request( self.make_wallet_request(
"listsinceblock", "listsinceblock",
&params!( params!(
Json::String(block_hash.to_string()), Json::String(block_hash.to_string()),
Json::Number(1.into()), // Default for min_confirmations for the returned Json::Number(1.into()), // Default for min_confirmations for the returned
Json::Bool(true), // Whether to include watchonly 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? // TODO: Maybe assert we got a -5 error, and not any other kind of error?
self.make_faillible_wallet_request( self.make_faillible_wallet_request(
"gettransaction", "gettransaction",
&params!(Json::String(txid.to_string())), params!(Json::String(txid.to_string())),
) )
.ok() .ok()
.map(|res| res.into()) .map(|res| res.into())
@ -837,7 +842,7 @@ impl BitcoinD {
// The result of gettxout is empty if the outpoint is spent. // The result of gettxout is empty if the outpoint is spent.
self.make_node_request( self.make_node_request(
"gettxout", "gettxout",
&params!( params!(
Json::String(op.txid.to_string()), Json::String(op.txid.to_string()),
Json::Number(op.vout.into()) Json::Number(op.vout.into())
), ),
@ -857,7 +862,7 @@ impl BitcoinD {
// unconfirmed, just use the tip. // unconfirmed, just use the tip.
let req = self.make_wallet_request( let req = self.make_wallet_request(
"gettransaction", "gettransaction",
&params!(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) { let list_since_height = match req.get("blockheight").and_then(Json::as_i64) {
Some(h) => h as i32, Some(h) => h as i32,
@ -865,7 +870,7 @@ impl BitcoinD {
}; };
let block_hash = if let Ok(res) = self.make_fallible_node_request( let block_hash = if let Ok(res) = self.make_fallible_node_request(
"getblockhash", "getblockhash",
&params!(Json::Number((list_since_height - 1).into())), params!(Json::Number((list_since_height - 1).into())),
) { ) {
res.as_str() res.as_str()
.expect("'getblockhash' result isn't a string") .expect("'getblockhash' result isn't a string")
@ -880,7 +885,7 @@ impl BitcoinD {
// TODO: merge this with the existing list_since_block method. // TODO: merge this with the existing list_since_block method.
let lsb_res = self.make_wallet_request( let lsb_res = self.make_wallet_request(
"listsinceblock", "listsinceblock",
&params!( params!(
Json::String(block_hash), Json::String(block_hash),
Json::Number(1.into()), // Default for min_confirmations for the returned Json::Number(1.into()), // Default for min_confirmations for the returned
Json::Bool(true), // Whether to include watchonly Json::Bool(true), // Whether to include watchonly
@ -915,7 +920,7 @@ impl BitcoinD {
let gettx_res = self.make_wallet_request( let gettx_res = self.make_wallet_request(
"gettransaction", "gettransaction",
&params!( params!(
Json::String(spending_txid.to_string()), Json::String(spending_txid.to_string()),
Json::Bool(true), // watchonly Json::Bool(true), // watchonly
Json::Bool(true) // verbose Json::Bool(true) // verbose
@ -968,7 +973,7 @@ impl BitcoinD {
pub fn get_block_stats(&self, blockhash: bitcoin::BlockHash) -> Option<BlockStats> { pub fn get_block_stats(&self, blockhash: bitcoin::BlockHash) -> Option<BlockStats> {
let res = match self.make_fallible_node_request( let res = match self.make_fallible_node_request(
"getblockheader", "getblockheader",
&params!(Json::String(blockhash.to_string()),), params!(Json::String(blockhash.to_string()),),
) { ) {
Ok(res) => res, Ok(res) => res,
Err(e) => { Err(e) => {
@ -1016,7 +1021,7 @@ impl BitcoinD {
pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> { pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> {
self.make_fallible_node_request( self.make_fallible_node_request(
"sendrawtransaction", "sendrawtransaction",
&params!(bitcoin::consensus::encode::serialize_hex(tx)), params!(bitcoin::consensus::encode::serialize_hex(tx).into()),
)?; )?;
Ok(()) Ok(())
} }
@ -1084,10 +1089,9 @@ impl BitcoinD {
const NUM_RETRIES: usize = 10; const NUM_RETRIES: usize = 10;
let mut i = 0; let mut i = 0;
loop { loop {
if let Err(e) = self.make_noreply_request( if let Err(e) = self
"importdescriptors", .make_noreply_request("importdescriptors", params!(Json::Array(desc_json.clone())))
&params!(Json::Array(desc_json.clone())), {
) {
log::error!( log::error!(
"Error when calling 'importdescriptors' for rescanning: {}", "Error when calling 'importdescriptors' for rescanning: {}",
e e
@ -1108,7 +1112,7 @@ impl BitcoinD {
/// Get the progress of the ongoing rescan, if there is any. /// Get the progress of the ongoing rescan, if there is any.
pub fn rescan_progress(&self) -> Option<f64> { pub fn rescan_progress(&self) -> Option<f64> {
self.make_wallet_request("getwalletinfo", &[]) self.make_wallet_request("getwalletinfo", None)
.get("scanning") .get("scanning")
// If no rescan is ongoing, it will fail cause it would be 'false' // If no rescan is ongoing, it will fail cause it would be 'false'
.and_then(Json::as_object) .and_then(Json::as_object)
@ -1135,7 +1139,7 @@ impl BitcoinD {
/// Returns `None` if it is not in the mempool. /// Returns `None` if it is not in the mempool.
pub fn mempool_entry(&self, txid: &bitcoin::Txid) -> Option<MempoolEntry> { pub fn mempool_entry(&self, txid: &bitcoin::Txid) -> Option<MempoolEntry> {
match self match self
.make_fallible_node_request("getmempoolentry", &params!(Json::String(txid.to_string()))) .make_fallible_node_request("getmempoolentry", params!(Json::String(txid.to_string())))
{ {
Ok(json) => Some(MempoolEntry::from(json)), Ok(json) => Some(MempoolEntry::from(json)),
Err(BitcoindError::Server(jsonrpc::Error::Rpc(jsonrpc::error::RpcError { Err(BitcoindError::Server(jsonrpc::Error::Rpc(jsonrpc::error::RpcError {
@ -1157,7 +1161,7 @@ impl BitcoinD {
.iter() .iter()
.map(|op| serde_json::json!({"txid": op.txid.to_string(), "vout": op.vout})) .map(|op| serde_json::json!({"txid": op.txid.to_string(), "vout": op.vout}))
.collect(); .collect();
self.make_node_request("gettxspendingprevout", &params!(prevouts)) self.make_node_request("gettxspendingprevout", params!(prevouts))
.as_array() .as_array()
.expect("Always returns an array") .expect("Always returns an array")
.iter() .iter()
@ -1173,7 +1177,7 @@ impl BitcoinD {
/// Stop bitcoind. /// Stop bitcoind.
pub fn stop(&self) { pub fn stop(&self) {
self.make_node_request("stop", &[]); self.make_node_request("stop", None);
} }
} }