@@ -1718,6 +1718,22 @@ impl OutboundPayments {
1718
1718
true
1719
1719
}
1720
1720
} ,
1721
+ PendingOutboundPayment :: StaticInvoiceReceived { route_params, payment_hash, .. } => {
1722
+ let is_stale =
1723
+ route_params. payment_params . expiry_time . unwrap_or_else ( u64:: max_value) <
1724
+ duration_since_epoch. as_secs ( ) ;
1725
+ if is_stale {
1726
+ let fail_ev = events:: Event :: PaymentFailed {
1727
+ payment_id : * payment_id,
1728
+ payment_hash : * payment_hash,
1729
+ reason : Some ( PaymentFailureReason :: PaymentExpired )
1730
+ } ;
1731
+ pending_events. push_back ( ( fail_ev, None ) ) ;
1732
+ false
1733
+ } else {
1734
+ true
1735
+ }
1736
+ } ,
1721
1737
_ => true ,
1722
1738
} ) ;
1723
1739
}
@@ -1982,11 +1998,11 @@ mod tests {
1982
1998
use core:: time:: Duration ;
1983
1999
1984
2000
use crate :: events:: { Event , PathFailure , PaymentFailureReason } ;
1985
- use crate :: ln:: types:: PaymentHash ;
2001
+ use crate :: ln:: types:: { PaymentHash , PaymentPreimage } ;
1986
2002
use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields } ;
1987
2003
use crate :: ln:: features:: { ChannelFeatures , NodeFeatures } ;
1988
2004
use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
1989
- use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , Retry , RetryableSendFailure , StaleExpiration } ;
2005
+ use crate :: ln:: outbound_payment:: { Bolt12PaymentError , OutboundPayments , PendingOutboundPayment , Retry , RetryableSendFailure , StaleExpiration } ;
1990
2006
#[ cfg( feature = "std" ) ]
1991
2007
use crate :: offers:: invoice:: DEFAULT_RELATIVE_EXPIRY ;
1992
2008
use crate :: offers:: offer:: OfferBuilder ;
@@ -2517,4 +2533,51 @@ mod tests {
2517
2533
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2518
2534
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2519
2535
}
2536
+
2537
+ #[ test]
2538
+ fn time_out_unreleased_async_payments ( ) {
2539
+ let pending_events = Mutex :: new ( VecDeque :: new ( ) ) ;
2540
+ let outbound_payments = OutboundPayments :: new ( ) ;
2541
+ let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2542
+ let absolute_expiry = 60 ;
2543
+
2544
+ let mut outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2545
+ let payment_params = PaymentParameters :: from_node_id ( test_utils:: pubkey ( 42 ) , 0 )
2546
+ . with_expiry_time ( absolute_expiry) ;
2547
+ let route_params = RouteParameters {
2548
+ payment_params,
2549
+ final_value_msat : 0 ,
2550
+ max_total_routing_fee_msat : None ,
2551
+ } ;
2552
+ let payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
2553
+ let outbound = PendingOutboundPayment :: StaticInvoiceReceived {
2554
+ payment_hash,
2555
+ keysend_preimage : PaymentPreimage ( [ 0 ; 32 ] ) ,
2556
+ retry_strategy : Retry :: Attempts ( 0 ) ,
2557
+ payment_release_secret : [ 0 ; 32 ] ,
2558
+ route_params,
2559
+ } ;
2560
+ outbounds. insert ( payment_id, outbound) ;
2561
+ core:: mem:: drop ( outbounds) ;
2562
+
2563
+ // The payment will not be removed if it isn't expired yet.
2564
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry) , & pending_events) ;
2565
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2566
+ assert_eq ! ( outbounds. len( ) , 1 ) ;
2567
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2568
+ assert_eq ! ( events. len( ) , 0 ) ;
2569
+ core:: mem:: drop ( outbounds) ;
2570
+ core:: mem:: drop ( events) ;
2571
+
2572
+ outbound_payments. remove_stale_payments ( Duration :: from_secs ( absolute_expiry + 1 ) , & pending_events) ;
2573
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2574
+ assert_eq ! ( outbounds. len( ) , 0 ) ;
2575
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2576
+ assert_eq ! ( events. len( ) , 1 ) ;
2577
+ assert_eq ! ( events[ 0 ] , ( Event :: PaymentFailed {
2578
+ payment_hash,
2579
+ payment_id,
2580
+ reason: Some ( PaymentFailureReason :: PaymentExpired ) ,
2581
+ } , None ) ) ;
2582
+ }
2520
2583
}
0 commit comments