@@ -517,6 +517,23 @@ where
517
517
}
518
518
}
519
519
520
+ fn remove_path_inflight_htlcs ( & self , hops : & Vec < RouteHop > ) {
521
+ // Here, just like `process_path_inflight_htlcs`, we are given a vector of hops that excludes
522
+ // any information about the payer. However, in our `total_inflight_map`, we keep track
523
+ // of possible inbound/outbound liquidity from the payer as well. Therefore, it is accounted
524
+ // for by hard-coding the same tuple as in `process_path_inflight_htlcs`
525
+ let our_node_id: PublicKey = self . payer . node_id ( ) ;
526
+ let hops_with_us = core:: iter:: once ( ( 0u64 , our_node_id) ) . chain ( hops. iter ( ) . map ( |hop| ( hop. fee_msat , hop. pubkey ) ) ) ;
527
+
528
+ for ( next_hop, prev_hop) in hops. iter ( ) . zip ( hops_with_us) {
529
+ println ! ( "Subtracting {} inflight msats from {}" , next_hop. fee_msat, next_hop. short_channel_id) ;
530
+ self . total_inflight_map . lock ( ) . unwrap ( )
531
+ . entry ( ( next_hop. short_channel_id , next_hop. pubkey < prev_hop. 1 ) )
532
+ . and_modify ( |used_liquidity_msat| * used_liquidity_msat = used_liquidity_msat. saturating_sub ( next_hop. fee_msat ) )
533
+ . or_insert ( 0 ) ;
534
+ }
535
+ }
536
+
520
537
fn retry_payment (
521
538
& self , payment_id : PaymentId , payment_hash : PaymentHash , params : & RouteParameters
522
539
) -> Result < ( ) , ( ) > {
@@ -613,22 +630,26 @@ where
613
630
} else if * rejected_by_dest {
614
631
log_trace ! ( self . logger, "Payment {} rejected by destination; not retrying" , log_bytes!( payment_hash. 0 ) ) ;
615
632
self . payer . abandon_payment ( payment_id. unwrap ( ) ) ;
633
+ self . remove_path_inflight_htlcs ( path) ;
616
634
} else if retry. is_none ( ) {
617
635
log_trace ! ( self . logger, "Payment {} missing retry params; not retrying" , log_bytes!( payment_hash. 0 ) ) ;
618
636
self . payer . abandon_payment ( payment_id. unwrap ( ) ) ;
637
+ self . remove_path_inflight_htlcs ( path) ;
619
638
} else if self . retry_payment ( payment_id. unwrap ( ) , * payment_hash, retry. as_ref ( ) . unwrap ( ) ) . is_ok ( ) {
620
639
// We retried at least somewhat, don't provide the PaymentPathFailed event to the user.
621
640
return ;
622
641
} else {
623
642
self . payer . abandon_payment ( payment_id. unwrap ( ) ) ;
643
+ self . remove_path_inflight_htlcs ( path) ;
624
644
}
625
645
} ,
626
646
Event :: PaymentFailed { payment_hash, .. } => {
627
647
self . remove_cached_payment ( & payment_hash) ;
628
648
} ,
629
649
Event :: PaymentPathSuccessful { path, .. } => {
630
- let path = path. iter ( ) . collect :: < Vec < _ > > ( ) ;
631
- self . scorer . lock ( ) . payment_path_successful ( & path) ;
650
+ let path_with_refs = path. iter ( ) . collect :: < Vec < _ > > ( ) ;
651
+ self . scorer . lock ( ) . payment_path_successful ( & path_with_refs) ;
652
+ self . remove_path_inflight_htlcs ( path) ;
632
653
} ,
633
654
Event :: PaymentSent { payment_hash, .. } => {
634
655
let mut payment_cache = self . payment_cache . lock ( ) . unwrap ( ) ;
@@ -766,11 +787,31 @@ mod tests {
766
787
let payment_id = Some ( invoice_payer. pay_invoice ( & invoice) . unwrap ( ) ) ;
767
788
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
768
789
790
+ let inflight_map = invoice_payer. total_inflight_map . lock ( ) . unwrap ( ) ;
791
+ // TestRouter returns two hops, with `fee_msat` divided by two. The invoice instantiated above
792
+ // is hard-coded to test sending an invoice with a value of 128 msats.
793
+ assert_eq ! ( inflight_map. get( & ( 0 , true ) ) . unwrap( ) . clone( ) , 64 ) ;
794
+ assert_eq ! ( inflight_map. get( & ( 1 , true ) ) . unwrap( ) . clone( ) , 64 ) ;
795
+ drop ( inflight_map) ;
796
+
769
797
invoice_payer. handle_event ( & Event :: PaymentSent {
770
798
payment_id, payment_preimage, payment_hash, fee_paid_msat : None
771
799
} ) ;
772
800
assert_eq ! ( * event_handled. borrow( ) , true ) ;
773
801
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
802
+
803
+ invoice_payer. handle_event ( & Event :: PaymentPathSuccessful {
804
+ payment_id : payment_id. unwrap ( ) , payment_hash : Some ( payment_hash) ,
805
+ path : TestRouter :: route_for_value ( final_value_msat) . paths [ 0 ] . clone ( )
806
+ } ) ;
807
+ invoice_payer. handle_event ( & Event :: PaymentPathSuccessful {
808
+ payment_id : payment_id. unwrap ( ) , payment_hash : Some ( payment_hash) ,
809
+ path : TestRouter :: route_for_value ( final_value_msat) . paths [ 1 ] . clone ( )
810
+ } ) ;
811
+
812
+ let inflight_map = invoice_payer. total_inflight_map . lock ( ) . unwrap ( ) ;
813
+ assert_eq ! ( inflight_map. get( & ( 0 , true ) ) . unwrap( ) . clone( ) , 0 ) ;
814
+ assert_eq ! ( inflight_map. get( & ( 1 , true ) ) . unwrap( ) . clone( ) , 0 ) ;
774
815
}
775
816
776
817
#[ test]
@@ -808,12 +849,28 @@ mod tests {
808
849
invoice_payer. handle_event ( & event) ;
809
850
assert_eq ! ( * event_handled. borrow( ) , false ) ;
810
851
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
852
+ let inflight_map = invoice_payer. total_inflight_map . lock ( ) . unwrap ( ) ;
853
+ assert_eq ! ( inflight_map. get( & ( 0 , true ) ) . unwrap( ) . clone( ) , 64 ) ;
854
+ assert_eq ! ( inflight_map. get( & ( 1 , true ) ) . unwrap( ) . clone( ) , 64 ) ;
855
+ drop ( inflight_map) ;
811
856
812
857
invoice_payer. handle_event ( & Event :: PaymentSent {
813
858
payment_id, payment_preimage, payment_hash, fee_paid_msat : None
814
859
} ) ;
815
860
assert_eq ! ( * event_handled. borrow( ) , true ) ;
816
861
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
862
+
863
+ invoice_payer. handle_event ( & Event :: PaymentPathSuccessful {
864
+ payment_id : payment_id. unwrap ( ) , payment_hash : Some ( payment_hash) ,
865
+ path : TestRouter :: route_for_value ( final_value_msat) . paths [ 0 ] . clone ( )
866
+ } ) ;
867
+ invoice_payer. handle_event ( & Event :: PaymentPathSuccessful {
868
+ payment_id : payment_id. unwrap ( ) , payment_hash : Some ( payment_hash) ,
869
+ path : TestRouter :: route_for_value ( final_value_msat) . paths [ 1 ] . clone ( )
870
+ } ) ;
871
+ let inflight_map = invoice_payer. total_inflight_map . lock ( ) . unwrap ( ) ;
872
+ assert_eq ! ( inflight_map. get( & ( 0 , true ) ) . unwrap( ) . clone( ) , 0 ) ;
873
+ assert_eq ! ( inflight_map. get( & ( 1 , true ) ) . unwrap( ) . clone( ) , 0 ) ;
817
874
}
818
875
819
876
#[ test]
0 commit comments