1 // This file is Copyright its original authors, visible in version control
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
10 //! A module for paying Lightning invoices.
12 //! Defines an [`InvoicePayer`] utility for paying invoices, parameterized by [`Payer`] and
13 //! [`Router`] traits. Implementations of [`Payer`] provide the payer's node id, channels, and means
14 //! to send a payment over a [`Route`]. Implementations of [`Router`] find a [`Route`] between payer
15 //! and payee using information provided by the payer and from the payee's [`Invoice`].
17 //! [`InvoicePayer`] is capable of retrying failed payments. It accomplishes this by implementing
18 //! [`EventHandler`] which decorates a user-provided handler. It will intercept any
19 //! [`Event::PaymentPathFailed`] events and retry the failed paths for a fixed number of total
20 //! attempts or until retry is no longer possible. In such a situation, [`InvoicePayer`] will pass
21 //! along the events to the user-provided handler.
26 //! # extern crate lightning;
27 //! # extern crate lightning_invoice;
28 //! # extern crate secp256k1;
30 //! # use lightning::ln::{PaymentHash, PaymentSecret};
31 //! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
32 //! # use lightning::ln::msgs::LightningError;
33 //! # use lightning::routing::router::{Route, RouteParameters};
34 //! # use lightning::util::events::{Event, EventHandler, EventsProvider};
35 //! # use lightning::util::logger::{Logger, Record};
36 //! # use lightning_invoice::Invoice;
37 //! # use lightning_invoice::payment::{InvoicePayer, Payer, RetryAttempts, Router};
38 //! # use secp256k1::key::PublicKey;
39 //! # use std::ops::Deref;
41 //! # struct FakeEventProvider {}
42 //! # impl EventsProvider for FakeEventProvider {
43 //! # fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {}
46 //! # struct FakePayer {}
47 //! # impl Payer for FakePayer {
48 //! # fn node_id(&self) -> PublicKey { unimplemented!() }
49 //! # fn first_hops(&self) -> Vec<ChannelDetails> { unimplemented!() }
50 //! # fn send_payment(
51 //! # &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>
52 //! # ) -> Result<PaymentId, PaymentSendFailure> { unimplemented!() }
53 //! # fn retry_payment(
54 //! # &self, route: &Route, payment_id: PaymentId
55 //! # ) -> Result<(), PaymentSendFailure> { unimplemented!() }
58 //! # struct FakeRouter {};
59 //! # impl Router for FakeRouter {
61 //! # &self, payer: &PublicKey, params: &RouteParameters,
62 //! # first_hops: Option<&[&ChannelDetails]>
63 //! # ) -> Result<Route, LightningError> { unimplemented!() }
66 //! # struct FakeLogger {};
67 //! # impl Logger for FakeLogger {
68 //! # fn log(&self, record: &Record) { unimplemented!() }
72 //! let event_handler = |event: &Event| {
74 //! Event::PaymentPathFailed { .. } => println!("payment failed after retries"),
75 //! Event::PaymentSent { .. } => println!("payment successful"),
79 //! # let payer = FakePayer {};
80 //! # let router = FakeRouter {};
81 //! # let logger = FakeLogger {};
82 //! let invoice_payer = InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
84 //! let invoice = "...";
85 //! let invoice = invoice.parse::<Invoice>().unwrap();
86 //! invoice_payer.pay_invoice(&invoice).unwrap();
88 //! # let event_provider = FakeEventProvider {};
90 //! event_provider.process_pending_events(&invoice_payer);
97 //! The [`Route`] is computed before each payment attempt. Any updates affecting path finding such
98 //! as updates to the network graph or changes to channel scores should be applied prior to
99 //! retries, typically by way of composing [`EventHandler`]s accordingly.
103 use bitcoin_hashes::Hash;
105 use lightning::ln::{PaymentHash, PaymentSecret};
106 use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
107 use lightning::ln::msgs::LightningError;
108 use lightning::routing::router::{Payee, Route, RouteParameters};
109 use lightning::util::events::{Event, EventHandler};
110 use lightning::util::logger::Logger;
112 use secp256k1::key::PublicKey;
114 use std::collections::hash_map::{self, HashMap};
116 use std::sync::Mutex;
118 /// A utility for paying [`Invoice]`s.
119 pub struct InvoicePayer<P: Deref, R, L: Deref, E>
130 payment_cache: Mutex<HashMap<PaymentHash, usize>>,
131 retry_attempts: RetryAttempts,
134 /// A trait defining behavior of an [`Invoice`] payer.
136 /// Returns the payer's node id.
137 fn node_id(&self) -> PublicKey;
139 /// Returns the payer's channels.
140 fn first_hops(&self) -> Vec<ChannelDetails>;
142 /// Sends a payment over the Lightning Network using the given [`Route`].
144 &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>
145 ) -> Result<PaymentId, PaymentSendFailure>;
147 /// Retries a failed payment path for the [`PaymentId`] using the given [`Route`].
148 fn retry_payment(&self, route: &Route, payment_id: PaymentId) -> Result<(), PaymentSendFailure>;
151 /// A trait defining behavior for routing an [`Invoice`] payment.
153 /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values.
155 &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>
156 ) -> Result<Route, LightningError>;
159 /// Number of attempts to retry payment path failures for an [`Invoice`].
160 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
161 pub struct RetryAttempts(pub usize);
163 /// An error that may occur when making a payment.
164 #[derive(Clone, Debug)]
165 pub enum PaymentError {
166 /// An error resulting from the provided [`Invoice`] or payment hash.
167 Invoice(&'static str),
168 /// An error occurring when finding a route.
169 Routing(LightningError),
170 /// An error occurring when sending a payment.
171 Sending(PaymentSendFailure),
174 impl<P: Deref, R, L: Deref, E> InvoicePayer<P, R, L, E>
181 /// Creates an invoice payer that retries failed payment paths.
183 /// Will forward any [`Event::PaymentPathFailed`] events to the decorated `event_handler` once
184 /// `retry_attempts` has been exceeded for a given [`Invoice`].
186 payer: P, router: R, logger: L, event_handler: E, retry_attempts: RetryAttempts
193 payment_cache: Mutex::new(HashMap::new()),
198 /// Pays the given [`Invoice`], caching it for later use in case a retry is needed.
199 pub fn pay_invoice(&self, invoice: &Invoice) -> Result<PaymentId, PaymentError> {
200 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
201 let mut payment_cache = self.payment_cache.lock().unwrap();
202 match payment_cache.entry(payment_hash) {
203 hash_map::Entry::Vacant(entry) => {
204 let payer = self.payer.node_id();
205 let mut payee = Payee::new(invoice.recover_payee_pub_key())
206 .with_route_hints(invoice.route_hints());
207 if let Some(features) = invoice.features() {
208 payee = payee.with_features(features.clone());
210 let final_value_msat = invoice.amount_milli_satoshis()
211 .ok_or(PaymentError::Invoice("amount missing"))?;
212 let params = RouteParameters {
215 final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
217 let first_hops = self.payer.first_hops();
218 let route = self.router.find_route(
221 Some(&first_hops.iter().collect::<Vec<_>>()),
222 ).map_err(|e| PaymentError::Routing(e))?;
224 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
225 let payment_secret = Some(invoice.payment_secret().clone());
226 let payment_id = self.payer.send_payment(&route, payment_hash, &payment_secret)
227 .map_err(|e| PaymentError::Sending(e))?;
231 hash_map::Entry::Occupied(_) => Err(PaymentError::Invoice("payment pending")),
236 &self, payment_id: PaymentId, params: &RouteParameters
237 ) -> Result<(), PaymentError> {
238 let payer = self.payer.node_id();
239 let first_hops = self.payer.first_hops();
240 let route = self.router.find_route(
241 &payer, ¶ms, Some(&first_hops.iter().collect::<Vec<_>>())
242 ).map_err(|e| PaymentError::Routing(e))?;
243 self.payer.retry_payment(&route, payment_id).map_err(|e| PaymentError::Sending(e))
246 /// Removes the payment cached by the given payment hash.
248 /// Should be called once a payment has failed or succeeded if not using [`InvoicePayer`] as an
249 /// [`EventHandler`]. Otherwise, calling this method is unnecessary.
250 pub fn remove_cached_payment(&self, payment_hash: &PaymentHash) {
251 self.payment_cache.lock().unwrap().remove(payment_hash);
255 impl<P: Deref, R, L: Deref, E> EventHandler for InvoicePayer<P, R, L, E>
262 fn handle_event(&self, event: &Event) {
264 Event::PaymentPathFailed { payment_id, payment_hash, rejected_by_dest, retry, .. } => {
265 let mut payment_cache = self.payment_cache.lock().unwrap();
267 let entry = payment_cache.entry(*payment_hash);
269 hash_map::Entry::Occupied(_) => break entry,
270 hash_map::Entry::Vacant(entry) => entry.insert(0),
273 if let hash_map::Entry::Occupied(mut entry) = entry {
274 let max_payment_attempts = self.retry_attempts.0 + 1;
275 let attempts = entry.get_mut();
278 if *rejected_by_dest {
279 log_trace!(self.logger, "Payment {} rejected by destination; not retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
280 } else if payment_id.is_none() {
281 log_trace!(self.logger, "Payment {} has no id; not retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
282 } else if *attempts >= max_payment_attempts {
283 log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
284 } else if retry.is_none() {
285 log_trace!(self.logger, "Payment {} missing retry params; not retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
286 } else if self.retry_payment(*payment_id.as_ref().unwrap(), retry.as_ref().unwrap()).is_err() {
287 log_trace!(self.logger, "Error retrying payment {}; not retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
289 log_trace!(self.logger, "Payment {} failed; retrying (attempts: {})", log_bytes!(payment_hash.0), attempts);
293 // Either the payment was rejected, the maximum attempts were exceeded, or an
294 // error occurred when attempting to retry.
300 Event::PaymentSent { payment_hash, .. } => {
301 let mut payment_cache = self.payment_cache.lock().unwrap();
302 let attempts = payment_cache
303 .remove(payment_hash)
304 .map_or(1, |attempts| attempts + 1);
305 log_trace!(self.logger, "Payment {} succeeded (attempts: {})", log_bytes!(payment_hash.0), attempts);
310 // Delegate to the decorated event handler unless the payment is retried.
311 self.event_handler.handle_event(event)
318 use crate::{InvoiceBuilder, Currency};
319 use bitcoin_hashes::sha256::Hash as Sha256;
320 use lightning::ln::PaymentPreimage;
321 use lightning::ln::features::{ChannelFeatures, NodeFeatures};
322 use lightning::ln::msgs::{ErrorAction, LightningError};
323 use lightning::routing::router::{Route, RouteHop};
324 use lightning::util::test_utils::TestLogger;
325 use lightning::util::errors::APIError;
326 use lightning::util::events::Event;
327 use secp256k1::{SecretKey, PublicKey, Secp256k1};
329 fn invoice(payment_preimage: PaymentPreimage) -> Invoice {
330 let payment_hash = Sha256::hash(&payment_preimage.0);
331 let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
332 InvoiceBuilder::new(Currency::Bitcoin)
333 .description("test".into())
334 .payment_hash(payment_hash)
335 .payment_secret(PaymentSecret([0; 32]))
337 .min_final_cltv_expiry(144)
338 .amount_milli_satoshis(128)
339 .build_signed(|hash| {
340 Secp256k1::new().sign_recoverable(hash, &private_key)
346 fn pays_invoice_on_first_attempt() {
347 let event_handled = core::cell::RefCell::new(false);
348 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
350 let payment_preimage = PaymentPreimage([1; 32]);
351 let invoice = invoice(payment_preimage);
352 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
354 let payer = TestPayer::new();
355 let router = TestRouter {};
356 let logger = TestLogger::new();
358 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(0));
360 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
361 assert_eq!(*payer.attempts.borrow(), 1);
363 invoice_payer.handle_event(&Event::PaymentSent {
364 payment_id, payment_preimage, payment_hash
366 assert_eq!(*event_handled.borrow(), true);
367 assert_eq!(*payer.attempts.borrow(), 1);
371 fn pays_invoice_on_retry() {
372 let event_handled = core::cell::RefCell::new(false);
373 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
375 let payment_preimage = PaymentPreimage([1; 32]);
376 let invoice = invoice(payment_preimage);
377 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
378 let final_value_msat = invoice.amount_milli_satoshis().unwrap();
380 let payer = TestPayer::new()
381 .expect_value_msat(final_value_msat)
382 .expect_value_msat(final_value_msat / 2);
383 let router = TestRouter {};
384 let logger = TestLogger::new();
386 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
388 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
389 assert_eq!(*payer.attempts.borrow(), 1);
391 let event = Event::PaymentPathFailed {
394 network_update: None,
395 rejected_by_dest: false,
396 all_paths_failed: false,
397 path: TestRouter::path_for_value(final_value_msat),
398 short_channel_id: None,
399 retry: Some(TestRouter::retry_for_invoice(&invoice)),
401 invoice_payer.handle_event(&event);
402 assert_eq!(*event_handled.borrow(), false);
403 assert_eq!(*payer.attempts.borrow(), 2);
405 invoice_payer.handle_event(&Event::PaymentSent {
406 payment_id, payment_preimage, payment_hash
408 assert_eq!(*event_handled.borrow(), true);
409 assert_eq!(*payer.attempts.borrow(), 2);
413 fn retries_payment_path_for_unknown_payment() {
414 let event_handled = core::cell::RefCell::new(false);
415 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
417 let payment_preimage = PaymentPreimage([1; 32]);
418 let invoice = invoice(payment_preimage);
419 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
420 let final_value_msat = invoice.amount_milli_satoshis().unwrap();
422 let payer = TestPayer::new();
423 let router = TestRouter {};
424 let logger = TestLogger::new();
426 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
428 let payment_id = Some(PaymentId([1; 32]));
429 let event = Event::PaymentPathFailed {
432 network_update: None,
433 rejected_by_dest: false,
434 all_paths_failed: false,
435 path: TestRouter::path_for_value(final_value_msat),
436 short_channel_id: None,
437 retry: Some(TestRouter::retry_for_invoice(&invoice)),
439 invoice_payer.handle_event(&event);
440 assert_eq!(*event_handled.borrow(), false);
441 assert_eq!(*payer.attempts.borrow(), 1);
443 invoice_payer.handle_event(&event);
444 assert_eq!(*event_handled.borrow(), false);
445 assert_eq!(*payer.attempts.borrow(), 2);
447 invoice_payer.handle_event(&Event::PaymentSent {
448 payment_id, payment_preimage, payment_hash
450 assert_eq!(*event_handled.borrow(), true);
451 assert_eq!(*payer.attempts.borrow(), 2);
455 fn fails_paying_invoice_after_max_retries() {
456 let event_handled = core::cell::RefCell::new(false);
457 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
459 let payment_preimage = PaymentPreimage([1; 32]);
460 let invoice = invoice(payment_preimage);
461 let final_value_msat = invoice.amount_milli_satoshis().unwrap();
463 let payer = TestPayer::new()
464 .expect_value_msat(final_value_msat)
465 .expect_value_msat(final_value_msat / 2)
466 .expect_value_msat(final_value_msat / 2);
467 let router = TestRouter {};
468 let logger = TestLogger::new();
470 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
472 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
473 assert_eq!(*payer.attempts.borrow(), 1);
475 let event = Event::PaymentPathFailed {
477 payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
478 network_update: None,
479 rejected_by_dest: false,
480 all_paths_failed: true,
481 path: TestRouter::path_for_value(final_value_msat),
482 short_channel_id: None,
483 retry: Some(TestRouter::retry_for_invoice(&invoice)),
485 invoice_payer.handle_event(&event);
486 assert_eq!(*event_handled.borrow(), false);
487 assert_eq!(*payer.attempts.borrow(), 2);
489 let event = Event::PaymentPathFailed {
491 payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
492 network_update: None,
493 rejected_by_dest: false,
494 all_paths_failed: false,
495 path: TestRouter::path_for_value(final_value_msat / 2),
496 short_channel_id: None,
497 retry: Some(RouteParameters {
498 final_value_msat: final_value_msat / 2, ..TestRouter::retry_for_invoice(&invoice)
501 invoice_payer.handle_event(&event);
502 assert_eq!(*event_handled.borrow(), false);
503 assert_eq!(*payer.attempts.borrow(), 3);
505 invoice_payer.handle_event(&event);
506 assert_eq!(*event_handled.borrow(), true);
507 assert_eq!(*payer.attempts.borrow(), 3);
511 fn fails_paying_invoice_with_missing_retry_params() {
512 let event_handled = core::cell::RefCell::new(false);
513 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
515 let payer = TestPayer::new();
516 let router = TestRouter {};
517 let logger = TestLogger::new();
519 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
521 let payment_preimage = PaymentPreimage([1; 32]);
522 let invoice = invoice(payment_preimage);
523 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
524 assert_eq!(*payer.attempts.borrow(), 1);
526 let event = Event::PaymentPathFailed {
528 payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
529 network_update: None,
530 rejected_by_dest: false,
531 all_paths_failed: false,
533 short_channel_id: None,
536 invoice_payer.handle_event(&event);
537 assert_eq!(*event_handled.borrow(), true);
538 assert_eq!(*payer.attempts.borrow(), 1);
542 fn fails_paying_invoice_after_retry_error() {
543 let event_handled = core::cell::RefCell::new(false);
544 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
546 let payment_preimage = PaymentPreimage([1; 32]);
547 let invoice = invoice(payment_preimage);
548 let final_value_msat = invoice.amount_milli_satoshis().unwrap();
550 let payer = TestPayer::new()
552 .expect_value_msat(final_value_msat);
553 let router = TestRouter {};
554 let logger = TestLogger::new();
556 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
558 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
559 assert_eq!(*payer.attempts.borrow(), 1);
561 let event = Event::PaymentPathFailed {
563 payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
564 network_update: None,
565 rejected_by_dest: false,
566 all_paths_failed: false,
567 path: TestRouter::path_for_value(final_value_msat / 2),
568 short_channel_id: None,
569 retry: Some(TestRouter::retry_for_invoice(&invoice)),
571 invoice_payer.handle_event(&event);
572 assert_eq!(*event_handled.borrow(), true);
573 assert_eq!(*payer.attempts.borrow(), 2);
577 fn fails_paying_invoice_after_rejected_by_payee() {
578 let event_handled = core::cell::RefCell::new(false);
579 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
581 let payer = TestPayer::new();
582 let router = TestRouter {};
583 let logger = TestLogger::new();
585 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(2));
587 let payment_preimage = PaymentPreimage([1; 32]);
588 let invoice = invoice(payment_preimage);
589 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
590 assert_eq!(*payer.attempts.borrow(), 1);
592 let event = Event::PaymentPathFailed {
594 payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
595 network_update: None,
596 rejected_by_dest: true,
597 all_paths_failed: false,
599 short_channel_id: None,
600 retry: Some(TestRouter::retry_for_invoice(&invoice)),
602 invoice_payer.handle_event(&event);
603 assert_eq!(*event_handled.borrow(), true);
604 assert_eq!(*payer.attempts.borrow(), 1);
608 fn fails_repaying_invoice_with_pending_payment() {
609 let event_handled = core::cell::RefCell::new(false);
610 let event_handler = |_: &_| { *event_handled.borrow_mut() = true; };
612 let payer = TestPayer::new();
613 let router = TestRouter {};
614 let logger = TestLogger::new();
616 InvoicePayer::new(&payer, router, &logger, event_handler, RetryAttempts(0));
618 let payment_preimage = PaymentPreimage([1; 32]);
619 let invoice = invoice(payment_preimage);
620 let payment_id = Some(invoice_payer.pay_invoice(&invoice).unwrap());
622 // Cannot repay an invoice pending payment.
623 match invoice_payer.pay_invoice(&invoice) {
624 Err(PaymentError::Invoice("payment pending")) => {},
625 Err(_) => panic!("unexpected error"),
626 Ok(_) => panic!("expected invoice error"),
629 // Can repay an invoice once cleared from cache.
630 let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
631 invoice_payer.remove_cached_payment(&payment_hash);
632 assert!(invoice_payer.pay_invoice(&invoice).is_ok());
634 // Cannot retry paying an invoice if cleared from cache.
635 invoice_payer.remove_cached_payment(&payment_hash);
636 let event = Event::PaymentPathFailed {
639 network_update: None,
640 rejected_by_dest: false,
641 all_paths_failed: false,
643 short_channel_id: None,
644 retry: Some(TestRouter::retry_for_invoice(&invoice)),
646 invoice_payer.handle_event(&event);
647 assert_eq!(*event_handled.borrow(), true);
651 fn fails_paying_invoice_with_routing_errors() {
652 let payer = TestPayer::new();
653 let router = FailingRouter {};
654 let logger = TestLogger::new();
656 InvoicePayer::new(&payer, router, &logger, |_: &_| {}, RetryAttempts(0));
658 let payment_preimage = PaymentPreimage([1; 32]);
659 let invoice = invoice(payment_preimage);
660 match invoice_payer.pay_invoice(&invoice) {
661 Err(PaymentError::Routing(_)) => {},
662 Err(_) => panic!("unexpected error"),
663 Ok(_) => panic!("expected routing error"),
668 fn fails_paying_invoice_with_sending_errors() {
669 let payer = TestPayer::new().fails_on_attempt(1);
670 let router = TestRouter {};
671 let logger = TestLogger::new();
673 InvoicePayer::new(&payer, router, &logger, |_: &_| {}, RetryAttempts(0));
675 let payment_preimage = PaymentPreimage([1; 32]);
676 let invoice = invoice(payment_preimage);
677 match invoice_payer.pay_invoice(&invoice) {
678 Err(PaymentError::Sending(_)) => {},
679 Err(_) => panic!("unexpected error"),
680 Ok(_) => panic!("expected sending error"),
687 fn route_for_value(final_value_msat: u64) -> Route {
691 pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
692 channel_features: ChannelFeatures::empty(),
693 node_features: NodeFeatures::empty(),
694 short_channel_id: 0, fee_msat: final_value_msat / 2, cltv_expiry_delta: 144
697 pubkey: PublicKey::from_slice(&hex::decode("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()[..]).unwrap(),
698 channel_features: ChannelFeatures::empty(),
699 node_features: NodeFeatures::empty(),
700 short_channel_id: 1, fee_msat: final_value_msat / 2, cltv_expiry_delta: 144
707 fn path_for_value(final_value_msat: u64) -> Vec<RouteHop> {
708 TestRouter::route_for_value(final_value_msat).paths[0].clone()
711 fn retry_for_invoice(invoice: &Invoice) -> RouteParameters {
712 let mut payee = Payee::new(invoice.recover_payee_pub_key())
713 .with_route_hints(invoice.route_hints());
714 if let Some(features) = invoice.features() {
715 payee = payee.with_features(features.clone());
717 let final_value_msat = invoice.amount_milli_satoshis().unwrap() / 2;
721 final_cltv_expiry_delta: invoice.min_final_cltv_expiry() as u32,
726 impl Router for TestRouter {
730 params: &RouteParameters,
731 _first_hops: Option<&[&ChannelDetails]>,
732 ) -> Result<Route, LightningError> {
734 payee: Some(params.payee.clone()), ..Self::route_for_value(params.final_value_msat)
739 struct FailingRouter;
741 impl Router for FailingRouter {
745 _params: &RouteParameters,
746 _first_hops: Option<&[&ChannelDetails]>,
747 ) -> Result<Route, LightningError> {
748 Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError })
753 expectations: core::cell::RefCell<std::collections::VecDeque<u64>>,
754 attempts: core::cell::RefCell<usize>,
755 failing_on_attempt: Option<usize>,
761 expectations: core::cell::RefCell::new(std::collections::VecDeque::new()),
762 attempts: core::cell::RefCell::new(0),
763 failing_on_attempt: None,
767 fn expect_value_msat(self, value_msat: u64) -> Self {
768 self.expectations.borrow_mut().push_back(value_msat);
772 fn fails_on_attempt(self, attempt: usize) -> Self {
774 expectations: core::cell::RefCell::new(self.expectations.borrow().clone()),
775 attempts: core::cell::RefCell::new(0),
776 failing_on_attempt: Some(attempt),
780 fn check_attempts(&self) -> bool {
781 let mut attempts = self.attempts.borrow_mut();
783 match self.failing_on_attempt {
785 Some(attempt) if attempt != *attempts => true,
790 fn check_value_msats(&self, route: &Route) {
791 let expected_value_msats = self.expectations.borrow_mut().pop_front();
792 if let Some(expected_value_msats) = expected_value_msats {
793 let actual_value_msats = route.get_total_amount();
794 assert_eq!(actual_value_msats, expected_value_msats);
799 impl Drop for TestPayer {
801 if std::thread::panicking() {
805 if !self.expectations.borrow().is_empty() {
806 panic!("Unsatisfied payment expectations: {:?}", self.expectations.borrow());
811 impl Payer for TestPayer {
812 fn node_id(&self) -> PublicKey {
813 let secp_ctx = Secp256k1::new();
814 PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
817 fn first_hops(&self) -> Vec<ChannelDetails> {
824 _payment_hash: PaymentHash,
825 _payment_secret: &Option<PaymentSecret>
826 ) -> Result<PaymentId, PaymentSendFailure> {
827 if self.check_attempts() {
828 self.check_value_msats(route);
829 Ok(PaymentId([1; 32]))
831 Err(PaymentSendFailure::ParameterError(APIError::MonitorUpdateFailed))
836 &self, route: &Route, _payment_id: PaymentId
837 ) -> Result<(), PaymentSendFailure> {
838 if self.check_attempts() {
839 self.check_value_msats(route);
842 Err(PaymentSendFailure::ParameterError(APIError::MonitorUpdateFailed))