diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs index 9b38a7ad..0376473f 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, - ForEachTxOut, SpkIterator, SpkTxOutIndex, + SpkIterator, SpkTxOutIndex, }; use alloc::vec::Vec; use bitcoin::{OutPoint, Script, TxOut}; @@ -112,7 +112,7 @@ impl Indexer for KeychainTxOutIndex { } impl KeychainTxOutIndex { - /// Scans an object for relevant outpoints, which are stored and indexed internally. + /// Scans a transaction for relevant outpoints, which are stored and indexed internally. /// /// If the matched script pubkey is part of the lookahead, the last stored index is updated for /// the script pubkey's keychain and the [`super::ChangeSet`] returned will reflect the @@ -124,13 +124,11 @@ impl KeychainTxOutIndex { /// your txouts. /// 2. When getting new data from the chain, you usually scan it before incorporating it into /// your chain state (i.e., `SparseChain`, `ChainGraph`). - /// - /// See [`ForEachTxout`] for the types that support this. - /// - /// [`ForEachTxout`]: crate::ForEachTxOut - pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> super::ChangeSet { + pub fn scan(&mut self, tx: &bitcoin::Transaction) -> super::ChangeSet { let mut changeset = super::ChangeSet::::default(); - txouts.for_each_txout(|(op, txout)| changeset.append(self.scan_txout(op, txout))); + for (op, txout) in tx.output.iter().enumerate() { + changeset.append(self.scan_txout(OutPoint::new(tx.txid(), op as u32), txout)); + } changeset } diff --git a/crates/chain/src/spk_txout_index.rs b/crates/chain/src/spk_txout_index.rs index 5547f37c..a4d6d7c2 100644 --- a/crates/chain/src/spk_txout_index.rs +++ b/crates/chain/src/spk_txout_index.rs @@ -3,7 +3,6 @@ use core::ops::RangeBounds; use crate::{ collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap}, indexed_tx_graph::Indexer, - ForEachTxOut, }; use bitcoin::{self, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid}; @@ -77,41 +76,23 @@ impl Indexer for SpkTxOutIndex { } } -/// This macro is used instead of a member function of `SpkTxOutIndex`, which would result in a -/// compiler error[E0521]: "borrowed data escapes out of closure" when we attempt to take a -/// reference out of the `ForEachTxOut` closure during scanning. -macro_rules! scan_txout { - ($self:ident, $op:expr, $txout:expr) => {{ - let spk_i = $self.spk_indices.get(&$txout.script_pubkey); - if let Some(spk_i) = spk_i { - $self.txouts.insert($op, (spk_i.clone(), $txout.clone())); - $self.spk_txouts.insert((spk_i.clone(), $op)); - $self.unused.remove(&spk_i); - } - spk_i - }}; -} - impl SpkTxOutIndex { - /// Scans an object containing many txouts. + /// Scans a transaction containing many txouts. /// /// Typically, this is used in two situations: /// /// 1. After loading transaction data from the disk, you may scan over all the txouts to restore all /// your txouts. /// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state. - /// - /// See [`ForEachTxout`] for the types that support this. - /// - /// [`ForEachTxout`]: crate::ForEachTxOut - pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> BTreeSet { + pub fn scan(&mut self, tx: &bitcoin::Transaction) -> BTreeSet { let mut scanned_indices = BTreeSet::new(); - txouts.for_each_txout(|(op, txout)| { - if let Some(spk_i) = scan_txout!(self, op, txout) { + for (i, txout) in tx.output.iter().enumerate() { + let op = OutPoint::new(tx.txid(), i as u32); + if let Some(spk_i) = self.scan_txout(op, txout) { scanned_indices.insert(spk_i.clone()); } - }); + } scanned_indices } @@ -119,7 +100,13 @@ impl SpkTxOutIndex { /// Scan a single `TxOut` for a matching script pubkey and returns the index that matches the /// script pubkey (if any). pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> Option<&I> { - scan_txout!(self, op, txout) + let spk_i = self.spk_indices.get(&txout.script_pubkey); + if let Some(spk_i) = spk_i { + self.txouts.insert(op, (spk_i.clone(), txout.clone())); + self.spk_txouts.insert((spk_i.clone(), op)); + self.unused.remove(spk_i); + } + spk_i } /// Get a reference to the set of indexed outpoints. diff --git a/crates/chain/src/tx_data_traits.rs b/crates/chain/src/tx_data_traits.rs index 43fc73b4..f28044c6 100644 --- a/crates/chain/src/tx_data_traits.rs +++ b/crates/chain/src/tx_data_traits.rs @@ -2,39 +2,6 @@ use crate::collections::BTreeMap; use crate::collections::BTreeSet; use crate::BlockId; use alloc::vec::Vec; -use bitcoin::{Block, OutPoint, Transaction, TxOut}; - -/// Trait to do something with every txout contained in a structure. -/// -/// We would prefer to just work with things that can give us an `Iterator` -/// here, but rust's type system makes it extremely hard to do this (without trait objects). -pub trait ForEachTxOut { - /// The provided closure `f` will be called with each `outpoint/txout` pair. - fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))); -} - -impl ForEachTxOut for Block { - fn for_each_txout(&self, mut f: impl FnMut((OutPoint, &TxOut))) { - for tx in self.txdata.iter() { - tx.for_each_txout(&mut f) - } - } -} - -impl ForEachTxOut for Transaction { - fn for_each_txout(&self, mut f: impl FnMut((OutPoint, &TxOut))) { - let txid = self.txid(); - for (i, txout) in self.output.iter().enumerate() { - f(( - OutPoint { - txid, - vout: i as u32, - }, - txout, - )) - } - } -} /// Trait that "anchors" blockchain data to a specific block of height and hash. /// diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index 7f58f203..cfd2de9d 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -52,7 +52,7 @@ use crate::{ collections::*, keychain::Balance, local_chain::LocalChain, Anchor, Append, BlockId, - ChainOracle, ChainPosition, ForEachTxOut, FullTxOut, + ChainOracle, ChainPosition, FullTxOut, }; use alloc::vec::Vec; use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid}; @@ -1137,18 +1137,6 @@ impl AsRef> for TxGraph { } } -impl ForEachTxOut for ChangeSet { - fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { - self.txouts().for_each(f) - } -} - -impl ForEachTxOut for TxGraph { - fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { - self.all_txouts().for_each(f) - } -} - /// An iterator that traverses transaction descendants. /// /// This `struct` is created by the [`walk_descendants`] method of [`TxGraph`].