From ab0315d14fa741a691ee0deef4567ea66cb44a60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=BF=97=E5=AE=87?= Date: Fri, 23 Aug 2024 18:12:46 +0000 Subject: [PATCH] feat!: move `spk_client`s to `bdk_core` Also introduced extension trait for builder methods that take in a `KeychainTxOutIndex`. `Indexed` and `KeychainIndexed` are also moved to `bdk_core`. --- crates/chain/src/indexer/keychain_txout.rs | 41 ++++++++++++++++ crates/chain/src/lib.rs | 6 --- crates/core/Cargo.toml | 3 ++ crates/core/src/lib.rs | 7 +++ crates/{chain => core}/src/spk_client.rs | 57 +++++----------------- crates/testenv/src/lib.rs | 3 +- crates/wallet/src/wallet/mod.rs | 2 + example-crates/example_esplora/src/main.rs | 1 + 8 files changed, 68 insertions(+), 52 deletions(-) rename crates/{chain => core}/src/spk_client.rs (90%) diff --git a/crates/chain/src/indexer/keychain_txout.rs b/crates/chain/src/indexer/keychain_txout.rs index ce9707c7..c4320809 100644 --- a/crates/chain/src/indexer/keychain_txout.rs +++ b/crates/chain/src/indexer/keychain_txout.rs @@ -4,6 +4,7 @@ use crate::{ collections::*, miniscript::{Descriptor, DescriptorPublicKey}, + spk_client::{FullScanRequestBuilder, SyncRequestBuilder}, spk_iter::BIP32_MAX_INDEX, spk_txout::SpkTxOutIndex, DescriptorExt, DescriptorId, Indexed, Indexer, KeychainIndexed, SpkIterator, @@ -875,3 +876,43 @@ impl Merge for ChangeSet { self.last_revealed.is_empty() } } + +/// Trait to extend [`SyncRequestBuilder`]. +pub trait SyncRequestBuilderExt { + /// Add [`Script`](bitcoin::Script)s that are revealed by the `indexer` of the given `spk_range` + /// that will be synced against. + fn revealed_spks_from_indexer(self, indexer: &KeychainTxOutIndex, spk_range: R) -> Self + where + R: core::ops::RangeBounds; + + /// Add [`Script`](bitcoin::Script)s that are revealed by the `indexer` but currently unused. + fn unused_spks_from_indexer(self, indexer: &KeychainTxOutIndex) -> Self; +} + +impl SyncRequestBuilderExt for SyncRequestBuilder<(K, u32)> { + fn revealed_spks_from_indexer(self, indexer: &KeychainTxOutIndex, spk_range: R) -> Self + where + R: core::ops::RangeBounds, + { + self.spks_with_indexes(indexer.revealed_spks(spk_range)) + } + + fn unused_spks_from_indexer(self, indexer: &KeychainTxOutIndex) -> Self { + self.spks_with_indexes(indexer.unused_spks()) + } +} + +/// Trait to extend [`FullScanRequestBuilder`]. +pub trait FullScanRequestBuilderExt { + /// Add spk iterators for each keychain tracked in `indexer`. + fn spks_from_indexer(self, indexer: &KeychainTxOutIndex) -> Self; +} + +impl FullScanRequestBuilderExt for FullScanRequestBuilder { + fn spks_from_indexer(mut self, indexer: &KeychainTxOutIndex) -> Self { + for (keychain, spks) in indexer.all_unbounded_spk_iters() { + self = self.spks_for_keychain(keychain, spks); + } + self + } +} diff --git a/crates/chain/src/lib.rs b/crates/chain/src/lib.rs index c1c55596..9667bb54 100644 --- a/crates/chain/src/lib.rs +++ b/crates/chain/src/lib.rs @@ -61,7 +61,6 @@ pub use indexer::keychain_txout; pub use spk_iter::*; #[cfg(feature = "rusqlite")] pub mod rusqlite_impl; -pub mod spk_client; pub extern crate bdk_core; pub use bdk_core::*; @@ -81,11 +80,6 @@ extern crate std; /// How many confirmations are needed f or a coinbase output to be spent. pub const COINBASE_MATURITY: u32 = 100; -/// A tuple of keychain index and `T` representing the indexed value. -pub type Indexed = (u32, T); -/// A tuple of keychain `K`, derivation index (`u32`) and a `T` associated with them. -pub type KeychainIndexed = ((K, u32), T); - /// A wrapper that we use to impl remote traits for types in our crate or dependency crates. pub struct Impl(pub T); diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index d74cf906..80741b07 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -19,3 +19,6 @@ hashbrown = { version = "0.9.1", optional = true } default = ["std"] std = ["bitcoin/std"] serde = ["dep:serde", "bitcoin/serde", "hashbrown?/serde"] + +[dev-dependencies] +bdk_chain = { version = "0.17.0", path = "../chain" } diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index bed9da4a..038bee62 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -54,12 +54,19 @@ pub mod collections { pub use hashbrown::hash_map; } +/// A tuple of keychain index and `T` representing the indexed value. +pub type Indexed = (u32, T); +/// A tuple of keychain `K`, derivation index (`u32`) and a `T` associated with them. +pub type KeychainIndexed = ((K, u32), T); + mod chain_data; pub use chain_data::*; mod checkpoint; pub use checkpoint::*; +pub mod spk_client; + /// Core structures for [`TxGraph`]. /// /// [`TxGraph`]: https://docs.rs/bdk_chain/latest/bdk_chain/tx_graph/struct.TxGraph.html diff --git a/crates/chain/src/spk_client.rs b/crates/core/src/spk_client.rs similarity index 90% rename from crates/chain/src/spk_client.rs rename to crates/core/src/spk_client.rs index e31b431d..e54849fb 100644 --- a/crates/chain/src/spk_client.rs +++ b/crates/core/src/spk_client.rs @@ -2,8 +2,7 @@ use crate::{ alloc::{boxed::Box, collections::VecDeque, vec::Vec}, collections::BTreeMap, - local_chain::CheckPoint, - ConfirmationBlockTime, Indexed, + CheckPoint, ConfirmationBlockTime, Indexed, }; use bitcoin::{OutPoint, Script, ScriptBuf, Txid}; @@ -101,27 +100,6 @@ impl Default for SyncRequestBuilder { } } -#[cfg(feature = "miniscript")] -impl SyncRequestBuilder<(K, u32)> { - /// Add [`Script`]s that are revealed by the `indexer` of the given `spk_range` that will be - /// synced against. - pub fn revealed_spks_from_indexer( - self, - indexer: &crate::indexer::keychain_txout::KeychainTxOutIndex, - spk_range: impl core::ops::RangeBounds, - ) -> Self { - self.spks_with_indexes(indexer.revealed_spks(spk_range)) - } - - /// Add [`Script`]s that are revealed by the `indexer` but currently unused. - pub fn unused_spks_from_indexer( - self, - indexer: &crate::indexer::keychain_txout::KeychainTxOutIndex, - ) -> Self { - self.spks_with_indexes(indexer.unused_spks()) - } -} - impl SyncRequestBuilder<()> { /// Add [`Script`]s that will be synced against. pub fn spks(self, spks: impl IntoIterator) -> Self { @@ -132,7 +110,7 @@ impl SyncRequestBuilder<()> { impl SyncRequestBuilder { /// Set the initial chain tip for the sync request. /// - /// This is used to update [`LocalChain`](crate::local_chain::LocalChain). + /// This is used to update [`LocalChain`](../../bdk_chain/local_chain/struct.LocalChain.html). pub fn chain_tip(mut self, cp: CheckPoint) -> Self { self.inner.chain_tip = Some(cp); self @@ -143,7 +121,7 @@ impl SyncRequestBuilder { /// # Example /// /// Sync revealed script pubkeys obtained from a - /// [`KeychainTxOutIndex`](crate::keychain_txout::KeychainTxOutIndex). + /// [`KeychainTxOutIndex`](../../bdk_chain/indexer/keychain_txout/struct.KeychainTxOutIndex.html). /// /// ```rust /// # use bdk_chain::spk_client::SyncRequest; @@ -216,9 +194,9 @@ impl SyncRequestBuilder { /// /// ```rust /// # use bdk_chain::{bitcoin::{hashes::Hash, ScriptBuf}, local_chain::LocalChain}; +/// # use bdk_chain::spk_client::SyncRequest; /// # let (local_chain, _) = LocalChain::from_genesis_hash(Hash::all_zeros()); /// # let scripts = [ScriptBuf::default(), ScriptBuf::default()]; -/// # use bdk_chain::spk_client::SyncRequest; /// // Construct a sync request. /// let sync_request = SyncRequest::builder() /// // Provide chain tip of the local wallet. @@ -345,9 +323,11 @@ impl SyncRequest { #[must_use] #[derive(Debug)] pub struct SyncResult { - /// The update to apply to the receiving [`TxGraph`](crate::tx_graph::TxGraph). + /// The update to apply to the receiving + /// [`TxGraph`](../../bdk_chain/tx_graph/struct.TxGraph.html). pub graph_update: crate::tx_graph::Update, - /// The update to apply to the receiving [`LocalChain`](crate::local_chain::LocalChain). + /// The update to apply to the receiving + /// [`LocalChain`](../../bdk_chain/local_chain/struct.LocalChain.html). pub chain_update: Option, } @@ -374,24 +354,10 @@ impl Default for FullScanRequestBuilder { } } -#[cfg(feature = "miniscript")] -impl FullScanRequestBuilder { - /// Add spk iterators for each keychain tracked in `indexer`. - pub fn spks_from_indexer( - mut self, - indexer: &crate::indexer::keychain_txout::KeychainTxOutIndex, - ) -> Self { - for (keychain, spks) in indexer.all_unbounded_spk_iters() { - self = self.spks_for_keychain(keychain, spks); - } - self - } -} - impl FullScanRequestBuilder { /// Set the initial chain tip for the full scan request. /// - /// This is used to update [`LocalChain`](crate::local_chain::LocalChain). + /// This is used to update [`LocalChain`](../../bdk_chain/local_chain/struct.LocalChain.html). pub fn chain_tip(mut self, tip: CheckPoint) -> Self { self.inner.chain_tip = Some(tip); self @@ -496,9 +462,10 @@ impl FullScanRequest { #[must_use] #[derive(Debug)] pub struct FullScanResult { - /// The update to apply to the receiving [`LocalChain`](crate::local_chain::LocalChain). + /// The update to apply to the receiving + /// [`LocalChain`](../../bdk_chain/local_chain/struct.LocalChain.html). pub graph_update: crate::tx_graph::Update, - /// The update to apply to the receiving [`TxGraph`](crate::tx_graph::TxGraph). + /// The update to apply to the receiving [`TxGraph`](../../bdk_chain/tx_graph/struct.TxGraph.html). pub chain_update: Option, /// Last active indices for the corresponding keychains (`K`). pub last_active_indices: BTreeMap, diff --git a/crates/testenv/src/lib.rs b/crates/testenv/src/lib.rs index 747acc44..6d169bdc 100644 --- a/crates/testenv/src/lib.rs +++ b/crates/testenv/src/lib.rs @@ -4,7 +4,8 @@ use bdk_chain::{ secp256k1::rand::random, transaction, Address, Amount, Block, BlockHash, CompactTarget, ScriptBuf, ScriptHash, Transaction, TxIn, TxOut, Txid, }, - BlockId, local_chain::CheckPoint, + local_chain::CheckPoint, + BlockId, }; use bitcoincore_rpc::{ bitcoincore_rpc_json::{GetBlockTemplateModes, GetBlockTemplateRules}, diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 638bb575..72c42ddf 100644 --- a/crates/wallet/src/wallet/mod.rs +++ b/crates/wallet/src/wallet/mod.rs @@ -2472,6 +2472,7 @@ impl Wallet { /// [`SyncRequest`] collects all revealed script pubkeys from the wallet keychain needed to /// start a blockchain sync with a spk based blockchain client. pub fn start_sync_with_revealed_spks(&self) -> SyncRequestBuilder<(KeychainKind, u32)> { + use bdk_chain::keychain_txout::SyncRequestBuilderExt; SyncRequest::builder() .chain_tip(self.chain.tip()) .revealed_spks_from_indexer(&self.indexed_graph.index, ..) @@ -2486,6 +2487,7 @@ impl Wallet { /// This operation is generally only used when importing or restoring a previously used wallet /// in which the list of used scripts is not known. pub fn start_full_scan(&self) -> FullScanRequestBuilder { + use bdk_chain::keychain_txout::FullScanRequestBuilderExt; FullScanRequest::builder() .chain_tip(self.chain.tip()) .spks_from_indexer(&self.indexed_graph.index) diff --git a/example-crates/example_esplora/src/main.rs b/example-crates/example_esplora/src/main.rs index d4692e35..7a400587 100644 --- a/example-crates/example_esplora/src/main.rs +++ b/example-crates/example_esplora/src/main.rs @@ -6,6 +6,7 @@ use std::{ use bdk_chain::{ bitcoin::Network, + keychain_txout::FullScanRequestBuilderExt, spk_client::{FullScanRequest, SyncRequest}, Merge, }; -- 2.49.0