@@ -188,10 +188,41 @@ 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 < PaymentInfoRouteHop > > ,
200
+ }
201
+
202
+ /// Subset of properties that is represented in `RouteHop`, so we only store what we need in
203
+ /// [`InvoicePayerUsingTime::payment_cache`]
204
+ ///
205
+ /// [`RouteHop`]: crate::routing::router::RouteHop
206
+ #[ derive( Clone , PartialEq , Eq ) ]
207
+ struct PaymentInfoRouteHop {
208
+ /// The node_id of the node at this hop.
209
+ pub pubkey : PublicKey ,
210
+ /// The channel that should be used from the previous hop to reach this node.
211
+ pub short_channel_id : u64 ,
212
+ /// The fee taken on this hop (for paying for the use of the *next* channel in the path).
213
+ /// For the last hop, this should be the full value of the payment (might be more than
214
+ /// requested if we had to match htlc_minimum_msat).
215
+ pub fee_msat : u64 ,
216
+ }
217
+
218
+ impl < T : Time > PaymentInfo < T > {
219
+ fn new ( ) -> Self {
220
+ PaymentInfo {
221
+ attempts : PaymentAttempts :: new ( ) ,
222
+ paths : vec ! [ ] ,
223
+ }
224
+ }
225
+ }
195
226
/// Storing minimal payment attempts information required for determining if a outbound payment can
196
227
/// be retried.
197
228
#[ derive( Clone , Copy ) ]
@@ -361,7 +392,7 @@ where
361
392
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
362
393
match self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash) {
363
394
hash_map:: Entry :: Occupied ( _) => return Err ( PaymentError :: Invoice ( "payment pending" ) ) ,
364
- hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentAttempts :: new ( ) ) ,
395
+ hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentInfo :: new ( ) ) ,
365
396
} ;
366
397
367
398
let payment_secret = Some ( invoice. payment_secret ( ) . clone ( ) ) ;
@@ -397,7 +428,7 @@ where
397
428
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
398
429
match self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash) {
399
430
hash_map:: Entry :: Occupied ( _) => return Err ( PaymentError :: Invoice ( "payment pending" ) ) ,
400
- hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentAttempts :: new ( ) ) ,
431
+ hash_map:: Entry :: Vacant ( entry) => entry. insert ( PaymentInfo :: new ( ) ) ,
401
432
} ;
402
433
403
434
let route_params = RouteParameters {
@@ -437,9 +468,9 @@ where
437
468
PaymentSendFailure :: PathParameterError ( _) => Err ( e) ,
438
469
PaymentSendFailure :: AllFailedRetrySafe ( _) => {
439
470
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 ) {
471
+ let payment_info = payment_cache. get_mut ( & payment_hash) . unwrap ( ) ;
472
+ payment_info . attempts . count += 1 ;
473
+ if self . retry . is_retryable_now ( & payment_info . attempts ) {
443
474
core:: mem:: drop ( payment_cache) ;
444
475
Ok ( self . pay_internal ( params, payment_hash, send_payment) ?)
445
476
} else {
@@ -469,13 +500,15 @@ where
469
500
fn retry_payment (
470
501
& self , payment_id : PaymentId , payment_hash : PaymentHash , params : & RouteParameters
471
502
) -> 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
- } ) ;
503
+ let attempts = self . payment_cache . lock ( ) . unwrap ( ) . entry ( payment_hash)
504
+ . and_modify ( |info| info. attempts . count += 1 )
505
+ . or_insert_with ( || PaymentInfo {
506
+ attempts : PaymentAttempts {
507
+ count : 1 ,
508
+ first_attempted_at : T :: now ( ) ,
509
+ } ,
510
+ paths : vec ! [ ] ,
511
+ } ) . attempts ;
479
512
480
513
if !self . retry . is_retryable_now ( & attempts) {
481
514
log_trace ! ( self . logger, "Payment {} exceeded maximum attempts; not retrying ({})" , log_bytes!( payment_hash. 0 ) , attempts) ;
@@ -583,7 +616,7 @@ where
583
616
let mut payment_cache = self . payment_cache . lock ( ) . unwrap ( ) ;
584
617
let attempts = payment_cache
585
618
. remove ( payment_hash)
586
- . map_or ( 1 , |attempts| attempts. count + 1 ) ;
619
+ . map_or ( 1 , |payment_info| payment_info . attempts . count + 1 ) ;
587
620
log_trace ! ( self . logger, "Payment {} succeeded (attempts: {})" , log_bytes!( payment_hash. 0 ) , attempts) ;
588
621
} ,
589
622
Event :: ProbeSuccessful { payment_hash, path, .. } => {
0 commit comments