From 101a09a97fa5e8d675c13396b9a800665b1b6c22 Mon Sep 17 00:00:00 2001 From: LLFourn Date: Fri, 7 Jun 2024 12:29:58 +1000 Subject: [PATCH] chore(chain): Standardise KeychainTxOutIndex return types The previous commit b9c5b9d08b040faf6c6b2d9b3745918031555b72 added IndexSpk. This goes further and adds `Indexed` and `KeychainIndexed` type alises (IndexSpk is Indexed) and attempts to standardize the structure of return types more generally. --- crates/chain/src/keychain.rs | 7 +- crates/chain/src/keychain/txout_index.rs | 114 ++++++++++-------- crates/chain/src/lib.rs | 1 + crates/chain/src/spk_client.rs | 9 +- crates/chain/src/spk_iter.rs | 6 +- .../chain/tests/test_keychain_txout_index.rs | 18 +-- crates/esplora/src/async_ext.rs | 4 +- crates/esplora/src/blocking_ext.rs | 4 +- crates/wallet/src/wallet/mod.rs | 15 +-- example-crates/example_cli/src/lib.rs | 7 +- example-crates/example_electrum/src/main.rs | 4 +- example-crates/example_esplora/src/main.rs | 4 +- 12 files changed, 103 insertions(+), 90 deletions(-) diff --git a/crates/chain/src/keychain.rs b/crates/chain/src/keychain.rs index b822dc901..e1e6de68c 100644 --- a/crates/chain/src/keychain.rs +++ b/crates/chain/src/keychain.rs @@ -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 = (u32, T); +/// A tuple of keychain, index and the [`ScriptBuf`] derived at that location. +pub type KeychainIndexed = ((K, u32), T); + impl core::fmt::Display for Balance { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs index 6d0b7623a..f62c2f164 100644 --- a/crates/chain/src/keychain/txout_index.rs +++ b/crates/chain/src/keychain/txout_index.rs @@ -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 { inner: SpkTxOutIndex<(K, u32)>, - // keychain -> (descriptor, descriptor id) map + /// keychain -> (descriptor id) map keychains_to_descriptor_ids: BTreeMap, - // descriptor id -> keychain map + /// descriptor id -> keychain map descriptor_ids_to_keychains: BTreeMap, - // 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>, - // last revealed indexes + /// last revealed indices for each descriptor. last_revealed: HashMap, - // lookahead settings for each keychain + /// lookahead setting lookahead: u32, } @@ -292,21 +293,28 @@ impl KeychainTxOutIndex { } /// Get the set of indexed outpoints, corresponding to tracked keychains. - pub fn outpoints(&self) -> &BTreeSet<((K, u32), OutPoint)> { + pub fn outpoints(&self) -> &BTreeSet> { self.inner.outpoints() } /// Iterate over known txouts that spend to tracked script pubkeys. - pub fn txouts(&self) -> impl DoubleEndedIterator + '_ { - self.inner.txouts() + pub fn txouts( + &self, + ) -> impl DoubleEndedIterator> + 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 { - self.inner.txouts_in_tx(txid) + ) -> impl DoubleEndedIterator> { + 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 KeychainTxOutIndex { /// 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> { + 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 KeychainTxOutIndex { /// 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`]. pub fn insert_descriptor( &mut self, keychain: K, @@ -575,7 +585,7 @@ impl KeychainTxOutIndex { pub fn revealed_spks( &self, range: impl RangeBounds, - ) -> impl Iterator { + ) -> impl Iterator> { let start = range.start_bound(); let end = range.end_bound(); let mut iter_last_revealed = self @@ -593,8 +603,7 @@ impl KeychainTxOutIndex { // 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 KeychainTxOutIndex { 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 KeychainTxOutIndex { pub fn revealed_keychain_spks<'a>( &'a self, keychain: &'a K, - ) -> impl DoubleEndedIterator + 'a { + ) -> impl DoubleEndedIterator> + 'a { let end = self .last_revealed_index(keychain) .map(|v| v + 1) @@ -627,7 +636,9 @@ impl KeychainTxOutIndex { } /// Iterate over revealed, but unused, spks of all keychains. - pub fn unused_spks(&self) -> impl DoubleEndedIterator + Clone { + pub fn unused_spks( + &self, + ) -> impl DoubleEndedIterator> + Clone { self.keychains_to_descriptor_ids .keys() .flat_map(|keychain| { @@ -641,7 +652,7 @@ impl KeychainTxOutIndex { pub fn unused_keychain_spks( &self, keychain: &K, - ) -> impl DoubleEndedIterator + Clone { + ) -> impl DoubleEndedIterator> + 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 KeychainTxOutIndex { &mut self, keychain: &K, target_index: u32, - ) -> Option<(Vec, ChangeSet)> { + ) -> Option<(Vec>, ChangeSet)> { let mut changeset = ChangeSet::default(); - let mut spks: Vec = vec![]; + let mut spks: Vec> = 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 KeychainTxOutIndex { /// 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)> { + pub fn reveal_next_spk(&mut self, keychain: &K) -> Option<(Indexed, ChangeSet)> { let (next_index, new) = self.next_index(keychain)?; let mut changeset = ChangeSet::default(); @@ -790,7 +801,7 @@ impl KeychainTxOutIndex { .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 KeychainTxOutIndex { /// 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)> { - 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, ChangeSet)> { + 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 KeychainTxOutIndex { pub fn keychain_outpoints<'a>( &'a self, keychain: &'a K, - ) -> impl DoubleEndedIterator + 'a { + ) -> impl DoubleEndedIterator> + '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 + 'a, - ) -> impl DoubleEndedIterator + 'a { - self.inner.outputs_in_range(self.map_to_inner_bounds(range)) + ) -> impl DoubleEndedIterator> + '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) -> impl RangeBounds<(K, u32)> { diff --git a/crates/chain/src/lib.rs b/crates/chain/src/lib.rs index 970969942..8204cf0eb 100644 --- a/crates/chain/src/lib.rs +++ b/crates/chain/src/lib.rs @@ -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; diff --git a/crates/chain/src/spk_client.rs b/crates/chain/src/spk_client.rs index cf78e7bdd..3cb87a407 100644 --- a/crates/chain/src/spk_client.rs +++ b/crates/chain/src/spk_client.rs @@ -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 { /// [`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 + Send>>, + pub spks_by_keychain: BTreeMap> + Send>>, } impl FullScanRequest { @@ -238,7 +239,7 @@ impl FullScanRequest { pub fn set_spks_for_keychain( mut self, keychain: K, - spks: impl IntoIterator + Send + 'static>, + spks: impl IntoIterator> + Send + 'static>, ) -> Self { self.spks_by_keychain .insert(keychain, Box::new(spks.into_iter())); @@ -252,7 +253,7 @@ impl FullScanRequest { pub fn chain_spks_for_keychain( mut self, keychain: K, - spks: impl IntoIterator + Send + 'static>, + spks: impl IntoIterator> + Send + 'static>, ) -> Self { match self.spks_by_keychain.remove(&keychain) { // clippy here suggests to remove `into_iter` from `spks.into_iter()`, but doing so diff --git a/crates/chain/src/spk_iter.rs b/crates/chain/src/spk_iter.rs index 8285036bf..dd4c0a8f5 100644 --- a/crates/chain/src/spk_iter.rs +++ b/crates/chain/src/spk_iter.rs @@ -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 Iterator for SpkIterator where D: Borrow>, { - type Item = IndexSpk; + type Item = Indexed; fn next(&mut self) -> Option { // For non-wildcard descriptors, we expect the first element to be Some((0, spk)), then None after. diff --git a/crates/chain/tests/test_keychain_txout_index.rs b/crates/chain/tests/test_keychain_txout_index.rs index c5fd974cb..2c1c34e70 100644 --- a/crates/chain/tests/test_keychain_txout_index.rs +++ b/crates/chain/tests/test_keychain_txout_index.rs @@ -408,10 +408,10 @@ fn test_wildcard_derivations() { // - next_unused() == ((0, ), 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) diff --git a/crates/esplora/src/async_ext.rs b/crates/esplora/src/async_ext.rs index a7dbc24fc..dff52fdd7 100644 --- a/crates/esplora/src/async_ext.rs +++ b/crates/esplora/src/async_ext.rs @@ -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( client: &esplora_client::AsyncClient, keychain_spks: BTreeMap< K, - impl IntoIterator + Send> + Send, + impl IntoIterator> + Send> + Send, >, stop_gap: usize, parallel_requests: usize, diff --git a/crates/esplora/src/blocking_ext.rs b/crates/esplora/src/blocking_ext.rs index 0b173c3af..15036a99a 100644 --- a/crates/esplora/src/blocking_ext.rs +++ b/crates/esplora/src/blocking_ext.rs @@ -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( /// [`KeychainTxOutIndex`](bdk_chain::keychain::KeychainTxOutIndex). fn full_scan_for_index_and_graph_blocking( client: &esplora_client::BlockingClient, - keychain_spks: BTreeMap>, + keychain_spks: BTreeMap>>, stop_gap: usize, parallel_requests: usize, ) -> Result<(TxGraph, BTreeMap), Error> { diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 184984122..33244ca61 100644 --- a/crates/wallet/src/wallet/mod.rs +++ b/crates/wallet/src/wallet/mod.rs @@ -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 + Clone> { + ) -> BTreeMap> + 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 + Clone { + ) -> impl Iterator> + 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 { - 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( diff --git a/example-crates/example_cli/src/lib.rs b/example-crates/example_cli/src/lib.rs index 993bde416..3c69a506f 100644 --- a/example-crates/example_cli/src/lib.rs +++ b/example-crates/example_cli/src/lib.rs @@ -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(()) } diff --git a/example-crates/example_electrum/src/main.rs b/example-crates/example_electrum/src/main.rs index 175b7ce59..38443e14c 100644 --- a/example-crates/example_electrum/src/main.rs +++ b/example-crates/example_electrum/src/main.rs @@ -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::>(); 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::>(); request = request.chain_spks(unused_spks.into_iter().map(move |((k, spk_i), spk)| { diff --git a/example-crates/example_esplora/src/main.rs b/example-crates/example_esplora/src/main.rs index d0b167269..3e605a037 100644 --- a/example-crates/example_esplora/src/main.rs +++ b/example-crates/example_esplora/src/main.rs @@ -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)| (k, i, spk.to_owned())) .collect::>(); 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::>(); request = request.chain_spks(unused_spks.into_iter().map(move |((k, i), spk)| {