48
48
//! # use lightning::util::logger::{Logger, Record};
49
49
//! # use lightning::util::ser::{Writeable, Writer};
50
50
//! # use lightning_invoice::Invoice;
51
- //! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry, Router};
51
+ //! # use lightning_invoice::payment::{InvoicePayer, Payer, Retry, Router, InflightHtlcs };
52
52
//! # use secp256k1::PublicKey;
53
53
//! # use std::cell::RefCell;
54
54
//! # use std::ops::Deref;
83
83
//! # impl Router for FakeRouter {
84
84
//! # fn find_route(
85
85
//! # &self, payer: &PublicKey, params: &RouteParameters, payment_hash: &PaymentHash,
86
- //! # first_hops: Option<&[&ChannelDetails]>, inflight_htlc_map: HashMap<(u64, bool), u64>
86
+ //! # first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InflightHtlcs
87
87
//! # ) -> Result<Route, LightningError> { unimplemented!() }
88
88
//! #
89
89
//! # fn notify_payment_path_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64) { unimplemented!() }
@@ -278,7 +278,7 @@ pub trait Router {
278
278
/// Finds a [`Route`] between `payer` and `payee` for a payment with the given values.
279
279
fn find_route (
280
280
& self , payer : & PublicKey , route_params : & RouteParameters , payment_hash : & PaymentHash ,
281
- first_hops : Option < & [ & ChannelDetails ] > , inflight_htlc_map : HashMap < ( u64 , bool ) , u64 >
281
+ first_hops : Option < & [ & ChannelDetails ] > , inflight_htlcs : InflightHtlcs
282
282
) -> Result < Route , LightningError > ;
283
283
/// Lets the router know that payment through a specific path has failed.
284
284
fn notify_payment_path_failed ( & self , path : Vec < & RouteHop > , short_channel_id : u64 ) ;
@@ -455,7 +455,7 @@ where
455
455
let inflight_htlcs = self . create_inflight_map ( ) ;
456
456
let route = self . router . find_route (
457
457
& payer, & params, & payment_hash, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
458
- inflight_htlcs
458
+ InflightHtlcs :: new ( Some ( inflight_htlcs) )
459
459
) . map_err ( |e| PaymentError :: Routing ( e) ) ?;
460
460
461
461
match send_payment ( & route) {
@@ -560,7 +560,7 @@ where
560
560
561
561
let route = self . router . find_route (
562
562
& payer, & params, & payment_hash, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
563
- inflight_htlcs
563
+ InflightHtlcs :: new ( Some ( inflight_htlcs) )
564
564
) ;
565
565
566
566
if route. is_err ( ) {
@@ -740,6 +740,28 @@ where
740
740
}
741
741
}
742
742
743
+ /// Data structure used to track information about inflight HTLCs.
744
+ pub struct InflightHtlcs {
745
+ /// A map with liquidity value (in msat) keyed by a short channel id and the direction the HTLC
746
+ /// is traveling in. The direction boolean is determined by checking if the HTLC source's public
747
+ /// key is less than its destination. See [`InflightHtlcs::used_liquidity_msat`] for more
748
+ /// details.
749
+ pub map : HashMap < ( u64 , bool ) , u64 >
750
+ }
751
+
752
+ impl InflightHtlcs {
753
+ /// Creates a new instance with an optional map of liquidity information.
754
+ pub fn new ( map : Option < HashMap < ( u64 , bool ) , u64 > > ) -> Self {
755
+ InflightHtlcs { map : map. unwrap_or ( HashMap :: new ( ) ) }
756
+ }
757
+
758
+ /// Returns liquidity in msat given the public key of the HTLC source, destination, and short
759
+ /// channel id.
760
+ pub fn used_liquidity_msat ( & self , source : PublicKey , destination : PublicKey , channel_scid : u64 ) -> Option < & u64 > {
761
+ self . map . get ( & ( channel_scid, source < destination) )
762
+ }
763
+ }
764
+
743
765
#[ cfg( test) ]
744
766
mod tests {
745
767
use super :: * ;
@@ -1817,7 +1839,7 @@ mod tests {
1817
1839
impl Router for TestRouter {
1818
1840
fn find_route (
1819
1841
& self , payer : & PublicKey , route_params : & RouteParameters , _payment_hash : & PaymentHash ,
1820
- _first_hops : Option < & [ & ChannelDetails ] > , inflight_htlc_map : HashMap < ( u64 , bool ) , u64 >
1842
+ _first_hops : Option < & [ & ChannelDetails ] > , inflight_htlcs : InflightHtlcs
1821
1843
) -> Result < Route , LightningError > {
1822
1844
// Simulate calling the Scorer just as you would in find_route
1823
1845
let route = Self :: route_for_value ( route_params. final_value_msat ) ;
@@ -1834,7 +1856,7 @@ mod tests {
1834
1856
// Since the path is reversed, the last element in our iteration is the first
1835
1857
// hop.
1836
1858
let mut locked_scorer = self . scorer . lock ( ) ;
1837
- let scorer = AccountForInFlightHtlcs :: new ( locked_scorer. deref_mut ( ) , inflight_htlc_map . clone ( ) ) ;
1859
+ let scorer = AccountForInFlightHtlcs :: new ( locked_scorer. deref_mut ( ) , inflight_htlcs . map . clone ( ) ) ;
1838
1860
if idx == path. len ( ) - 1 {
1839
1861
scorer. channel_penalty_msat ( hop. short_channel_id , & NodeId :: from_pubkey ( payer) , & NodeId :: from_pubkey ( & hop. pubkey ) , usage) ;
1840
1862
} else {
@@ -1870,7 +1892,7 @@ mod tests {
1870
1892
impl Router for FailingRouter {
1871
1893
fn find_route (
1872
1894
& self , _payer : & PublicKey , _params : & RouteParameters , _payment_hash : & PaymentHash ,
1873
- _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlc_map : HashMap < ( u64 , bool ) , u64 >
1895
+ _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlcs : InflightHtlcs
1874
1896
) -> Result < Route , LightningError > {
1875
1897
Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } )
1876
1898
}
@@ -2132,7 +2154,7 @@ mod tests {
2132
2154
impl Router for ManualRouter {
2133
2155
fn find_route (
2134
2156
& self , _payer : & PublicKey , _params : & RouteParameters , _payment_hash : & PaymentHash ,
2135
- _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlc_map : HashMap < ( u64 , bool ) , u64 >
2157
+ _first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlcs : InflightHtlcs
2136
2158
) -> Result < Route , LightningError > {
2137
2159
self . 0 . borrow_mut ( ) . pop_front ( ) . unwrap ( )
2138
2160
}
0 commit comments