@@ -1848,6 +1848,22 @@ impl OutboundPayments {
1848
1848
true
1849
1849
}
1850
1850
} ,
1851
+ PendingOutboundPayment :: StaticInvoiceReceived { route_params, payment_hash, .. } => {
1852
+ let is_stale =
1853
+ route_params. payment_params . expiry_time . unwrap_or_else ( u64:: max_value) <
1854
+ duration_since_epoch. as_secs ( ) ;
1855
+ if is_stale {
1856
+ let fail_ev = events:: Event :: PaymentFailed {
1857
+ payment_id : * payment_id,
1858
+ payment_hash : Some ( * payment_hash) ,
1859
+ reason : Some ( PaymentFailureReason :: PaymentExpired )
1860
+ } ;
1861
+ pending_events. push_back ( ( fail_ev, None ) ) ;
1862
+ false
1863
+ } else {
1864
+ true
1865
+ }
1866
+ } ,
1851
1867
_ => true ,
1852
1868
} ) ;
1853
1869
}
@@ -2103,11 +2119,11 @@ mod tests {
2103
2119
2104
2120
use crate :: blinded_path:: EmptyNodeIdLookUp ;
2105
2121
use crate :: events:: { Event , PathFailure , PaymentFailureReason } ;
2106
- use crate :: ln:: types:: PaymentHash ;
2122
+ use crate :: ln:: types:: { PaymentHash , PaymentPreimage } ;
2107
2123
use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields } ;
2108
2124
use crate :: ln:: features:: { Bolt12InvoiceFeatures , ChannelFeatures , NodeFeatures } ;
2109
2125
use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
2110
- use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , Retry , RetryableSendFailure , StaleExpiration } ;
2126
+ use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , PendingOutboundPayment , Retry , RetryableSendFailure , StaleExpiration } ;
2111
2127
#[ cfg( feature = "std" ) ]
2112
2128
use crate :: offers:: invoice:: DEFAULT_RELATIVE_EXPIRY ;
2113
2129
use crate :: offers:: offer:: OfferBuilder ;
@@ -2656,4 +2672,51 @@ mod tests {
2656
2672
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2657
2673
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2658
2674
}
2675
+
2676
+ #[ test]
2677
+ fn time_out_unreleased_async_payments ( ) {
2678
+ let pending_events = Mutex :: new ( VecDeque :: new ( ) ) ;
2679
+ let outbound_payments = OutboundPayments :: new ( ) ;
2680
+ let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2681
+ let absolute_expiry = 60 ;
2682
+
2683
+ let mut outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2684
+ let payment_params = PaymentParameters :: from_node_id ( test_utils:: pubkey ( 42 ) , 0 )
2685
+ . with_expiry_time ( absolute_expiry) ;
2686
+ let route_params = RouteParameters {
2687
+ payment_params,
2688
+ final_value_msat : 0 ,
2689
+ max_total_routing_fee_msat : None ,
2690
+ } ;
2691
+ let payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
2692
+ let outbound = PendingOutboundPayment :: StaticInvoiceReceived {
2693
+ payment_hash,
2694
+ keysend_preimage : PaymentPreimage ( [ 0 ; 32 ] ) ,
2695
+ retry_strategy : Retry :: Attempts ( 0 ) ,
2696
+ payment_release_secret : [ 0 ; 32 ] ,
2697
+ route_params,
2698
+ } ;
2699
+ outbounds. insert ( payment_id, outbound) ;
2700
+ core:: mem:: drop ( outbounds) ;
2701
+
2702
+ // The payment will not be removed if it isn't expired yet.
2703
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry) , & pending_events) ;
2704
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2705
+ assert_eq ! ( outbounds. len( ) , 1 ) ;
2706
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2707
+ assert_eq ! ( events. len( ) , 0 ) ;
2708
+ core:: mem:: drop ( outbounds) ;
2709
+ core:: mem:: drop ( events) ;
2710
+
2711
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry + 1 ) , & pending_events) ;
2712
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2713
+ assert_eq ! ( outbounds. len( ) , 0 ) ;
2714
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2715
+ assert_eq ! ( events. len( ) , 1 ) ;
2716
+ assert_eq ! ( events[ 0 ] , ( Event :: PaymentFailed {
2717
+ payment_hash: Some ( payment_hash) ,
2718
+ payment_id,
2719
+ reason: Some ( PaymentFailureReason :: PaymentExpired ) ,
2720
+ } , None ) ) ;
2721
+ }
2659
2722
}
0 commit comments