@@ -106,15 +106,19 @@ use core::{
106
106
ops:: { Deref , RangeInclusive } ,
107
107
} ;
108
108
109
- impl < A > From < TxGraph < A > > for TxUpdate < A > {
109
+ impl < A : Ord > From < TxGraph < A > > for TxUpdate < A > {
110
110
fn from ( graph : TxGraph < A > ) -> Self {
111
111
Self {
112
112
txs : graph. full_txs ( ) . map ( |tx_node| tx_node. tx ) . collect ( ) ,
113
113
txouts : graph
114
114
. floating_txouts ( )
115
115
. map ( |( op, txo) | ( op, txo. clone ( ) ) )
116
116
. collect ( ) ,
117
- anchors : graph. anchors ,
117
+ anchors : graph
118
+ . anchors
119
+ . into_iter ( )
120
+ . flat_map ( |( txid, anchors) | anchors. into_iter ( ) . map ( move |a| ( a, txid) ) )
121
+ . collect ( ) ,
118
122
seen_ats : graph. last_seen . into_iter ( ) . collect ( ) ,
119
123
}
120
124
}
@@ -135,15 +139,15 @@ impl<A: Ord + Clone> From<TxUpdate<A>> for TxGraph<A> {
135
139
/// [module-level documentation]: crate::tx_graph
136
140
#[ derive( Clone , Debug , PartialEq ) ]
137
141
pub struct TxGraph < A = ( ) > {
138
- // all transactions that the graph is aware of in format: `(tx_node, tx_anchors)`
139
- txs : HashMap < Txid , ( TxNodeInternal , BTreeSet < A > ) > ,
142
+ txs : HashMap < Txid , TxNodeInternal > ,
140
143
spends : BTreeMap < OutPoint , HashSet < Txid > > ,
141
- anchors : BTreeSet < ( A , Txid ) > ,
144
+ anchors : HashMap < Txid , BTreeSet < A > > ,
142
145
last_seen : HashMap < Txid , u64 > ,
143
146
144
147
// This atrocity exists so that `TxGraph::outspends()` can return a reference.
145
148
// FIXME: This can be removed once `HashSet::new` is a const fn.
146
149
empty_outspends : HashSet < Txid > ,
150
+ empty_anchors : BTreeSet < A > ,
147
151
}
148
152
149
153
impl < A > Default for TxGraph < A > {
@@ -154,6 +158,7 @@ impl<A> Default for TxGraph<A> {
154
158
anchors : Default :: default ( ) ,
155
159
last_seen : Default :: default ( ) ,
156
160
empty_outspends : Default :: default ( ) ,
161
+ empty_anchors : Default :: default ( ) ,
157
162
}
158
163
}
159
164
}
@@ -238,7 +243,7 @@ impl<A> TxGraph<A> {
238
243
///
239
244
/// This includes txouts of both full transactions as well as floating transactions.
240
245
pub fn all_txouts ( & self ) -> impl Iterator < Item = ( OutPoint , & TxOut ) > {
241
- self . txs . iter ( ) . flat_map ( |( txid, ( tx , _ ) ) | match tx {
246
+ self . txs . iter ( ) . flat_map ( |( txid, tx ) | match tx {
242
247
TxNodeInternal :: Whole ( tx) => tx
243
248
. as_ref ( )
244
249
. output
@@ -260,7 +265,7 @@ impl<A> TxGraph<A> {
260
265
pub fn floating_txouts ( & self ) -> impl Iterator < Item = ( OutPoint , & TxOut ) > {
261
266
self . txs
262
267
. iter ( )
263
- . filter_map ( |( txid, ( tx_node, _ ) ) | match tx_node {
268
+ . filter_map ( |( txid, tx_node) | match tx_node {
264
269
TxNodeInternal :: Whole ( _) => None ,
265
270
TxNodeInternal :: Partial ( txouts) => Some (
266
271
txouts
@@ -273,17 +278,15 @@ impl<A> TxGraph<A> {
273
278
274
279
/// Iterate over all full transactions in the graph.
275
280
pub fn full_txs ( & self ) -> impl Iterator < Item = TxNode < ' _ , Arc < Transaction > , A > > {
276
- self . txs
277
- . iter ( )
278
- . filter_map ( |( & txid, ( tx, anchors) ) | match tx {
279
- TxNodeInternal :: Whole ( tx) => Some ( TxNode {
280
- txid,
281
- tx : tx. clone ( ) ,
282
- anchors,
283
- last_seen_unconfirmed : self . last_seen . get ( & txid) . copied ( ) ,
284
- } ) ,
285
- TxNodeInternal :: Partial ( _) => None ,
286
- } )
281
+ self . txs . iter ( ) . filter_map ( |( & txid, tx) | match tx {
282
+ TxNodeInternal :: Whole ( tx) => Some ( TxNode {
283
+ txid,
284
+ tx : tx. clone ( ) ,
285
+ anchors : self . anchors . get ( & txid) . unwrap_or ( & self . empty_anchors ) ,
286
+ last_seen_unconfirmed : self . last_seen . get ( & txid) . copied ( ) ,
287
+ } ) ,
288
+ TxNodeInternal :: Partial ( _) => None ,
289
+ } )
287
290
}
288
291
289
292
/// Iterate over graph transactions with no anchors or last-seen.
@@ -311,10 +314,10 @@ impl<A> TxGraph<A> {
311
314
/// Get a transaction node by txid. This only returns `Some` for full transactions.
312
315
pub fn get_tx_node ( & self , txid : Txid ) -> Option < TxNode < ' _ , Arc < Transaction > , A > > {
313
316
match & self . txs . get ( & txid) ? {
314
- ( TxNodeInternal :: Whole ( tx) , anchors ) => Some ( TxNode {
317
+ TxNodeInternal :: Whole ( tx) => Some ( TxNode {
315
318
txid,
316
319
tx : tx. clone ( ) ,
317
- anchors,
320
+ anchors : self . anchors . get ( & txid ) . unwrap_or ( & self . empty_anchors ) ,
318
321
last_seen_unconfirmed : self . last_seen . get ( & txid) . copied ( ) ,
319
322
} ) ,
320
323
_ => None ,
@@ -323,7 +326,7 @@ impl<A> TxGraph<A> {
323
326
324
327
/// Obtains a single tx output (if any) at the specified outpoint.
325
328
pub fn get_txout ( & self , outpoint : OutPoint ) -> Option < & TxOut > {
326
- match & self . txs . get ( & outpoint. txid ) ?. 0 {
329
+ match & self . txs . get ( & outpoint. txid ) ? {
327
330
TxNodeInternal :: Whole ( tx) => tx. as_ref ( ) . output . get ( outpoint. vout as usize ) ,
328
331
TxNodeInternal :: Partial ( txouts) => txouts. get ( & outpoint. vout ) ,
329
332
}
@@ -333,7 +336,7 @@ impl<A> TxGraph<A> {
333
336
///
334
337
/// Returns a [`BTreeMap`] of vout to output of the provided `txid`.
335
338
pub fn tx_outputs ( & self , txid : Txid ) -> Option < BTreeMap < u32 , & TxOut > > {
336
- Some ( match & self . txs . get ( & txid) ?. 0 {
339
+ Some ( match & self . txs . get ( & txid) ? {
337
340
TxNodeInternal :: Whole ( tx) => tx
338
341
. as_ref ( )
339
342
. output
@@ -496,7 +499,7 @@ impl<A> TxGraph<A> {
496
499
}
497
500
498
501
/// Get all transaction anchors known by [`TxGraph`].
499
- pub fn all_anchors ( & self ) -> & BTreeSet < ( A , Txid ) > {
502
+ pub fn all_anchors ( & self ) -> & HashMap < Txid , BTreeSet < A > > {
500
503
& self . anchors
501
504
}
502
505
@@ -540,7 +543,7 @@ impl<A: Clone + Ord> TxGraph<A> {
540
543
/// [`apply_changeset`]: Self::apply_changeset
541
544
pub fn insert_txout ( & mut self , outpoint : OutPoint , txout : TxOut ) -> ChangeSet < A > {
542
545
let mut changeset = ChangeSet :: < A > :: default ( ) ;
543
- let ( tx_node, _ ) = self . txs . entry ( outpoint. txid ) . or_default ( ) ;
546
+ let tx_node = self . txs . entry ( outpoint. txid ) . or_default ( ) ;
544
547
match tx_node {
545
548
TxNodeInternal :: Whole ( _) => {
546
549
// ignore this txout we have the full one already.
@@ -573,7 +576,7 @@ impl<A: Clone + Ord> TxGraph<A> {
573
576
let txid = tx. compute_txid ( ) ;
574
577
let mut changeset = ChangeSet :: < A > :: default ( ) ;
575
578
576
- let ( tx_node, _ ) = self . txs . entry ( txid) . or_default ( ) ;
579
+ let tx_node = self . txs . entry ( txid) . or_default ( ) ;
577
580
match tx_node {
578
581
TxNodeInternal :: Whole ( existing_tx) => {
579
582
debug_assert_eq ! (
@@ -625,13 +628,7 @@ impl<A: Clone + Ord> TxGraph<A> {
625
628
/// `anchor`.
626
629
pub fn insert_anchor ( & mut self , txid : Txid , anchor : A ) -> ChangeSet < A > {
627
630
let mut changeset = ChangeSet :: < A > :: default ( ) ;
628
- if self . anchors . insert ( ( anchor. clone ( ) , txid) ) {
629
- let ( _tx_node, anchors) = self . txs . entry ( txid) . or_default ( ) ;
630
- let _inserted = anchors. insert ( anchor. clone ( ) ) ;
631
- debug_assert ! (
632
- _inserted,
633
- "anchors in `.anchors` and `.txs` should be consistent"
634
- ) ;
631
+ if self . anchors . entry ( txid) . or_default ( ) . insert ( anchor. clone ( ) ) {
635
632
changeset. anchors . insert ( ( anchor, txid) ) ;
636
633
}
637
634
changeset
@@ -711,7 +708,11 @@ impl<A: Clone + Ord> TxGraph<A> {
711
708
. floating_txouts ( )
712
709
. map ( |( op, txout) | ( op, txout. clone ( ) ) )
713
710
. collect ( ) ,
714
- anchors : self . anchors . clone ( ) ,
711
+ anchors : self
712
+ . anchors
713
+ . iter ( )
714
+ . flat_map ( |( txid, anchors) | anchors. iter ( ) . map ( |a| ( a. clone ( ) , * txid) ) )
715
+ . collect ( ) ,
715
716
last_seen : self . last_seen . iter ( ) . map ( |( & k, & v) | ( k, v) ) . collect ( ) ,
716
717
}
717
718
}
@@ -763,12 +764,12 @@ impl<A: Anchor> TxGraph<A> {
763
764
chain_tip : BlockId ,
764
765
txid : Txid ,
765
766
) -> Result < Option < ChainPosition < & A > > , C :: Error > {
766
- let ( tx_node, anchors ) = match self . txs . get ( & txid) {
767
+ let tx_node = match self . txs . get ( & txid) {
767
768
Some ( v) => v,
768
769
None => return Ok ( None ) ,
769
770
} ;
770
771
771
- for anchor in anchors {
772
+ for anchor in self . anchors . get ( & txid ) . unwrap_or ( & self . empty_anchors ) {
772
773
match chain. is_block_in_chain ( anchor. anchor_block ( ) , chain_tip) ? {
773
774
Some ( true ) => return Ok ( Some ( ChainPosition :: Confirmed ( anchor) ) ) ,
774
775
_ => continue ,
0 commit comments