14
14
//! to send a payment over a [`Route`]. Implementations of [`Router`] find a [`Route`] between payer
15
15
//! and payee using information provided by the payer and from the payee's [`Invoice`].
16
16
//!
17
- //! [`InvoicePayer`] caches each [`Invoice`] by its `payment_hash` so that [`PaymentRetryHandler`]
18
- //! can retry the payment if it fails. It accomplishes this by implementing [`EventHandler`] which
19
- //! decorates a user-provided handler. It will intercepts any [`Event::PaymentFailed`] events and
20
- //! retry the payment a fixed number of times before failing or succeeding as needed.
17
+ //! [`InvoicePayer`] caches each [`Invoice`] by its `payment_hash` so that it can retry the payment
18
+ //! if it fails. It accomplishes this by implementing [`EventHandler`] which decorates a
19
+ //! user-provided handler. It will intercepts any [`Event::PaymentFailed`] events and retry the
20
+ //! payment a fixed number of times before failing or succeeding as needed.
21
21
//!
22
22
//! # Example
23
23
//!
28
28
//! The [`Route`] is compute before each payment attempt. Any updates affecting path finding such as
29
29
//! updates to the network graph or changes to channels scores should be applied prior to retries.
30
30
//! This typically means any [`EventHandler`] decorators responsible for this should decorate
31
- //! [`PaymentRetryHandler `] so that such changes take effect before retrying.
31
+ //! [`InvoicePayer `] so that such changes take effect before retrying.
32
32
33
33
use crate :: Invoice ;
34
34
@@ -44,7 +44,6 @@ use lightning::routing::router::{Route, RouteHint};
44
44
use lightning:: util:: events:: { Event , EventHandler } ;
45
45
use lightning:: util:: logger:: Logger ;
46
46
47
- use std:: cell:: RefCell ;
48
47
use std:: collections:: hash_map:: { self , HashMap } ;
49
48
use std:: ops:: Deref ;
50
49
use std:: sync:: Mutex ;
@@ -54,10 +53,20 @@ use std::sync::Mutex;
54
53
const MAX_PAYMENT_ATTEMPTS : usize = 3 ;
55
54
56
55
/// A utility for paying [`Invoice]`s.
57
- pub struct InvoicePayer < P : Deref , R > where P :: Target : Payer , R : Router {
56
+ pub struct InvoicePayer < P : Deref , R , L : Deref , E >
57
+ where
58
+ P :: Target : Payer ,
59
+ R : Router ,
60
+ L :: Target : Logger ,
61
+ E : EventHandler ,
62
+ {
58
63
payer : P ,
59
64
router : R ,
65
+ logger : L ,
66
+ event_handler : E ,
67
+ // Lock order: payment_attempts -> invoice_cache
60
68
invoice_cache : Mutex < HashMap < PaymentHash , Invoice > > ,
69
+ payment_attempts : Mutex < HashMap < PaymentHash , usize > > ,
61
70
}
62
71
63
72
/// A trait defining behavior of an [`Invoice`] payer.
@@ -101,28 +110,22 @@ pub enum PaymentError {
101
110
Sending ( PaymentSendFailure ) ,
102
111
}
103
112
104
- /// An [`EventHandler`] decorator for retrying failed payments.
105
- pub struct PaymentRetryHandler < I , P : Deref , R , L : Deref , E >
113
+ impl < P : Deref , R , L : Deref , E > InvoicePayer < P , R , L , E >
106
114
where
107
- I : Deref < Target = InvoicePayer < P , R > > ,
108
115
P :: Target : Payer ,
109
116
R : Router ,
110
117
L :: Target : Logger ,
111
118
E : EventHandler ,
112
119
{
113
- invoice_payer : I ,
114
- payment_attempts : RefCell < HashMap < PaymentHash , usize > > ,
115
- logger : L ,
116
- event_handler : E ,
117
- }
118
-
119
- impl < P : Deref , R > InvoicePayer < P , R > where P :: Target : Payer , R : Router {
120
120
/// Creates an invoice payer.
121
- pub fn new ( payer : P , router : R ) -> Self {
121
+ pub fn new ( payer : P , router : R , logger : L , event_handler : E ) -> Self {
122
122
Self {
123
123
payer,
124
124
router,
125
+ logger,
126
+ event_handler,
125
127
invoice_cache : Mutex :: new ( HashMap :: new ( ) ) ,
128
+ payment_attempts : Mutex :: new ( HashMap :: new ( ) ) ,
126
129
}
127
130
}
128
131
@@ -175,35 +178,15 @@ impl<P: Deref, R> InvoicePayer<P, R> where P::Target: Payer, R: Router {
175
178
176
179
/// Removes the [`Invoice`] cached by the given payment hash.
177
180
///
178
- /// Should be called once a payment has failed or succeeded. This is taken care of by
179
- /// [`PaymentRetryHandler`], but can be called independently as well.
181
+ /// Should be called once a payment has failed or succeeded. This is taken care of when
182
+ /// [`InvoicePayer`] is used as an [`EventHandler`] but can be called independently as well.
180
183
pub fn remove_cached_invoice ( & self , payment_hash : & PaymentHash ) {
181
184
self . invoice_cache . lock ( ) . unwrap ( ) . remove ( payment_hash) ;
182
185
}
183
186
}
184
187
185
- impl < I , P : Deref , R , L : Deref , E > PaymentRetryHandler < I , P , R , L , E >
186
- where
187
- I : Deref < Target = InvoicePayer < P , R > > ,
188
- P :: Target : Payer ,
189
- R : Router ,
190
- L :: Target : Logger ,
191
- E : EventHandler ,
192
- {
193
- /// Creates a payment retry handler.
194
- pub fn new ( invoice_payer : I , logger : L , event_handler : E ) -> Self {
195
- Self {
196
- invoice_payer,
197
- payment_attempts : RefCell :: new ( HashMap :: new ( ) ) ,
198
- logger,
199
- event_handler,
200
- }
201
- }
202
- }
203
-
204
- impl < I , P : Deref , R , L : Deref , E > EventHandler for PaymentRetryHandler < I , P , R , L , E >
188
+ impl < P : Deref , R , L : Deref , E > EventHandler for InvoicePayer < P , R , L , E >
205
189
where
206
- I : Deref < Target = InvoicePayer < P , R > > ,
207
190
P :: Target : Payer ,
208
191
R : Router ,
209
192
L :: Target : Logger ,
@@ -212,14 +195,14 @@ where
212
195
fn handle_event ( & self , event : & Event ) {
213
196
match event {
214
197
Event :: PaymentFailed { payment_hash, rejected_by_dest, .. } => {
215
- let mut attempts_by_payment_hash = self . payment_attempts . borrow_mut ( ) ;
198
+ let mut attempts_by_payment_hash = self . payment_attempts . lock ( ) . unwrap ( ) ;
216
199
let attempts = attempts_by_payment_hash
217
200
. entry ( * payment_hash)
218
201
. and_modify ( |attempts| * attempts += 1 )
219
202
. or_insert ( 1 ) ;
220
203
if !rejected_by_dest {
221
204
if * attempts < MAX_PAYMENT_ATTEMPTS {
222
- if self . invoice_payer . pay_cached_invoice ( payment_hash) . is_ok ( ) {
205
+ if self . pay_cached_invoice ( payment_hash) . is_ok ( ) {
223
206
log_trace ! ( self . logger, "Payment {} failed; retrying (attempts: {})" , log_bytes!( payment_hash. 0 ) , attempts) ;
224
207
return ;
225
208
} else {
@@ -233,18 +216,18 @@ where
233
216
}
234
217
235
218
// Either the payment was rejected, exceeded the maximum attempts, or failed retry.
236
- self . invoice_payer . remove_cached_invoice ( payment_hash) ;
219
+ self . remove_cached_invoice ( payment_hash) ;
237
220
attempts_by_payment_hash. remove ( payment_hash) ;
238
221
} ,
239
222
Event :: PaymentSent { payment_preimage } => {
240
223
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
241
- self . invoice_payer . remove_cached_invoice ( & payment_hash) ;
242
-
243
- let attempts = self . payment_attempts
244
- . borrow_mut ( )
224
+ let mut attempts_by_payment_hash = self . payment_attempts . lock ( ) . unwrap ( ) ;
225
+ let attempts = attempts_by_payment_hash
245
226
. remove ( & payment_hash)
246
227
. map_or ( 1 , |attempts| attempts + 1 ) ;
247
228
log_trace ! ( self . logger, "Payment {} succeeded (attempts: {})" , log_bytes!( payment_hash. 0 ) , attempts) ;
229
+
230
+ self . remove_cached_invoice ( & payment_hash) ;
248
231
} ,
249
232
_ => { } ,
250
233
}
@@ -284,35 +267,33 @@ mod tests {
284
267
285
268
#[ test]
286
269
fn pays_invoice_on_first_attempt ( ) {
270
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
271
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
272
+
287
273
let payer = TestPayer :: new ( ) ;
288
274
let router = NullRouter { } ;
289
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
290
-
291
275
let logger = TestLogger :: new ( ) ;
292
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
293
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
294
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
276
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
295
277
296
278
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
297
279
let invoice = invoice ( payment_preimage) ;
298
280
assert ! ( invoice_payer. pay_invoice( & invoice) . is_ok( ) ) ;
299
281
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
300
282
301
- retry_handler . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
283
+ invoice_payer . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
302
284
assert_eq ! ( * event_handled. borrow( ) , true ) ;
303
285
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
304
286
}
305
287
306
288
#[ test]
307
289
fn pays_invoice_on_retry ( ) {
290
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
291
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
292
+
308
293
let payer = TestPayer :: new ( ) ;
309
294
let router = NullRouter { } ;
310
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
311
-
312
295
let logger = TestLogger :: new ( ) ;
313
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
314
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
315
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
296
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
316
297
317
298
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
318
299
let invoice = invoice ( payment_preimage) ;
@@ -324,25 +305,24 @@ mod tests {
324
305
network_update : None ,
325
306
rejected_by_dest : false ,
326
307
} ;
327
- retry_handler . handle_event ( & event) ;
308
+ invoice_payer . handle_event ( & event) ;
328
309
assert_eq ! ( * event_handled. borrow( ) , false ) ;
329
310
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
330
311
331
- retry_handler . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
312
+ invoice_payer . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
332
313
assert_eq ! ( * event_handled. borrow( ) , true ) ;
333
314
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
334
315
}
335
316
336
317
#[ test]
337
318
fn fails_paying_invoice_after_max_retries ( ) {
319
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
320
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
321
+
338
322
let payer = TestPayer :: new ( ) ;
339
323
let router = NullRouter { } ;
340
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
341
-
342
324
let logger = TestLogger :: new ( ) ;
343
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
344
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
345
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
325
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
346
326
347
327
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
348
328
let invoice = invoice ( payment_preimage) ;
@@ -354,29 +334,28 @@ mod tests {
354
334
network_update : None ,
355
335
rejected_by_dest : false ,
356
336
} ;
357
- retry_handler . handle_event ( & event) ;
337
+ invoice_payer . handle_event ( & event) ;
358
338
assert_eq ! ( * event_handled. borrow( ) , false ) ;
359
339
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
360
340
361
- retry_handler . handle_event ( & event) ;
341
+ invoice_payer . handle_event ( & event) ;
362
342
assert_eq ! ( * event_handled. borrow( ) , false ) ;
363
343
assert_eq ! ( * payer. attempts. borrow( ) , 3 ) ;
364
344
365
- retry_handler . handle_event ( & event) ;
345
+ invoice_payer . handle_event ( & event) ;
366
346
assert_eq ! ( * event_handled. borrow( ) , true ) ;
367
347
assert_eq ! ( * payer. attempts. borrow( ) , 3 ) ;
368
348
}
369
349
370
350
#[ test]
371
351
fn fails_paying_invoice_after_retry_error ( ) {
352
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
353
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
354
+
372
355
let payer = TestPayer :: new ( ) . fails_on_attempt ( 2 ) ;
373
356
let router = NullRouter { } ;
374
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
375
-
376
357
let logger = TestLogger :: new ( ) ;
377
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
378
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
379
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
358
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
380
359
381
360
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
382
361
let invoice = invoice ( payment_preimage) ;
@@ -388,21 +367,20 @@ mod tests {
388
367
network_update : None ,
389
368
rejected_by_dest : false ,
390
369
} ;
391
- retry_handler . handle_event ( & event) ;
370
+ invoice_payer . handle_event ( & event) ;
392
371
assert_eq ! ( * event_handled. borrow( ) , true ) ;
393
372
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
394
373
}
395
374
396
375
#[ test]
397
376
fn fails_paying_invoice_after_rejected_by_payee ( ) {
377
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
378
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
379
+
398
380
let payer = TestPayer :: new ( ) ;
399
381
let router = NullRouter { } ;
400
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
401
-
402
382
let logger = TestLogger :: new ( ) ;
403
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
404
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
405
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
383
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
406
384
407
385
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
408
386
let invoice = invoice ( payment_preimage) ;
@@ -414,21 +392,20 @@ mod tests {
414
392
network_update : None ,
415
393
rejected_by_dest : true ,
416
394
} ;
417
- retry_handler . handle_event ( & event) ;
395
+ invoice_payer . handle_event ( & event) ;
418
396
assert_eq ! ( * event_handled. borrow( ) , true ) ;
419
397
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
420
398
}
421
399
422
400
#[ test]
423
401
fn fails_repaying_invoice_with_pending_payment ( ) {
402
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
403
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
404
+
424
405
let payer = TestPayer :: new ( ) ;
425
406
let router = NullRouter { } ;
426
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
427
-
428
407
let logger = TestLogger :: new ( ) ;
429
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
430
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
431
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
408
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
432
409
433
410
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
434
411
let invoice = invoice ( payment_preimage) ;
@@ -453,15 +430,16 @@ mod tests {
453
430
network_update : None ,
454
431
rejected_by_dest : false ,
455
432
} ;
456
- retry_handler . handle_event ( & event) ;
433
+ invoice_payer . handle_event ( & event) ;
457
434
assert_eq ! ( * event_handled. borrow( ) , true ) ;
458
435
}
459
436
460
437
#[ test]
461
438
fn fails_paying_invoice_with_routing_errors ( ) {
462
439
let payer = TestPayer :: new ( ) ;
463
440
let router = FailingRouter { } ;
464
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
441
+ let logger = TestLogger :: new ( ) ;
442
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, |_: & _ | { } ) ;
465
443
466
444
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
467
445
let invoice = invoice ( payment_preimage) ;
@@ -476,7 +454,8 @@ mod tests {
476
454
fn fails_paying_invoice_with_sending_errors ( ) {
477
455
let payer = TestPayer :: new ( ) . fails_on_attempt ( 1 ) ;
478
456
let router = NullRouter { } ;
479
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
457
+ let logger = TestLogger :: new ( ) ;
458
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, |_: & _ | { } ) ;
480
459
481
460
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
482
461
let invoice = invoice ( payment_preimage) ;
0 commit comments