@@ -837,6 +837,10 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRA
837
837
#[ allow( dead_code) ]
838
838
const CHECK_CLTV_EXPIRY_SANITY_2 : u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2 * CLTV_CLAIM_BUFFER ;
839
839
840
+ /// The number of blocks before we consider an outbound payment for expiry if it doesn't have any
841
+ /// pending HTLCs in flight.
842
+ pub ( crate ) const PAYMENT_EXPIRY_BLOCKS : u32 = 3 ;
843
+
840
844
/// Information needed for constructing an invoice route hint for this channel.
841
845
#[ derive( Clone , Debug , PartialEq ) ]
842
846
pub struct CounterpartyForwardingInfo {
@@ -2408,15 +2412,26 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2408
2412
/// Signals that no further retries for the given payment will occur.
2409
2413
///
2410
2414
/// After this method returns, any future calls to [`retry_payment`] for the given `payment_id`
2411
- /// will fail with an [`PaymentSendFailure::ParameterError`] error.
2415
+ /// will fail with an [`PaymentSendFailure::ParameterError`] error. If no such event has been
2416
+ /// generated, an [`Event::PaymentFailed`] event will be generated as soon as there are no
2417
+ /// remaining pending HTLCs for this payment.
2412
2418
///
2413
2419
/// [`retry_payment`]: Self::retry_payment
2420
+ /// [`Event::PaymentFailed`]: events::Event::PaymentFailed
2414
2421
pub fn no_further_payment_retries ( & self , payment_id : PaymentId ) {
2415
2422
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
2416
2423
2417
2424
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
2418
2425
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
2419
- let _ = payment. get_mut ( ) . mark_retries_exceeded ( ) ;
2426
+ if let Ok ( ( ) ) = payment. get_mut ( ) . mark_retries_exceeded ( ) {
2427
+ if payment. get ( ) . remaining_parts ( ) == 0 {
2428
+ self . pending_events . lock ( ) . unwrap ( ) . push ( events:: Event :: PaymentFailed {
2429
+ payment_id,
2430
+ payment_hash : payment. get ( ) . payment_hash ( ) . expect ( "RetriesExceeded PendintOutboundPayments always have a payment hash set" ) ,
2431
+ } ) ;
2432
+ payment. remove ( ) ;
2433
+ }
2434
+ }
2420
2435
}
2421
2436
}
2422
2437
@@ -3245,22 +3260,28 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3245
3260
final_cltv_expiry_delta : path_last_hop. cltv_expiry_delta ,
3246
3261
} )
3247
3262
} else { None } ;
3248
- self . pending_events . lock ( ) . unwrap ( ) . push (
3249
- events:: Event :: PaymentPathFailed {
3250
- payment_id : Some ( payment_id) ,
3251
- payment_hash,
3252
- rejected_by_dest : false ,
3253
- network_update : None ,
3254
- all_paths_failed : payment. get ( ) . remaining_parts ( ) == 0 ,
3255
- path : path. clone ( ) ,
3256
- short_channel_id : None ,
3257
- retry,
3258
- #[ cfg( test) ]
3259
- error_code : None ,
3260
- #[ cfg( test) ]
3261
- error_data : None ,
3262
- }
3263
- ) ;
3263
+ let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
3264
+ pending_events. push ( events:: Event :: PaymentPathFailed {
3265
+ payment_id : Some ( payment_id) ,
3266
+ payment_hash,
3267
+ rejected_by_dest : false ,
3268
+ network_update : None ,
3269
+ all_paths_failed : payment. get ( ) . remaining_parts ( ) == 0 ,
3270
+ path : path. clone ( ) ,
3271
+ short_channel_id : None ,
3272
+ retry,
3273
+ #[ cfg( test) ]
3274
+ error_code : None ,
3275
+ #[ cfg( test) ]
3276
+ error_data : None ,
3277
+ } ) ;
3278
+ if payment. get ( ) . retries_exceeded ( ) && payment. get ( ) . remaining_parts ( ) == 0 {
3279
+ pending_events. push ( events:: Event :: PaymentFailed {
3280
+ payment_id,
3281
+ payment_hash : payment. get ( ) . payment_hash ( ) . expect ( "RetriesExceeded PendintOutboundPayments always have a payment hash set" ) ,
3282
+ } ) ;
3283
+ payment. remove ( ) ;
3284
+ }
3264
3285
}
3265
3286
} else {
3266
3287
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
@@ -3291,6 +3312,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3291
3312
session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
3292
3313
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3293
3314
let mut all_paths_failed = false ;
3315
+ let mut full_failure_ev = None ;
3294
3316
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3295
3317
if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( & path) ) {
3296
3318
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
@@ -3302,6 +3324,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3302
3324
}
3303
3325
if payment. get ( ) . remaining_parts ( ) == 0 {
3304
3326
all_paths_failed = true ;
3327
+ if payment. get ( ) . retries_exceeded ( ) {
3328
+ full_failure_ev = Some ( events:: Event :: PaymentFailed {
3329
+ payment_id,
3330
+ payment_hash : payment. get ( ) . payment_hash ( ) . expect ( "RetriesExceeded PendintOutboundPayments always have a payment hash set" ) ,
3331
+ } ) ;
3332
+ payment. remove ( ) ;
3333
+ }
3305
3334
}
3306
3335
} else {
3307
3336
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
@@ -3317,6 +3346,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3317
3346
} )
3318
3347
} else { None } ;
3319
3348
log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3349
+
3320
3350
match & onion_error {
3321
3351
& HTLCFailReason :: LightningError { ref err } => {
3322
3352
#[ cfg( test) ]
@@ -3326,22 +3356,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3326
3356
// TODO: If we decided to blame ourselves (or one of our channels) in
3327
3357
// process_onion_failure we should close that channel as it implies our
3328
3358
// next-hop is needlessly blaming us!
3329
- self . pending_events . lock ( ) . unwrap ( ) . push (
3330
- events:: Event :: PaymentPathFailed {
3331
- payment_id : Some ( payment_id) ,
3332
- payment_hash : payment_hash. clone ( ) ,
3333
- rejected_by_dest : !payment_retryable,
3334
- network_update,
3335
- all_paths_failed,
3336
- path : path. clone ( ) ,
3337
- short_channel_id,
3338
- retry,
3359
+ let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
3360
+ pending_events . push ( events:: Event :: PaymentPathFailed {
3361
+ payment_id : Some ( payment_id) ,
3362
+ payment_hash : payment_hash. clone ( ) ,
3363
+ rejected_by_dest : !payment_retryable,
3364
+ network_update,
3365
+ all_paths_failed,
3366
+ path : path. clone ( ) ,
3367
+ short_channel_id,
3368
+ retry,
3339
3369
#[ cfg( test) ]
3340
- error_code : onion_error_code,
3370
+ error_code : onion_error_code,
3341
3371
#[ cfg( test) ]
3342
- error_data : onion_error_data
3343
- }
3344
- ) ;
3372
+ error_data : onion_error_data
3373
+ } ) ;
3374
+ if let Some ( ev ) = full_failure_ev { pending_events . push ( ev ) ; }
3345
3375
} ,
3346
3376
& HTLCFailReason :: Reason {
3347
3377
#[ cfg( test) ]
@@ -3356,22 +3386,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3356
3386
// ChannelDetails.
3357
3387
// TODO: For non-temporary failures, we really should be closing the
3358
3388
// channel here as we apparently can't relay through them anyway.
3359
- self . pending_events . lock ( ) . unwrap ( ) . push (
3360
- events:: Event :: PaymentPathFailed {
3361
- payment_id : Some ( payment_id) ,
3362
- payment_hash : payment_hash. clone ( ) ,
3363
- rejected_by_dest : path. len ( ) == 1 ,
3364
- network_update : None ,
3365
- all_paths_failed,
3366
- path : path. clone ( ) ,
3367
- short_channel_id : Some ( path. first ( ) . unwrap ( ) . short_channel_id ) ,
3368
- retry,
3389
+ let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
3390
+ pending_events . push ( events:: Event :: PaymentPathFailed {
3391
+ payment_id : Some ( payment_id) ,
3392
+ payment_hash : payment_hash. clone ( ) ,
3393
+ rejected_by_dest : path. len ( ) == 1 ,
3394
+ network_update : None ,
3395
+ all_paths_failed,
3396
+ path : path. clone ( ) ,
3397
+ short_channel_id : Some ( path. first ( ) . unwrap ( ) . short_channel_id ) ,
3398
+ retry,
3369
3399
#[ cfg( test) ]
3370
- error_code : Some ( * failure_code) ,
3400
+ error_code : Some ( * failure_code) ,
3371
3401
#[ cfg( test) ]
3372
- error_data : Some ( data. clone ( ) ) ,
3373
- }
3374
- ) ;
3402
+ error_data : Some ( data. clone ( ) ) ,
3403
+ } ) ;
3404
+ if let Some ( ev ) = full_failure_ev { pending_events . push ( ev ) ; }
3375
3405
}
3376
3406
}
3377
3407
} ,
@@ -4900,14 +4930,19 @@ where
4900
4930
inbound_payment. expiry_time > header. time as u64
4901
4931
} ) ;
4902
4932
4933
+ let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
4903
4934
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
4904
- outbounds. retain ( |_, payment| {
4905
- const PAYMENT_EXPIRY_BLOCKS : u32 = 3 ;
4935
+ outbounds. retain ( |payment_id, payment| {
4906
4936
if payment. remaining_parts ( ) != 0 { return true }
4907
- if let PendingOutboundPayment :: Retryable { starting_block_height, .. } = payment {
4908
- return * starting_block_height + PAYMENT_EXPIRY_BLOCKS > height
4909
- }
4910
- true
4937
+ if let PendingOutboundPayment :: Retryable { starting_block_height, payment_hash, .. } = payment {
4938
+ if * starting_block_height + PAYMENT_EXPIRY_BLOCKS <= height {
4939
+ log_info ! ( self . logger, "Timing out payment with id {} and hash {}" , log_bytes!( payment_id. 0 ) , log_bytes!( payment_hash. 0 ) ) ;
4940
+ pending_events. push ( events:: Event :: PaymentFailed {
4941
+ payment_id : * payment_id, payment_hash : * payment_hash,
4942
+ } ) ;
4943
+ false
4944
+ } else { true }
4945
+ } else { true }
4911
4946
} ) ;
4912
4947
}
4913
4948
0 commit comments