]> Untitled Git - bdk/commitdiff
chore(chain): Standardise KeychainTxOutIndex return types
authorLLFourn <lloyd.fourn@gmail.com>
Fri, 7 Jun 2024 02:29:58 +0000 (12:29 +1000)
committer志宇 <hello@evanlinjin.me>
Thu, 13 Jun 2024 14:52:44 +0000 (22:52 +0800)
The previous commit b9c5b9d08b040faf6c6b2d9b3745918031555b72 added
IndexSpk. This goes further and adds `Indexed` and `KeychainIndexed`
type alises (IndexSpk is Indexed<ScriptBuf>) and attempts to standardize
the structure of return types more generally.

12 files changed:
crates/chain/src/keychain.rs
crates/chain/src/keychain/txout_index.rs
crates/chain/src/lib.rs
crates/chain/src/spk_client.rs
crates/chain/src/spk_iter.rs
crates/chain/tests/test_keychain_txout_index.rs
crates/esplora/src/async_ext.rs
crates/esplora/src/blocking_ext.rs
crates/wallet/src/wallet/mod.rs
example-crates/example_cli/src/lib.rs
example-crates/example_electrum/src/main.rs
example-crates/example_esplora/src/main.rs

index b822dc90156248f185dcadd8eff1e4144cf0fbc0..e1e6de68c887d59531c7f313f3651c3730df6ba9 100644 (file)
@@ -12,7 +12,7 @@
 
 #[cfg(feature = "miniscript")]
 mod txout_index;
-use bitcoin::Amount;
+use bitcoin::{Amount, ScriptBuf};
 #[cfg(feature = "miniscript")]
 pub use txout_index::*;
 
@@ -49,6 +49,11 @@ impl Balance {
     }
 }
 
+/// A tuple of keychain index and corresponding [`ScriptBuf`].
+pub type Indexed<T> = (u32, T);
+/// A tuple of keychain, index and the [`ScriptBuf`] derived at that location.
+pub type KeychainIndexed<K, T> = ((K, u32), T);
+
 impl core::fmt::Display for Balance {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(
index 6d0b7623ae1ef2487079ba359886812b1f026339..f62c2f164b69993e6c1cf2e0b9230ea8bea63a05 100644 (file)
@@ -3,7 +3,7 @@ use crate::{
     indexed_tx_graph::Indexer,
     miniscript::{Descriptor, DescriptorPublicKey},
     spk_iter::BIP32_MAX_INDEX,
-    DescriptorExt, DescriptorId, IndexSpk, SpkIterator, SpkTxOutIndex,
+    DescriptorExt, DescriptorId, SpkIterator, SpkTxOutIndex,
 };
 use alloc::{borrow::ToOwned, vec::Vec};
 use bitcoin::{Amount, OutPoint, Script, SignedAmount, Transaction, TxOut, Txid};
@@ -12,6 +12,7 @@ use core::{
     ops::{Bound, RangeBounds},
 };
 
+use super::*;
 use crate::Append;
 
 /// Represents updates to the derivation index of a [`KeychainTxOutIndex`].
@@ -140,7 +141,7 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
 /// # Change sets
 ///
 /// Methods that can update the last revealed index or add keychains will return [`ChangeSet`] to report
-/// these changes. This can be persisted for future recovery.
+/// these changes. This should be persisted for future recovery.
 ///
 /// ## Synopsis
 ///
@@ -191,18 +192,18 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
 #[derive(Clone, Debug)]
 pub struct KeychainTxOutIndex<K> {
     inner: SpkTxOutIndex<(K, u32)>,
-    // keychain -> (descriptor, descriptor id) map
+    /// keychain -> (descriptor id) map
     keychains_to_descriptor_ids: BTreeMap<K, DescriptorId>,
-    // descriptor id -> keychain map
+    /// descriptor id -> keychain map
     descriptor_ids_to_keychains: BTreeMap<DescriptorId, K>,
-    // descriptor_id -> descriptor map
-    // This is a "monotone" map, meaning that its size keeps growing, i.e., we never delete
-    // descriptors from it. This is useful for revealing spks for descriptors that don't have
-    // keychains associated.
+    /// descriptor_id -> descriptor map
+    /// This is a "monotone" map, meaning that its size keeps growing, i.e., we never delete
+    /// descriptors from it. This is useful for revealing spks for descriptors that don't have
+    /// keychains associated.
     descriptor_ids_to_descriptors: BTreeMap<DescriptorId, Descriptor<DescriptorPublicKey>>,
-    // last revealed indexes
+    /// last revealed indices for each descriptor.
     last_revealed: HashMap<DescriptorId, u32>,
-    // lookahead settings for each keychain
+    /// lookahead setting
     lookahead: u32,
 }
 
@@ -292,21 +293,28 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     }
 
     /// Get the set of indexed outpoints, corresponding to tracked keychains.
-    pub fn outpoints(&self) -> &BTreeSet<((K, u32), OutPoint)> {
+    pub fn outpoints(&self) -> &BTreeSet<KeychainIndexed<K, OutPoint>> {
         self.inner.outpoints()
     }
 
     /// Iterate over known txouts that spend to tracked script pubkeys.
-    pub fn txouts(&self) -> impl DoubleEndedIterator<Item = (&(K, u32), OutPoint, &TxOut)> + '_ {
-        self.inner.txouts()
+    pub fn txouts(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, (OutPoint, &TxOut)>> + ExactSizeIterator
+    {
+        self.inner
+            .txouts()
+            .map(|(index, op, txout)| (index.clone(), (op, txout)))
     }
 
     /// Finds all txouts on a transaction that has previously been scanned and indexed.
     pub fn txouts_in_tx(
         &self,
         txid: Txid,
-    ) -> impl DoubleEndedIterator<Item = (&(K, u32), OutPoint, &TxOut)> {
-        self.inner.txouts_in_tx(txid)
+    ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, (OutPoint, &TxOut)>> {
+        self.inner
+            .txouts_in_tx(txid)
+            .map(|(index, op, txout)| (index.clone(), (op, txout)))
     }
 
     /// Return the [`TxOut`] of `outpoint` if it has been indexed, and if it corresponds to a
@@ -315,8 +323,10 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     /// The associated keychain and keychain index of the txout's spk is also returned.
     ///
     /// This calls [`SpkTxOutIndex::txout`] internally.
-    pub fn txout(&self, outpoint: OutPoint) -> Option<(&(K, u32), &TxOut)> {
-        self.inner.txout(outpoint)
+    pub fn txout(&self, outpoint: OutPoint) -> Option<KeychainIndexed<K, &TxOut>> {
+        self.inner
+            .txout(outpoint)
+            .map(|(index, txout)| (index.clone(), txout))
     }
 
     /// Return the script that exists under the given `keychain`'s `index`.
@@ -420,12 +430,12 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
 
     /// Insert a descriptor with a keychain associated to it.
     ///
-    /// Adding a descriptor means you will be able to derive new script pubkeys under it
-    /// and the txout index will discover transaction outputs with those script pubkeys.
+    /// Adding a descriptor means you will be able to derive new script pubkeys under it and the
+    /// txout index will discover transaction outputs with those script pubkeys (once they've been
+    /// derived and added to the index).
     ///
-    /// keychain <-> descriptor is a one-to-one mapping -- in `--release` this method will ignore calls that try to
-    /// associate a keychain with the descriptor of another keychain or to re-assign the keychain to
-    /// new descriptor. If `debug_assertions` are enabled then it will panic.
+    /// keychain <-> descriptor is a one-to-one mapping that cannot be changed. Attempting to do so
+    /// will return a [`InsertDescriptorError<K>`].
     pub fn insert_descriptor(
         &mut self,
         keychain: K,
@@ -575,7 +585,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     pub fn revealed_spks(
         &self,
         range: impl RangeBounds<K>,
-    ) -> impl Iterator<Item = (&(K, u32), &Script)> {
+    ) -> impl Iterator<Item = KeychainIndexed<K, &Script>> {
         let start = range.start_bound();
         let end = range.end_bound();
         let mut iter_last_revealed = self
@@ -593,8 +603,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
         // iterate through the last_revealed for each keychain and the spks for each keychain in
         // tandem. This minimizes BTreeMap queries.
         core::iter::from_fn(move || loop {
-            let (path, spk) = iter_spks.next()?;
-            let (keychain, index) = path;
+            let ((keychain, index), spk) = iter_spks.next()?;
             // We need to find the last revealed that matches the current spk we are considering so
             // we skip ahead.
             while current_keychain?.0 < keychain {
@@ -603,7 +612,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
             let (current_keychain, last_revealed) = current_keychain?;
 
             if current_keychain == keychain && Some(*index) <= last_revealed {
-                break Some((path, spk.as_script()));
+                break Some(((keychain.clone(), *index), spk.as_script()));
             }
         })
     }
@@ -615,7 +624,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     pub fn revealed_keychain_spks<'a>(
         &'a self,
         keychain: &'a K,
-    ) -> impl DoubleEndedIterator<Item = (u32, &Script)> + 'a {
+    ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + 'a {
         let end = self
             .last_revealed_index(keychain)
             .map(|v| v + 1)
@@ -627,7 +636,9 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     }
 
     /// Iterate over revealed, but unused, spks of all keychains.
-    pub fn unused_spks(&self) -> impl DoubleEndedIterator<Item = ((K, u32), &Script)> + Clone {
+    pub fn unused_spks(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, &Script>> + Clone {
         self.keychains_to_descriptor_ids
             .keys()
             .flat_map(|keychain| {
@@ -641,7 +652,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     pub fn unused_keychain_spks(
         &self,
         keychain: &K,
-    ) -> impl DoubleEndedIterator<Item = (u32, &Script)> + Clone {
+    ) -> impl DoubleEndedIterator<Item = Indexed<&Script>> + Clone {
         let end = match self.keychains_to_descriptor_ids.get(keychain) {
             Some(did) => self.last_revealed.get(did).map(|v| *v + 1).unwrap_or(0),
             None => 0,
@@ -739,16 +750,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
         &mut self,
         keychain: &K,
         target_index: u32,
-    ) -> Option<(Vec<IndexSpk>, ChangeSet<K>)> {
+    ) -> Option<(Vec<Indexed<ScriptBuf>>, ChangeSet<K>)> {
         let mut changeset = ChangeSet::default();
-        let mut spks: Vec<IndexSpk> = vec![];
+        let mut spks: Vec<Indexed<ScriptBuf>> = vec![];
         while let Some((i, new)) = self.next_index(keychain) {
             if !new || i > target_index {
                 break;
             }
             match self.reveal_next_spk(keychain) {
                 Some(((i, spk), change)) => {
-                    spks.push((i, spk.to_owned()));
+                    spks.push((i, spk));
                     changeset.append(change);
                 }
                 None => break,
@@ -770,7 +781,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     ///  1. The descriptor has no wildcard and already has one script revealed.
     ///  2. The descriptor has already revealed scripts up to the numeric bound.
     ///  3. There is no descriptor associated with the given keychain.
-    pub fn reveal_next_spk(&mut self, keychain: &K) -> Option<((u32, &Script), ChangeSet<K>)> {
+    pub fn reveal_next_spk(&mut self, keychain: &K) -> Option<(Indexed<ScriptBuf>, ChangeSet<K>)> {
         let (next_index, new) = self.next_index(keychain)?;
         let mut changeset = ChangeSet::default();
 
@@ -790,7 +801,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
             .inner
             .spk_at_index(&(keychain.clone(), next_index))
             .expect("we just inserted it");
-        Some(((next_index, script), changeset))
+        Some(((next_index, script.into()), changeset))
     }
 
     /// Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest
@@ -802,20 +813,17 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     /// has used all scripts up to the derivation bounds, then the last derived script pubkey will be
     /// returned.
     ///
-    /// Returns None if the provided keychain doesn't exist.
-    pub fn next_unused_spk(&mut self, keychain: &K) -> Option<((u32, &Script), ChangeSet<K>)> {
-        let need_new = self.unused_keychain_spks(keychain).next().is_none();
-        // this rather strange branch is needed because of some lifetime issues
-        if need_new {
-            self.reveal_next_spk(keychain)
-        } else {
-            Some((
-                self.unused_keychain_spks(keychain)
-                    .next()
-                    .expect("we already know next exists"),
-                ChangeSet::default(),
-            ))
-        }
+    /// Returns `None` if there are no script pubkeys that have been used and no new script pubkey
+    /// could be revealed (see [`reveal_next_spk`] for when this happens).
+    ///
+    /// [`reveal_next_spk`]: Self::reveal_next_spk
+    pub fn next_unused_spk(&mut self, keychain: &K) -> Option<(Indexed<ScriptBuf>, ChangeSet<K>)> {
+        let next_unused = self
+            .unused_keychain_spks(keychain)
+            .next()
+            .map(|(i, spk)| ((i, spk.to_owned()), ChangeSet::default()));
+
+        next_unused.or_else(|| self.reveal_next_spk(keychain))
     }
 
     /// Iterate over all [`OutPoint`]s that have `TxOut`s with script pubkeys derived from
@@ -823,17 +831,19 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
     pub fn keychain_outpoints<'a>(
         &'a self,
         keychain: &'a K,
-    ) -> impl DoubleEndedIterator<Item = (u32, OutPoint)> + 'a {
+    ) -> impl DoubleEndedIterator<Item = Indexed<OutPoint>> + 'a {
         self.keychain_outpoints_in_range(keychain..=keychain)
-            .map(|((_, i), op)| (*i, op))
+            .map(|((_, i), op)| (i, op))
     }
 
     /// Iterate over [`OutPoint`]s that have script pubkeys derived from keychains in `range`.
     pub fn keychain_outpoints_in_range<'a>(
         &'a self,
         range: impl RangeBounds<K> + 'a,
-    ) -> impl DoubleEndedIterator<Item = (&(K, u32), OutPoint)> + 'a {
-        self.inner.outputs_in_range(self.map_to_inner_bounds(range))
+    ) -> impl DoubleEndedIterator<Item = KeychainIndexed<K, OutPoint>> + 'a {
+        self.inner
+            .outputs_in_range(self.map_to_inner_bounds(range))
+            .map(|((k, i), op)| ((k.clone(), *i), op))
     }
 
     fn map_to_inner_bounds(&self, bound: impl RangeBounds<K>) -> impl RangeBounds<(K, u32)> {
index 9709699427f4a8c3f5fca29cb96e402112246af8..8204cf0eb63453e584c1daefd828152dbc80254d 100644 (file)
@@ -28,6 +28,7 @@ pub use chain_data::*;
 pub mod indexed_tx_graph;
 pub use indexed_tx_graph::IndexedTxGraph;
 pub mod keychain;
+pub use keychain::{Indexed, KeychainIndexed};
 pub mod local_chain;
 mod tx_data_traits;
 pub mod tx_graph;
index cf78e7bdd58e493589eef50d0e6851c2f5163882..3cb87a407eabfeee401378ef402a9bd489639965 100644 (file)
@@ -1,7 +1,8 @@
 //! Helper types for spk-based blockchain clients.
 
 use crate::{
-    collections::BTreeMap, local_chain::CheckPoint, ConfirmationTimeHeightAnchor, IndexSpk, TxGraph,
+    collections::BTreeMap, keychain::Indexed, local_chain::CheckPoint,
+    ConfirmationTimeHeightAnchor, TxGraph,
 };
 use alloc::{boxed::Box, vec::Vec};
 use bitcoin::{OutPoint, Script, ScriptBuf, Txid};
@@ -195,7 +196,7 @@ pub struct FullScanRequest<K> {
     /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
     pub chain_tip: CheckPoint,
     /// Iterators of script pubkeys indexed by the keychain index.
-    pub spks_by_keychain: BTreeMap<K, Box<dyn Iterator<Item = IndexSpk> + Send>>,
+    pub spks_by_keychain: BTreeMap<K, Box<dyn Iterator<Item = Indexed<ScriptBuf>> + Send>>,
 }
 
 impl<K: Ord + Clone> FullScanRequest<K> {
@@ -238,7 +239,7 @@ impl<K: Ord + Clone> FullScanRequest<K> {
     pub fn set_spks_for_keychain(
         mut self,
         keychain: K,
-        spks: impl IntoIterator<IntoIter = impl Iterator<Item = IndexSpk> + Send + 'static>,
+        spks: impl IntoIterator<IntoIter = impl Iterator<Item = Indexed<ScriptBuf>> + Send + 'static>,
     ) -> Self {
         self.spks_by_keychain
             .insert(keychain, Box::new(spks.into_iter()));
@@ -252,7 +253,7 @@ impl<K: Ord + Clone> FullScanRequest<K> {
     pub fn chain_spks_for_keychain(
         mut self,
         keychain: K,
-        spks: impl IntoIterator<IntoIter = impl Iterator<Item = IndexSpk> + Send + 'static>,
+        spks: impl IntoIterator<IntoIter = impl Iterator<Item = Indexed<ScriptBuf>> + Send + 'static>,
     ) -> Self {
         match self.spks_by_keychain.remove(&keychain) {
             // clippy here suggests to remove `into_iter` from `spks.into_iter()`, but doing so
index 8285036bf4a1f3b58d870799d6cc891d4c33a25b..dd4c0a8f56294f4b937728b7d1eb2d796e4312e1 100644 (file)
@@ -1,5 +1,6 @@
 use crate::{
     bitcoin::{secp256k1::Secp256k1, ScriptBuf},
+    keychain::Indexed,
     miniscript::{Descriptor, DescriptorPublicKey},
 };
 use core::{borrow::Borrow, ops::Bound, ops::RangeBounds};
@@ -7,9 +8,6 @@ use core::{borrow::Borrow, ops::Bound, ops::RangeBounds};
 /// Maximum [BIP32](https://bips.xyz/32) derivation index.
 pub const BIP32_MAX_INDEX: u32 = (1 << 31) - 1;
 
-/// A tuple of keychain index and corresponding [`ScriptBuf`].
-pub type IndexSpk = (u32, ScriptBuf);
-
 /// An iterator for derived script pubkeys.
 ///
 /// [`SpkIterator`] is an implementation of the [`Iterator`] trait which possesses its own `next()`
@@ -100,7 +98,7 @@ impl<D> Iterator for SpkIterator<D>
 where
     D: Borrow<Descriptor<DescriptorPublicKey>>,
 {
-    type Item = IndexSpk;
+    type Item = Indexed<ScriptBuf>;
 
     fn next(&mut self) -> Option<Self::Item> {
         // For non-wildcard descriptors, we expect the first element to be Some((0, spk)), then None after.
index c5fd974cb2028945704d434bc2e70aaf425a16ed..2c1c34e705ba0951686232fc959b13d8cd805489 100644 (file)
@@ -408,10 +408,10 @@ fn test_wildcard_derivations() {
     // - next_unused() == ((0, <spk>), keychain::ChangeSet:is_empty())
     assert_eq!(txout_index.next_index(&TestKeychain::External).unwrap(), (0, true));
     let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External).unwrap();
-    assert_eq!(spk, (0_u32, external_spk_0.as_script()));
+    assert_eq!(spk, (0_u32, external_spk_0.clone()));
     assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 0)].into());
     let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap();
-    assert_eq!(spk, (0_u32, external_spk_0.as_script()));
+    assert_eq!(spk, (0_u32, external_spk_0.clone()));
     assert_eq!(&changeset.last_revealed, &[].into());
 
     // - derived till 25
@@ -431,12 +431,12 @@ fn test_wildcard_derivations() {
     assert_eq!(txout_index.next_index(&TestKeychain::External).unwrap(), (26, true));
 
     let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External).unwrap();
-    assert_eq!(spk, (26, external_spk_26.as_script()));
+    assert_eq!(spk, (26, external_spk_26));
 
     assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 26)].into());
 
     let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap();
-    assert_eq!(spk, (16, external_spk_16.as_script()));
+    assert_eq!(spk, (16, external_spk_16));
     assert_eq!(&changeset.last_revealed, &[].into());
 
     // - Use all the derived till 26.
@@ -446,7 +446,7 @@ fn test_wildcard_derivations() {
     });
 
     let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External).unwrap();
-    assert_eq!(spk, (27, external_spk_27.as_script()));
+    assert_eq!(spk, (27, external_spk_27));
     assert_eq!(&changeset.last_revealed, &[(external_descriptor.descriptor_id(), 27)].into());
 }
 
@@ -479,7 +479,7 @@ fn test_non_wildcard_derivations() {
     let (spk, changeset) = txout_index
         .reveal_next_spk(&TestKeychain::External)
         .unwrap();
-    assert_eq!(spk, (0, external_spk.as_script()));
+    assert_eq!(spk, (0, external_spk.clone()));
     assert_eq!(
         &changeset.last_revealed,
         &[(no_wildcard_descriptor.descriptor_id(), 0)].into()
@@ -488,7 +488,7 @@ fn test_non_wildcard_derivations() {
     let (spk, changeset) = txout_index
         .next_unused_spk(&TestKeychain::External)
         .unwrap();
-    assert_eq!(spk, (0, external_spk.as_script()));
+    assert_eq!(spk, (0, external_spk.clone()));
     assert_eq!(&changeset.last_revealed, &[].into());
 
     // given:
@@ -506,13 +506,13 @@ fn test_non_wildcard_derivations() {
     let (spk, changeset) = txout_index
         .reveal_next_spk(&TestKeychain::External)
         .unwrap();
-    assert_eq!(spk, (0, external_spk.as_script()));
+    assert_eq!(spk, (0, external_spk.clone()));
     assert_eq!(&changeset.last_revealed, &[].into());
 
     let (spk, changeset) = txout_index
         .next_unused_spk(&TestKeychain::External)
         .unwrap();
-    assert_eq!(spk, (0, external_spk.as_script()));
+    assert_eq!(spk, (0, external_spk.clone()));
     assert_eq!(&changeset.last_revealed, &[].into());
     let (revealed_spks, revealed_changeset) = txout_index
         .reveal_to_target(&TestKeychain::External, 200)
index a7dbc24fcfb3f658757cb4e4d900bd776dda799b..dff52fdd7726cd371edf6684f67f32a4164d0ff9 100644 (file)
@@ -8,7 +8,7 @@ use bdk_chain::{
     local_chain::CheckPoint,
     BlockId, ConfirmationTimeHeightAnchor, TxGraph,
 };
-use bdk_chain::{Anchor, IndexSpk};
+use bdk_chain::{Anchor, Indexed};
 use esplora_client::{Amount, TxStatus};
 use futures::{stream::FuturesOrdered, TryStreamExt};
 
@@ -236,7 +236,7 @@ async fn full_scan_for_index_and_graph<K: Ord + Clone + Send>(
     client: &esplora_client::AsyncClient,
     keychain_spks: BTreeMap<
         K,
-        impl IntoIterator<IntoIter = impl Iterator<Item = IndexSpk> + Send> + Send,
+        impl IntoIterator<IntoIter = impl Iterator<Item = Indexed<ScriptBuf>> + Send> + Send,
     >,
     stop_gap: usize,
     parallel_requests: usize,
index 0b173c3af507f1f98ad29f5ae4c29d9cbdcfca8b..15036a99a2f206391bfc0aaa89d957250d422089 100644 (file)
@@ -9,7 +9,7 @@ use bdk_chain::{
     local_chain::CheckPoint,
     BlockId, ConfirmationTimeHeightAnchor, TxGraph,
 };
-use bdk_chain::{Anchor, IndexSpk};
+use bdk_chain::{Anchor, Indexed};
 use esplora_client::TxStatus;
 
 use crate::anchor_from_status;
@@ -217,7 +217,7 @@ fn chain_update<A: Anchor>(
 /// [`KeychainTxOutIndex`](bdk_chain::keychain::KeychainTxOutIndex).
 fn full_scan_for_index_and_graph_blocking<K: Ord + Clone>(
     client: &esplora_client::BlockingClient,
-    keychain_spks: BTreeMap<K, impl IntoIterator<Item = IndexSpk>>,
+    keychain_spks: BTreeMap<K, impl IntoIterator<Item = Indexed<ScriptBuf>>>,
     stop_gap: usize,
     parallel_requests: usize,
 ) -> Result<(TxGraph<ConfirmationTimeHeightAnchor>, BTreeMap<K, u32>), Error> {
index 184984122cb14c960963e222970dabb5b34a1e41..33244ca6134c57d4d91ad8fd63f5819c7ea77950 100644 (file)
@@ -29,7 +29,7 @@ use bdk_chain::{
     spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
     tx_graph::{CanonicalTx, TxGraph},
     Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut,
-    IndexSpk, IndexedTxGraph,
+    Indexed, IndexedTxGraph,
 };
 use bdk_persist::{Persist, PersistBackend};
 use bitcoin::secp256k1::{All, Secp256k1};
@@ -752,7 +752,8 @@ impl Wallet {
 
         Ok(AddressInfo {
             index,
-            address: Address::from_script(spk, self.network).expect("must have address form"),
+            address: Address::from_script(spk.as_script(), self.network)
+                .expect("must have address form"),
             keychain,
         })
     }
@@ -809,7 +810,8 @@ impl Wallet {
 
         Ok(AddressInfo {
             index,
-            address: Address::from_script(spk, self.network).expect("must have address form"),
+            address: Address::from_script(spk.as_script(), self.network)
+                .expect("must have address form"),
             keychain,
         })
     }
@@ -910,7 +912,7 @@ impl Wallet {
     /// script pubkeys the wallet is storing internally).
     pub fn all_unbounded_spk_iters(
         &self,
-    ) -> BTreeMap<KeychainKind, impl Iterator<Item = IndexSpk> + Clone> {
+    ) -> BTreeMap<KeychainKind, impl Iterator<Item = Indexed<ScriptBuf>> + Clone> {
         self.indexed_graph.index.all_unbounded_spk_iters()
     }
 
@@ -922,7 +924,7 @@ impl Wallet {
     pub fn unbounded_spk_iter(
         &self,
         keychain: KeychainKind,
-    ) -> impl Iterator<Item = IndexSpk> + Clone {
+    ) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone {
         self.indexed_graph
             .index
             .unbounded_spk_iter(&keychain)
@@ -932,7 +934,7 @@ impl Wallet {
     /// Returns the utxo owned by this wallet corresponding to `outpoint` if it exists in the
     /// wallet's database.
     pub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput> {
-        let (&(keychain, index), _) = self.indexed_graph.index.txout(op)?;
+        let ((keychain, index), _) = self.indexed_graph.index.txout(op)?;
         self.indexed_graph
             .graph()
             .filter_chain_unspents(
@@ -1511,7 +1513,6 @@ impl Wallet {
                     .index
                     .next_unused_spk(&change_keychain)
                     .expect("keychain must exist");
-                let spk = spk.into();
                 self.indexed_graph.index.mark_used(change_keychain, index);
                 self.persist
                     .stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from(
index 993bde416c4c7c97566c683233784ca0d800ae8f..3c69a506f11808e965476c657ae0b1b4b4ccddc9 100644 (file)
@@ -265,9 +265,6 @@ where
         .expect("Must exist");
     changeset.append(change_changeset);
 
-    // Clone to drop the immutable reference.
-    let change_script = change_script.into();
-
     let change_plan = bdk_tmp_plan::plan_satisfaction(
         &graph
             .index
@@ -481,8 +478,8 @@ where
                         local_chain::ChangeSet::default(),
                         indexed_tx_graph::ChangeSet::from(index_changeset),
                     )))?;
-                    let addr =
-                        Address::from_script(spk, network).context("failed to derive address")?;
+                    let addr = Address::from_script(spk.as_script(), network)
+                        .context("failed to derive address")?;
                     println!("[address @ {}] {}", spk_i, addr);
                     Ok(())
                 }
index 175b7ce59d0b0507f58185e91b1b5df7423005b4..38443e14c433f500e70025a25bb8b0b64cb62b28 100644 (file)
@@ -228,7 +228,7 @@ fn main() -> anyhow::Result<()> {
                 let all_spks = graph
                     .index
                     .revealed_spks(..)
-                    .map(|(index, spk)| (index.to_owned(), spk.to_owned()))
+                    .map(|(index, spk)| (index, spk.to_owned()))
                     .collect::<Vec<_>>();
                 request = request.chain_spks(all_spks.into_iter().map(|((k, spk_i), spk)| {
                     eprint!("Scanning {}: {}", k, spk_i);
@@ -239,7 +239,7 @@ fn main() -> anyhow::Result<()> {
                 let unused_spks = graph
                     .index
                     .unused_spks()
-                    .map(|(index, spk)| (index.to_owned(), spk.to_owned()))
+                    .map(|(index, spk)| (index, spk.to_owned()))
                     .collect::<Vec<_>>();
                 request =
                     request.chain_spks(unused_spks.into_iter().map(move |((k, spk_i), spk)| {
index d0b167269cc985d5a6e3d818654f05b3dfaf6187..3e605a037f48abd06fbf4068368777fe74d57435 100644 (file)
@@ -245,7 +245,7 @@ fn main() -> anyhow::Result<()> {
                     let all_spks = graph
                         .index
                         .revealed_spks(..)
-                        .map(|((k, i), spk)| (k.to_owned(), *i, spk.to_owned()))
+                        .map(|((k, i), spk)| (ki, spk.to_owned()))
                         .collect::<Vec<_>>();
                     request = request.chain_spks(all_spks.into_iter().map(|(k, i, spk)| {
                         eprint!("scanning {}:{}", k, i);
@@ -258,7 +258,7 @@ fn main() -> anyhow::Result<()> {
                     let unused_spks = graph
                         .index
                         .unused_spks()
-                        .map(|(index, spk)| (index.to_owned(), spk.to_owned()))
+                        .map(|(index, spk)| (index, spk.to_owned()))
                         .collect::<Vec<_>>();
                     request =
                         request.chain_spks(unused_spks.into_iter().map(move |((k, i), spk)| {