@@ -130,18 +130,27 @@ impl<'a, S: Deref> ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: Scor
130
130
131
131
impl < ' a , S : Deref > ScoreLookUp for ScorerAccountingForInFlightHtlcs < ' a , S > where S :: Target : ScoreLookUp {
132
132
type ScoreParams = <S :: Target as ScoreLookUp >:: ScoreParams ;
133
- fn channel_penalty_msat ( & self , short_channel_id : u64 , source : & NodeId , target : & NodeId , usage : ChannelUsage , score_params : & Self :: ScoreParams ) -> u64 {
133
+ fn channel_penalty_msat ( & self , candidate : & CandidateRouteHop , usage : ChannelUsage , score_params : & Self :: ScoreParams ) -> u64 {
134
+ let target = match candidate. target ( ) {
135
+ Some ( target) => target,
136
+ None => return self . scorer . channel_penalty_msat ( candidate, usage, score_params) ,
137
+ } ;
138
+ let short_channel_id = match candidate. short_channel_id ( ) {
139
+ Some ( short_channel_id) => short_channel_id,
140
+ None => return self . scorer . channel_penalty_msat ( candidate, usage, score_params) ,
141
+ } ;
142
+ let source = candidate. source ( ) ;
134
143
if let Some ( used_liquidity) = self . inflight_htlcs . used_liquidity_msat (
135
- source, target, short_channel_id
144
+ & source, & target, short_channel_id
136
145
) {
137
146
let usage = ChannelUsage {
138
147
inflight_htlc_msat : usage. inflight_htlc_msat . saturating_add ( used_liquidity) ,
139
148
..usage
140
149
} ;
141
150
142
- self . scorer . channel_penalty_msat ( short_channel_id , source , target , usage, score_params)
151
+ self . scorer . channel_penalty_msat ( candidate , usage, score_params)
143
152
} else {
144
- self . scorer . channel_penalty_msat ( short_channel_id , source , target , usage, score_params)
153
+ self . scorer . channel_penalty_msat ( candidate , usage, score_params)
145
154
}
146
155
}
147
156
}
@@ -1059,9 +1068,13 @@ pub enum CandidateRouteHop<'a> {
1059
1068
}
1060
1069
1061
1070
impl < ' a > CandidateRouteHop < ' a > {
1062
- fn short_channel_id ( & self ) -> Option < u64 > {
1071
+ /// Returns short_channel_id if known.
1072
+ /// For `FirstHop` we assume [`ChannelDetails::get_outbound_payment_scid`] is always set, this assumption is checked in
1073
+ /// [`find_route`] method.
1074
+ /// For `Blinded` and `OneHopBlinded` we return `None` because next hop is not known.
1075
+ pub fn short_channel_id ( & self ) -> Option < u64 > {
1063
1076
match self {
1064
- CandidateRouteHop :: FirstHop { details, .. } => Some ( details. get_outbound_payment_scid ( ) . unwrap ( ) ) ,
1077
+ CandidateRouteHop :: FirstHop { details, .. } => details. get_outbound_payment_scid ( ) ,
1065
1078
CandidateRouteHop :: PublicHop { short_channel_id, .. } => Some ( * short_channel_id) ,
1066
1079
CandidateRouteHop :: PrivateHop { hint, .. } => Some ( hint. short_channel_id ) ,
1067
1080
CandidateRouteHop :: Blinded { .. } => None ,
@@ -1080,7 +1093,8 @@ impl<'a> CandidateRouteHop<'a> {
1080
1093
}
1081
1094
}
1082
1095
1083
- fn cltv_expiry_delta ( & self ) -> u32 {
1096
+ /// Returns cltv_expiry_delta for this hop.
1097
+ pub fn cltv_expiry_delta ( & self ) -> u32 {
1084
1098
match self {
1085
1099
CandidateRouteHop :: FirstHop { .. } => 0 ,
1086
1100
CandidateRouteHop :: PublicHop { info, .. } => info. direction ( ) . cltv_expiry_delta as u32 ,
@@ -1090,7 +1104,8 @@ impl<'a> CandidateRouteHop<'a> {
1090
1104
}
1091
1105
}
1092
1106
1093
- fn htlc_minimum_msat ( & self ) -> u64 {
1107
+ /// Returns the htlc_minimum_msat for this hop.
1108
+ pub fn htlc_minimum_msat ( & self ) -> u64 {
1094
1109
match self {
1095
1110
CandidateRouteHop :: FirstHop { details, .. } => details. next_outbound_htlc_minimum_msat ,
1096
1111
CandidateRouteHop :: PublicHop { info, .. } => info. direction ( ) . htlc_minimum_msat ,
@@ -1100,7 +1115,8 @@ impl<'a> CandidateRouteHop<'a> {
1100
1115
}
1101
1116
}
1102
1117
1103
- fn fees ( & self ) -> RoutingFees {
1118
+ /// Returns the fees for this hop.
1119
+ pub fn fees ( & self ) -> RoutingFees {
1104
1120
match self {
1105
1121
CandidateRouteHop :: FirstHop { .. } => RoutingFees {
1106
1122
base_msat : 0 , proportional_millionths : 0 ,
@@ -1164,7 +1180,7 @@ impl<'a> CandidateRouteHop<'a> {
1164
1180
CandidateRouteHop :: PublicHop { source_node_id, .. } => * source_node_id,
1165
1181
CandidateRouteHop :: PrivateHop { hint, .. } => hint. src_node_id . into ( ) ,
1166
1182
CandidateRouteHop :: Blinded { hint, .. } => hint. 1 . introduction_node_id . into ( ) ,
1167
- CandidateRouteHop :: OneHopBlinded { hint, .. } => hint. 1 . introduction_node_id . into ( )
1183
+ CandidateRouteHop :: OneHopBlinded { hint, .. } => hint. 1 . introduction_node_id . into ( ) ,
1168
1184
}
1169
1185
}
1170
1186
/// Returns the target node id of this hop, if known.
@@ -1183,10 +1199,10 @@ impl<'a> CandidateRouteHop<'a> {
1183
1199
}
1184
1200
}
1185
1201
1186
- /// Represents a hop id in a potential route .
1202
+ /// A wrapper around the various hop id representations .
1187
1203
///
1188
- /// `Clear` contains the channel id and the direction of the channel.
1189
- /// `Blinded` contains the index of the blinded route hint in [`Payee::Blinded::route_hints`] .
1204
+ /// `CandidateHopId:: Clear` is used to identify a hop with a known short channel id and direction .
1205
+ /// `CandidateHopId:: Blinded` is used to identify a blinded hop `hint_idx` .
1190
1206
#[ derive( Clone , Copy , Eq , Hash , Ord , PartialOrd , PartialEq ) ]
1191
1207
pub enum CandidateHopId {
1192
1208
/// Contains (scid, src_node_id < target_node_id)
@@ -1791,7 +1807,7 @@ where L::Target: Logger {
1791
1807
let mut num_ignored_htlc_minimum_msat_limit: u32 = 0 ;
1792
1808
1793
1809
macro_rules! add_entry {
1794
- // Adds entry which goes from $src_node_id to $dest_node_id over the $candidate hop.
1810
+ // Adds entry which goes from candidate.source() to candiadte.target() over the $candidate hop.
1795
1811
// $next_hops_fee_msat represents the fees paid for using all the channels *after* this one,
1796
1812
// since that value has to be transferred over this channel.
1797
1813
// Returns the contribution amount of $candidate if the channel caused an update to `targets`.
@@ -1807,7 +1823,7 @@ where L::Target: Logger {
1807
1823
// - for first and last hops early in get_route
1808
1824
let src_node_id = $candidate. source( ) ;
1809
1825
let dest_node_id = $candidate. target( ) . unwrap_or( maybe_dummy_payee_node_id) ;
1810
- if src_node_id != dest_node_id {
1826
+ if Some ( $candidate . source ( ) ) != $candidate . target ( ) {
1811
1827
let scid_opt = $candidate. short_channel_id( ) ;
1812
1828
let effective_capacity = $candidate. effective_capacity( ) ;
1813
1829
let htlc_maximum_msat = max_htlc_from_capacity( effective_capacity, channel_saturation_pow_half) ;
@@ -1922,7 +1938,7 @@ where L::Target: Logger {
1922
1938
// (recall it goes payee-to-payer) of short_channel_id, first add a
1923
1939
// semi-dummy record just to compute the fees to reach the source node.
1924
1940
// This will affect our decision on selecting short_channel_id
1925
- // as a way to reach the $dest_node_id .
1941
+ // as a way to reach the $dest_ node_id .
1926
1942
PathBuildingHop {
1927
1943
node_id: dest_node_id. clone( ) ,
1928
1944
candidate: $candidate. clone( ) ,
@@ -1972,9 +1988,10 @@ where L::Target: Logger {
1972
1988
inflight_htlc_msat: used_liquidity_msat,
1973
1989
effective_capacity,
1974
1990
} ;
1975
- let channel_penalty_msat = scid_opt. map_or( 0 ,
1976
- |scid| scorer. channel_penalty_msat( scid, & src_node_id, & dest_node_id,
1977
- channel_usage, score_params) ) ;
1991
+ let channel_penalty_msat =
1992
+ scorer. channel_penalty_msat( $candidate,
1993
+ channel_usage,
1994
+ score_params) ;
1978
1995
let path_penalty_msat = $next_hops_path_penalty_msat
1979
1996
. saturating_add( channel_penalty_msat) ;
1980
1997
let new_graph_node = RouteGraphNode {
@@ -1987,7 +2004,7 @@ where L::Target: Logger {
1987
2004
path_length_to_node,
1988
2005
} ;
1989
2006
1990
- // Update the way of reaching $src_node_id with the given short_channel_id (from $dest_node_id ),
2007
+ // Update the way of reaching $candidate.source() with the given short_channel_id (from $candidate.target() ),
1991
2008
// if this way is cheaper than the already known
1992
2009
// (considering the cost to "reach" this channel from the route destination,
1993
2010
// the cost of using this channel,
@@ -2281,7 +2298,7 @@ where L::Target: Logger {
2281
2298
effective_capacity : candidate. effective_capacity ( ) ,
2282
2299
} ;
2283
2300
let channel_penalty_msat = scorer. channel_penalty_msat (
2284
- hop . short_channel_id , & source , & target , channel_usage, score_params
2301
+ & candidate , channel_usage, score_params
2285
2302
) ;
2286
2303
aggregate_next_hops_path_penalty_msat = aggregate_next_hops_path_penalty_msat
2287
2304
. saturating_add ( channel_penalty_msat) ;
@@ -2645,7 +2662,6 @@ where L::Target: Logger {
2645
2662
let mut paths = Vec :: new ( ) ;
2646
2663
for payment_path in selected_route {
2647
2664
let mut hops = Vec :: with_capacity ( payment_path. hops . len ( ) ) ;
2648
- let mut prev_hop_node_id = our_node_id;
2649
2665
for ( hop, node_features) in payment_path. hops . iter ( )
2650
2666
. filter ( |( h, _) | h. candidate . short_channel_id ( ) . is_some ( ) )
2651
2667
{
@@ -2662,7 +2678,7 @@ where L::Target: Logger {
2662
2678
// an alias, in which case we don't take any chances here.
2663
2679
network_graph. node ( & hop. node_id ) . map_or ( false , |hop_node|
2664
2680
hop_node. channels . iter ( ) . any ( |scid| network_graph. channel ( * scid)
2665
- . map_or ( false , |c| c. as_directed_from ( & prev_hop_node_id ) . is_some ( ) ) )
2681
+ . map_or ( false , |c| c. as_directed_from ( & hop . candidate . source ( ) ) . is_some ( ) ) )
2666
2682
)
2667
2683
} ;
2668
2684
@@ -2675,8 +2691,6 @@ where L::Target: Logger {
2675
2691
cltv_expiry_delta : hop. candidate . cltv_expiry_delta ( ) ,
2676
2692
maybe_announced_channel,
2677
2693
} ) ;
2678
-
2679
- prev_hop_node_id = hop. node_id ;
2680
2694
}
2681
2695
let mut final_cltv_delta = final_cltv_expiry_delta;
2682
2696
let blinded_tail = payment_path. hops . last ( ) . and_then ( |( h, _) | {
@@ -2839,13 +2853,13 @@ fn build_route_from_hops_internal<L: Deref>(
2839
2853
2840
2854
impl ScoreLookUp for HopScorer {
2841
2855
type ScoreParams = ( ) ;
2842
- fn channel_penalty_msat ( & self , _short_channel_id : u64 , source : & NodeId , target : & NodeId ,
2856
+ fn channel_penalty_msat ( & self , candidate : & CandidateRouteHop ,
2843
2857
_usage : ChannelUsage , _score_params : & Self :: ScoreParams ) -> u64
2844
2858
{
2845
2859
let mut cur_id = self . our_node_id ;
2846
2860
for i in 0 ..self . hop_ids . len ( ) {
2847
2861
if let Some ( next_id) = self . hop_ids [ i] {
2848
- if cur_id == * source && next_id == * target {
2862
+ if cur_id == candidate . source ( ) && Some ( next_id) == candidate . target ( ) {
2849
2863
return 0 ;
2850
2864
}
2851
2865
cur_id = next_id;
@@ -2921,6 +2935,8 @@ mod tests {
2921
2935
2922
2936
use core:: convert:: TryInto ;
2923
2937
2938
+ use super :: CandidateRouteHop ;
2939
+
2924
2940
fn get_channel_details ( short_channel_id : Option < u64 > , node_id : PublicKey ,
2925
2941
features : InitFeatures , outbound_capacity_msat : u64 ) -> channelmanager:: ChannelDetails {
2926
2942
channelmanager:: ChannelDetails {
@@ -6193,7 +6209,11 @@ mod tests {
6193
6209
}
6194
6210
impl ScoreLookUp for BadChannelScorer {
6195
6211
type ScoreParams = ( ) ;
6196
- fn channel_penalty_msat ( & self , short_channel_id : u64 , _: & NodeId , _: & NodeId , _: ChannelUsage , _score_params : & Self :: ScoreParams ) -> u64 {
6212
+ fn channel_penalty_msat ( & self , candidate : & CandidateRouteHop , _: ChannelUsage , _score_params : & Self :: ScoreParams ) -> u64 {
6213
+ let short_channel_id = match candidate. short_channel_id ( ) {
6214
+ Some ( id) => id,
6215
+ None => return 0 ,
6216
+ } ;
6197
6217
if short_channel_id == self . short_channel_id { u64:: max_value ( ) } else { 0 }
6198
6218
}
6199
6219
}
@@ -6209,8 +6229,8 @@ mod tests {
6209
6229
6210
6230
impl ScoreLookUp for BadNodeScorer {
6211
6231
type ScoreParams = ( ) ;
6212
- fn channel_penalty_msat ( & self , _ : u64 , _ : & NodeId , target : & NodeId , _: ChannelUsage , _score_params : & Self :: ScoreParams ) -> u64 {
6213
- if * target == self . node_id { u64:: max_value ( ) } else { 0 }
6232
+ fn channel_penalty_msat ( & self , candidate : & CandidateRouteHop , _: ChannelUsage , _score_params : & Self :: ScoreParams ) -> u64 {
6233
+ if candidate . target ( ) == Some ( self . node_id ) { u64:: max_value ( ) } else { 0 }
6214
6234
}
6215
6235
}
6216
6236
@@ -6698,26 +6718,34 @@ mod tests {
6698
6718
} ;
6699
6719
scorer_params. set_manual_penalty ( & NodeId :: from_pubkey ( & nodes[ 3 ] ) , 123 ) ;
6700
6720
scorer_params. set_manual_penalty ( & NodeId :: from_pubkey ( & nodes[ 4 ] ) , 456 ) ;
6701
- assert_eq ! ( scorer. channel_penalty_msat( 42 , & NodeId :: from_pubkey( & nodes[ 3 ] ) , & NodeId :: from_pubkey( & nodes[ 4 ] ) , usage, & scorer_params) , 456 ) ;
6721
+ let network_graph = network_graph. read_only ( ) ;
6722
+ let channels = network_graph. channels ( ) ;
6723
+ let channel = channels. get ( & 5 ) . unwrap ( ) ;
6724
+ let info = channel. as_directed_from ( & NodeId :: from_pubkey ( & nodes[ 3 ] ) ) . unwrap ( ) ;
6725
+ let candidate: CandidateRouteHop = CandidateRouteHop :: PublicHop {
6726
+ info : info. 0 ,
6727
+ short_channel_id : 5 ,
6728
+ source_node_id : NodeId :: from_pubkey ( & nodes[ 3 ] ) ,
6729
+ target_node_id : NodeId :: from_pubkey ( & nodes[ 4 ] ) ,
6730
+ } ;
6731
+ assert_eq ! ( scorer. channel_penalty_msat( & candidate, usage, & scorer_params) , 456 ) ;
6702
6732
6703
6733
// Then check we can get a normal route
6704
6734
let payment_params = PaymentParameters :: from_node_id ( nodes[ 10 ] , 42 ) ;
6705
6735
let route_params = RouteParameters :: from_payment_params_and_value (
6706
6736
payment_params, 100 ) ;
6707
- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
6737
+ let route = get_route ( & our_id, & route_params, & network_graph, None ,
6708
6738
Arc :: clone ( & logger) , & scorer, & scorer_params, & random_seed_bytes) ;
6709
6739
assert ! ( route. is_ok( ) ) ;
6710
6740
6711
6741
// Then check that we can't get a route if we ban an intermediate node.
6712
6742
scorer_params. add_banned ( & NodeId :: from_pubkey ( & nodes[ 3 ] ) ) ;
6713
- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
6714
- Arc :: clone ( & logger) , & scorer, & scorer_params, & random_seed_bytes) ;
6743
+ let route = get_route ( & our_id, & route_params, & network_graph, None , Arc :: clone ( & logger) , & scorer, & scorer_params, & random_seed_bytes) ;
6715
6744
assert ! ( route. is_err( ) ) ;
6716
6745
6717
6746
// Finally make sure we can route again, when we remove the ban.
6718
6747
scorer_params. remove_banned ( & NodeId :: from_pubkey ( & nodes[ 3 ] ) ) ;
6719
- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
6720
- Arc :: clone ( & logger) , & scorer, & scorer_params, & random_seed_bytes) ;
6748
+ let route = get_route ( & our_id, & route_params, & network_graph, None , Arc :: clone ( & logger) , & scorer, & scorer_params, & random_seed_bytes) ;
6721
6749
assert ! ( route. is_ok( ) ) ;
6722
6750
}
6723
6751
0 commit comments