Skip to content

Commit afdb131

Browse files
committed
f - Merge InvoicePayer and PaymentRetryHandler
1 parent e4e8362 commit afdb131

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,35 +267,33 @@ 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);
@@ -324,25 +305,24 @@ mod tests {
324305
network_update: None,
325306
rejected_by_dest: false,
326307
};
327-
retry_handler.handle_event(&event);
308+
invoice_payer.handle_event(&event);
328309
assert_eq!(*event_handled.borrow(), false);
329310
assert_eq!(*payer.attempts.borrow(), 2);
330311

331-
retry_handler.handle_event(&Event::PaymentSent { payment_preimage });
312+
invoice_payer.handle_event(&Event::PaymentSent { payment_preimage });
332313
assert_eq!(*event_handled.borrow(), true);
333314
assert_eq!(*payer.attempts.borrow(), 2);
334315
}
335316

336317
#[test]
337318
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+
338322
let payer = TestPayer::new();
339323
let router = NullRouter {};
340-
let invoice_payer = InvoicePayer::new(&payer, router);
341-
342324
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);
346326

347327
let payment_preimage = PaymentPreimage([1; 32]);
348328
let invoice = invoice(payment_preimage);
@@ -354,29 +334,28 @@ mod tests {
354334
network_update: None,
355335
rejected_by_dest: false,
356336
};
357-
retry_handler.handle_event(&event);
337+
invoice_payer.handle_event(&event);
358338
assert_eq!(*event_handled.borrow(), false);
359339
assert_eq!(*payer.attempts.borrow(), 2);
360340

361-
retry_handler.handle_event(&event);
341+
invoice_payer.handle_event(&event);
362342
assert_eq!(*event_handled.borrow(), false);
363343
assert_eq!(*payer.attempts.borrow(), 3);
364344

365-
retry_handler.handle_event(&event);
345+
invoice_payer.handle_event(&event);
366346
assert_eq!(*event_handled.borrow(), true);
367347
assert_eq!(*payer.attempts.borrow(), 3);
368348
}
369349

370350
#[test]
371351
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+
372355
let payer = TestPayer::new().fails_on_attempt(2);
373356
let router = NullRouter {};
374-
let invoice_payer = InvoicePayer::new(&payer, router);
375-
376357
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);
380359

381360
let payment_preimage = PaymentPreimage([1; 32]);
382361
let invoice = invoice(payment_preimage);
@@ -388,21 +367,20 @@ mod tests {
388367
network_update: None,
389368
rejected_by_dest: false,
390369
};
391-
retry_handler.handle_event(&event);
370+
invoice_payer.handle_event(&event);
392371
assert_eq!(*event_handled.borrow(), true);
393372
assert_eq!(*payer.attempts.borrow(), 2);
394373
}
395374

396375
#[test]
397376
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+
398380
let payer = TestPayer::new();
399381
let router = NullRouter {};
400-
let invoice_payer = InvoicePayer::new(&payer, router);
401-
402382
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);
406384

407385
let payment_preimage = PaymentPreimage([1; 32]);
408386
let invoice = invoice(payment_preimage);
@@ -414,21 +392,20 @@ mod tests {
414392
network_update: None,
415393
rejected_by_dest: true,
416394
};
417-
retry_handler.handle_event(&event);
395+
invoice_payer.handle_event(&event);
418396
assert_eq!(*event_handled.borrow(), true);
419397
assert_eq!(*payer.attempts.borrow(), 1);
420398
}
421399

422400
#[test]
423401
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+
424405
let payer = TestPayer::new();
425406
let router = NullRouter {};
426-
let invoice_payer = InvoicePayer::new(&payer, router);
427-
428407
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);
432409

433410
let payment_preimage = PaymentPreimage([1; 32]);
434411
let invoice = invoice(payment_preimage);
@@ -453,15 +430,16 @@ mod tests {
453430
network_update: None,
454431
rejected_by_dest: false,
455432
};
456-
retry_handler.handle_event(&event);
433+
invoice_payer.handle_event(&event);
457434
assert_eq!(*event_handled.borrow(), true);
458435
}
459436

460437
#[test]
461438
fn fails_paying_invoice_with_routing_errors() {
462439
let payer = TestPayer::new();
463440
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, |_: &_| {});
465443

466444
let payment_preimage = PaymentPreimage([1; 32]);
467445
let invoice = invoice(payment_preimage);
@@ -476,7 +454,8 @@ mod tests {
476454
fn fails_paying_invoice_with_sending_errors() {
477455
let payer = TestPayer::new().fails_on_attempt(1);
478456
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, |_: &_| {});
480459

481460
let payment_preimage = PaymentPreimage([1; 32]);
482461
let invoice = invoice(payment_preimage);

0 commit comments

Comments
 (0)