}
AddressIndex::Peek(index) => {
let (index, spk) = txout_index
- .spks_of_keychain(&keychain)
+ .unbounded_spk_iter(&keychain)
.take(index as usize + 1)
.last()
.unwrap();
///
/// Will only return `Some(_)` if the wallet has given out the spk.
pub fn derivation_of_spk(&self, spk: &Script) -> Option<(KeychainKind, u32)> {
- self.indexed_graph.index.index_of_spk(spk).copied()
+ self.indexed_graph.index.index_of_spk(spk)
}
/// Return the list of unspent outputs of this wallet
self.chain.tip()
}
- /// Returns a iterators of all the script pubkeys for the `Internal` and External` variants in `KeychainKind`.
+ /// Returns a iterators of all the script pubkeys for the `Internal` and `External` variants in
+ /// `KeychainKind`.
///
/// This is intended to be used when doing a full scan of your addresses (e.g. after restoring
/// from seed words). You pass the `BTreeMap` of iterators to a blockchain data source (e.g.
///
/// Note carefully that iterators go over **all** script pubkeys on the keychains (not what
/// script pubkeys the wallet is storing internally).
- pub fn spks_of_all_keychains(
+ pub fn all_unbounded_spk_iters(
&self,
) -> BTreeMap<KeychainKind, impl Iterator<Item = (u32, ScriptBuf)> + Clone> {
- self.indexed_graph.index.spks_of_all_keychains()
+ self.indexed_graph.index.all_unbounded_spk_iters()
}
/// Gets an iterator over all the script pubkeys in a single keychain.
///
- /// See [`spks_of_all_keychains`] for more documentation
+ /// See [`all_unbounded_spk_iters`] for more documentation
///
- /// [`spks_of_all_keychains`]: Self::spks_of_all_keychains
- pub fn spks_of_keychain(
+ /// [`all_unbounded_spk_iters`]: Self::all_unbounded_spk_iters
+ pub fn unbounded_spk_iter(
&self,
keychain: KeychainKind,
) -> impl Iterator<Item = (u32, ScriptBuf)> + Clone {
- self.indexed_graph.index.spks_of_keychain(&keychain)
+ self.indexed_graph.index.unbounded_spk_iter(&keychain)
}
/// 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 (&spk_i, _) = self.indexed_graph.index.txout(op)?;
+ let (keychain, index, _) = self.indexed_graph.index.txout(op)?;
self.indexed_graph
.graph()
.filter_chain_unspents(
&self.chain,
self.chain.tip().block_id(),
- core::iter::once((spk_i, op)),
+ core::iter::once(((), op)),
)
- .map(|((k, i), full_txo)| new_local_utxo(k, i, full_txo))
+ .map(|(_, full_txo)| new_local_utxo(keychain, index, full_txo))
.next()
}
let ((index, spk), index_changeset) =
self.indexed_graph.index.next_unused_spk(&change_keychain);
let spk = spk.into();
- self.indexed_graph.index.mark_used(&change_keychain, index);
+ self.indexed_graph.index.mark_used(change_keychain, index);
self.persist
.stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from(
index_changeset,
.into();
let weighted_utxo = match txout_index.index_of_spk(&txout.script_pubkey) {
- Some(&(keychain, derivation_index)) => {
+ Some((keychain, derivation_index)) => {
#[allow(deprecated)]
let satisfaction_weight = self
.get_descriptor_for_keychain(keychain)
for (index, txout) in tx.output.iter().enumerate() {
let change_type = self.map_keychain(KeychainKind::Internal);
match txout_index.index_of_spk(&txout.script_pubkey) {
- Some(&(keychain, _)) if keychain == change_type => change_index = Some(index),
+ Some((keychain, _)) if keychain == change_type => change_index = Some(index),
_ => {}
}
}
pub fn cancel_tx(&mut self, tx: &Transaction) {
let txout_index = &mut self.indexed_graph.index;
for txout in &tx.output {
- if let Some(&(keychain, index)) = txout_index.index_of_spk(&txout.script_pubkey) {
+ if let Some((keychain, index)) = txout_index.index_of_spk(&txout.script_pubkey) {
// NOTE: unmark_used will **not** make something unused if it has actually been used
// by a tx in the tracker. It only removes the superficial marking.
- txout_index.unmark_used(&keychain, index);
+ txout_index.unmark_used(keychain, index);
}
}
}
}
fn get_descriptor_for_txout(&self, txout: &TxOut) -> Option<DerivedDescriptor> {
- let &(keychain, child) = self
+ let (keychain, child) = self
.indexed_graph
.index
.index_of_spk(&txout.script_pubkey)?;
{
// Try to find the prev_script in our db to figure out if this is internal or external,
// and the derivation index
- let &(keychain, child) = self
+ let (keychain, child) = self
.indexed_graph
.index
.index_of_spk(&utxo.txout.script_pubkey)
// Try to figure out the keychain and derivation for every input and output
for (is_input, index, out) in utxos.into_iter() {
- if let Some(&(keychain, child)) =
+ if let Some((keychain, child)) =
self.indexed_graph.index.index_of_spk(&out.script_pubkey)
{
let desc = self.get_descriptor_for_keychain(keychain);
spk_iter::BIP32_MAX_INDEX,
SpkIterator, SpkTxOutIndex,
};
-use bitcoin::{OutPoint, Script, TxOut};
-use core::{fmt::Debug, ops::Deref};
+use bitcoin::{OutPoint, Script, Transaction, TxOut};
+use core::fmt::Debug;
use crate::Append;
}
}
-impl<K> Deref for KeychainTxOutIndex<K> {
- type Target = SpkTxOutIndex<(K, u32)>;
-
- fn deref(&self) -> &Self::Target {
- &self.inner
- }
-}
-
impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
type ChangeSet = super::ChangeSet<K>;
}
fn is_tx_relevant(&self, tx: &bitcoin::Transaction) -> bool {
- self.is_relevant(tx)
+ self.inner.is_relevant(tx)
}
}
}
}
+/// Methods that are *re-exposed* from the internal [`SpkTxOutIndex`].
impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
/// Return a reference to the internal [`SpkTxOutIndex`].
+ ///
+ /// **WARNING:** The internal index will contain lookahead spks.
pub fn inner(&self) -> &SpkTxOutIndex<(K, u32)> {
&self.inner
}
self.inner.outpoints()
}
- /// Return a reference to the internal map of the keychain to descriptors.
+ /// Return the [`TxOut`] of `outpoint` if it has been indexed.
+ ///
+ /// 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)
+ .map(|((k, i), txo)| (k.clone(), *i, txo))
+ }
+
+ /// Return the script that exists under the given `keychain`'s `index`.
+ ///
+ /// This calls [`SpkTxOutIndex::spk_at_index`] internally.
+ pub fn spk_at_index(&self, keychain: K, index: u32) -> Option<&Script> {
+ self.inner.spk_at_index(&(keychain, index))
+ }
+
+ /// Returns the keychain and keychain index associated with the spk.
+ ///
+ /// This calls [`SpkTxOutIndex::index_of_spk`] internally.
+ pub fn index_of_spk(&self, script: &Script) -> Option<(K, u32)> {
+ self.inner.index_of_spk(script).cloned()
+ }
+
+ /// Returns whether the spk under the `keychain`'s `index` has been used.
+ ///
+ /// Here, "unused" means that after the script pubkey was stored in the index, the index has
+ /// never scanned a transaction output with it.
+ ///
+ /// This calls [`SpkTxOutIndex::is_used`] internally.
+ pub fn is_used(&self, keychain: K, index: u32) -> bool {
+ self.inner.is_used(&(keychain, index))
+ }
+
+ /// Marks the script pubkey at `index` as used even though the tracker hasn't seen an output
+ /// with it.
+ ///
+ /// This only has an effect when the `index` had been added to `self` already and was unused.
+ ///
+ /// Returns whether the `index` was initially present as `unused`.
+ ///
+ /// This is useful when you want to reserve a script pubkey for something but don't want to add
+ /// the transaction output using it to the index yet. Other callers will consider `index` on
+ /// `keychain` used until you call [`unmark_used`].
+ ///
+ /// This calls [`SpkTxOutIndex::mark_used`] internally.
+ ///
+ /// [`unmark_used`]: Self::unmark_used
+ pub fn mark_used(&mut self, keychain: K, index: u32) -> bool {
+ self.inner.mark_used(&(keychain, index))
+ }
+
+ /// Undoes the effect of [`mark_used`]. Returns whether the `index` is inserted back into
+ /// `unused`.
+ ///
+ /// Note that if `self` has scanned an output with this script pubkey, then this will have no
+ /// effect.
+ ///
+ /// This calls [`SpkTxOutIndex::unmark_used`] internally.
+ ///
+ /// [`mark_used`]: Self::mark_used
+ pub fn unmark_used(&mut self, keychain: K, index: u32) -> bool {
+ self.inner.unmark_used(&(keychain, index))
+ }
+
+ /// Computes total input value going from script pubkeys in the index (sent) and the total output
+ /// value going to script pubkeys in the index (received) in `tx`. For the `sent` to be computed
+ /// correctly, the output being spent must have already been scanned by the index. Calculating
+ /// received just uses the [`Transaction`] outputs directly, so it will be correct even if it has
+ /// not been scanned.
+ ///
+ /// This calls [`SpkTxOutIndex::sent_and_received`] internally.
+ pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64) {
+ self.inner.sent_and_received(tx)
+ }
+
+ /// Computes the net value that this transaction gives to the script pubkeys in the index and
+ /// *takes* from the transaction outputs in the index. Shorthand for calling
+ /// [`sent_and_received`] and subtracting sent from received.
+ ///
+ /// This calls [`SpkTxOutIndex::net_value`] internally.
+ ///
+ /// [`sent_and_received`]: Self::sent_and_received
+ pub fn net_value(&self, tx: &Transaction) -> i64 {
+ self.inner.net_value(tx)
+ }
+}
+
+impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
+ /// Return a reference to the internal map of keychain to descriptors.
pub fn keychains(&self) -> &BTreeMap<K, Descriptor<DescriptorPublicKey>> {
&self.keychains
}
.map_or(0, |((_, index), _)| *index + 1)
}
- /// Generates script pubkey iterators for every `keychain`. The iterators iterate over all
- /// derivable script pubkeys.
- pub fn spks_of_all_keychains(
+ /// Get an unbounded spk iterator over a given `keychain`.
+ ///
+ /// # Panics
+ ///
+ /// This will panic if the given `keychain`'s descriptor does not exist.
+ pub fn unbounded_spk_iter(&self, keychain: &K) -> SpkIterator<Descriptor<DescriptorPublicKey>> {
+ SpkIterator::new(
+ self.keychains
+ .get(keychain)
+ .expect("keychain does not exist")
+ .clone(),
+ )
+ }
+
+ /// Get unbounded spk iterators for all keychains.
+ pub fn all_unbounded_spk_iters(
&self,
) -> BTreeMap<K, SpkIterator<Descriptor<DescriptorPublicKey>>> {
self.keychains
.iter()
- .map(|(keychain, descriptor)| {
- (
- keychain.clone(),
- SpkIterator::new_with_range(descriptor.clone(), 0..),
- )
- })
+ .map(|(k, descriptor)| (k.clone(), SpkIterator::new(descriptor.clone())))
.collect()
}
- /// Generates a script pubkey iterator for the given `keychain`'s descriptor (if it exists). The
- /// iterator iterates over all derivable scripts of the keychain's descriptor.
- ///
- /// # Panics
- ///
- /// This will panic if the `keychain` does not exist.
- pub fn spks_of_keychain(&self, keychain: &K) -> SpkIterator<Descriptor<DescriptorPublicKey>> {
- let descriptor = self
- .keychains
- .get(keychain)
- .expect("keychain must exist")
- .clone();
- SpkIterator::new_with_range(descriptor, 0..)
+ /// Iterate over revealed spks of all keychains.
+ pub fn revealed_spks(&self) -> impl DoubleEndedIterator<Item = (K, u32, &Script)> + Clone {
+ self.keychains.keys().flat_map(|keychain| {
+ self.revealed_keychain_spks(keychain)
+ .map(|(i, spk)| (keychain.clone(), i, spk))
+ })
}
- /// Convenience method to get [`revealed_spks_of_keychain`] of all keychains.
- ///
- /// [`revealed_spks_of_keychain`]: Self::revealed_spks_of_keychain
- pub fn revealed_spks_of_all_keychains(
+ /// Iterate over revealed spks of the given `keychain`.
+ pub fn revealed_keychain_spks(
&self,
- ) -> BTreeMap<K, impl Iterator<Item = (u32, &Script)> + Clone> {
- self.keychains
- .keys()
- .map(|keychain| (keychain.clone(), self.revealed_spks_of_keychain(keychain)))
- .collect()
+ keychain: &K,
+ ) -> impl DoubleEndedIterator<Item = (u32, &Script)> + Clone {
+ let next_i = self.last_revealed.get(keychain).map_or(0, |&i| i + 1);
+ self.inner
+ .all_spks()
+ .range((keychain.clone(), u32::MIN)..(keychain.clone(), next_i))
+ .map(|((_, i), spk)| (*i, spk.as_script()))
}
- /// Iterates over the script pubkeys revealed by this index under `keychain`.
- pub fn revealed_spks_of_keychain(
+ /// Iterate over revealed, but unused, spks of all keychains.
+ pub fn unused_spks(&self) -> impl DoubleEndedIterator<Item = (K, u32, &Script)> + Clone {
+ self.keychains.keys().flat_map(|keychain| {
+ self.unused_keychain_spks(keychain)
+ .map(|(i, spk)| (keychain.clone(), i, spk))
+ })
+ }
+
+ /// Iterate over revealed, but unused, spks of the given `keychain`.
+ pub fn unused_keychain_spks(
&self,
keychain: &K,
) -> impl DoubleEndedIterator<Item = (u32, &Script)> + Clone {
- let next_index = self.last_revealed.get(keychain).map_or(0, |v| *v + 1);
+ let next_i = self.last_revealed.get(keychain).map_or(0, |&i| i + 1);
self.inner
- .all_spks()
- .range((keychain.clone(), u32::MIN)..(keychain.clone(), next_index))
- .map(|((_, derivation_index), spk)| (*derivation_index, spk.as_script()))
+ .unused_spks((keychain.clone(), u32::MIN)..(keychain.clone(), next_i))
+ .map(|((_, i), spk)| (*i, spk))
}
/// Get the next derivation index for `keychain`. The next index is the index after the last revealed
///
/// Panics if `keychain` has never been added to the index
pub fn next_unused_spk(&mut self, keychain: &K) -> ((u32, &Script), super::ChangeSet<K>) {
- let need_new = self.unused_spks_of_keychain(keychain).next().is_none();
+ 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 {
(
- self.unused_spks_of_keychain(keychain)
+ self.unused_keychain_spks(keychain)
.next()
.expect("we already know next exists"),
super::ChangeSet::default(),
}
}
- /// Marks the script pubkey at `index` as used even though the tracker hasn't seen an output with it.
- /// This only has an effect when the `index` had been added to `self` already and was unused.
- ///
- /// Returns whether the `index` was initially present as `unused`.
- ///
- /// This is useful when you want to reserve a script pubkey for something but don't want to add
- /// the transaction output using it to the index yet. Other callers will consider `index` on
- /// `keychain` used until you call [`unmark_used`].
- ///
- /// [`unmark_used`]: Self::unmark_used
- pub fn mark_used(&mut self, keychain: &K, index: u32) -> bool {
- self.inner.mark_used(&(keychain.clone(), index))
- }
-
- /// Undoes the effect of [`mark_used`]. Returns whether the `index` is inserted back into
- /// `unused`.
- ///
- /// Note that if `self` has scanned an output with this script pubkey, then this will have no
- /// effect.
- ///
- /// [`mark_used`]: Self::mark_used
- pub fn unmark_used(&mut self, keychain: &K, index: u32) -> bool {
- self.inner.unmark_used(&(keychain.clone(), index))
- }
-
- /// Iterates over all unused script pubkeys for a `keychain` stored in the index.
- pub fn unused_spks_of_keychain(
- &self,
- keychain: &K,
- ) -> impl DoubleEndedIterator<Item = (u32, &Script)> {
- let next_index = self.last_revealed.get(keychain).map_or(0, |&v| v + 1);
- let range = (keychain.clone(), u32::MIN)..(keychain.clone(), next_index);
- self.inner
- .unused_spks(range)
- .map(|((_, i), script)| (*i, script))
- }
-
/// Iterates over all the [`OutPoint`] that have a `TxOut` with a script pubkey derived from
/// `keychain`.
- pub fn txouts_of_keychain(
+ pub fn keychain_outpoints(
&self,
keychain: &K,
) -> impl DoubleEndedIterator<Item = (u32, OutPoint)> + '_ {
/// Returns the highest derivation index of the `keychain` where [`KeychainTxOutIndex`] has
/// found a [`TxOut`] with it's script pubkey.
pub fn last_used_index(&self, keychain: &K) -> Option<u32> {
- self.txouts_of_keychain(keychain).last().map(|(i, _)| i)
+ self.keychain_outpoints(keychain).last().map(|(i, _)| i)
}
/// Returns the highest derivation index of each keychain that [`KeychainTxOutIndex`] has found
);
assert_eq!(
txout_index
- .revealed_spks_of_keychain(&TestKeychain::External)
+ .revealed_keychain_spks(&TestKeychain::External)
.count(),
index as usize + 1,
);
assert_eq!(
txout_index
- .revealed_spks_of_keychain(&TestKeychain::Internal)
+ .revealed_keychain_spks(&TestKeychain::Internal)
.count(),
0,
);
assert_eq!(
txout_index
- .unused_spks_of_keychain(&TestKeychain::External)
+ .unused_keychain_spks(&TestKeychain::External)
.count(),
index as usize + 1,
);
assert_eq!(
txout_index
- .unused_spks_of_keychain(&TestKeychain::Internal)
+ .unused_keychain_spks(&TestKeychain::Internal)
.count(),
0,
);
);
assert_eq!(
txout_index
- .revealed_spks_of_keychain(&TestKeychain::Internal)
+ .revealed_keychain_spks(&TestKeychain::Internal)
.count(),
25,
);
);
assert_eq!(
txout_index
- .revealed_spks_of_keychain(&TestKeychain::External)
+ .revealed_keychain_spks(&TestKeychain::External)
.count(),
last_external_index as usize + 1,
);
assert_eq!(
txout_index
- .revealed_spks_of_keychain(&TestKeychain::Internal)
+ .revealed_keychain_spks(&TestKeychain::Internal)
.count(),
last_internal_index as usize + 1,
);
(0..=15)
.chain([17, 20, 23])
- .for_each(|index| assert!(txout_index.mark_used(&TestKeychain::External, index)));
+ .for_each(|index| assert!(txout_index.mark_used(TestKeychain::External, index)));
assert_eq!(txout_index.next_index(&TestKeychain::External), (26, true));
// - Use all the derived till 26.
// - next_unused() = ((27, <spk>), keychain::ChangeSet)
(0..=26).for_each(|index| {
- txout_index.mark_used(&TestKeychain::External, index);
+ txout_index.mark_used(TestKeychain::External, index);
});
let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External);
// - derive new and next unused should return the old script
// - store_up_to should not panic and return empty changeset
assert_eq!(txout_index.next_index(&TestKeychain::External), (0, false));
- txout_index.mark_used(&TestKeychain::External, 0);
+ txout_index.mark_used(TestKeychain::External, 0);
let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External);
assert_eq!(spk, (0, external_spk.as_script()));
// we check that spks_of_keychain returns a SpkIterator with just one element
assert_eq!(
txout_index
- .spks_of_keychain(&TestKeychain::External)
+ .revealed_keychain_spks(&TestKeychain::External)
.count(),
1,
);
) -> Result<(ElectrumUpdate, BTreeMap<K, u32>), Error> {
let mut request_spks = keychain_spks
.into_iter()
- .map(|(k, s)| (k, s.into_iter()))
+ .map(|(k, s)| (k.clone(), s.into_iter()))
.collect::<BTreeMap<K, _>>();
let mut scanned_spks = BTreeMap::<(K, u32), (ScriptBuf, bool)>::new();
true => Keychain::Internal,
false => Keychain::External,
};
- for (spk_i, spk) in index.revealed_spks_of_keychain(&target_keychain) {
+ for (spk_i, spk) in index.revealed_keychain_spks(&target_keychain) {
let address = Address::from_script(spk, network)
.expect("should always be able to derive address");
println!(
"{:?} {} used:{}",
spk_i,
address,
- index.is_used(&(target_keychain, spk_i))
+ index.is_used(target_keychain, spk_i)
);
}
Ok(())
// We don't want other callers/threads to use this address while we're using it
// but we also don't want to scan the tx we just created because it's not
// technically in the blockchain yet.
- graph.index.mark_used(&change_keychain, index);
+ graph.index.mark_used(change_keychain, index);
(tx, Some((change_keychain, index)))
} else {
(tx, None)
Err(e) => {
if let Some((keychain, index)) = change_index {
// We failed to broadcast, so allow our change address to be used in the future
- graph.lock().unwrap().index.unmark_used(&keychain, index);
+ graph.lock().unwrap().index.unmark_used(keychain, index);
}
Err(e)
}
};
use bdk_chain::{
- bitcoin::{constants::genesis_block, Address, Network, OutPoint, ScriptBuf, Txid},
+ bitcoin::{constants::genesis_block, Address, Network, OutPoint, Txid},
indexed_tx_graph::{self, IndexedTxGraph},
keychain,
local_chain::{self, LocalChain},
let keychain_spks = graph
.index
- .spks_of_all_keychains()
+ .all_unbounded_spk_iters()
.into_iter()
.map(|(keychain, iter)| {
let mut first = true;
if all_spks {
let all_spks = graph
.index
- .all_spks()
- .iter()
- .map(|(k, v)| (*k, v.clone()))
+ .revealed_spks()
+ .map(|(k, i, spk)| (k, i, spk.to_owned()))
.collect::<Vec<_>>();
- spks = Box::new(spks.chain(all_spks.into_iter().map(|(index, script)| {
- eprintln!("scanning {:?}", index);
- script
+ spks = Box::new(spks.chain(all_spks.into_iter().map(|(k, i, spk)| {
+ eprintln!("scanning {}:{}", k, i);
+ spk
})));
}
if unused_spks {
let unused_spks = graph
.index
- .unused_spks(..)
- .map(|(k, v)| (*k, ScriptBuf::from(v)))
+ .unused_spks()
+ .map(|(k, i, spk)| (k, i, spk.to_owned()))
.collect::<Vec<_>>();
- spks = Box::new(spks.chain(unused_spks.into_iter().map(|(index, script)| {
+ spks = Box::new(spks.chain(unused_spks.into_iter().map(|(k, i, spk)| {
eprintln!(
- "Checking if address {} {:?} has been used",
- Address::from_script(&script, args.network).unwrap(),
- index
+ "Checking if address {} {}:{} has been used",
+ Address::from_script(&spk, args.network).unwrap(),
+ k,
+ i,
);
-
- script
+ spk
})));
}
.lock()
.expect("mutex must not be poisoned")
.index
- .spks_of_all_keychains()
+ .all_unbounded_spk_iters()
.into_iter()
// This `map` is purely for logging.
.map(|(keychain, iter)| {
if *all_spks {
let all_spks = graph
.index
- .all_spks()
- .iter()
- .map(|(k, v)| (*k, v.clone()))
+ .revealed_spks()
+ .map(|(k, i, spk)| (k, i, spk.to_owned()))
.collect::<Vec<_>>();
- spks = Box::new(spks.chain(all_spks.into_iter().map(|(index, script)| {
- eprintln!("scanning {:?}", index);
+ spks = Box::new(spks.chain(all_spks.into_iter().map(|(k, i, spk)| {
+ eprintln!("scanning {}:{}", k, i);
// Flush early to ensure we print at every iteration.
let _ = io::stderr().flush();
- script
+ spk
})));
}
if unused_spks {
let unused_spks = graph
.index
- .unused_spks(..)
- .map(|(k, v)| (*k, v.to_owned()))
+ .unused_spks()
+ .map(|(k, i, spk)| (k, i, spk.to_owned()))
.collect::<Vec<_>>();
- spks = Box::new(spks.chain(unused_spks.into_iter().map(|(index, script)| {
+ spks = Box::new(spks.chain(unused_spks.into_iter().map(|(k, i, spk)| {
eprintln!(
- "Checking if address {} {:?} has been used",
- Address::from_script(&script, args.network).unwrap(),
- index
+ "Checking if address {} {}:{} has been used",
+ Address::from_script(&spk, args.network).unwrap(),
+ k,
+ i,
);
// Flush early to ensure we print at every iteration.
let _ = io::stderr().flush();
- script
+ spk
})));
}
if utxos {
let prev_tip = wallet.latest_checkpoint();
let keychain_spks = wallet
- .spks_of_all_keychains()
+ .all_unbounded_spk_iters()
.into_iter()
.map(|(k, k_spks)| {
let mut once = Some(());
let prev_tip = wallet.latest_checkpoint();
let keychain_spks = wallet
- .spks_of_all_keychains()
+ .all_unbounded_spk_iters()
.into_iter()
.map(|(k, k_spks)| {
let mut once = Some(());
let prev_tip = wallet.latest_checkpoint();
let keychain_spks = wallet
- .spks_of_all_keychains()
+ .all_unbounded_spk_iters()
.into_iter()
.map(|(k, k_spks)| {
let mut once = Some(());