Skip to content

Commit d1bfb35

Browse files
committed
Change CandidateRouteHop functions visbility
- Change `short_channel_id` to pub and add docs - Change `cltv_expiry_delta` to pub and add docs - Change `fees` to pub and add docs - Change `htlc_minimum_msat` to pub and add docs
1 parent eb3989c commit d1bfb35

File tree

4 files changed

+557
-265
lines changed

4 files changed

+557
-265
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,8 +863,8 @@ mod tests {
863863
use lightning::ln::msgs::{ChannelMessageHandler, Init};
864864
use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
865865
use lightning::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
866-
use lightning::routing::router::{DefaultRouter, Path, RouteHop};
867866
use lightning::routing::scoring::{ChannelUsage, ScoreUpdate, ScoreLookUp, LockableScore};
867+
use lightning::routing::router::{DefaultRouter, Path, RouteHop, CandidateRouteHop};
868868
use lightning::util::config::UserConfig;
869869
use lightning::util::ser::Writeable;
870870
use lightning::util::test_utils;
@@ -1071,7 +1071,7 @@ mod tests {
10711071
impl ScoreLookUp for TestScorer {
10721072
type ScoreParams = ();
10731073
fn channel_penalty_msat(
1074-
&self, _short_channel_id: u64, _source: &NodeId, _target: &NodeId, _usage: ChannelUsage, _score_params: &Self::ScoreParams
1074+
&self, _candidate: &CandidateRouteHop, _usage: ChannelUsage, _score_params: &Self::ScoreParams
10751075
) -> u64 { unimplemented!(); }
10761076
}
10771077

lightning/src/routing/router.rs

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,27 @@ impl<'a, S: Deref> ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: Scor
130130

131131
impl<'a, S: Deref> ScoreLookUp for ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: ScoreLookUp {
132132
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();
134143
if let Some(used_liquidity) = self.inflight_htlcs.used_liquidity_msat(
135-
source, target, short_channel_id
144+
&source, &target, short_channel_id
136145
) {
137146
let usage = ChannelUsage {
138147
inflight_htlc_msat: usage.inflight_htlc_msat.saturating_add(used_liquidity),
139148
..usage
140149
};
141150

142-
self.scorer.channel_penalty_msat(short_channel_id, source, target, usage, score_params)
151+
self.scorer.channel_penalty_msat(candidate, usage, score_params)
143152
} 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)
145154
}
146155
}
147156
}
@@ -1059,9 +1068,13 @@ pub enum CandidateRouteHop<'a> {
10591068
}
10601069

10611070
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> {
10631076
match self {
1064-
CandidateRouteHop::FirstHop { details, .. } => Some(details.get_outbound_payment_scid().unwrap()),
1077+
CandidateRouteHop::FirstHop { details, .. } => details.get_outbound_payment_scid(),
10651078
CandidateRouteHop::PublicHop { short_channel_id, .. } => Some(*short_channel_id),
10661079
CandidateRouteHop::PrivateHop { hint, .. } => Some(hint.short_channel_id),
10671080
CandidateRouteHop::Blinded { .. } => None,
@@ -1080,7 +1093,8 @@ impl<'a> CandidateRouteHop<'a> {
10801093
}
10811094
}
10821095

1083-
fn cltv_expiry_delta(&self) -> u32 {
1096+
/// Returns cltv_expiry_delta for this hop.
1097+
pub fn cltv_expiry_delta(&self) -> u32 {
10841098
match self {
10851099
CandidateRouteHop::FirstHop { .. } => 0,
10861100
CandidateRouteHop::PublicHop { info, .. } => info.direction().cltv_expiry_delta as u32,
@@ -1090,7 +1104,8 @@ impl<'a> CandidateRouteHop<'a> {
10901104
}
10911105
}
10921106

1093-
fn htlc_minimum_msat(&self) -> u64 {
1107+
/// Returns the htlc_minimum_msat for this hop.
1108+
pub fn htlc_minimum_msat(&self) -> u64 {
10941109
match self {
10951110
CandidateRouteHop::FirstHop { details, .. } => details.next_outbound_htlc_minimum_msat,
10961111
CandidateRouteHop::PublicHop { info, .. } => info.direction().htlc_minimum_msat,
@@ -1100,7 +1115,8 @@ impl<'a> CandidateRouteHop<'a> {
11001115
}
11011116
}
11021117

1103-
fn fees(&self) -> RoutingFees {
1118+
/// Returns the fees for this hop.
1119+
pub fn fees(&self) -> RoutingFees {
11041120
match self {
11051121
CandidateRouteHop::FirstHop { .. } => RoutingFees {
11061122
base_msat: 0, proportional_millionths: 0,
@@ -1164,7 +1180,7 @@ impl<'a> CandidateRouteHop<'a> {
11641180
CandidateRouteHop::PublicHop { source_node_id, .. } => *source_node_id,
11651181
CandidateRouteHop::PrivateHop { hint, .. } => hint.src_node_id.into(),
11661182
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(),
11681184
}
11691185
}
11701186
/// Returns the target node id of this hop, if known.
@@ -1183,10 +1199,10 @@ impl<'a> CandidateRouteHop<'a> {
11831199
}
11841200
}
11851201

1186-
/// Represents a hop id in a potential route.
1202+
/// A wrapper around the various hop id representations.
11871203
///
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`.
11901206
#[derive(Clone, Copy, Eq, Hash, Ord, PartialOrd, PartialEq)]
11911207
pub enum CandidateHopId {
11921208
/// Contains (scid, src_node_id < target_node_id)
@@ -1791,7 +1807,7 @@ where L::Target: Logger {
17911807
let mut num_ignored_htlc_minimum_msat_limit: u32 = 0;
17921808

17931809
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.
17951811
// $next_hops_fee_msat represents the fees paid for using all the channels *after* this one,
17961812
// since that value has to be transferred over this channel.
17971813
// Returns the contribution amount of $candidate if the channel caused an update to `targets`.
@@ -1807,7 +1823,7 @@ where L::Target: Logger {
18071823
// - for first and last hops early in get_route
18081824
let src_node_id = $candidate.source();
18091825
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() {
18111827
let scid_opt = $candidate.short_channel_id();
18121828
let effective_capacity = $candidate.effective_capacity();
18131829
let htlc_maximum_msat = max_htlc_from_capacity(effective_capacity, channel_saturation_pow_half);
@@ -1922,7 +1938,7 @@ where L::Target: Logger {
19221938
// (recall it goes payee-to-payer) of short_channel_id, first add a
19231939
// semi-dummy record just to compute the fees to reach the source node.
19241940
// 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.
19261942
PathBuildingHop {
19271943
node_id: dest_node_id.clone(),
19281944
candidate: $candidate.clone(),
@@ -1972,9 +1988,10 @@ where L::Target: Logger {
19721988
inflight_htlc_msat: used_liquidity_msat,
19731989
effective_capacity,
19741990
};
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);
19781995
let path_penalty_msat = $next_hops_path_penalty_msat
19791996
.saturating_add(channel_penalty_msat);
19801997
let new_graph_node = RouteGraphNode {
@@ -1987,7 +2004,7 @@ where L::Target: Logger {
19872004
path_length_to_node,
19882005
};
19892006

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()),
19912008
// if this way is cheaper than the already known
19922009
// (considering the cost to "reach" this channel from the route destination,
19932010
// the cost of using this channel,
@@ -2281,7 +2298,7 @@ where L::Target: Logger {
22812298
effective_capacity: candidate.effective_capacity(),
22822299
};
22832300
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
22852302
);
22862303
aggregate_next_hops_path_penalty_msat = aggregate_next_hops_path_penalty_msat
22872304
.saturating_add(channel_penalty_msat);
@@ -2645,7 +2662,6 @@ where L::Target: Logger {
26452662
let mut paths = Vec::new();
26462663
for payment_path in selected_route {
26472664
let mut hops = Vec::with_capacity(payment_path.hops.len());
2648-
let mut prev_hop_node_id = our_node_id;
26492665
for (hop, node_features) in payment_path.hops.iter()
26502666
.filter(|(h, _)| h.candidate.short_channel_id().is_some())
26512667
{
@@ -2662,7 +2678,7 @@ where L::Target: Logger {
26622678
// an alias, in which case we don't take any chances here.
26632679
network_graph.node(&hop.node_id).map_or(false, |hop_node|
26642680
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()))
26662682
)
26672683
};
26682684

@@ -2675,8 +2691,6 @@ where L::Target: Logger {
26752691
cltv_expiry_delta: hop.candidate.cltv_expiry_delta(),
26762692
maybe_announced_channel,
26772693
});
2678-
2679-
prev_hop_node_id = hop.node_id;
26802694
}
26812695
let mut final_cltv_delta = final_cltv_expiry_delta;
26822696
let blinded_tail = payment_path.hops.last().and_then(|(h, _)| {
@@ -2839,13 +2853,13 @@ fn build_route_from_hops_internal<L: Deref>(
28392853

28402854
impl ScoreLookUp for HopScorer {
28412855
type ScoreParams = ();
2842-
fn channel_penalty_msat(&self, _short_channel_id: u64, source: &NodeId, target: &NodeId,
2856+
fn channel_penalty_msat(&self, candidate: &CandidateRouteHop,
28432857
_usage: ChannelUsage, _score_params: &Self::ScoreParams) -> u64
28442858
{
28452859
let mut cur_id = self.our_node_id;
28462860
for i in 0..self.hop_ids.len() {
28472861
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() {
28492863
return 0;
28502864
}
28512865
cur_id = next_id;
@@ -2921,6 +2935,8 @@ mod tests {
29212935

29222936
use core::convert::TryInto;
29232937

2938+
use super::CandidateRouteHop;
2939+
29242940
fn get_channel_details(short_channel_id: Option<u64>, node_id: PublicKey,
29252941
features: InitFeatures, outbound_capacity_msat: u64) -> channelmanager::ChannelDetails {
29262942
channelmanager::ChannelDetails {
@@ -6193,7 +6209,11 @@ mod tests {
61936209
}
61946210
impl ScoreLookUp for BadChannelScorer {
61956211
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+
};
61976217
if short_channel_id == self.short_channel_id { u64::max_value() } else { 0 }
61986218
}
61996219
}
@@ -6209,8 +6229,8 @@ mod tests {
62096229

62106230
impl ScoreLookUp for BadNodeScorer {
62116231
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 }
62146234
}
62156235
}
62166236

@@ -6698,26 +6718,34 @@ mod tests {
66986718
};
66996719
scorer_params.set_manual_penalty(&NodeId::from_pubkey(&nodes[3]), 123);
67006720
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);
67026732

67036733
// Then check we can get a normal route
67046734
let payment_params = PaymentParameters::from_node_id(nodes[10], 42);
67056735
let route_params = RouteParameters::from_payment_params_and_value(
67066736
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,
67086738
Arc::clone(&logger), &scorer, &scorer_params, &random_seed_bytes);
67096739
assert!(route.is_ok());
67106740

67116741
// Then check that we can't get a route if we ban an intermediate node.
67126742
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);
67156744
assert!(route.is_err());
67166745

67176746
// Finally make sure we can route again, when we remove the ban.
67186747
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);
67216749
assert!(route.is_ok());
67226750
}
67236751

0 commit comments

Comments
 (0)