@@ -145,7 +145,7 @@ use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
145
145
use lightning:: ln:: channelmanager:: { ChannelDetails , PaymentId , PaymentSendFailure } ;
146
146
use lightning:: ln:: msgs:: LightningError ;
147
147
use lightning:: routing:: scoring:: { LockableScore , Score } ;
148
- use lightning:: routing:: router:: { PaymentParameters , Route , RouteParameters } ;
148
+ use lightning:: routing:: router:: { PaymentParameters , Route , RouteHop , RouteParameters } ;
149
149
use lightning:: util:: events:: { Event , EventHandler } ;
150
150
use lightning:: util:: logger:: Logger ;
151
151
use time_utils:: Time ;
@@ -188,10 +188,25 @@ where
188
188
logger : L ,
189
189
event_handler : E ,
190
190
/// Caches the overall attempts at making a payment, which is updated prior to retrying.
191
- payment_cache : Mutex < HashMap < PaymentHash , PaymentAttempts < T > > > ,
191
+ payment_cache : Mutex < HashMap < PaymentHash , PaymentInfo < T > > > ,
192
192
retry : Retry ,
193
193
}
194
194
195
+ /// Used by [`InvoicePayerUsingTime::payment_cache`] to track the payments that are either
196
+ /// currently being made, or have outstanding paths that need retrying.
197
+ struct PaymentInfo < T : Time > {
198
+ attempts : PaymentAttempts < T > ,
199
+ paths : Vec < Vec < RouteHop > > ,
200
+ }
201
+
202
+ impl < T : Time > PaymentInfo < T > {
203
+ fn new ( ) -> Self {
204
+ PaymentInfo {
205
+ attempts : PaymentAttempts :: new ( ) ,
206
+ paths : vec ! [ ] ,
207
+ }
208
+ }
209
+ }
195
210
/// Storing minimal payment attempts information required for determining if a outbound payment can
196
211
/// be retried.
197
212
#[ derive( Clone , Copy ) ]
@@ -361,7 +376,7 @@ where
361
376
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
362
377
match self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash) {
363
378
hash_map:: Entry :: Occupied ( _) => return Err ( PaymentError :: Invoice ( "payment pending" ) ) ,
364
- hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentAttempts :: new ( ) ) ,
379
+ hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentInfo :: new ( ) ) ,
365
380
} ;
366
381
367
382
let payment_secret = Some ( invoice. payment_secret ( ) . clone ( ) ) ;
@@ -397,7 +412,7 @@ where
397
412
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
398
413
match self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash) {
399
414
hash_map:: Entry :: Occupied ( _) => return Err ( PaymentError :: Invoice ( "payment pending" ) ) ,
400
- hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentAttempts :: new ( ) ) ,
415
+ hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentInfo :: new ( ) ) ,
401
416
} ;
402
417
403
418
let route_params = RouteParameters {
@@ -437,9 +452,9 @@ where
437
452
PaymentSendFailure :: PathParameterError ( _) => Err ( e) ,
438
453
PaymentSendFailure :: AllFailedRetrySafe ( _) => {
439
454
let mut payment_cache = self . payment_cache . lock ( ) . unwrap ( ) ;
440
- let payment_attempts = payment_cache. get_mut ( & payment_hash) . unwrap ( ) ;
441
- payment_attempts . count += 1 ;
442
- if self . retry . is_retryable_now ( payment_attempts ) {
455
+ let payment_info = payment_cache. get_mut ( & payment_hash) . unwrap ( ) ;
456
+ payment_info . attempts . count += 1 ;
457
+ if self . retry . is_retryable_now ( & payment_info . attempts ) {
443
458
core:: mem:: drop ( payment_cache) ;
444
459
Ok ( self . pay_internal ( params, payment_hash, send_payment) ?)
445
460
} else {
@@ -469,13 +484,15 @@ where
469
484
fn retry_payment (
470
485
& self , payment_id : PaymentId , payment_hash : PaymentHash , params : & RouteParameters
471
486
) -> Result < ( ) , ( ) > {
472
- let attempts =
473
- * self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash)
474
- . and_modify ( |attempts| attempts. count += 1 )
475
- . or_insert ( PaymentAttempts {
476
- count : 1 ,
477
- first_attempted_at : T :: now ( )
478
- } ) ;
487
+ let attempts = self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash)
488
+ . and_modify ( |info| info. attempts . count += 1 )
489
+ . or_insert_with ( || PaymentInfo {
490
+ attempts : PaymentAttempts {
491
+ count : 1 ,
492
+ first_attempted_at : T :: now ( ) ,
493
+ } ,
494
+ paths : vec ! [ ] ,
495
+ } ) . attempts ;
479
496
480
497
if !self . retry . is_retryable_now ( & attempts) {
481
498
log_trace ! ( self . logger, "Payment {} exceeded maximum attempts; not retrying ({})" , log_bytes!( payment_hash. 0 ) , attempts) ;
@@ -583,7 +600,7 @@ where
583
600
let mut payment_cache = self . payment_cache . lock ( ) . unwrap ( ) ;
584
601
let attempts = payment_cache
585
602
. remove ( payment_hash)
586
- . map_or ( 1 , |attempts| attempts. count + 1 ) ;
603
+ . map_or ( 1 , |payment_info| payment_info . attempts . count + 1 ) ;
587
604
log_trace ! ( self . logger, "Payment {} succeeded (attempts: {})" , log_bytes!( payment_hash. 0 ) , attempts) ;
588
605
} ,
589
606
Event :: ProbeSuccessful { payment_hash, path, .. } => {
0 commit comments