diff --git a/crates/chain/src/lib.rs b/crates/chain/src/lib.rs index ed167ebf6c..7bd118b54b 100644 --- a/crates/chain/src/lib.rs +++ b/crates/chain/src/lib.rs @@ -1,4 +1,4 @@ -//! This crate is a collection of core structures for [Bitcoin Dev Kit] (alpha release). +//! This crate is a collection of core structures for [Bitcoin Dev Kit]. //! //! The goal of this crate is to give wallets the mechanisms needed to: //! diff --git a/crates/esplora/src/async_ext.rs b/crates/esplora/src/async_ext.rs index b41050533e..2d0ae24aaf 100644 --- a/crates/esplora/src/async_ext.rs +++ b/crates/esplora/src/async_ext.rs @@ -36,7 +36,7 @@ pub trait EsploraAsyncExt { request_heights: impl IntoIterator + Send> + Send, ) -> Result; - /// Scan Esplora for the data specified and return a [`TxGraph`] and a map of last active + /// Full scan Esplora for the data specified and return a [`TxGraph`] and a map of last active /// indices. /// /// * `keychain_spks`: keychains that we want to scan transactions for @@ -48,7 +48,7 @@ pub trait EsploraAsyncExt { /// transactions. `parallel_requests` specifies the max number of HTTP requests to make in /// parallel. #[allow(clippy::result_large_err)] - async fn scan_txs_with_keychains( + async fn full_scan( &self, keychain_spks: BTreeMap< K, @@ -60,18 +60,18 @@ pub trait EsploraAsyncExt { parallel_requests: usize, ) -> Result<(TxGraph, BTreeMap), Error>; - /// Convenience method to call [`scan_txs_with_keychains`] without requiring a keychain. + /// Convenience method to call [`full_scan`] without requiring a keychain. /// - /// [`scan_txs_with_keychains`]: EsploraAsyncExt::scan_txs_with_keychains + /// [`full_scan`]: EsploraAsyncExt::full_scan #[allow(clippy::result_large_err)] - async fn scan_txs( + async fn sync( &self, misc_spks: impl IntoIterator + Send> + Send, txids: impl IntoIterator + Send> + Send, outpoints: impl IntoIterator + Send> + Send, parallel_requests: usize, ) -> Result, Error> { - self.scan_txs_with_keychains( + self.full_scan( [( (), misc_spks @@ -199,7 +199,7 @@ impl EsploraAsyncExt for esplora_client::AsyncClient { }) } - async fn scan_txs_with_keychains( + async fn full_scan( &self, keychain_spks: BTreeMap< K, diff --git a/crates/esplora/src/blocking_ext.rs b/crates/esplora/src/blocking_ext.rs index bde24f832b..718213feb1 100644 --- a/crates/esplora/src/blocking_ext.rs +++ b/crates/esplora/src/blocking_ext.rs @@ -34,7 +34,7 @@ pub trait EsploraExt { request_heights: impl IntoIterator, ) -> Result; - /// Scan Esplora for the data specified and return a [`TxGraph`] and a map of last active + /// Full scan Esplora for the data specified and return a [`TxGraph`] and a map of last active /// indices. /// /// * `keychain_spks`: keychains that we want to scan transactions for @@ -46,7 +46,7 @@ pub trait EsploraExt { /// transactions. `parallel_requests` specifies the max number of HTTP requests to make in /// parallel. #[allow(clippy::result_large_err)] - fn scan_txs_with_keychains( + fn full_scan( &self, keychain_spks: BTreeMap>, txids: impl IntoIterator, @@ -55,18 +55,18 @@ pub trait EsploraExt { parallel_requests: usize, ) -> Result<(TxGraph, BTreeMap), Error>; - /// Convenience method to call [`scan_txs_with_keychains`] without requiring a keychain. + /// Convenience method to call [`full_scan`] without requiring a keychain. /// - /// [`scan_txs_with_keychains`]: EsploraExt::scan_txs_with_keychains + /// [`full_scan`]: EsploraExt::full_scan #[allow(clippy::result_large_err)] - fn scan_txs( + fn sync( &self, misc_spks: impl IntoIterator, txids: impl IntoIterator, outpoints: impl IntoIterator, parallel_requests: usize, ) -> Result, Error> { - self.scan_txs_with_keychains( + self.full_scan( [( (), misc_spks @@ -190,7 +190,7 @@ impl EsploraExt for esplora_client::BlockingClient { }) } - fn scan_txs_with_keychains( + fn full_scan( &self, keychain_spks: BTreeMap>, txids: impl IntoIterator, diff --git a/crates/esplora/src/lib.rs b/crates/esplora/src/lib.rs index e8c6672779..727c8c53b2 100644 --- a/crates/esplora/src/lib.rs +++ b/crates/esplora/src/lib.rs @@ -1,4 +1,21 @@ #![doc = include_str!("../README.md")] + +//! This crate is used for updating structures of [`bdk_chain`] with data from an Esplora server. +//! +//! The two primary methods are [`EsploraExt::sync`] and [`EsploraExt::full_scan`]. In most cases +//! [`EsploraExt::sync`] is used to sync the transaction histories of scripts that the application +//! cares about, for example the scripts for all the receive addresses of a Wallet's keychain that it +//! has shown a user. [`EsploraExt::full_scan`] is meant to be used when importing or restoring a +//! keychain where the range of possibly used scripts is not known. In this case it is necessary to +//! scan all keychain scripts until a number (the "stop gap") of unused scripts is discovered. For a +//! sync or full scan the user receives relevant blockchain data and output updates for [`bdk_chain`] +//! via a new [`TxGraph`] to be appended to any existing [`TxGraph`] data. +//! +//! Refer to [`example_esplora`] for a complete example. +//! +//! [`TxGraph`]: bdk_chain::tx_graph::TxGraph +//! [`example_esplora`]: https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_esplora + use bdk_chain::{BlockId, ConfirmationTimeHeightAnchor}; use esplora_client::TxStatus; diff --git a/crates/esplora/tests/async_ext.rs b/crates/esplora/tests/async_ext.rs index 38833f588e..2a5d4f09b5 100644 --- a/crates/esplora/tests/async_ext.rs +++ b/crates/esplora/tests/async_ext.rs @@ -101,7 +101,7 @@ pub async fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> { let graph_update = env .client - .scan_txs( + .sync( misc_spks.into_iter(), vec![].into_iter(), vec![].into_iter(), @@ -168,7 +168,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> { // will. let (graph_update, active_indices) = env .client - .scan_txs_with_keychains( + .full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -180,7 +180,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> { assert!(active_indices.is_empty()); let (graph_update, active_indices) = env .client - .scan_txs_with_keychains( + .full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -211,7 +211,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> { // The last active indice won't be updated in the first case but will in the second one. let (graph_update, active_indices) = env .client - .scan_txs_with_keychains( + .full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -225,7 +225,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> { assert_eq!(active_indices[&0], 3); let (graph_update, active_indices) = env .client - .scan_txs_with_keychains(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1) + .full_scan(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1) .await?; let txs: HashSet<_> = graph_update.full_txs().map(|tx| tx.txid).collect(); assert_eq!(txs.len(), 2); diff --git a/crates/esplora/tests/blocking_ext.rs b/crates/esplora/tests/blocking_ext.rs index 5a76172325..4ee894ca8c 100644 --- a/crates/esplora/tests/blocking_ext.rs +++ b/crates/esplora/tests/blocking_ext.rs @@ -99,7 +99,7 @@ pub fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> { sleep(Duration::from_millis(10)) } - let graph_update = env.client.scan_txs( + let graph_update = env.client.sync( misc_spks.into_iter(), vec![].into_iter(), vec![].into_iter(), @@ -164,7 +164,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> { // A scan with a gap limit of 2 won't find the transaction, but a scan with a gap limit of 3 // will. - let (graph_update, active_indices) = env.client.scan_txs_with_keychains( + let (graph_update, active_indices) = env.client.full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -173,7 +173,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> { )?; assert!(graph_update.full_txs().next().is_none()); assert!(active_indices.is_empty()); - let (graph_update, active_indices) = env.client.scan_txs_with_keychains( + let (graph_update, active_indices) = env.client.full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -201,7 +201,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> { // A scan with gap limit 4 won't find the second transaction, but a scan with gap limit 5 will. // The last active indice won't be updated in the first case but will in the second one. - let (graph_update, active_indices) = env.client.scan_txs_with_keychains( + let (graph_update, active_indices) = env.client.full_scan( keychains.clone(), vec![].into_iter(), vec![].into_iter(), @@ -212,13 +212,9 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> { assert_eq!(txs.len(), 1); assert!(txs.contains(&txid_4th_addr)); assert_eq!(active_indices[&0], 3); - let (graph_update, active_indices) = env.client.scan_txs_with_keychains( - keychains, - vec![].into_iter(), - vec![].into_iter(), - 5, - 1, - )?; + let (graph_update, active_indices) = + env.client + .full_scan(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1)?; let txs: HashSet<_> = graph_update.full_txs().map(|tx| tx.txid).collect(); assert_eq!(txs.len(), 2); assert!(txs.contains(&txid_4th_addr) && txs.contains(&txid_last_addr)); diff --git a/example-crates/example_esplora/src/main.rs b/example-crates/example_esplora/src/main.rs index cabd8ea828..81e8bf80a6 100644 --- a/example-crates/example_esplora/src/main.rs +++ b/example-crates/example_esplora/src/main.rs @@ -188,7 +188,7 @@ fn main() -> anyhow::Result<()> { // represents the last active spk derivation indices of keychains // (`keychain_indices_update`). let (graph_update, last_active_indices) = client - .scan_txs_with_keychains( + .full_scan( keychain_spks, core::iter::empty(), core::iter::empty(), @@ -312,7 +312,7 @@ fn main() -> anyhow::Result<()> { } let graph_update = - client.scan_txs(spks, txids, outpoints, scan_options.parallel_requests)?; + client.sync(spks, txids, outpoints, scan_options.parallel_requests)?; graph.lock().unwrap().apply_update(graph_update) } diff --git a/example-crates/wallet_esplora_async/src/main.rs b/example-crates/wallet_esplora_async/src/main.rs index fb8f7b5105..259f98507d 100644 --- a/example-crates/wallet_esplora_async/src/main.rs +++ b/example-crates/wallet_esplora_async/src/main.rs @@ -54,7 +54,7 @@ async fn main() -> Result<(), anyhow::Error> { }) .collect(); let (update_graph, last_active_indices) = client - .scan_txs_with_keychains(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS) + .full_scan(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS) .await?; let missing_heights = update_graph.missing_heights(wallet.local_chain()); let chain_update = client.update_local_chain(prev_tip, missing_heights).await?; diff --git a/example-crates/wallet_esplora_blocking/src/main.rs b/example-crates/wallet_esplora_blocking/src/main.rs index 09e7c3ad4a..cdcb479553 100644 --- a/example-crates/wallet_esplora_blocking/src/main.rs +++ b/example-crates/wallet_esplora_blocking/src/main.rs @@ -54,7 +54,7 @@ fn main() -> Result<(), anyhow::Error> { .collect(); let (update_graph, last_active_indices) = - client.scan_txs_with_keychains(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)?; + client.full_scan(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)?; let missing_heights = update_graph.missing_heights(wallet.local_chain()); let chain_update = client.update_local_chain(prev_tip, missing_heights)?; let update = Update {