@@ -184,6 +184,17 @@ enum TxNodeInternal {
184184 Partial ( BTreeMap < u32 , TxOut > ) ,
185185}
186186
187+ impl TxNodeInternal {
188+ fn iter_txouts (
189+ txid : Txid ,
190+ partial : & BTreeMap < u32 , TxOut > ,
191+ ) -> impl Iterator < Item = ( OutPoint , & TxOut ) > {
192+ partial
193+ . iter ( )
194+ . map ( move |( & vout, txout) | ( OutPoint { txid, vout } , txout) )
195+ }
196+ }
197+
187198impl Default for TxNodeInternal {
188199 fn default ( ) -> Self {
189200 Self :: Partial ( BTreeMap :: new ( ) )
@@ -233,18 +244,17 @@ impl<A, X> TxGraph<A, X> {
233244 ///
234245 /// This includes txouts of both full transactions as well as floating transactions.
235246 pub fn all_txouts ( & self ) -> impl Iterator < Item = ( OutPoint , & TxOut ) > {
236- self . txs . iter ( ) . flat_map ( |( txid, tx) | match tx {
247+ self . txs . iter ( ) . flat_map ( |( & txid, tx) | match tx {
237248 TxNodeInternal :: Whole ( tx) => tx
238249 . as_ref ( )
239250 . output
240251 . iter ( )
241252 . enumerate ( )
242- . map ( |( vout, txout) | ( OutPoint :: new ( * txid, vout as _ ) , txout) )
243- . collect :: < Vec < _ > > ( ) ,
244- TxNodeInternal :: Partial ( txouts) => txouts
245- . iter ( )
246- . map ( |( vout, txout) | ( OutPoint :: new ( * txid, * vout as _ ) , txout) )
253+ . map ( |( vout, txout) | ( OutPoint :: new ( txid, vout as _ ) , txout) )
247254 . collect :: < Vec < _ > > ( ) ,
255+ TxNodeInternal :: Partial ( partial) => {
256+ TxNodeInternal :: iter_txouts ( txid, partial) . collect :: < Vec < _ > > ( )
257+ }
248258 } )
249259 }
250260
@@ -255,13 +265,11 @@ impl<A, X> TxGraph<A, X> {
255265 pub fn floating_txouts ( & self ) -> impl Iterator < Item = ( OutPoint , & TxOut ) > {
256266 self . txs
257267 . iter ( )
258- . filter_map ( |( txid, tx_node) | match tx_node {
268+ . filter_map ( |( & txid, tx_node) | match tx_node {
259269 TxNodeInternal :: Whole ( _) => None ,
260- TxNodeInternal :: Partial ( txouts) => Some (
261- txouts
262- . iter ( )
263- . map ( |( & vout, txout) | ( OutPoint :: new ( * txid, vout) , txout) ) ,
264- ) ,
270+ TxNodeInternal :: Partial ( partial) => {
271+ Some ( TxNodeInternal :: iter_txouts ( txid, partial) )
272+ }
265273 } )
266274 . flatten ( )
267275 }
@@ -806,8 +814,13 @@ impl<A: Clone + Ord, X: Indexer> TxGraph<A, X> {
806814 /// Extends this graph with another so that `self` becomes the union of the two sets of
807815 /// transactions.
808816 ///
817+ /// `X` must be `()` for the `update` tx graph. If you want to update with a `TxGraph` that
818+ /// happens to have an indexer first use [`swap_indexer`] to get rid of it.
819+ ///
809820 /// The returned [`ChangeSet`] is the set difference between `update` and `self` (transactions that
810821 /// exist in `update` but not in `self`).
822+ ///
823+ /// [`swap_indexer`]: Self::swap_indexer
811824 pub fn apply_update ( & mut self , update : TxGraph < A > ) -> ChangeSet < A , X :: ChangeSet > {
812825 let mut changeset = ChangeSet :: default ( ) ;
813826 for tx in update. full_txs ( ) {
@@ -829,6 +842,48 @@ impl<A: Clone + Ord, X: Indexer> TxGraph<A, X> {
829842 changeset
830843 }
831844
845+ /// Changes the [`Indexer`] for a `TxGraph`. **This doesn't re-index the transactions in the
846+ /// graph** for that call [`reindex`].
847+ ///
848+ /// Returns the new `TxGraph` and the old indexer.
849+ ///
850+ /// [`reindex`]: Self::reindex
851+ pub fn swap_indexer < XNew > ( self , indexer : XNew ) -> ( TxGraph < A , XNew > , X ) {
852+ (
853+ TxGraph {
854+ txs : self . txs ,
855+ spends : self . spends ,
856+ anchors : self . anchors ,
857+ rev_anchors : self . rev_anchors ,
858+ last_seen : self . last_seen ,
859+ empty_outspends : self . empty_outspends ,
860+ empty_anchors : self . empty_anchors ,
861+ indexer,
862+ } ,
863+ self . indexer ,
864+ )
865+ }
866+
867+ /// Reindexs the transaction graph by calling the [`Indexer`] on every transaction.
868+ ///
869+ /// The returned changeset will only bne non-empty in the `indexer` field.
870+ pub fn reindex ( & mut self ) -> ChangeSet < A , X :: ChangeSet > {
871+ let mut changeset = ChangeSet :: < A , X :: ChangeSet > :: default ( ) ;
872+ for ( txid, node) in & self . txs {
873+ match node {
874+ TxNodeInternal :: Whole ( tx) => {
875+ changeset. merge ( self . indexer . index_tx ( tx. as_ref ( ) ) . into ( ) )
876+ }
877+ TxNodeInternal :: Partial ( txouts) => {
878+ for ( op, txout) in TxNodeInternal :: iter_txouts ( * txid, txouts) {
879+ changeset. merge ( self . indexer . index_txout ( op, txout) . into ( ) ) ;
880+ }
881+ }
882+ } ;
883+ }
884+ changeset
885+ }
886+
832887 /// Determines the [`ChangeSet`] between `self` and an empty [`TxGraph`].
833888 pub fn initial_changeset ( & self ) -> ChangeSet < A , X :: ChangeSet > {
834889 ChangeSet {
0 commit comments