@@ -495,43 +495,7 @@ where
495
495
496
496
let payer = self . payer . node_id ( ) ;
497
497
let first_hops = self . payer . first_hops ( ) ;
498
- let inflight_htlcs = {
499
- // Make an attempt at finding existing payment information from `payment_cache`. If it
500
- // does not exist, it probably is a fresh payment and we can just return an empty
501
- // HashMap.
502
- if let Some ( payment_info) = self . payment_cache . lock ( ) . unwrap ( ) . get ( & payment_hash) {
503
- let mut total_inflight_map: HashMap < ( u64 , bool ) , u64 > = HashMap :: new ( ) ;
504
-
505
- for path in & payment_info. paths {
506
- if path. is_empty ( ) { break } ;
507
- // total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
508
- // that is held up. However, the `hops` array, which is a path returned by `find_route` in
509
- // the router excludes the payer node. In the following lines, the payer's information is
510
- // hardcoded with an inflight value of 0 so that we can correctly represent the first hop
511
- // in our sliding window of two.
512
- let our_node_id: PublicKey = self . payer . node_id ( ) ;
513
- let reversed_hops_with_payer = core:: iter:: once ( ( 0u64 , our_node_id) ) . chain (
514
- path. split_last ( ) . unwrap ( ) . 1 . iter ( ) . map ( |hop| ( hop. fee_msat , hop. pubkey ) ) ) . rev ( ) ;
515
- let mut cumulative_msat = path. last ( ) . unwrap ( ) . fee_msat ;
516
-
517
- // Taking the reversed vector from above, we zip it with just the reversed hops list to
518
- // work "backwards" of the given path, since the last hop's `fee_msat` actually represents
519
- // the total amount sent.
520
- for ( next_hop, prev_hop) in path. iter ( ) . rev ( ) . zip ( reversed_hops_with_payer) {
521
- cumulative_msat += prev_hop. 0 ;
522
- total_inflight_map
523
- . entry ( ( next_hop. short_channel_id , next_hop. pubkey < prev_hop. 1 ) )
524
- . and_modify ( |used_liquidity_msat| * used_liquidity_msat += cumulative_msat)
525
- . or_insert ( cumulative_msat) ;
526
- }
527
- }
528
-
529
- total_inflight_map
530
- } else {
531
- HashMap :: new ( )
532
- }
533
- } ;
534
-
498
+ let inflight_htlcs = self . create_inflight_map ( & payment_hash) ;
535
499
let route = self . router . find_route (
536
500
& payer, & params, & payment_hash, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
537
501
& AccountForInFlightHtlcs { scorer : & mut self . scorer . lock ( ) , inflight_htlcs }
@@ -631,7 +595,13 @@ where
631
595
) -> Result < ( ) , ( ) > {
632
596
let attempts = self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash)
633
597
. and_modify ( |info| info. attempts . count += 1 )
634
- . or_insert ( { PaymentInfo :: new ( ) } ) . attempts ;
598
+ . or_insert ( PaymentInfo {
599
+ attempts : PaymentAttempts {
600
+ count : 1 ,
601
+ first_attempted_at : T :: now ( ) ,
602
+ } ,
603
+ paths : vec ! [ ] ,
604
+ } ) . attempts ;
635
605
636
606
if !self . retry . is_retryable_now ( & attempts) {
637
607
log_trace ! ( self . logger, "Payment {} exceeded maximum attempts; not retrying ({})" , log_bytes!( payment_hash. 0 ) , attempts) ;
@@ -647,42 +617,7 @@ where
647
617
648
618
let payer = self . payer . node_id ( ) ;
649
619
let first_hops = self . payer . first_hops ( ) ;
650
- let inflight_htlcs = {
651
- // Make an attempt at finding existing payment information from `payment_cache`. If it
652
- // does not exist, it probably is a fresh payment and we can just return an empty
653
- // HashMap.
654
- if let Some ( payment_info) = self . payment_cache . lock ( ) . unwrap ( ) . get ( & payment_hash) {
655
- let mut total_inflight_map: HashMap < ( u64 , bool ) , u64 > = HashMap :: new ( ) ;
656
-
657
- for hops in & payment_info. paths {
658
- if hops. len ( ) < 1 { break } ;
659
- // total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
660
- // that is held up. However, the `hops` array, which is a path returned by `find_route` in
661
- // the router excludes the payer node. In the following lines, the payer's information is
662
- // hardcoded with an inflight value of 0 so that we can correctly represent the first hop
663
- // in our sliding window of two.
664
- let our_node_id: PublicKey = self . payer . node_id ( ) ;
665
- let reversed_hops_with_payer = core:: iter:: once ( ( 0u64 , our_node_id) ) . chain (
666
- hops. split_last ( ) . unwrap ( ) . 1 . iter ( ) . map ( |hop| ( hop. fee_msat , hop. pubkey ) ) ) . rev ( ) ;
667
- let mut cumulative_msat = hops. last ( ) . unwrap ( ) . fee_msat ;
668
-
669
- // Taking the reversed vector from above, we zip it with just the reversed hops list to
670
- // work "backwards" of the given path, since the last hop's `fee_msat` actually represents
671
- // the total amount sent.
672
- for ( next_hop, prev_hop) in hops. iter ( ) . rev ( ) . zip ( reversed_hops_with_payer) {
673
- cumulative_msat += prev_hop. 0 ;
674
- total_inflight_map
675
- . entry ( ( next_hop. short_channel_id , next_hop. pubkey < prev_hop. 1 ) )
676
- . and_modify ( |used_liquidity_msat| * used_liquidity_msat += cumulative_msat)
677
- . or_insert ( cumulative_msat) ;
678
- }
679
- }
680
-
681
- total_inflight_map
682
- } else {
683
- HashMap :: new ( )
684
- }
685
- } ;
620
+ let inflight_htlcs = self . create_inflight_map ( & payment_hash) ;
686
621
687
622
let route = {
688
623
let scorer = AccountForInFlightHtlcs { scorer : & mut self . scorer . lock ( ) , inflight_htlcs } ;
@@ -693,13 +628,11 @@ where
693
628
)
694
629
} ;
695
630
696
-
697
631
if route. is_err ( ) {
698
632
log_trace ! ( self . logger, "Failed to find a route for payment {}; not retrying ({:})" , log_bytes!( payment_hash. 0 ) , attempts) ;
699
633
return Err ( ( ) ) ;
700
634
}
701
635
702
-
703
636
match self . payer . retry_payment ( & route. unwrap ( ) , payment_id) {
704
637
Ok ( ( ) ) => Ok ( ( ) ) ,
705
638
Err ( PaymentSendFailure :: ParameterError ( _) ) |
@@ -727,6 +660,49 @@ where
727
660
pub fn remove_cached_payment ( & self , payment_hash : & PaymentHash ) {
728
661
self . payment_cache . lock ( ) . unwrap ( ) . remove ( payment_hash) ;
729
662
}
663
+
664
+ /// Given a [`PaymentHash`], this function looks up inflight path attempts in the payment_cache.
665
+ /// Then, it uses the path information inside the cache to construct a HashMap mapping a channel's
666
+ /// short channel id and direction to the amount being sent through it.
667
+ ///
668
+ /// This function should be called whenever we need information about currently used up liquidity
669
+ /// across payments.
670
+ pub fn create_inflight_map ( & self , payment_hash : & PaymentHash ) -> HashMap < ( u64 , bool ) , u64 > {
671
+ // Make an attempt at finding existing payment information from `payment_cache`. If it
672
+ // does not exist, it probably is a fresh payment and we can just return an empty
673
+ // HashMap.
674
+ if let Some ( payment_info) = self . payment_cache . lock ( ) . unwrap ( ) . get ( & payment_hash) {
675
+ let mut total_inflight_map: HashMap < ( u64 , bool ) , u64 > = HashMap :: new ( ) ;
676
+
677
+ for path in & payment_info. paths {
678
+ if path. is_empty ( ) { break } ;
679
+ // total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
680
+ // that is held up. However, the `hops` array, which is a path returned by `find_route` in
681
+ // the router excludes the payer node. In the following lines, the payer's information is
682
+ // hardcoded with an inflight value of 0 so that we can correctly represent the first hop
683
+ // in our sliding window of two.
684
+ let our_node_id: PublicKey = self . payer . node_id ( ) ;
685
+ let reversed_hops_with_payer = core:: iter:: once ( ( 0u64 , our_node_id) ) . chain (
686
+ path. split_last ( ) . unwrap ( ) . 1 . iter ( ) . map ( |hop| ( hop. fee_msat , hop. pubkey ) ) ) . rev ( ) ;
687
+ let mut cumulative_msat = path. last ( ) . unwrap ( ) . fee_msat ;
688
+
689
+ // Taking the reversed vector from above, we zip it with just the reversed hops list to
690
+ // work "backwards" of the given path, since the last hop's `fee_msat` actually represents
691
+ // the total amount sent.
692
+ for ( next_hop, prev_hop) in path. iter ( ) . rev ( ) . zip ( reversed_hops_with_payer) {
693
+ cumulative_msat += prev_hop. 0 ;
694
+ total_inflight_map
695
+ . entry ( ( next_hop. short_channel_id , next_hop. pubkey < prev_hop. 1 ) )
696
+ . and_modify ( |used_liquidity_msat| * used_liquidity_msat += cumulative_msat)
697
+ . or_insert ( cumulative_msat) ;
698
+ }
699
+ }
700
+
701
+ return total_inflight_map
702
+ } else {
703
+ return HashMap :: new ( )
704
+ }
705
+ }
730
706
}
731
707
732
708
fn expiry_time_from_unix_epoch ( invoice : & Invoice ) -> Duration {
0 commit comments