Use BaseEventHandler to expose async event handling on InvoicePayer

We introduce a new sealed trait BaseEventHandler that has a blanket
implementation for any T. Since the trait cannot be implemented outside
of the crate, this allow us to expose specific implementations of
InvoicePayer that allow for synchronous and asynchronous event handling.
This commit is contained in:
Wilmer Paulino 2022-11-07 18:09:16 -08:00
parent b0d0f3d749
commit f0059f5083
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F

View file

@ -157,6 +157,7 @@ use secp256k1::PublicKey;
use core::fmt; use core::fmt;
use core::fmt::{Debug, Display, Formatter}; use core::fmt::{Debug, Display, Formatter};
use core::future::Future;
use core::ops::Deref; use core::ops::Deref;
use core::time::Duration; use core::time::Duration;
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -176,9 +177,21 @@ use crate::time_utils;
#[cfg(feature = "no-std")] #[cfg(feature = "no-std")]
type ConfiguredTime = time_utils::Eternity; type ConfiguredTime = time_utils::Eternity;
/// Sealed trait with a blanket implementation to allow both sync and async implementations of event
/// handling to exist within the InvoicePayer.
mod sealed {
pub trait BaseEventHandler {}
impl<T> BaseEventHandler for T {}
}
/// (C-not exported) generally all users should use the [`InvoicePayer`] type alias. /// (C-not exported) generally all users should use the [`InvoicePayer`] type alias.
pub struct InvoicePayerUsingTime<P: Deref, R: ScoringRouter, L: Deref, E: EventHandler, T: Time> pub struct InvoicePayerUsingTime<
where P: Deref,
R: ScoringRouter,
L: Deref,
E: sealed::BaseEventHandler,
T: Time
> where
P::Target: Payer, P::Target: Payer,
L::Target: Logger, L::Target: Logger,
{ {
@ -342,7 +355,8 @@ pub enum PaymentError {
Sending(PaymentSendFailure), Sending(PaymentSendFailure),
} }
impl<P: Deref, R: ScoringRouter, L: Deref, E: EventHandler, T: Time> InvoicePayerUsingTime<P, R, L, E, T> impl<P: Deref, R: ScoringRouter, L: Deref, E: sealed::BaseEventHandler, T: Time>
InvoicePayerUsingTime<P, R, L, E, T>
where where
P::Target: Payer, P::Target: Payer,
L::Target: Logger, L::Target: Logger,
@ -744,12 +758,15 @@ fn has_expired(route_params: &RouteParameters) -> bool {
} else { false } } else { false }
} }
impl<P: Deref, R: ScoringRouter, L: Deref, E: EventHandler, T: Time> EventHandler for InvoicePayerUsingTime<P, R, L, E, T> impl<P: Deref, R: ScoringRouter, L: Deref, E: sealed::BaseEventHandler, T: Time>
InvoicePayerUsingTime<P, R, L, E, T>
where where
P::Target: Payer, P::Target: Payer,
L::Target: Logger, L::Target: Logger,
{ {
fn handle_event(&self, event: &Event) { /// Returns a bool indicating whether the processed event should be forwarded to a user-provided
/// event handler.
fn handle_event_internal(&self, event: &Event) -> bool {
match event { match event {
Event::PaymentPathFailed { payment_hash, path, .. } Event::PaymentPathFailed { payment_hash, path, .. }
| Event::PaymentPathSuccessful { path, payment_hash: Some(payment_hash), .. } | Event::PaymentPathSuccessful { path, payment_hash: Some(payment_hash), .. }
@ -779,7 +796,7 @@ where
self.payer.abandon_payment(payment_id.unwrap()); self.payer.abandon_payment(payment_id.unwrap());
} else if self.retry_payment(payment_id.unwrap(), *payment_hash, retry.as_ref().unwrap()).is_ok() { } else if self.retry_payment(payment_id.unwrap(), *payment_hash, retry.as_ref().unwrap()).is_ok() {
// We retried at least somewhat, don't provide the PaymentPathFailed event to the user. // We retried at least somewhat, don't provide the PaymentPathFailed event to the user.
return; return false;
} else { } else {
self.payer.abandon_payment(payment_id.unwrap()); self.payer.abandon_payment(payment_id.unwrap());
} }
@ -814,7 +831,37 @@ where
} }
// Delegate to the decorated event handler unless the payment is retried. // Delegate to the decorated event handler unless the payment is retried.
self.event_handler.handle_event(event) true
}
}
impl<P: Deref, R: ScoringRouter, L: Deref, E: EventHandler, T: Time>
EventHandler for InvoicePayerUsingTime<P, R, L, E, T>
where
P::Target: Payer,
L::Target: Logger,
{
fn handle_event(&self, event: &Event) {
let should_forward = self.handle_event_internal(&event);
if should_forward {
self.event_handler.handle_event(&event)
}
}
}
impl<P: Deref, R: ScoringRouter, L: Deref, T: Time, F: Future, H: Fn(Event) -> F>
InvoicePayerUsingTime<P, R, L, H, T>
where
P::Target: Payer,
L::Target: Logger,
{
/// Intercepts events required by the [`InvoicePayer`] and forwards them to the underlying event
/// handler, if necessary, to handle them asynchronously.
pub async fn handle_event_async(&self, event: Event) {
let should_forward = self.handle_event_internal(&event);
if should_forward {
(self.event_handler)(event).await;
}
} }
} }
@ -913,7 +960,7 @@ mod tests {
#[test] #[test]
fn pays_invoice_on_first_attempt() { fn pays_invoice_on_first_attempt() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -939,7 +986,7 @@ mod tests {
#[test] #[test]
fn pays_invoice_on_retry() { fn pays_invoice_on_retry() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -980,7 +1027,7 @@ mod tests {
#[test] #[test]
fn pays_invoice_on_partial_failure() { fn pays_invoice_on_partial_failure() {
let event_handler = |_: &_| { panic!() }; let event_handler = |_: &Event| { panic!() };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1004,7 +1051,7 @@ mod tests {
#[test] #[test]
fn retries_payment_path_for_unknown_payment() { fn retries_payment_path_for_unknown_payment() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1048,7 +1095,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_after_max_retry_counts() { fn fails_paying_invoice_after_max_retry_counts() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1105,7 +1152,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_after_max_retry_timeout() { fn fails_paying_invoice_after_max_retry_timeout() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1149,7 +1196,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_with_missing_retry_params() { fn fails_paying_invoice_with_missing_retry_params() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1184,7 +1231,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_after_expiration() { fn fails_paying_invoice_after_expiration() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payer = TestPayer::new(); let payer = TestPayer::new();
let router = TestRouter::new(TestScorer::new()); let router = TestRouter::new(TestScorer::new());
@ -1204,7 +1251,7 @@ mod tests {
#[test] #[test]
fn fails_retrying_invoice_after_expiration() { fn fails_retrying_invoice_after_expiration() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1241,7 +1288,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_after_retry_error() { fn fails_paying_invoice_after_retry_error() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1277,7 +1324,7 @@ mod tests {
#[test] #[test]
fn fails_paying_invoice_after_rejected_by_payee() { fn fails_paying_invoice_after_rejected_by_payee() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1310,7 +1357,7 @@ mod tests {
#[test] #[test]
fn fails_repaying_invoice_with_pending_payment() { fn fails_repaying_invoice_with_pending_payment() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1360,7 +1407,7 @@ mod tests {
let router = FailingRouter {}; let router = FailingRouter {};
let logger = TestLogger::new(); let logger = TestLogger::new();
let invoice_payer = let invoice_payer =
InvoicePayer::new(&payer, router, &logger, |_: &_| {}, Retry::Attempts(0)); InvoicePayer::new(&payer, router, &logger, |_: &Event| {}, Retry::Attempts(0));
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1383,7 +1430,7 @@ mod tests {
let router = TestRouter::new(TestScorer::new()); let router = TestRouter::new(TestScorer::new());
let logger = TestLogger::new(); let logger = TestLogger::new();
let invoice_payer = let invoice_payer =
InvoicePayer::new(&payer, router, &logger, |_: &_| {}, Retry::Attempts(0)); InvoicePayer::new(&payer, router, &logger, |_: &Event| {}, Retry::Attempts(0));
match invoice_payer.pay_invoice(&invoice) { match invoice_payer.pay_invoice(&invoice) {
Err(PaymentError::Sending(_)) => {}, Err(PaymentError::Sending(_)) => {},
@ -1395,7 +1442,7 @@ mod tests {
#[test] #[test]
fn pays_zero_value_invoice_using_amount() { fn pays_zero_value_invoice_using_amount() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = zero_value_invoice(payment_preimage); let invoice = zero_value_invoice(payment_preimage);
@ -1422,7 +1469,7 @@ mod tests {
#[test] #[test]
fn fails_paying_zero_value_invoice_with_amount() { fn fails_paying_zero_value_invoice_with_amount() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payer = TestPayer::new(); let payer = TestPayer::new();
let router = TestRouter::new(TestScorer::new()); let router = TestRouter::new(TestScorer::new());
@ -1444,7 +1491,7 @@ mod tests {
#[test] #[test]
fn pays_pubkey_with_amount() { fn pays_pubkey_with_amount() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let pubkey = pubkey(); let pubkey = pubkey();
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
@ -1494,7 +1541,7 @@ mod tests {
#[test] #[test]
fn scores_failed_channel() { fn scores_failed_channel() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1532,7 +1579,7 @@ mod tests {
#[test] #[test]
fn scores_successful_channels() { fn scores_successful_channels() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1564,7 +1611,7 @@ mod tests {
#[test] #[test]
fn generates_correct_inflight_map_data() { fn generates_correct_inflight_map_data() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice = invoice(payment_preimage); let invoice = invoice(payment_preimage);
@ -1610,7 +1657,7 @@ mod tests {
fn considers_inflight_htlcs_between_invoice_payments_when_path_succeeds() { fn considers_inflight_htlcs_between_invoice_payments_when_path_succeeds() {
// First, let's just send a payment through, but only make sure one of the path completes // First, let's just send a payment through, but only make sure one of the path completes
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let payment_invoice = invoice(payment_preimage); let payment_invoice = invoice(payment_preimage);
@ -1661,7 +1708,7 @@ mod tests {
fn considers_inflight_htlcs_between_retries() { fn considers_inflight_htlcs_between_retries() {
// First, let's just send a payment through, but only make sure one of the path completes // First, let's just send a payment through, but only make sure one of the path completes
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let payment_invoice = invoice(payment_preimage); let payment_invoice = invoice(payment_preimage);
@ -1732,7 +1779,7 @@ mod tests {
#[test] #[test]
fn accounts_for_some_inflight_htlcs_sent_during_partial_failure() { fn accounts_for_some_inflight_htlcs_sent_during_partial_failure() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice_to_pay = invoice(payment_preimage); let invoice_to_pay = invoice(payment_preimage);
@ -1763,7 +1810,7 @@ mod tests {
#[test] #[test]
fn accounts_for_all_inflight_htlcs_sent_during_partial_failure() { fn accounts_for_all_inflight_htlcs_sent_during_partial_failure() {
let event_handled = core::cell::RefCell::new(false); let event_handled = core::cell::RefCell::new(false);
let event_handler = |_: &_| { *event_handled.borrow_mut() = true; }; let event_handler = |_: &Event| { *event_handled.borrow_mut() = true; };
let payment_preimage = PaymentPreimage([1; 32]); let payment_preimage = PaymentPreimage([1; 32]);
let invoice_to_pay = invoice(payment_preimage); let invoice_to_pay = invoice(payment_preimage);
@ -2260,7 +2307,7 @@ mod tests {
route.paths[1][0].fee_msat = 50_000_000; route.paths[1][0].fee_msat = 50_000_000;
router.expect_find_route(Ok(route.clone())); router.expect_find_route(Ok(route.clone()));
let event_handler = |_: &_| { panic!(); }; let event_handler = |_: &Event| { panic!(); };
let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1)); let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1));
assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch( assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
@ -2305,7 +2352,7 @@ mod tests {
route.paths[1][0].fee_msat = 50_000_001; route.paths[1][0].fee_msat = 50_000_001;
router.expect_find_route(Ok(route.clone())); router.expect_find_route(Ok(route.clone()));
let event_handler = |_: &_| { panic!(); }; let event_handler = |_: &Event| { panic!(); };
let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1)); let invoice_payer = InvoicePayer::new(nodes[0].node, router, nodes[0].logger, event_handler, Retry::Attempts(1));
assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch( assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(