Skip to content

add scanblocks call #317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
32 changes: 32 additions & 0 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand Down
52 changes: 51 additions & 1 deletion json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe scanobjects can be a Vec<ScanBlocksRequestDescriptor> (since ScanBlocksRequestDescriptor already owns its descriptor), then we could do away with the lifetime 'a.

Can possibly also derive Default for this whole struct.

Copy link
Author

@chrisguida chrisguida Jan 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty much just copied this from another json array example in the file

pub pubkeys: &'a [PublicKey],

Is this giving you issues and did you test it your way? I seem to remember testing it with a Vec and having issues.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to make a PR into my branch with how you're doing it I'm happy to merge it into my branch

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, no issue. I think I tried it both ways.

/// 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).
Expand Down