diff --git a/client/Cargo.toml b/client/Cargo.toml index 7b55d406..05068acd 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -22,7 +22,9 @@ path = "src/lib.rs" bitcoincore-rpc-json = { version = "0.17.0", path = "../json" } log = "0.4.5" -jsonrpc = "0.14.0" +# jsonrpc = "0.14.0" +# jsonrpc = { path = "../../rust-jsonrpc" } +jsonrpc = { git = "https://github.com/chrisguida/rust-jsonrpc", branch = "feat/simple-http-timeout" } # Used for deserialization of JSON. serde = "1" diff --git a/client/src/client.rs b/client/src/client.rs index 47c648c6..c756698a 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -13,6 +13,7 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::iter::FromIterator; use std::path::PathBuf; +use std::time::Duration; use std::{fmt, result}; use crate::{bitcoin, deserialize_hex}; @@ -1255,12 +1256,34 @@ pub trait RpcApi: Sized { } } + fn scan_blocks_blocking( + &self, + request: json::ScanBlocksRequest, + ) -> Result<json::ScanBlocksResult> { + self.call( + "scanblocks", + &[ + "start".into(), + into_json(request.scanobjects)?, + into_json(request.start_height)?, + into_json(request.stop_height)?, + into_json(request.filtertype)?, + into_json(request.options)?, + ], + ) + } + + fn scan_blocks_status(&self) -> Result<Option<json::ScanBlocksStatusResult>> { + opt_result(self.call("scanblocks",&["status".into(),],)?) + } + fn scan_tx_out_set_blocking( &self, descriptors: &[json::ScanTxOutRequest], ) -> Result<json::ScanTxOutResult> { self.call("scantxoutset", &["start".into(), into_json(descriptors)?]) } + } /// Client implements a JSON-RPC client for the Bitcoin Core daemon or compatible APIs. @@ -1287,6 +1310,15 @@ impl Client { .map_err(|e| super::error::Error::JsonRpc(e.into())) } + pub fn new_with_timeout(url: &str, auth: Auth, timeout: Duration) -> Result<Self> { + let (user, pass) = auth.get_user_pass()?; + jsonrpc::client::Client::simple_http_with_timeout(url, user, pass, Some(timeout)) + .map(|client| Client { + client, + }) + .map_err(|e| super::error::Error::JsonRpc(e.into())) + } + /// Create a new Client using the given [jsonrpc::Client]. pub fn from_jsonrpc(client: jsonrpc::client::Client) -> Client { Client { diff --git a/json/src/lib.rs b/json/src/lib.rs index f6b13675..4926c53b 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -30,7 +30,7 @@ use bitcoin::block::Version; use bitcoin::consensus::encode; use bitcoin::hashes::hex::FromHex; use bitcoin::hashes::sha256; -use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network}; +use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network, BlockHash}; use serde::de::Error as SerdeError; use serde::{Deserialize, Serialize}; use std::fmt; @@ -2087,6 +2087,56 @@ pub enum PubKeyOrAddress<'a> { PubKey(&'a PublicKey), } +#[derive(Serialize, Clone, PartialEq, Eq, Debug)] +/// Start a scan of the block filter index for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md). +pub struct ScanBlocksRequest<'a> { + /// List of descriptors to scan + pub scanobjects: &'a [ScanBlocksRequestDescriptor], + /// Height at which to start scanning + pub start_height: Option<u64>, + /// Height at which to stop scanning + pub stop_height: Option<u64>, + /// Filter type. Only "basic" is supported for now. + pub filtertype: Option<String>, + /// Additional scan options. Only "filter_false_positives" is supported for now. + pub options: Option<ScanBlocksOptions>, +} + +#[derive(Serialize, Clone, PartialEq, Eq, Debug)] +/// Options struct for `scanblocks` rpc +pub struct ScanBlocksOptions { + /// Scan for a single descriptor + pub filter_false_positives: Option<bool>, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] +#[serde(untagged)] +/// Descriptors to scan in `scanblocks` rpc +pub enum ScanBlocksRequestDescriptor { + /// Scan for a single descriptor + Single(String), + /// Scan for a descriptor with xpubs + Extended { + /// Descriptor + desc: String, + /// Range of the xpub derivations to scan + range: Option<(u64, u64)>, + }, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] +pub struct ScanBlocksResult { + pub from_height: u64, + pub to_height: u64, + pub relevant_blocks: Vec<BlockHash>, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] +pub struct ScanBlocksStatusResult { + pub progress: Option<u64>, + pub current_height: Option<u64>, +} + #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] #[serde(untagged)] /// Start a scan of the UTXO set for an [output descriptor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).