@@ -23,12 +23,14 @@ pub trait ElectrumExt {
2323 ///
2424 /// The full scan for each keychain stops after a gap of `stop_gap` script pubkeys with no associated
2525 /// transactions. `batch_size` specifies the max number of script pubkeys to request for in a
26- /// single batch request.
26+ /// single batch request. `fetch_prev_txouts` specifies whether or not we want previous `TxOut`s
27+ /// for fee calculation.
2728 fn full_scan < K : Ord + Clone > (
2829 & self ,
2930 request : FullScanRequest < K > ,
3031 stop_gap : usize ,
3132 batch_size : usize ,
33+ fetch_prev_txouts : bool ,
3234 ) -> Result < ElectrumFullScanResult < K > , Error > ;
3335
3436 /// Sync a set of scripts with the blockchain (via an Electrum client) for the data specified
@@ -38,13 +40,19 @@ pub trait ElectrumExt {
3840 /// see [`SyncRequest`]
3941 ///
4042 /// `batch_size` specifies the max number of script pubkeys to request for in a single batch
41- /// request.
43+ /// request. `fetch_prev_txouts` specifies whether or not we want previous `TxOut`s for fee
44+ /// calculation.
4245 ///
4346 /// If the scripts to sync are unknown, such as when restoring or importing a keychain that
4447 /// may include scripts that have been used, use [`full_scan`] with the keychain.
4548 ///
4649 /// [`full_scan`]: ElectrumExt::full_scan
47- fn sync ( & self , request : SyncRequest , batch_size : usize ) -> Result < ElectrumSyncResult , Error > ;
50+ fn sync (
51+ & self ,
52+ request : SyncRequest ,
53+ batch_size : usize ,
54+ fetch_prev_txouts : bool ,
55+ ) -> Result < ElectrumSyncResult , Error > ;
4856}
4957
5058impl < E : ElectrumApi > ElectrumExt for E {
@@ -53,6 +61,7 @@ impl<E: ElectrumApi> ElectrumExt for E {
5361 mut request : FullScanRequest < K > ,
5462 stop_gap : usize ,
5563 batch_size : usize ,
64+ fetch_prev_txouts : bool ,
5665 ) -> Result < ElectrumFullScanResult < K > , Error > {
5766 let mut request_spks = request. spks_by_keychain ;
5867
@@ -104,6 +113,11 @@ impl<E: ElectrumApi> ElectrumExt for E {
104113 }
105114 }
106115
116+ // Fetch previous `TxOut`s for fee calculation if flag is enabled.
117+ if fetch_prev_txouts {
118+ fetch_prev_txout ( self , & mut request. tx_cache , & mut graph_update) ?;
119+ }
120+
107121 // check for reorgs during scan process
108122 let server_blockhash = self . block_header ( tip. height ( ) as usize ) ?. block_hash ( ) ;
109123 if tip. hash ( ) != server_blockhash {
@@ -133,14 +147,19 @@ impl<E: ElectrumApi> ElectrumExt for E {
133147 Ok ( ElectrumFullScanResult ( update) )
134148 }
135149
136- fn sync ( & self , request : SyncRequest , batch_size : usize ) -> Result < ElectrumSyncResult , Error > {
150+ fn sync (
151+ & self ,
152+ request : SyncRequest ,
153+ batch_size : usize ,
154+ fetch_prev_txouts : bool ,
155+ ) -> Result < ElectrumSyncResult , Error > {
137156 let mut tx_cache = request. tx_cache . clone ( ) ;
138157
139158 let full_scan_req = FullScanRequest :: from_chain_tip ( request. chain_tip . clone ( ) )
140159 . cache_txs ( request. tx_cache )
141160 . set_spks_for_keychain ( ( ) , request. spks . enumerate ( ) . map ( |( i, spk) | ( i as u32 , spk) ) ) ;
142161 let mut full_scan_res = self
143- . full_scan ( full_scan_req, usize:: MAX , batch_size) ?
162+ . full_scan ( full_scan_req, usize:: MAX , batch_size, fetch_prev_txouts ) ?
144163 . with_confirmation_height_anchor ( ) ;
145164
146165 let ( tip, _) = construct_update_tip ( self , request. chain_tip ) ?;
@@ -165,6 +184,11 @@ impl<E: ElectrumApi> ElectrumExt for E {
165184 request. outpoints ,
166185 ) ?;
167186
187+ // Fetch previous `TxOut`s for fee calculation if flag is enabled.
188+ if fetch_prev_txouts {
189+ fetch_prev_txout ( self , & mut tx_cache, & mut full_scan_res. graph_update ) ?;
190+ }
191+
168192 Ok ( ElectrumSyncResult ( SyncResult {
169193 chain_update : full_scan_res. chain_update ,
170194 graph_update : full_scan_res. graph_update ,
@@ -374,7 +398,7 @@ fn populate_with_outpoints(
374398 client : & impl ElectrumApi ,
375399 cps : & BTreeMap < u32 , CheckPoint > ,
376400 tx_cache : & mut TxCache ,
377- tx_graph : & mut TxGraph < ConfirmationHeightAnchor > ,
401+ graph_update : & mut TxGraph < ConfirmationHeightAnchor > ,
378402 outpoints : impl IntoIterator < Item = OutPoint > ,
379403) -> Result < ( ) , Error > {
380404 for outpoint in outpoints {
@@ -399,18 +423,18 @@ fn populate_with_outpoints(
399423 continue ;
400424 }
401425 has_residing = true ;
402- if tx_graph . get_tx ( res. tx_hash ) . is_none ( ) {
403- let _ = tx_graph . insert_tx ( tx. clone ( ) ) ;
426+ if graph_update . get_tx ( res. tx_hash ) . is_none ( ) {
427+ let _ = graph_update . insert_tx ( tx. clone ( ) ) ;
404428 }
405429 } else {
406430 if has_spending {
407431 continue ;
408432 }
409- let res_tx = match tx_graph . get_tx ( res. tx_hash ) {
433+ let res_tx = match graph_update . get_tx ( res. tx_hash ) {
410434 Some ( tx) => tx,
411435 None => {
412436 let res_tx = fetch_tx ( client, tx_cache, res. tx_hash ) ?;
413- let _ = tx_graph . insert_tx ( Arc :: clone ( & res_tx) ) ;
437+ let _ = graph_update . insert_tx ( Arc :: clone ( & res_tx) ) ;
414438 res_tx
415439 }
416440 } ;
@@ -424,7 +448,7 @@ fn populate_with_outpoints(
424448 } ;
425449
426450 if let Some ( anchor) = determine_tx_anchor ( cps, res. height , res. tx_hash ) {
427- let _ = tx_graph . insert_anchor ( res. tx_hash , anchor) ;
451+ let _ = graph_update . insert_anchor ( res. tx_hash , anchor) ;
428452 }
429453 }
430454 }
@@ -484,6 +508,25 @@ fn fetch_tx<C: ElectrumApi>(
484508 } )
485509}
486510
511+ // Helper function which fetches the `TxOut`s of our relevant transactions' previous transactions,
512+ // which we do not have by default. This data is needed to calculate the transaction fee.
513+ fn fetch_prev_txout < C : ElectrumApi > (
514+ client : & C ,
515+ tx_cache : & mut TxCache ,
516+ graph_update : & mut TxGraph < ConfirmationHeightAnchor > ,
517+ ) -> Result < ( ) , Error > {
518+ for tx in graph_update. clone ( ) . full_txs ( ) {
519+ for vin in tx. input . clone ( ) {
520+ let outpoint = vin. previous_output ;
521+ let prev_tx = fetch_tx ( client, tx_cache, outpoint. txid ) ?;
522+ for txout in prev_tx. output . clone ( ) {
523+ let _ = graph_update. insert_txout ( outpoint, txout) ;
524+ }
525+ }
526+ }
527+ Ok ( ( ) )
528+ }
529+
487530fn populate_with_spks < I : Ord + Clone > (
488531 client : & impl ElectrumApi ,
489532 cps : & BTreeMap < u32 , CheckPoint > ,
0 commit comments