@@ -206,20 +206,26 @@ impl PendingOutboundPayment {
206
206
}
207
207
208
208
fn mark_abandoned ( & mut self , reason : PaymentFailureReason ) {
209
- if let PendingOutboundPayment :: Retryable { session_privs, payment_hash, .. } = self {
210
- let mut our_session_privs = new_hash_set ( ) ;
211
- core:: mem:: swap ( & mut our_session_privs, session_privs) ;
212
- * self = PendingOutboundPayment :: Abandoned {
213
- session_privs : our_session_privs,
214
- payment_hash : * payment_hash,
215
- reason : Some ( reason)
216
- } ;
217
- } else if let PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } = self {
218
- * self = PendingOutboundPayment :: Abandoned {
219
- session_privs : new_hash_set ( ) ,
220
- payment_hash : * payment_hash,
221
- reason : Some ( reason)
222
- } ;
209
+ let session_privs = match self {
210
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
211
+ let mut our_session_privs = new_hash_set ( ) ;
212
+ core:: mem:: swap ( & mut our_session_privs, session_privs) ;
213
+ our_session_privs
214
+ } ,
215
+ _ => new_hash_set ( ) ,
216
+ } ;
217
+ match self {
218
+ Self :: Retryable { payment_hash, .. } |
219
+ Self :: InvoiceReceived { payment_hash, .. } |
220
+ Self :: StaticInvoiceReceived { payment_hash, .. } =>
221
+ {
222
+ * self = Self :: Abandoned {
223
+ session_privs,
224
+ payment_hash : * payment_hash,
225
+ reason : Some ( reason) ,
226
+ } ;
227
+ } ,
228
+ _ => { }
223
229
}
224
230
}
225
231
@@ -2719,4 +2725,44 @@ mod tests {
2719
2725
reason: Some ( PaymentFailureReason :: PaymentExpired ) ,
2720
2726
} , None ) ) ;
2721
2727
}
2728
+
2729
+ #[ test]
2730
+ fn abandon_unreleased_async_payment ( ) {
2731
+ let pending_events = Mutex :: new ( VecDeque :: new ( ) ) ;
2732
+ let outbound_payments = OutboundPayments :: new ( ) ;
2733
+ let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2734
+ let absolute_expiry = 60 ;
2735
+
2736
+ let mut outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2737
+ let payment_params = PaymentParameters :: from_node_id ( test_utils:: pubkey ( 42 ) , 0 )
2738
+ . with_expiry_time ( absolute_expiry) ;
2739
+ let route_params = RouteParameters {
2740
+ payment_params,
2741
+ final_value_msat : 0 ,
2742
+ max_total_routing_fee_msat : None ,
2743
+ } ;
2744
+ let payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
2745
+ let outbound = PendingOutboundPayment :: StaticInvoiceReceived {
2746
+ payment_hash,
2747
+ keysend_preimage : PaymentPreimage ( [ 0 ; 32 ] ) ,
2748
+ retry_strategy : Retry :: Attempts ( 0 ) ,
2749
+ payment_release_secret : [ 0 ; 32 ] ,
2750
+ route_params,
2751
+ } ;
2752
+ outbounds. insert ( payment_id, outbound) ;
2753
+ core:: mem:: drop ( outbounds) ;
2754
+
2755
+ outbound_payments. abandon_payment (
2756
+ payment_id, PaymentFailureReason :: UserAbandoned , & pending_events
2757
+ ) ;
2758
+ let outbounds = outbound_payments. pending_outbound_payments . lock ( ) . unwrap ( ) ;
2759
+ assert_eq ! ( outbounds. len( ) , 0 ) ;
2760
+ let events = pending_events. lock ( ) . unwrap ( ) ;
2761
+ assert_eq ! ( events. len( ) , 1 ) ;
2762
+ assert_eq ! ( events[ 0 ] , ( Event :: PaymentFailed {
2763
+ payment_hash: Some ( payment_hash) ,
2764
+ payment_id,
2765
+ reason: Some ( PaymentFailureReason :: UserAbandoned ) ,
2766
+ } , None ) ) ;
2767
+ }
2722
2768
}
0 commit comments