From: Valentine Wallace Date: Thu, 27 Oct 2022 22:00:23 +0000 (-0400) Subject: Move InvoicePayer's Router into ChannelManager X-Git-Tag: v0.0.113~57^2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=9d3324968c175661ae2d11c5c754688978f2fb7f;p=rust-lightning Move InvoicePayer's Router into ChannelManager This helps prepare to parameterize ChannelManager with a Router, to eventually use in trampoline payments. --- diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index 7d5aee052..a64c84403 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -38,13 +38,13 @@ //! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure}; //! # use lightning::ln::msgs::LightningError; //! # use lightning::routing::gossip::NodeId; -//! # use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters}; +//! # use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters, Router}; //! # use lightning::routing::scoring::{ChannelUsage, Score}; //! # use lightning::util::events::{Event, EventHandler, EventsProvider}; //! # use lightning::util::logger::{Logger, Record}; //! # use lightning::util::ser::{Writeable, Writer}; //! # use lightning_invoice::Invoice; -//! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry, Router}; +//! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry, ScoringRouter}; //! # use secp256k1::PublicKey; //! # use std::cell::RefCell; //! # use std::ops::Deref; @@ -76,7 +76,8 @@ //! # &self, payer: &PublicKey, params: &RouteParameters, //! # first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InFlightHtlcs //! # ) -> Result { unimplemented!() } -//! # +//! # } +//! # impl ScoringRouter for FakeRouter { //! # fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) { unimplemented!() } //! # fn notify_payment_path_successful(&self, path: &[&RouteHop]) { unimplemented!() } //! # fn notify_payment_probe_successful(&self, path: &[&RouteHop]) { unimplemented!() } @@ -144,7 +145,7 @@ use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure}; use lightning::ln::msgs::LightningError; use lightning::routing::gossip::NodeId; -use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters}; +use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, Router}; use lightning::util::errors::APIError; use lightning::util::events::{Event, EventHandler}; use lightning::util::logger::Logger; @@ -175,7 +176,7 @@ use crate::time_utils; type ConfiguredTime = time_utils::Eternity; /// (C-not exported) generally all users should use the [`InvoicePayer`] type alias. -pub struct InvoicePayerUsingTime +pub struct InvoicePayerUsingTime where P::Target: Payer, L::Target: Logger, @@ -264,13 +265,20 @@ pub trait Payer { fn abandon_payment(&self, payment_id: PaymentId); } -/// A trait defining behavior for routing an [`Invoice`] payment. -pub trait Router { - /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values. - fn find_route( +/// A trait defining behavior for a [`Router`] implementation that also supports scoring channels +/// based on payment and probe success/failure. +/// +/// [`Router`]: lightning::routing::router::Router +pub trait ScoringRouter: Router { + /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values. Includes + /// `PaymentHash` and `PaymentId` to be able to correlate the request with a specific payment. + fn find_route_with_id( &self, payer: &PublicKey, route_params: &RouteParameters, - first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs - ) -> Result; + first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs, + _payment_hash: PaymentHash, _payment_id: PaymentId + ) -> Result { + self.find_route(payer, route_params, first_hops, inflight_htlcs) + } /// Lets the router know that payment through a specific path has failed. fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64); /// Lets the router know that payment through a specific path was successful. @@ -320,7 +328,7 @@ pub enum PaymentError { Sending(PaymentSendFailure), } -impl InvoicePayerUsingTime +impl InvoicePayerUsingTime where P::Target: Payer, L::Target: Logger, @@ -654,7 +662,7 @@ fn has_expired(route_params: &RouteParameters) -> bool { } else { false } } -impl EventHandler for InvoicePayerUsingTime +impl EventHandler for InvoicePayerUsingTime where P::Target: Payer, L::Target: Logger, @@ -740,7 +748,7 @@ mod tests { use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError}; use lightning::routing::gossip::{EffectiveCapacity, NodeId}; - use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop}; + use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, Router}; use lightning::routing::scoring::{ChannelUsage, LockableScore, Score}; use lightning::util::test_utils::TestLogger; use lightning::util::errors::APIError; @@ -1814,7 +1822,9 @@ mod tests { payment_params: Some(route_params.payment_params.clone()), ..Self::route_for_value(route_params.final_value_msat) }) } + } + impl ScoringRouter for TestRouter { fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) { self.scorer.lock().payment_path_failed(path, short_channel_id); } @@ -1841,7 +1851,9 @@ mod tests { ) -> Result { Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }) } + } + impl ScoringRouter for FailingRouter { fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {} fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {} @@ -2103,7 +2115,8 @@ mod tests { ) -> Result { self.0.borrow_mut().pop_front().unwrap() } - + } + impl ScoringRouter for ManualRouter { fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {} fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {} diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 52bfd31d8..4c9c589b7 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -1,7 +1,7 @@ //! Convenient utilities to create an invoice. use crate::{CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError}; -use crate::payment::{Payer, Router}; +use crate::payment::{Payer, ScoringRouter}; use crate::{prelude::*, Description, InvoiceDescription, Sha256}; use bech32::ToBase32; @@ -16,7 +16,7 @@ use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA}; use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey}; use lightning::ln::msgs::LightningError; use lightning::routing::gossip::{NetworkGraph, NodeId, RoutingFees}; -use lightning::routing::router::{InFlightHtlcs, Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop}; +use lightning::routing::router::{InFlightHtlcs, Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop, Router}; use lightning::routing::scoring::{ChannelUsage, LockableScore, Score}; use lightning::util::logger::Logger; use secp256k1::PublicKey; @@ -567,7 +567,12 @@ impl>, L: Deref, S: Deref> Router for DefaultR &random_seed_bytes ) } +} +impl>, L: Deref, S: Deref> ScoringRouter for DefaultRouter where + L::Target: Logger, + S::Target: for <'a> LockableScore<'a>, +{ fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) { self.scorer.lock().payment_path_failed(path, short_channel_id); } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index fcb93c5f1..f102ad8da 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -29,6 +29,15 @@ use alloc::collections::BinaryHeap; use core::cmp; use core::ops::Deref; +/// A trait defining behavior for routing a payment. +pub trait Router { + /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values. + fn find_route( + &self, payer: &PublicKey, route_params: &RouteParameters, + first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs + ) -> Result; +} + /// A map with liquidity value (in msat) keyed by a short channel id and the direction the HTLC /// is traveling in. The direction boolean is determined by checking if the HTLC source's public /// key is less than its destination. See [`InFlightHtlcs::used_liquidity_msat`] for more