Skip to content

Commit 4879b56

Browse files
committed
f - Merge InvoicePayer and PaymentRetryHandler
1 parent 79d497c commit 4879b56

File tree

1 file changed

+68
-89
lines changed

1 file changed

+68
-89
lines changed

lightning-invoice/src/payment.rs

Lines changed: 68 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
//! to send a payment over a [`Route`]. Implementations of [`Router`] find a [`Route`] between payer
1515
//! and payee using information provided by the payer and from the payee's [`Invoice`].
1616
//!
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.
2121
//!
2222
//! # Example
2323
//!
@@ -28,7 +28,7 @@
2828
//! The [`Route`] is compute before each payment attempt. Any updates affecting path finding such as
2929
//! updates to the network graph or changes to channels scores should be applied prior to retries.
3030
//! 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.
3232
3333
use crate::Invoice;
3434

@@ -44,7 +44,6 @@ use lightning::routing::router::{Route, RouteHint};
4444
use lightning::util::events::{Event, EventHandler};
4545
use lightning::util::logger::Logger;
4646

47-
use std::cell::RefCell;
4847
use std::collections::hash_map::{self, HashMap};
4948
use std::ops::Deref;
5049
use std::sync::Mutex;
@@ -54,10 +53,20 @@ use std::sync::Mutex;
5453
const MAX_PAYMENT_ATTEMPTS: usize = 3;
5554

5655
/// 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+
{
5863
payer: P,
5964
router: R,
65+
logger: L,
66+
event_handler: E,
67+
// Lock order: payment_attempts -> invoice_cache
6068
invoice_cache: Mutex<HashMap<PaymentHash, Invoice>>,
69+
payment_attempts: Mutex<HashMap<PaymentHash, usize>>,
6170
}
6271

6372
/// A trait defining behavior of an [`Invoice`] payer.
@@ -101,28 +110,22 @@ pub enum PaymentError {
101110
Sending(PaymentSendFailure),
102111
}
103112

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>
106114
where
107-
I: Deref<Target = InvoicePayer<P, R>>,
108115
P::Target: Payer,
109116
R: Router,
110117
L::Target: Logger,
111118
E: EventHandler,
112119
{
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 {
120120
/// 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 {
122122
Self {
123123
payer,
124124
router,
125+
logger,
126+
event_handler,
125127
invoice_cache: Mutex::new(HashMap::new()),
128+
payment_attempts: Mutex::new(HashMap::new()),
126129
}
127130
}
128131

@@ -175,35 +178,15 @@ impl<P: Deref, R> InvoicePayer<P, R> where P::Target: Payer, R: Router {
175178

176179
/// Removes the [`Invoice`] cached by the given payment hash.
177180
///
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.
180183
pub fn remove_cached_invoice(&self, payment_hash: &PaymentHash) {
181184
self.invoice_cache.lock().unwrap().remove(payment_hash);
182185
}
183186
}
184187

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>
205189
where
206-
I: Deref<Target = InvoicePayer<P, R>>,
207190
P::Target: Payer,
208191
R: Router,
209192
L::Target: Logger,
@@ -212,14 +195,14 @@ where
212195
fn handle_event(&self, event: &Event) {
213196
match event {
214197
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();
216199
let attempts = attempts_by_payment_hash
217200
.entry(*payment_hash)
218201
.and_modify(|attempts| *attempts += 1)
219202
.or_insert(1);
220203
if !rejected_by_dest {
221204
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() {
223206
log_trace!(self.logger, "Payment {} failed; retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
224207
return;
225208
} else {
@@ -233,18 +216,18 @@ where
233216
}
234217

235218
// 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);
237220
attempts_by_payment_hash.remove(payment_hash);
238221
},
239222
Event::PaymentSent { payment_preimage } => {
240223
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
245226
.remove(&payment_hash)
246227
.map_or(1, |attempts| attempts + 1);
247228
log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
229+
230+
self.remove_cached_invoice(&payment_hash);
248231
},
249232
_ => {},
250233
}
@@ -284,135 +267,129 @@ mod tests {
284267

285268
#[test]
286269
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+
287273
let payer = TestPayer::new();
288274
let router = NullRouter {};
289-
let invoice_payer = InvoicePayer::new(&payer, router);
290-
291275
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);
295277

296278
let payment_preimage = PaymentPreimage([1; 32]);
297279
let invoice = invoice(payment_preimage);
298280
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
299281
assert_eq!(*payer.attempts.borrow(), 1);
300282

301-
retry_handler.handle_event(&Event::PaymentSent { payment_preimage });
283+
invoice_payer.handle_event(&Event::PaymentSent { payment_preimage });
302284
assert_eq!(*event_handled.borrow(), true);
303285
assert_eq!(*payer.attempts.borrow(), 1);
304286
}
305287

306288
#[test]
307289
fn pays_invoice_on_retry() {
290+
let event_handled = core::cell::RefCell::new(false);
291+
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
292+
308293
let payer = TestPayer::new();
309294
let router = NullRouter {};
310-
let invoice_payer = InvoicePayer::new(&payer, router);
311-
312295
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);
316297

317298
let payment_preimage = PaymentPreimage([1; 32]);
318299
let invoice = invoice(payment_preimage);
319300
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
320301
assert_eq!(*payer.attempts.borrow(), 1);
321302

322303
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 });
324305
assert_eq!(*event_handled.borrow(), false);
325306
assert_eq!(*payer.attempts.borrow(), 2);
326307

327-
retry_handler.handle_event(&Event::PaymentSent { payment_preimage });
308+
invoice_payer.handle_event(&Event::PaymentSent { payment_preimage });
328309
assert_eq!(*event_handled.borrow(), true);
329310
assert_eq!(*payer.attempts.borrow(), 2);
330311
}
331312

332313
#[test]
333314
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+
334318
let payer = TestPayer::new();
335319
let router = NullRouter {};
336-
let invoice_payer = InvoicePayer::new(&payer, router);
337-
338320
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);
342322

343323
let payment_preimage = PaymentPreimage([1; 32]);
344324
let invoice = invoice(payment_preimage);
345325
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
346326
assert_eq!(*payer.attempts.borrow(), 1);
347327

348328
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 });
350330
assert_eq!(*event_handled.borrow(), false);
351331
assert_eq!(*payer.attempts.borrow(), 2);
352332

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 });
354334
assert_eq!(*event_handled.borrow(), false);
355335
assert_eq!(*payer.attempts.borrow(), 3);
356336

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 });
358338
assert_eq!(*event_handled.borrow(), true);
359339
assert_eq!(*payer.attempts.borrow(), 3);
360340
}
361341

362342
#[test]
363343
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+
364347
let payer = TestPayer::new().fails_on_attempt(2);
365348
let router = NullRouter {};
366-
let invoice_payer = InvoicePayer::new(&payer, router);
367-
368349
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);
372351

373352
let payment_preimage = PaymentPreimage([1; 32]);
374353
let invoice = invoice(payment_preimage);
375354
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
376355
assert_eq!(*payer.attempts.borrow(), 1);
377356

378357
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 });
380359
assert_eq!(*event_handled.borrow(), true);
381360
assert_eq!(*payer.attempts.borrow(), 2);
382361
}
383362

384363
#[test]
385364
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+
386368
let payer = TestPayer::new();
387369
let router = NullRouter {};
388-
let invoice_payer = InvoicePayer::new(&payer, router);
389-
390370
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);
394372

395373
let payment_preimage = PaymentPreimage([1; 32]);
396374
let invoice = invoice(payment_preimage);
397375
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
398376
assert_eq!(*payer.attempts.borrow(), 1);
399377

400378
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 });
402380
assert_eq!(*event_handled.borrow(), true);
403381
assert_eq!(*payer.attempts.borrow(), 1);
404382
}
405383

406384
#[test]
407385
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+
408389
let payer = TestPayer::new();
409390
let router = NullRouter {};
410-
let invoice_payer = InvoicePayer::new(&payer, router);
411-
412391
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);
416393

417394
let payment_preimage = PaymentPreimage([1; 32]);
418395
let invoice = invoice(payment_preimage);
@@ -432,15 +409,16 @@ mod tests {
432409

433410
// Cannot retry paying an invoice if cleared from cache.
434411
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 });
436413
assert_eq!(*event_handled.borrow(), true);
437414
}
438415

439416
#[test]
440417
fn fails_paying_invoice_with_routing_errors() {
441418
let payer = TestPayer::new();
442419
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, |_: &_| {});
444422

445423
let payment_preimage = PaymentPreimage([1; 32]);
446424
let invoice = invoice(payment_preimage);
@@ -455,7 +433,8 @@ mod tests {
455433
fn fails_paying_invoice_with_sending_errors() {
456434
let payer = TestPayer::new().fails_on_attempt(1);
457435
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, |_: &_| {});
459438

460439
let payment_preimage = PaymentPreimage([1; 32]);
461440
let invoice = invoice(payment_preimage);

0 commit comments

Comments
 (0)