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,135 +267,129 @@ 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) ;
319
300
assert ! ( invoice_payer. pay_invoice( & invoice) . is_ok( ) ) ;
320
301
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
321
302
322
303
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
323
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
304
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
324
305
assert_eq ! ( * event_handled. borrow( ) , false ) ;
325
306
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
326
307
327
- retry_handler . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
308
+ invoice_payer . handle_event ( & Event :: PaymentSent { payment_preimage } ) ;
328
309
assert_eq ! ( * event_handled. borrow( ) , true ) ;
329
310
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
330
311
}
331
312
332
313
#[ test]
333
314
fn fails_paying_invoice_after_max_retries ( ) {
315
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
316
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
317
+
334
318
let payer = TestPayer :: new ( ) ;
335
319
let router = NullRouter { } ;
336
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
337
-
338
320
let logger = TestLogger :: new ( ) ;
339
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
340
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
341
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
321
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
342
322
343
323
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
344
324
let invoice = invoice ( payment_preimage) ;
345
325
assert ! ( invoice_payer. pay_invoice( & invoice) . is_ok( ) ) ;
346
326
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
347
327
348
328
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
349
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
329
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
350
330
assert_eq ! ( * event_handled. borrow( ) , false ) ;
351
331
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
352
332
353
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
333
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
354
334
assert_eq ! ( * event_handled. borrow( ) , false ) ;
355
335
assert_eq ! ( * payer. attempts. borrow( ) , 3 ) ;
356
336
357
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
337
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
358
338
assert_eq ! ( * event_handled. borrow( ) , true ) ;
359
339
assert_eq ! ( * payer. attempts. borrow( ) , 3 ) ;
360
340
}
361
341
362
342
#[ test]
363
343
fn fails_paying_invoice_after_retry_error ( ) {
344
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
345
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
346
+
364
347
let payer = TestPayer :: new ( ) . fails_on_attempt ( 2 ) ;
365
348
let router = NullRouter { } ;
366
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
367
-
368
349
let logger = TestLogger :: new ( ) ;
369
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
370
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
371
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
350
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
372
351
373
352
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
374
353
let invoice = invoice ( payment_preimage) ;
375
354
assert ! ( invoice_payer. pay_invoice( & invoice) . is_ok( ) ) ;
376
355
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
377
356
378
357
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
379
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
358
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
380
359
assert_eq ! ( * event_handled. borrow( ) , true ) ;
381
360
assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
382
361
}
383
362
384
363
#[ test]
385
364
fn fails_paying_invoice_after_rejected_by_payee ( ) {
365
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
366
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
367
+
386
368
let payer = TestPayer :: new ( ) ;
387
369
let router = NullRouter { } ;
388
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
389
-
390
370
let logger = TestLogger :: new ( ) ;
391
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
392
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
393
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
371
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
394
372
395
373
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
396
374
let invoice = invoice ( payment_preimage) ;
397
375
assert ! ( invoice_payer. pay_invoice( & invoice) . is_ok( ) ) ;
398
376
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
399
377
400
378
let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
401
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : true } ) ;
379
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : true } ) ;
402
380
assert_eq ! ( * event_handled. borrow( ) , true ) ;
403
381
assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
404
382
}
405
383
406
384
#[ test]
407
385
fn fails_repaying_invoice_with_pending_payment ( ) {
386
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
387
+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
388
+
408
389
let payer = TestPayer :: new ( ) ;
409
390
let router = NullRouter { } ;
410
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
411
-
412
391
let logger = TestLogger :: new ( ) ;
413
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
414
- let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
415
- let retry_handler = PaymentRetryHandler :: new ( & invoice_payer, & logger, event_handler) ;
392
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, event_handler) ;
416
393
417
394
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
418
395
let invoice = invoice ( payment_preimage) ;
@@ -432,15 +409,16 @@ mod tests {
432
409
433
410
// Cannot retry paying an invoice if cleared from cache.
434
411
invoice_payer. remove_cached_invoice ( & payment_hash) ;
435
- retry_handler . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
412
+ invoice_payer . handle_event ( & Event :: PaymentFailed { payment_hash, rejected_by_dest : false } ) ;
436
413
assert_eq ! ( * event_handled. borrow( ) , true ) ;
437
414
}
438
415
439
416
#[ test]
440
417
fn fails_paying_invoice_with_routing_errors ( ) {
441
418
let payer = TestPayer :: new ( ) ;
442
419
let router = FailingRouter { } ;
443
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
420
+ let logger = TestLogger :: new ( ) ;
421
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, |_: & _ | { } ) ;
444
422
445
423
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
446
424
let invoice = invoice ( payment_preimage) ;
@@ -455,7 +433,8 @@ mod tests {
455
433
fn fails_paying_invoice_with_sending_errors ( ) {
456
434
let payer = TestPayer :: new ( ) . fails_on_attempt ( 1 ) ;
457
435
let router = NullRouter { } ;
458
- let invoice_payer = InvoicePayer :: new ( & payer, router) ;
436
+ let logger = TestLogger :: new ( ) ;
437
+ let invoice_payer = InvoicePayer :: new ( & payer, router, & logger, |_: & _ | { } ) ;
459
438
460
439
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
461
440
let invoice = invoice ( payment_preimage) ;
0 commit comments