Skip to content

Commit b9cbcc3

Browse files
committed
refactor(esplora_ext): rename scan_txs to sync and scan_txs_with_keychains to full_scan
1 parent 348d117 commit b9cbcc3

File tree

9 files changed

+78
-39
lines changed

9 files changed

+78
-39
lines changed

crates/chain/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! This crate is a collection of core structures for [Bitcoin Dev Kit] (alpha release).
1+
//! This crate is a collection of core structures for [Bitcoin Dev Kit].
22
//!
33
//! The goal of this crate is to give wallets the mechanisms needed to:
44
//!

crates/esplora/src/async_ext.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@ pub trait EsploraAsyncExt {
3636
request_heights: impl IntoIterator<IntoIter = impl Iterator<Item = u32> + Send> + Send,
3737
) -> Result<local_chain::Update, Error>;
3838

39-
/// Scan Esplora for the data specified and return a [`TxGraph`] and a map of last active
40-
/// indices.
39+
/// Full scan the keychain scripts specified with the blockchain (via an Esplora client) and
40+
/// returns a [`TxGraph`] and a map of last active indices.
4141
///
4242
/// * `keychain_spks`: keychains that we want to scan transactions for
4343
/// * `txids`: transactions for which we want updated [`ConfirmationTimeHeightAnchor`]s
4444
/// * `outpoints`: transactions associated with these outpoints (residing, spending) that we
4545
/// want to include in the update
4646
///
47-
/// The scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
47+
/// The full scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
4848
/// transactions. `parallel_requests` specifies the max number of HTTP requests to make in
4949
/// parallel.
5050
#[allow(clippy::result_large_err)]
51-
async fn scan_txs_with_keychains<K: Ord + Clone + Send>(
51+
async fn full_scan<K: Ord + Clone + Send>(
5252
&self,
5353
keychain_spks: BTreeMap<
5454
K,
@@ -60,18 +60,31 @@ pub trait EsploraAsyncExt {
6060
parallel_requests: usize,
6161
) -> Result<(TxGraph<ConfirmationTimeHeightAnchor>, BTreeMap<K, u32>), Error>;
6262

63-
/// Convenience method to call [`scan_txs_with_keychains`] without requiring a keychain.
63+
/// Sync a set of scripts with with the blockchain (via an Esplora client) for the data
64+
/// specified and return a [`TxGraph`] and a map of last active indices.
65+
///
66+
/// * `misc_spks`: scripts that we want to sync transactions for
67+
/// * `txids`: transactions for which we want updated [`ConfirmationTimeHeightAnchor`]s
68+
/// * `outpoints`: transactions associated with these outpoints (residing, spending) that we
69+
/// want to include in the update
70+
///
71+
/// The scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
72+
/// transactions. `parallel_requests` specifies the max number of HTTP requests to make in
73+
/// parallel.
74+
///
75+
/// If the scripts to sync are unknown, such as when restoring or importing a keychain that
76+
/// may include scripts that have been used, use [`full_scan`] with the keychain.
6477
///
65-
/// [`scan_txs_with_keychains`]: EsploraAsyncExt::scan_txs_with_keychains
78+
/// [`full_scan`]: EsploraAsyncExt::full_scan
6679
#[allow(clippy::result_large_err)]
67-
async fn scan_txs(
80+
async fn sync(
6881
&self,
6982
misc_spks: impl IntoIterator<IntoIter = impl Iterator<Item = ScriptBuf> + Send> + Send,
7083
txids: impl IntoIterator<IntoIter = impl Iterator<Item = Txid> + Send> + Send,
7184
outpoints: impl IntoIterator<IntoIter = impl Iterator<Item = OutPoint> + Send> + Send,
7285
parallel_requests: usize,
7386
) -> Result<TxGraph<ConfirmationTimeHeightAnchor>, Error> {
74-
self.scan_txs_with_keychains(
87+
self.full_scan(
7588
[(
7689
(),
7790
misc_spks
@@ -199,7 +212,7 @@ impl EsploraAsyncExt for esplora_client::AsyncClient {
199212
})
200213
}
201214

202-
async fn scan_txs_with_keychains<K: Ord + Clone + Send>(
215+
async fn full_scan<K: Ord + Clone + Send>(
203216
&self,
204217
keychain_spks: BTreeMap<
205218
K,

crates/esplora/src/blocking_ext.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ pub trait EsploraExt {
3434
request_heights: impl IntoIterator<Item = u32>,
3535
) -> Result<local_chain::Update, Error>;
3636

37-
/// Scan Esplora for the data specified and return a [`TxGraph`] and a map of last active
38-
/// indices.
37+
/// Full scan the keychain scripts specified with the blockchain (via an Esplora client) and
38+
/// returns a [`TxGraph`] and a map of last active indices.
3939
///
4040
/// * `keychain_spks`: keychains that we want to scan transactions for
4141
/// * `txids`: transactions for which we want updated [`ConfirmationTimeHeightAnchor`]s
4242
/// * `outpoints`: transactions associated with these outpoints (residing, spending) that we
4343
/// want to include in the update
4444
///
45-
/// The scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
45+
/// The full scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
4646
/// transactions. `parallel_requests` specifies the max number of HTTP requests to make in
4747
/// parallel.
4848
#[allow(clippy::result_large_err)]
49-
fn scan_txs_with_keychains<K: Ord + Clone>(
49+
fn full_scan<K: Ord + Clone>(
5050
&self,
5151
keychain_spks: BTreeMap<K, impl IntoIterator<Item = (u32, ScriptBuf)>>,
5252
txids: impl IntoIterator<Item = Txid>,
@@ -55,18 +55,31 @@ pub trait EsploraExt {
5555
parallel_requests: usize,
5656
) -> Result<(TxGraph<ConfirmationTimeHeightAnchor>, BTreeMap<K, u32>), Error>;
5757

58-
/// Convenience method to call [`scan_txs_with_keychains`] without requiring a keychain.
58+
/// Sync a set of scripts with with the blockchain (via an Esplora client) for the data
59+
/// specified and return a [`TxGraph`] and a map of last active indices.
60+
///
61+
/// * `misc_spks`: scripts that we want to sync transactions for
62+
/// * `txids`: transactions for which we want updated [`ConfirmationTimeHeightAnchor`]s
63+
/// * `outpoints`: transactions associated with these outpoints (residing, spending) that we
64+
/// want to include in the update
65+
///
66+
/// The scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
67+
/// transactions. `parallel_requests` specifies the max number of HTTP requests to make in
68+
/// parallel.
69+
///
70+
/// If the scripts to sync are unknown, such as when restoring or importing a keychain that
71+
/// may include scripts that have been used, use [`full_scan`] with the keychain.
5972
///
60-
/// [`scan_txs_with_keychains`]: EsploraExt::scan_txs_with_keychains
73+
/// [`full_scan`]: EsploraExt::full_scan
6174
#[allow(clippy::result_large_err)]
62-
fn scan_txs(
75+
fn sync(
6376
&self,
6477
misc_spks: impl IntoIterator<Item = ScriptBuf>,
6578
txids: impl IntoIterator<Item = Txid>,
6679
outpoints: impl IntoIterator<Item = OutPoint>,
6780
parallel_requests: usize,
6881
) -> Result<TxGraph<ConfirmationTimeHeightAnchor>, Error> {
69-
self.scan_txs_with_keychains(
82+
self.full_scan(
7083
[(
7184
(),
7285
misc_spks
@@ -190,7 +203,7 @@ impl EsploraExt for esplora_client::BlockingClient {
190203
})
191204
}
192205

193-
fn scan_txs_with_keychains<K: Ord + Clone>(
206+
fn full_scan<K: Ord + Clone>(
194207
&self,
195208
keychain_spks: BTreeMap<K, impl IntoIterator<Item = (u32, ScriptBuf)>>,
196209
txids: impl IntoIterator<Item = Txid>,

crates/esplora/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
#![doc = include_str!("../README.md")]
2+
3+
//! This crate is used for updating structures of [`bdk_chain`] with data from an Esplora server.
4+
//!
5+
//! The two primary methods are [`EsploraExt::sync`] and [`EsploraExt::full_scan`]. In most cases
6+
//! [`EsploraExt::sync`] is used to sync the transaction histories of scripts that the application
7+
//! cares about, for example the scripts for all the receive addresses of a Wallet's keychain that it
8+
//! has shown a user. [`EsploraExt::full_scan`] is meant to be used when importing or restoring a
9+
//! keychain where the range of possibly used scripts is not known. In this case it is necessary to
10+
//! scan all keychain scripts until a number (the "stop gap") of unused scripts is discovered. For a
11+
//! sync or full scan the user receives relevant blockchain data and output updates for [`bdk_chain`]
12+
//! via a new [`TxGraph`] to be appended to any existing [`TxGraph`] data.
13+
//!
14+
//! Refer to [`example_esplora`] for a complete example.
15+
//!
16+
//! [`TxGraph`]: bdk_chain::tx_graph::TxGraph
17+
//! [`example_esplora`]: https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_esplora
18+
219
use bdk_chain::{BlockId, ConfirmationTimeHeightAnchor};
320
use esplora_client::TxStatus;
421

crates/esplora/tests/async_ext.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub async fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
101101

102102
let graph_update = env
103103
.client
104-
.scan_txs(
104+
.sync(
105105
misc_spks.into_iter(),
106106
vec![].into_iter(),
107107
vec![].into_iter(),
@@ -168,7 +168,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> {
168168
// will.
169169
let (graph_update, active_indices) = env
170170
.client
171-
.scan_txs_with_keychains(
171+
.full_scan(
172172
keychains.clone(),
173173
vec![].into_iter(),
174174
vec![].into_iter(),
@@ -180,7 +180,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> {
180180
assert!(active_indices.is_empty());
181181
let (graph_update, active_indices) = env
182182
.client
183-
.scan_txs_with_keychains(
183+
.full_scan(
184184
keychains.clone(),
185185
vec![].into_iter(),
186186
vec![].into_iter(),
@@ -211,7 +211,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> {
211211
// The last active indice won't be updated in the first case but will in the second one.
212212
let (graph_update, active_indices) = env
213213
.client
214-
.scan_txs_with_keychains(
214+
.full_scan(
215215
keychains.clone(),
216216
vec![].into_iter(),
217217
vec![].into_iter(),
@@ -225,7 +225,7 @@ pub async fn test_async_update_tx_graph_gap_limit() -> anyhow::Result<()> {
225225
assert_eq!(active_indices[&0], 3);
226226
let (graph_update, active_indices) = env
227227
.client
228-
.scan_txs_with_keychains(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1)
228+
.full_scan(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1)
229229
.await?;
230230
let txs: HashSet<_> = graph_update.full_txs().map(|tx| tx.txid).collect();
231231
assert_eq!(txs.len(), 2);

crates/esplora/tests/blocking_ext.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
9999
sleep(Duration::from_millis(10))
100100
}
101101

102-
let graph_update = env.client.scan_txs(
102+
let graph_update = env.client.sync(
103103
misc_spks.into_iter(),
104104
vec![].into_iter(),
105105
vec![].into_iter(),
@@ -164,7 +164,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> {
164164

165165
// A scan with a gap limit of 2 won't find the transaction, but a scan with a gap limit of 3
166166
// will.
167-
let (graph_update, active_indices) = env.client.scan_txs_with_keychains(
167+
let (graph_update, active_indices) = env.client.full_scan(
168168
keychains.clone(),
169169
vec![].into_iter(),
170170
vec![].into_iter(),
@@ -173,7 +173,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> {
173173
)?;
174174
assert!(graph_update.full_txs().next().is_none());
175175
assert!(active_indices.is_empty());
176-
let (graph_update, active_indices) = env.client.scan_txs_with_keychains(
176+
let (graph_update, active_indices) = env.client.full_scan(
177177
keychains.clone(),
178178
vec![].into_iter(),
179179
vec![].into_iter(),
@@ -201,7 +201,7 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> {
201201

202202
// A scan with gap limit 4 won't find the second transaction, but a scan with gap limit 5 will.
203203
// The last active indice won't be updated in the first case but will in the second one.
204-
let (graph_update, active_indices) = env.client.scan_txs_with_keychains(
204+
let (graph_update, active_indices) = env.client.full_scan(
205205
keychains.clone(),
206206
vec![].into_iter(),
207207
vec![].into_iter(),
@@ -212,13 +212,9 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> {
212212
assert_eq!(txs.len(), 1);
213213
assert!(txs.contains(&txid_4th_addr));
214214
assert_eq!(active_indices[&0], 3);
215-
let (graph_update, active_indices) = env.client.scan_txs_with_keychains(
216-
keychains,
217-
vec![].into_iter(),
218-
vec![].into_iter(),
219-
5,
220-
1,
221-
)?;
215+
let (graph_update, active_indices) =
216+
env.client
217+
.full_scan(keychains, vec![].into_iter(), vec![].into_iter(), 5, 1)?;
222218
let txs: HashSet<_> = graph_update.full_txs().map(|tx| tx.txid).collect();
223219
assert_eq!(txs.len(), 2);
224220
assert!(txs.contains(&txid_4th_addr) && txs.contains(&txid_last_addr));

example-crates/example_esplora/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ fn main() -> anyhow::Result<()> {
188188
// represents the last active spk derivation indices of keychains
189189
// (`keychain_indices_update`).
190190
let (graph_update, last_active_indices) = client
191-
.scan_txs_with_keychains(
191+
.full_scan(
192192
keychain_spks,
193193
core::iter::empty(),
194194
core::iter::empty(),
@@ -312,7 +312,7 @@ fn main() -> anyhow::Result<()> {
312312
}
313313

314314
let graph_update =
315-
client.scan_txs(spks, txids, outpoints, scan_options.parallel_requests)?;
315+
client.sync(spks, txids, outpoints, scan_options.parallel_requests)?;
316316

317317
graph.lock().unwrap().apply_update(graph_update)
318318
}

example-crates/wallet_esplora_async/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async fn main() -> Result<(), anyhow::Error> {
5454
})
5555
.collect();
5656
let (update_graph, last_active_indices) = client
57-
.scan_txs_with_keychains(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)
57+
.full_scan(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)
5858
.await?;
5959
let missing_heights = update_graph.missing_heights(wallet.local_chain());
6060
let chain_update = client.update_local_chain(prev_tip, missing_heights).await?;

example-crates/wallet_esplora_blocking/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn main() -> Result<(), anyhow::Error> {
5454
.collect();
5555

5656
let (update_graph, last_active_indices) =
57-
client.scan_txs_with_keychains(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)?;
57+
client.full_scan(keychain_spks, None, None, STOP_GAP, PARALLEL_REQUESTS)?;
5858
let missing_heights = update_graph.missing_heights(wallet.local_chain());
5959
let chain_update = client.update_local_chain(prev_tip, missing_heights)?;
6060
let update = Update {

0 commit comments

Comments
 (0)