3838//! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
3939//! # use lightning::ln::msgs::LightningError;
4040//! # use lightning::routing::gossip::NodeId;
41- //! # use lightning::routing::router::{Route, RouteHop, RouteParameters};
41+ //! # use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters, Router };
4242//! # use lightning::routing::scoring::{ChannelUsage, Score};
4343//! # use lightning::util::events::{Event, EventHandler, EventsProvider};
4444//! # use lightning::util::logger::{Logger, Record};
4545//! # use lightning::util::ser::{Writeable, Writer};
4646//! # use lightning_invoice::Invoice;
47- //! # use lightning_invoice::payment::{InFlightHtlcs, InvoicePayer, Payer, Retry, Router };
47+ //! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry, ScoringRouter };
4848//! # use secp256k1::PublicKey;
4949//! # use std::cell::RefCell;
5050//! # use std::ops::Deref;
7474//! # struct FakeRouter {}
7575//! # impl Router for FakeRouter {
7676//! # fn find_route(
77- //! # &self, payer: &PublicKey, params: &RouteParameters, payment_hash: &PaymentHash,
77+ //! # &self, payer: &PublicKey, params: &RouteParameters,
7878//! # first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InFlightHtlcs
7979//! # ) -> Result<Route, LightningError> { unimplemented!() }
80- //! #
80+ //! # }
81+ //! # impl ScoringRouter for FakeRouter {
8182//! # fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) { unimplemented!() }
8283//! # fn notify_payment_path_successful(&self, path: &[&RouteHop]) { unimplemented!() }
8384//! # fn notify_payment_probe_successful(&self, path: &[&RouteHop]) { unimplemented!() }
@@ -141,16 +142,14 @@ use bitcoin_hashes::Hash;
141142use bitcoin_hashes:: sha256:: Hash as Sha256 ;
142143
143144use crate :: prelude:: * ;
144- use lightning:: io;
145145use lightning:: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
146146use lightning:: ln:: channelmanager:: { ChannelDetails , PaymentId , PaymentSendFailure } ;
147147use lightning:: ln:: msgs:: LightningError ;
148148use lightning:: routing:: gossip:: NodeId ;
149- use lightning:: routing:: router:: { PaymentParameters , Route , RouteHop , RouteParameters } ;
149+ use lightning:: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteHop , RouteParameters , Router } ;
150150use lightning:: util:: errors:: APIError ;
151151use lightning:: util:: events:: { Event , EventHandler } ;
152152use lightning:: util:: logger:: Logger ;
153- use lightning:: util:: ser:: Writeable ;
154153use crate :: time_utils:: Time ;
155154use crate :: sync:: Mutex ;
156155
@@ -178,7 +177,7 @@ use crate::time_utils;
178177type ConfiguredTime = time_utils:: Eternity ;
179178
180179/// (C-not exported) generally all users should use the [`InvoicePayer`] type alias.
181- pub struct InvoicePayerUsingTime < P : Deref , R : Router , L : Deref , E : EventHandler , T : Time >
180+ pub struct InvoicePayerUsingTime < P : Deref , R : ScoringRouter , L : Deref , E : EventHandler , T : Time >
182181where
183182 P :: Target : Payer ,
184183 L :: Target : Logger ,
@@ -280,13 +279,20 @@ pub trait Payer {
280279 fn abandon_payment ( & self , payment_id : PaymentId ) ;
281280}
282281
283- /// A trait defining behavior for routing an [`Invoice`] payment.
284- pub trait Router {
285- /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values.
286- fn find_route (
287- & self , payer : & PublicKey , route_params : & RouteParameters , payment_hash : & PaymentHash ,
288- first_hops : Option < & [ & ChannelDetails ] > , inflight_htlcs : InFlightHtlcs
289- ) -> Result < Route , LightningError > ;
282+ /// A trait defining behavior for a [`Router`] implementation that also supports scoring channels
283+ /// based on payment and probe success/failure.
284+ ///
285+ /// [`Router`]: lightning::routing::router::Router
286+ pub trait ScoringRouter : Router {
287+ /// Finds a [`Route`] between `payer` and `payee` for a payment with the given values. Includes
288+ /// `PaymentHash` and `PaymentId` to be able to correlate the request with a specific payment.
289+ fn find_route_with_id (
290+ & self , payer : & PublicKey , route_params : & RouteParameters ,
291+ first_hops : Option < & [ & ChannelDetails ] > , inflight_htlcs : InFlightHtlcs ,
292+ _payment_hash : PaymentHash , _payment_id : PaymentId
293+ ) -> Result < Route , LightningError > {
294+ self . find_route ( payer, route_params, first_hops, inflight_htlcs)
295+ }
290296 /// Lets the router know that payment through a specific path has failed.
291297 fn notify_payment_path_failed ( & self , path : & [ & RouteHop ] , short_channel_id : u64 ) ;
292298 /// Lets the router know that payment through a specific path was successful.
@@ -336,7 +342,7 @@ pub enum PaymentError {
336342 Sending ( PaymentSendFailure ) ,
337343}
338344
339- impl < P : Deref , R : Router , L : Deref , E : EventHandler , T : Time > InvoicePayerUsingTime < P , R , L , E , T >
345+ impl < P : Deref , R : ScoringRouter , L : Deref , E : EventHandler , T : Time > InvoicePayerUsingTime < P , R , L , E , T >
340346where
341347 P :: Target : Payer ,
342348 L :: Target : Logger ,
@@ -529,8 +535,7 @@ where
529535 let first_hops = self . payer . first_hops ( ) ;
530536 let inflight_htlcs = self . create_inflight_map ( ) ;
531537 let route = self . router . find_route (
532- & payer, & params, & payment_hash, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
533- inflight_htlcs
538+ & payer, & params, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs
534539 ) . map_err ( |e| PaymentError :: Routing ( e) ) ?;
535540
536541 match send_payment ( & route) {
@@ -634,8 +639,7 @@ where
634639 let inflight_htlcs = self . create_inflight_map ( ) ;
635640
636641 let route = self . router . find_route (
637- & payer, & params, & payment_hash, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
638- inflight_htlcs
642+ & payer, & params, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs
639643 ) ;
640644
641645 if route. is_err ( ) {
@@ -688,9 +692,8 @@ where
688692 self . payment_cache . lock ( ) . unwrap ( ) . remove ( payment_hash) ;
689693 }
690694
691- /// Given a [`PaymentHash`], this function looks up inflight path attempts in the payment_cache.
692- /// Then, it uses the path information inside the cache to construct a HashMap mapping a channel's
693- /// short channel id and direction to the amount being sent through it.
695+ /// Use path information in the payment_cache to construct a HashMap mapping a channel's short
696+ /// channel id and direction to the amount being sent through it.
694697 ///
695698 /// This function should be called whenever we need information about currently used up liquidity
696699 /// across payments.
@@ -726,7 +729,7 @@ where
726729 }
727730 }
728731
729- InFlightHtlcs ( total_inflight_map)
732+ InFlightHtlcs :: new ( total_inflight_map)
730733 }
731734}
732735
@@ -741,7 +744,7 @@ fn has_expired(route_params: &RouteParameters) -> bool {
741744 } else { false }
742745}
743746
744- impl < P : Deref , R : Router , L : Deref , E : EventHandler , T : Time > EventHandler for InvoicePayerUsingTime < P , R , L , E , T >
747+ impl < P : Deref , R : ScoringRouter , L : Deref , E : EventHandler , T : Time > EventHandler for InvoicePayerUsingTime < P , R , L , E , T >
745748where
746749 P :: Target : Payer ,
747750 L :: Target : Logger ,
@@ -815,31 +818,6 @@ where
815818 }
816819}
817820
818- /// A map with liquidity value (in msat) keyed by a short channel id and the direction the HTLC
819- /// is traveling in. The direction boolean is determined by checking if the HTLC source's public
820- /// key is less than its destination. See [`InFlightHtlcs::used_liquidity_msat`] for more
821- /// details.
822- pub struct InFlightHtlcs ( HashMap < ( u64 , bool ) , u64 > ) ;
823-
824- impl InFlightHtlcs {
825- /// Returns liquidity in msat given the public key of the HTLC source, target, and short channel
826- /// id.
827- pub fn used_liquidity_msat ( & self , source : & NodeId , target : & NodeId , channel_scid : u64 ) -> Option < u64 > {
828- self . 0 . get ( & ( channel_scid, source < target) ) . map ( |v| * v)
829- }
830- }
831-
832- impl Writeable for InFlightHtlcs {
833- fn write < W : lightning:: util:: ser:: Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > { self . 0 . write ( writer) }
834- }
835-
836- impl lightning:: util:: ser:: Readable for InFlightHtlcs {
837- fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , lightning:: ln:: msgs:: DecodeError > {
838- let infight_map: HashMap < ( u64 , bool ) , u64 > = lightning:: util:: ser:: Readable :: read ( reader) ?;
839- Ok ( Self ( infight_map) )
840- }
841- }
842-
843821#[ cfg( test) ]
844822mod tests {
845823 use super :: * ;
@@ -852,7 +830,7 @@ mod tests {
852830 use lightning:: ln:: functional_test_utils:: * ;
853831 use lightning:: ln:: msgs:: { ChannelMessageHandler , ErrorAction , LightningError } ;
854832 use lightning:: routing:: gossip:: { EffectiveCapacity , NodeId } ;
855- use lightning:: routing:: router:: { PaymentParameters , Route , RouteHop } ;
833+ use lightning:: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteHop , Router } ;
856834 use lightning:: routing:: scoring:: { ChannelUsage , LockableScore , Score } ;
857835 use lightning:: util:: test_utils:: TestLogger ;
858836 use lightning:: util:: errors:: APIError ;
@@ -1895,7 +1873,7 @@ mod tests {
18951873
18961874 impl Router for TestRouter {
18971875 fn find_route (
1898- & self , payer : & PublicKey , route_params : & RouteParameters , _payment_hash : & PaymentHash ,
1876+ & self , payer : & PublicKey , route_params : & RouteParameters ,
18991877 _first_hops : Option < & [ & ChannelDetails ] > , inflight_htlcs : InFlightHtlcs
19001878 ) -> Result < Route , LightningError > {
19011879 // Simulate calling the Scorer just as you would in find_route
@@ -1926,7 +1904,9 @@ mod tests {
19261904 payment_params : Some ( route_params. payment_params . clone ( ) ) , ..Self :: route_for_value ( route_params. final_value_msat )
19271905 } )
19281906 }
1907+ }
19291908
1909+ impl ScoringRouter for TestRouter {
19301910 fn notify_payment_path_failed ( & self , path : & [ & RouteHop ] , short_channel_id : u64 ) {
19311911 self . scorer . lock ( ) . payment_path_failed ( path, short_channel_id) ;
19321912 }
@@ -1948,12 +1928,14 @@ mod tests {
19481928
19491929 impl Router for FailingRouter {
19501930 fn find_route (
1951- & self , _payer : & PublicKey , _params : & RouteParameters , _payment_hash : & PaymentHash ,
1952- _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlcs : InFlightHtlcs
1931+ & self , _payer : & PublicKey , _params : & RouteParameters , _first_hops : Option < & [ & ChannelDetails ] > ,
1932+ _inflight_htlcs : InFlightHtlcs ,
19531933 ) -> Result < Route , LightningError > {
19541934 Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } )
19551935 }
1936+ }
19561937
1938+ impl ScoringRouter for FailingRouter {
19571939 fn notify_payment_path_failed ( & self , _path : & [ & RouteHop ] , _short_channel_id : u64 ) { }
19581940
19591941 fn notify_payment_path_successful ( & self , _path : & [ & RouteHop ] ) { }
@@ -2210,12 +2192,13 @@ mod tests {
22102192
22112193 impl Router for ManualRouter {
22122194 fn find_route (
2213- & self , _payer : & PublicKey , _params : & RouteParameters , _payment_hash : & PaymentHash ,
2214- _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlcs : InFlightHtlcs
2195+ & self , _payer : & PublicKey , _params : & RouteParameters , _first_hops : Option < & [ & ChannelDetails ] > ,
2196+ _inflight_htlcs : InFlightHtlcs
22152197 ) -> Result < Route , LightningError > {
22162198 self . 0 . borrow_mut ( ) . pop_front ( ) . unwrap ( )
22172199 }
2218-
2200+ }
2201+ impl ScoringRouter for ManualRouter {
22192202 fn notify_payment_path_failed ( & self , _path : & [ & RouteHop ] , _short_channel_id : u64 ) { }
22202203
22212204 fn notify_payment_path_successful ( & self , _path : & [ & RouteHop ] ) { }
0 commit comments