@@ -1892,6 +1892,22 @@ impl OutboundPayments {
1892
1892
true
1893
1893
}
1894
1894
} ,
1895
+ PendingOutboundPayment :: StaticInvoiceReceived { route_params, payment_hash, .. } => {
1896
+ let is_stale =
1897
+ route_params. payment_params . expiry_time . unwrap_or ( u64:: MAX ) <
1898
+ duration_since_epoch. as_secs ( ) ;
1899
+ if is_stale {
1900
+ let fail_ev = events:: Event :: PaymentFailed {
1901
+ payment_id : * payment_id,
1902
+ payment_hash : Some ( * payment_hash) ,
1903
+ reason : Some ( PaymentFailureReason :: PaymentExpired )
1904
+ } ;
1905
+ pending_events. push_back ( ( fail_ev, None ) ) ;
1906
+ false
1907
+ } else {
1908
+ true
1909
+ }
1910
+ } ,
1895
1911
_ => true ,
1896
1912
} ) ;
1897
1913
}
@@ -2172,11 +2188,11 @@ mod tests {
2172
2188
2173
2189
use crate :: blinded_path:: EmptyNodeIdLookUp ;
2174
2190
use crate :: events:: { Event , PathFailure , PaymentFailureReason } ;
2175
- use crate :: ln:: types:: PaymentHash ;
2191
+ use crate :: ln:: types:: { PaymentHash , PaymentPreimage } ;
2176
2192
use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields } ;
2177
2193
use crate :: ln:: features:: { Bolt12InvoiceFeatures , ChannelFeatures , NodeFeatures } ;
2178
2194
use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
2179
- use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , Retry , RetryableSendFailure , StaleExpiration } ;
2195
+ use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , PendingOutboundPayment , Retry , RetryableSendFailure , StaleExpiration } ;
2180
2196
#[ cfg( feature = "std" ) ]
2181
2197
use crate :: offers:: invoice:: DEFAULT_RELATIVE_EXPIRY ;
2182
2198
use crate :: offers:: offer:: OfferBuilder ;
@@ -2726,4 +2742,51 @@ mod tests {
2726
2742
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2727
2743
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2728
2744
}
2745
+
2746
+ #[ test]
2747
+ fn time_out_unreleased_async_payments ( ) {
2748
+ let pending_events = Mutex :: new ( VecDeque :: new ( ) ) ;
2749
+ let outbound_payments = OutboundPayments :: new ( new_hash_map ( ) ) ;
2750
+ let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2751
+ let absolute_expiry = 60 ;
2752
+
2753
+ let mut outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2754
+ let payment_params = PaymentParameters :: from_node_id ( test_utils:: pubkey ( 42 ) , 0 )
2755
+ . with_expiry_time ( absolute_expiry) ;
2756
+ let route_params = RouteParameters {
2757
+ payment_params,
2758
+ final_value_msat : 0 ,
2759
+ max_total_routing_fee_msat : None ,
2760
+ } ;
2761
+ let payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
2762
+ let outbound = PendingOutboundPayment :: StaticInvoiceReceived {
2763
+ payment_hash,
2764
+ keysend_preimage : PaymentPreimage ( [ 0 ; 32 ] ) ,
2765
+ retry_strategy : Retry :: Attempts ( 0 ) ,
2766
+ payment_release_secret : [ 0 ; 32 ] ,
2767
+ route_params,
2768
+ } ;
2769
+ outbounds. insert ( payment_id, outbound) ;
2770
+ core:: mem:: drop ( outbounds) ;
2771
+
2772
+ // The payment will not be removed if it isn't expired yet.
2773
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry) , & pending_events) ;
2774
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2775
+ assert_eq ! ( outbounds. len( ) , 1 ) ;
2776
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2777
+ assert_eq ! ( events. len( ) , 0 ) ;
2778
+ core:: mem:: drop ( outbounds) ;
2779
+ core:: mem:: drop ( events) ;
2780
+
2781
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry + 1 ) , & pending_events) ;
2782
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2783
+ assert_eq ! ( outbounds. len( ) , 0 ) ;
2784
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2785
+ assert_eq ! ( events. len( ) , 1 ) ;
2786
+ assert_eq ! ( events[ 0 ] , ( Event :: PaymentFailed {
2787
+ payment_hash: Some ( payment_hash) ,
2788
+ payment_id,
2789
+ reason: Some ( PaymentFailureReason :: PaymentExpired ) ,
2790
+ } , None ) ) ;
2791
+ }
2729
2792
}
0 commit comments