refactor: Remove ForEachTxout trait
This commit is contained in:
parent
6bcbb93233
commit
7c12dc9942
@ -3,7 +3,7 @@ use crate::{
|
|||||||
indexed_tx_graph::Indexer,
|
indexed_tx_graph::Indexer,
|
||||||
miniscript::{Descriptor, DescriptorPublicKey},
|
miniscript::{Descriptor, DescriptorPublicKey},
|
||||||
spk_iter::BIP32_MAX_INDEX,
|
spk_iter::BIP32_MAX_INDEX,
|
||||||
ForEachTxOut, SpkIterator, SpkTxOutIndex,
|
SpkIterator, SpkTxOutIndex,
|
||||||
};
|
};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use bitcoin::{OutPoint, Script, TxOut};
|
use bitcoin::{OutPoint, Script, TxOut};
|
||||||
@ -112,7 +112,7 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
|
impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
|
||||||
/// 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
|
/// 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
|
/// the script pubkey's keychain and the [`super::ChangeSet`] returned will reflect the
|
||||||
@ -124,13 +124,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
|
|||||||
/// your txouts.
|
/// your txouts.
|
||||||
/// 2. When getting new data from the chain, you usually scan it before incorporating it into
|
/// 2. When getting new data from the chain, you usually scan it before incorporating it into
|
||||||
/// your chain state (i.e., `SparseChain`, `ChainGraph`).
|
/// your chain state (i.e., `SparseChain`, `ChainGraph`).
|
||||||
///
|
pub fn scan(&mut self, tx: &bitcoin::Transaction) -> super::ChangeSet<K> {
|
||||||
/// See [`ForEachTxout`] for the types that support this.
|
|
||||||
///
|
|
||||||
/// [`ForEachTxout`]: crate::ForEachTxOut
|
|
||||||
pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> super::ChangeSet<K> {
|
|
||||||
let mut changeset = super::ChangeSet::<K>::default();
|
let mut changeset = super::ChangeSet::<K>::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
|
changeset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ use core::ops::RangeBounds;
|
|||||||
use crate::{
|
use crate::{
|
||||||
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap},
|
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap},
|
||||||
indexed_tx_graph::Indexer,
|
indexed_tx_graph::Indexer,
|
||||||
ForEachTxOut,
|
|
||||||
};
|
};
|
||||||
use bitcoin::{self, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
|
use bitcoin::{self, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
|
||||||
|
|
||||||
@ -77,41 +76,23 @@ impl<I: Clone + Ord> Indexer for SpkTxOutIndex<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<I: Clone + Ord> SpkTxOutIndex<I> {
|
impl<I: Clone + Ord> SpkTxOutIndex<I> {
|
||||||
/// Scans an object containing many txouts.
|
/// Scans a transaction containing many txouts.
|
||||||
///
|
///
|
||||||
/// Typically, this is used in two situations:
|
/// 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
|
/// 1. After loading transaction data from the disk, you may scan over all the txouts to restore all
|
||||||
/// your txouts.
|
/// your txouts.
|
||||||
/// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state.
|
/// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state.
|
||||||
///
|
pub fn scan(&mut self, tx: &bitcoin::Transaction) -> BTreeSet<I> {
|
||||||
/// See [`ForEachTxout`] for the types that support this.
|
|
||||||
///
|
|
||||||
/// [`ForEachTxout`]: crate::ForEachTxOut
|
|
||||||
pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> BTreeSet<I> {
|
|
||||||
let mut scanned_indices = BTreeSet::new();
|
let mut scanned_indices = BTreeSet::new();
|
||||||
|
|
||||||
txouts.for_each_txout(|(op, txout)| {
|
for (i, txout) in tx.output.iter().enumerate() {
|
||||||
if let Some(spk_i) = scan_txout!(self, op, txout) {
|
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.insert(spk_i.clone());
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
scanned_indices
|
scanned_indices
|
||||||
}
|
}
|
||||||
@ -119,7 +100,13 @@ impl<I: Clone + Ord> SpkTxOutIndex<I> {
|
|||||||
/// Scan a single `TxOut` for a matching script pubkey and returns the index that matches the
|
/// Scan a single `TxOut` for a matching script pubkey and returns the index that matches the
|
||||||
/// script pubkey (if any).
|
/// script pubkey (if any).
|
||||||
pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> Option<&I> {
|
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.
|
/// Get a reference to the set of indexed outpoints.
|
||||||
|
@ -2,39 +2,6 @@ use crate::collections::BTreeMap;
|
|||||||
use crate::collections::BTreeSet;
|
use crate::collections::BTreeSet;
|
||||||
use crate::BlockId;
|
use crate::BlockId;
|
||||||
use alloc::vec::Vec;
|
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<Item=(OutPoint, &TxOut)>`
|
|
||||||
/// 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.
|
/// Trait that "anchors" blockchain data to a specific block of height and hash.
|
||||||
///
|
///
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
collections::*, keychain::Balance, local_chain::LocalChain, Anchor, Append, BlockId,
|
collections::*, keychain::Balance, local_chain::LocalChain, Anchor, Append, BlockId,
|
||||||
ChainOracle, ChainPosition, ForEachTxOut, FullTxOut,
|
ChainOracle, ChainPosition, FullTxOut,
|
||||||
};
|
};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
|
use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
|
||||||
@ -1137,18 +1137,6 @@ impl<A> AsRef<TxGraph<A>> for TxGraph<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> ForEachTxOut for ChangeSet<A> {
|
|
||||||
fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) {
|
|
||||||
self.txouts().for_each(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A> ForEachTxOut for TxGraph<A> {
|
|
||||||
fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) {
|
|
||||||
self.all_txouts().for_each(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An iterator that traverses transaction descendants.
|
/// An iterator that traverses transaction descendants.
|
||||||
///
|
///
|
||||||
/// This `struct` is created by the [`walk_descendants`] method of [`TxGraph`].
|
/// This `struct` is created by the [`walk_descendants`] method of [`TxGraph`].
|
||||||
|
Loading…
x
Reference in New Issue
Block a user