Skip to content
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
6 changes: 4 additions & 2 deletions crates/bitcoind_rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ workspace = true

[dependencies]
bitcoin = { version = "0.32.0", default-features = false }
bitcoincore-rpc = { version = "0.19.0" }
bdk-bitcoind-client = { git = "https://github.com/bitcoindevkit/bdk-bitcoind-client", rev = "06526db5c25047b61d29f81b25cfee7bd0f3abc8"}
bdk_core = { path = "../core", version = "0.6.1", default-features = false }

[dev-dependencies]
Expand All @@ -26,9 +26,11 @@ bdk_testenv = { path = "../testenv" }
bdk_chain = { path = "../chain" }

[features]
default = ["std"]
default = ["std", "bitcoind_28_0"]
std = ["bitcoin/std", "bdk_core/std"]
serde = ["bitcoin/serde", "bdk_core/serde"]
# select the version to use
bitcoind_28_0 = ["bdk-bitcoind-client/28_0"]

[[example]]
name = "filter_iter"
Expand Down
4 changes: 2 additions & 2 deletions crates/bitcoind_rpc/examples/filter_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::time::Instant;

use anyhow::Context;
use bdk_bitcoind_client::{Auth, Client};
use bdk_bitcoind_rpc::bip158::{Event, FilterIter};
use bdk_chain::bitcoin::{constants::genesis_block, secp256k1::Secp256k1, Network};
use bdk_chain::indexer::keychain_txout::KeychainTxOutIndex;
Expand Down Expand Up @@ -44,8 +45,7 @@ fn main() -> anyhow::Result<()> {
// Configure RPC client
let url = std::env::var("RPC_URL").context("must set RPC_URL")?;
let cookie = std::env::var("RPC_COOKIE").context("must set RPC_COOKIE")?;
let rpc_client =
bitcoincore_rpc::Client::new(&url, bitcoincore_rpc::Auth::CookieFile(cookie.into()))?;
let rpc_client = Client::with_auth(&url, Auth::CookieFile(cookie.into()))?;

// Initialize `FilterIter`
let mut spks = vec![];
Expand Down
42 changes: 22 additions & 20 deletions crates/bitcoind_rpc/src/bip158.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
//! [0]: https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki
//! [1]: https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki

use bdk_bitcoind_client::corepc_types::model::GetBlockHeaderVerbose;
use bdk_bitcoind_client::Client;
use bdk_core::bitcoin;
use bdk_core::CheckPoint;
use bitcoin::BlockHash;
use bitcoin::{bip158::BlockFilter, Block, ScriptBuf};
use bitcoincore_rpc;
use bitcoincore_rpc::{json::GetBlockHeaderResult, RpcApi};

/// Type that returns Bitcoin blocks by matching a list of script pubkeys (SPKs) against a
/// [`bip158::BlockFilter`](bitcoin::bip158::BlockFilter).
///
/// * `FilterIter` talks to bitcoind via JSON-RPC interface, which is handled by the
/// [`bitcoincore_rpc::Client`].
/// [`bdk_bitcoind_client::Client`].
/// * Collect the script pubkeys (SPKs) you want to watch. These will usually correspond to wallet
/// addresses that have been handed out for receiving payments.
/// * Construct `FilterIter` with the RPC client, SPKs, and [`CheckPoint`]. The checkpoint tip
Expand All @@ -31,19 +31,19 @@ use bitcoincore_rpc::{json::GetBlockHeaderResult, RpcApi};
#[derive(Debug)]
pub struct FilterIter<'a> {
/// RPC client
client: &'a bitcoincore_rpc::Client,
client: &'a Client,
/// SPK inventory
spks: Vec<ScriptBuf>,
/// checkpoint
cp: CheckPoint<BlockHash>,
/// Header info, contains the prev and next hashes for each header.
header: Option<GetBlockHeaderResult>,
header: Option<GetBlockHeaderVerbose>,
}

impl<'a> FilterIter<'a> {
/// Construct [`FilterIter`] with checkpoint, RPC client and SPKs.
pub fn new(
client: &'a bitcoincore_rpc::Client,
client: &'a Client,
cp: CheckPoint,
spks: impl IntoIterator<Item = ScriptBuf>,
) -> Self {
Expand All @@ -58,9 +58,9 @@ impl<'a> FilterIter<'a> {
/// Return the agreement header with the remote node.
///
/// Error if no agreement header is found.
fn find_base(&self) -> Result<GetBlockHeaderResult, Error> {
fn find_base(&self) -> Result<GetBlockHeaderVerbose, Error> {
for cp in self.cp.iter() {
match self.client.get_block_header_info(&cp.hash()) {
match self.client.get_block_header_verbose(&cp.hash()) {
Err(e) if is_not_found(&e) => continue,
Ok(header) if header.confirmations <= 0 => continue,
Ok(header) => return Ok(header),
Expand Down Expand Up @@ -111,20 +111,20 @@ impl Iterator for FilterIter<'_> {
None => return Ok(None),
};

let mut next_header = self.client.get_block_header_info(&next_hash)?;
let mut next_header = self.client.get_block_header_verbose(&next_hash)?;

// In case of a reorg, rewind by fetching headers of previous hashes until we find
// one with enough confirmations.
while next_header.confirmations < 0 {
let prev_hash = next_header
.previous_block_hash
.ok_or(Error::ReorgDepthExceeded)?;
let prev_header = self.client.get_block_header_info(&prev_hash)?;
let prev_header = self.client.get_block_header_verbose(&prev_hash)?;
next_header = prev_header;
}

next_hash = next_header.hash;
let next_height: u32 = next_header.height.try_into()?;
let next_height: u32 = next_header.height;

cp = cp.insert(next_height, next_hash);

Expand Down Expand Up @@ -153,7 +153,7 @@ impl Iterator for FilterIter<'_> {
#[derive(Debug)]
pub enum Error {
/// RPC error
Rpc(bitcoincore_rpc::Error),
Rpc(bdk_bitcoind_client::Error),
/// `bitcoin::bip158` error
Bip158(bitcoin::bip158::Error),
/// Max reorg depth exceeded.
Expand All @@ -176,8 +176,8 @@ impl core::fmt::Display for Error {
#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl From<bitcoincore_rpc::Error> for Error {
fn from(e: bitcoincore_rpc::Error) -> Self {
impl From<bdk_bitcoind_client::Error> for Error {
fn from(e: bdk_bitcoind_client::Error) -> Self {
Self::Rpc(e)
}
}
Expand All @@ -189,10 +189,12 @@ impl From<core::num::TryFromIntError> for Error {
}

/// Whether the RPC error is a "not found" error (code: `-5`).
fn is_not_found(e: &bitcoincore_rpc::Error) -> bool {
matches!(
e,
bitcoincore_rpc::Error::JsonRpc(bitcoincore_rpc::jsonrpc::Error::Rpc(e))
if e.code == -5
)
fn is_not_found(e: &bdk_bitcoind_client::Error) -> bool {
if let bdk_bitcoind_client::Error::JsonRpc(bdk_bitcoind_client::jsonrpc::Error::Rpc(rpc_err)) =
e
{
rpc_err.code == -5
} else {
false
}
}
Loading