@@ -395,6 +395,12 @@ fn determine_tx_anchor(
395395 }
396396}
397397
398+ /// Populate the `graph_update` with associated transactions/anchors of `outpoints`.
399+ ///
400+ /// Transactions in which the outpoint resides, and transactions that spend from the outpoint are
401+ /// included. Anchors of the aforementioned transactions are included.
402+ ///
403+ /// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
398404fn populate_with_outpoints (
399405 client : & impl ElectrumApi ,
400406 cps : & BTreeMap < u32 , CheckPoint > ,
@@ -403,59 +409,52 @@ fn populate_with_outpoints(
403409 outpoints : impl IntoIterator < Item = OutPoint > ,
404410) -> Result < ( ) , Error > {
405411 for outpoint in outpoints {
406- let txid = outpoint. txid ;
407- let tx = client. transaction_get ( & txid) ?;
408- debug_assert_eq ! ( tx. txid( ) , txid) ;
409- let txout = match tx. output . get ( outpoint. vout as usize ) {
412+ let op_txid = outpoint. txid ;
413+ let op_tx = fetch_tx ( client, tx_cache, op_txid) ?;
414+ let op_txout = match op_tx. output . get ( outpoint. vout as usize ) {
410415 Some ( txout) => txout,
411416 None => continue ,
412417 } ;
418+ debug_assert_eq ! ( op_tx. txid( ) , op_txid) ;
419+
413420 // attempt to find the following transactions (alongside their chain positions), and
414421 // add to our sparsechain `update`:
415422 let mut has_residing = false ; // tx in which the outpoint resides
416423 let mut has_spending = false ; // tx that spends the outpoint
417- for res in client. script_get_history ( & txout . script_pubkey ) ? {
424+ for res in client. script_get_history ( & op_txout . script_pubkey ) ? {
418425 if has_residing && has_spending {
419426 break ;
420427 }
421428
422- if res. tx_hash == txid {
423- if has_residing {
424- continue ;
425- }
429+ if !has_residing && res. tx_hash == op_txid {
426430 has_residing = true ;
427- if graph_update. get_tx ( res. tx_hash ) . is_none ( ) {
428- let _ = graph_update. insert_tx ( tx. clone ( ) ) ;
431+ let _ = graph_update. insert_tx ( Arc :: clone ( & op_tx) ) ;
432+ if let Some ( anchor) = determine_tx_anchor ( cps, res. height , res. tx_hash ) {
433+ let _ = graph_update. insert_anchor ( res. tx_hash , anchor) ;
429434 }
430- } else {
431- if has_spending {
432- continue ;
433- }
434- let res_tx = match graph_update. get_tx ( res. tx_hash ) {
435- Some ( tx) => tx,
436- None => {
437- let res_tx = fetch_tx ( client, tx_cache, res. tx_hash ) ?;
438- let _ = graph_update. insert_tx ( Arc :: clone ( & res_tx) ) ;
439- res_tx
440- }
441- } ;
435+ }
436+
437+ if !has_spending && res. tx_hash != op_txid {
438+ let res_tx = fetch_tx ( client, tx_cache, res. tx_hash ) ?;
439+ // we exclude txs/anchors that do not spend our specified outpoint(s)
442440 has_spending = res_tx
443441 . input
444442 . iter ( )
445443 . any ( |txin| txin. previous_output == outpoint) ;
446444 if !has_spending {
447445 continue ;
448446 }
449- } ;
450-
451- if let Some ( anchor ) = determine_tx_anchor ( cps , res. height , res . tx_hash ) {
452- let _ = graph_update . insert_anchor ( res . tx_hash , anchor ) ;
447+ let _ = graph_update . insert_tx ( Arc :: clone ( & res_tx ) ) ;
448+ if let Some ( anchor ) = determine_tx_anchor ( cps , res . height , res . tx_hash ) {
449+ let _ = graph_update . insert_anchor ( res. tx_hash , anchor ) ;
450+ }
453451 }
454452 }
455453 }
456454 Ok ( ( ) )
457455}
458456
457+ /// Populate the `graph_update` with transactions/anchors of the provided `txids`.
459458fn populate_with_txids (
460459 client : & impl ElectrumApi ,
461460 cps : & BTreeMap < u32 , CheckPoint > ,
@@ -476,6 +475,8 @@ fn populate_with_txids(
476475 . map ( |txo| & txo. script_pubkey )
477476 . expect ( "tx must have an output" ) ;
478477
478+ // because of restrictions of the Electrum API, we have to use the `script_get_history`
479+ // call to get confirmation status of our transaction
479480 let anchor = match client
480481 . script_get_history ( spk) ?
481482 . into_iter ( )
@@ -485,16 +486,17 @@ fn populate_with_txids(
485486 None => continue ,
486487 } ;
487488
488- if graph_update. get_tx ( txid) . is_none ( ) {
489- let _ = graph_update. insert_tx ( tx) ;
490- }
489+ let _ = graph_update. insert_tx ( tx) ;
491490 if let Some ( anchor) = anchor {
492491 let _ = graph_update. insert_anchor ( txid, anchor) ;
493492 }
494493 }
495494 Ok ( ( ) )
496495}
497496
497+ /// Fetch transaction of given `txid`.
498+ ///
499+ /// We maintain a `tx_cache` so that we won't need to fetch from Electrum with every call.
498500fn fetch_tx < C : ElectrumApi > (
499501 client : & C ,
500502 tx_cache : & mut TxCache ,
@@ -530,6 +532,13 @@ fn fetch_prev_txout<C: ElectrumApi>(
530532 Ok ( ( ) )
531533}
532534
535+ /// Populate the `graph_update` with transactions/anchors associated with the given `spks`.
536+ ///
537+ /// Transactions that contains an output with requested spk, or spends form an output with
538+ /// requested spk will be added to `graph_update`. Anchors of the aforementioned transactions are
539+ /// also included.
540+ ///
541+ /// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
533542fn populate_with_spks < I : Ord + Clone > (
534543 client : & impl ElectrumApi ,
535544 cps : & BTreeMap < u32 , CheckPoint > ,
0 commit comments