From 71fff1613d1c167d180636857063e181f6acedf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=97=E5=AE=87?= Date: Thu, 18 Jan 2024 14:30:29 +0800 Subject: [PATCH] feat(chain): add txout methods to `KeychainTxOutIndex` `txouts` and `txouts_in_tx` are exposed from `SpkTxOutIndex`, but modified to remove nested unions. Add `keychain_outpoints_in_range` that iterates over outpoints of a given keychain derivation range. --- crates/chain/src/keychain/txout_index.rs | 53 ++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs index a7922ce4..11ea76bc 100644 --- a/crates/chain/src/keychain/txout_index.rs +++ b/crates/chain/src/keychain/txout_index.rs @@ -5,8 +5,11 @@ use crate::{ spk_iter::BIP32_MAX_INDEX, SpkIterator, SpkTxOutIndex, }; -use bitcoin::{OutPoint, Script, Transaction, TxOut}; -use core::fmt::Debug; +use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid}; +use core::{ + fmt::Debug, + ops::{Bound, RangeBounds}, +}; use crate::Append; @@ -180,6 +183,25 @@ impl KeychainTxOutIndex { self.inner.outpoints() } + /// Iterate over known txouts that spend to tracked script pubkeys. + pub fn txouts( + &self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + self.inner + .txouts() + .map(|((k, i), op, txo)| (k.clone(), *i, op, txo)) + } + + /// 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) + .map(|((k, i), op, txo)| (k.clone(), *i, op, txo)) + } + /// Return the [`TxOut`] of `outpoint` if it has been indexed. /// /// The associated keychain and keychain index of the txout's spk is also returned. @@ -590,14 +612,37 @@ impl KeychainTxOutIndex { } } - /// Iterates over all the [`OutPoint`] that have a `TxOut` with a script pubkey derived from + /// Iterate over all [`OutPoint`]s that point to `TxOut`s with script pubkeys derived from /// `keychain`. + /// + /// Use [`keychain_outpoints_in_range`](KeychainTxOutIndex::keychain_outpoints_in_range) to + /// iterate over a specific derivation range. pub fn keychain_outpoints( &self, keychain: &K, ) -> impl DoubleEndedIterator + '_ { + self.keychain_outpoints_in_range(keychain, ..) + } + + /// Iterate over [`OutPoint`]s that point to `TxOut`s with script pubkeys derived from + /// `keychain` in a given derivation `range`. + pub fn keychain_outpoints_in_range( + &self, + keychain: &K, + range: impl RangeBounds, + ) -> impl DoubleEndedIterator + '_ { + let start = match range.start_bound() { + Bound::Included(i) => Bound::Included((keychain.clone(), *i)), + Bound::Excluded(i) => Bound::Excluded((keychain.clone(), *i)), + Bound::Unbounded => Bound::Unbounded, + }; + let end = match range.end_bound() { + Bound::Included(i) => Bound::Included((keychain.clone(), *i)), + Bound::Excluded(i) => Bound::Excluded((keychain.clone(), *i)), + Bound::Unbounded => Bound::Unbounded, + }; self.inner - .outputs_in_range((keychain.clone(), u32::MIN)..(keychain.clone(), u32::MAX)) + .outputs_in_range((start, end)) .map(|((_, i), op)| (*i, op)) }