Skip to content

Commit 3601653

Browse files
committed
Add source and target functions to CandidateRouteHop
- Make methods public and add docs
1 parent 6d5c5ba commit 3601653

File tree

2 files changed

+77
-20
lines changed

2 files changed

+77
-20
lines changed

lightning/src/routing/gossip.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,8 @@ impl Readable for ChannelInfo {
977977
/// source node to a target node.
978978
#[derive(Clone)]
979979
pub struct DirectedChannelInfo<'a> {
980-
channel: &'a ChannelInfo,
980+
/// Provides information about a channel between two nodes.
981+
pub channel: &'a ChannelInfo,
981982
direction: &'a ChannelUpdateInfo,
982983
htlc_maximum_msat: u64,
983984
effective_capacity: EffectiveCapacity,

lightning/src/routing/router.rs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -968,42 +968,78 @@ impl cmp::PartialOrd for RouteGraphNode {
968968
///
969969
/// Used to construct a [`PathBuildingHop`] and to estimate [`EffectiveCapacity`].
970970
#[derive(Clone, Debug)]
971-
enum CandidateRouteHop<'a> {
971+
pub enum CandidateRouteHop<'a> {
972972
/// A hop from the payer, where the outbound liquidity is known.
973973
FirstHop {
974+
/// The channel details of the first hop.
975+
/// `get_outbound_payment_scid` is assumed to always return Some(scid) - this assumption is checked in
976+
/// `find_route` method.
974977
details: &'a ChannelDetails,
978+
/// The node id of the payer.
979+
/// Can be accessed via `source` method.
980+
node_id: NodeId
975981
},
976982
/// A hop found in the [`ReadOnlyNetworkGraph`], where the channel capacity may be unknown.
977983
PublicHop {
984+
/// The channel info of the hop.
978985
info: DirectedChannelInfo<'a>,
986+
/// The short_channel_id of the channel.
979987
short_channel_id: u64,
988+
/// The node id of the current hop in route.
989+
source_node_id: NodeId,
990+
/// The node id of next hop in route.
991+
target_node_id: NodeId,
980992
},
981993
/// A hop to the payee found in the BOLT 11 payment invoice, though not necessarily a direct
982994
/// channel.
983995
PrivateHop {
996+
/// Hint provides information about a private hop, needed while routing through a private
997+
/// channel.
984998
hint: &'a RouteHintHop,
999+
/// The node id of the next hop in route.
1000+
target_node_id: NodeId
9851001
},
9861002
/// The payee's identity is concealed behind blinded paths provided in a BOLT 12 invoice.
9871003
Blinded {
1004+
/// Hint provides information about a blinded hop, needed while routing through a blinded
1005+
/// channel.
1006+
/// `BlindedPayInfo` provides information needed about the
1007+
/// payment while routing through a blinded
1008+
/// path.
1009+
/// `BlindedPath` is the blinded path to the destination.
9881010
hint: &'a (BlindedPayInfo, BlindedPath),
1011+
/// The index of the hint in the original list of blinded hints.
1012+
/// Provided to uniquely identify a hop as we are
1013+
/// route building.
9891014
hint_idx: usize,
9901015
},
9911016
/// Similar to [`Self::Blinded`], but the path here has 1 blinded hop. `BlindedPayInfo` provided
9921017
/// for 1-hop blinded paths is ignored because it is meant to apply to the hops *between* the
9931018
/// introduction node and the destination. Useful for tracking that we need to include a blinded
9941019
/// path at the end of our [`Route`].
9951020
OneHopBlinded {
1021+
/// Hint provides information about a single blinded hop, needed while routing through a blinded
1022+
/// channel.
1023+
/// `BlindedPayInfo` is ignored here.
1024+
/// `BlindedPath` is the blinded path to the destination.
9961025
hint: &'a (BlindedPayInfo, BlindedPath),
1026+
/// The index of the hint in the original list of blinded hints.
1027+
/// Provided to uniquely identify a hop as we are
1028+
/// route building.
9971029
hint_idx: usize,
9981030
},
9991031
}
10001032

10011033
impl<'a> CandidateRouteHop<'a> {
1002-
fn short_channel_id(&self) -> Option<u64> {
1034+
/// Returns short_channel_id if known.
1035+
/// For `FirstHop` we assume `get_outbound_payment_scid` is always set, this assumption is checked in
1036+
/// `find_route` method.
1037+
/// For `Blinded` and `OneHopBlinded` we return None because we don't know the channel id.
1038+
pub fn short_channel_id(&self) -> Option<u64> {
10031039
match self {
1004-
CandidateRouteHop::FirstHop { details } => Some(details.get_outbound_payment_scid().unwrap()),
1040+
CandidateRouteHop::FirstHop { details, .. } => Some(details.get_outbound_payment_scid().unwrap()),
10051041
CandidateRouteHop::PublicHop { short_channel_id, .. } => Some(*short_channel_id),
1006-
CandidateRouteHop::PrivateHop { hint } => Some(hint.short_channel_id),
1042+
CandidateRouteHop::PrivateHop { hint, .. } => Some(hint.short_channel_id),
10071043
CandidateRouteHop::Blinded { .. } => None,
10081044
CandidateRouteHop::OneHopBlinded { .. } => None,
10091045
}
@@ -1012,7 +1048,7 @@ impl<'a> CandidateRouteHop<'a> {
10121048
// NOTE: This may alloc memory so avoid calling it in a hot code path.
10131049
fn features(&self) -> ChannelFeatures {
10141050
match self {
1015-
CandidateRouteHop::FirstHop { details } => details.counterparty.features.to_context(),
1051+
CandidateRouteHop::FirstHop { details, .. } => details.counterparty.features.to_context(),
10161052
CandidateRouteHop::PublicHop { info, .. } => info.channel().features.clone(),
10171053
CandidateRouteHop::PrivateHop { .. } => ChannelFeatures::empty(),
10181054
CandidateRouteHop::Blinded { .. } => ChannelFeatures::empty(),
@@ -1024,17 +1060,17 @@ impl<'a> CandidateRouteHop<'a> {
10241060
match self {
10251061
CandidateRouteHop::FirstHop { .. } => 0,
10261062
CandidateRouteHop::PublicHop { info, .. } => info.direction().cltv_expiry_delta as u32,
1027-
CandidateRouteHop::PrivateHop { hint } => hint.cltv_expiry_delta as u32,
1063+
CandidateRouteHop::PrivateHop { hint, .. } => hint.cltv_expiry_delta as u32,
10281064
CandidateRouteHop::Blinded { hint, .. } => hint.0.cltv_expiry_delta as u32,
10291065
CandidateRouteHop::OneHopBlinded { .. } => 0,
10301066
}
10311067
}
10321068

10331069
fn htlc_minimum_msat(&self) -> u64 {
10341070
match self {
1035-
CandidateRouteHop::FirstHop { details } => details.next_outbound_htlc_minimum_msat,
1071+
CandidateRouteHop::FirstHop { details, .. } => details.next_outbound_htlc_minimum_msat,
10361072
CandidateRouteHop::PublicHop { info, .. } => info.direction().htlc_minimum_msat,
1037-
CandidateRouteHop::PrivateHop { hint } => hint.htlc_minimum_msat.unwrap_or(0),
1073+
CandidateRouteHop::PrivateHop { hint, .. } => hint.htlc_minimum_msat.unwrap_or(0),
10381074
CandidateRouteHop::Blinded { hint, .. } => hint.0.htlc_minimum_msat,
10391075
CandidateRouteHop::OneHopBlinded { .. } => 0,
10401076
}
@@ -1046,7 +1082,7 @@ impl<'a> CandidateRouteHop<'a> {
10461082
base_msat: 0, proportional_millionths: 0,
10471083
},
10481084
CandidateRouteHop::PublicHop { info, .. } => info.direction().fees,
1049-
CandidateRouteHop::PrivateHop { hint } => hint.fees,
1085+
CandidateRouteHop::PrivateHop { hint, .. } => hint.fees,
10501086
CandidateRouteHop::Blinded { hint, .. } => {
10511087
RoutingFees {
10521088
base_msat: hint.0.fee_base_msat,
@@ -1060,13 +1096,13 @@ impl<'a> CandidateRouteHop<'a> {
10601096

10611097
fn effective_capacity(&self) -> EffectiveCapacity {
10621098
match self {
1063-
CandidateRouteHop::FirstHop { details } => EffectiveCapacity::ExactLiquidity {
1099+
CandidateRouteHop::FirstHop { details, .. } => EffectiveCapacity::ExactLiquidity {
10641100
liquidity_msat: details.next_outbound_htlc_limit_msat,
10651101
},
10661102
CandidateRouteHop::PublicHop { info, .. } => info.effective_capacity(),
1067-
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: Some(max), .. }} =>
1103+
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: Some(max), .. }, ..} =>
10681104
EffectiveCapacity::HintMaxHTLC { amount_msat: *max },
1069-
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: None, .. }} =>
1105+
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: None, .. }, ..} =>
10701106
EffectiveCapacity::Infinite,
10711107
CandidateRouteHop::Blinded { hint, .. } =>
10721108
EffectiveCapacity::HintMaxHTLC { amount_msat: hint.0.htlc_maximum_msat },
@@ -1089,6 +1125,26 @@ impl<'a> CandidateRouteHop<'a> {
10891125
_ => None,
10901126
}
10911127
}
1128+
/// Returns the source node id of this hop.
1129+
pub fn source(&self) -> NodeId {
1130+
match self {
1131+
CandidateRouteHop::FirstHop { node_id, .. } => *node_id,
1132+
CandidateRouteHop::PublicHop { info, .. } => info.channel.node_one.into(),
1133+
CandidateRouteHop::PrivateHop { hint, .. } => hint.src_node_id.into(),
1134+
CandidateRouteHop::Blinded { hint, .. } => hint.1.introduction_node_id.into(),
1135+
CandidateRouteHop::OneHopBlinded { hint, .. } => hint.1.introduction_node_id.into()
1136+
}
1137+
}
1138+
/// Returns the target node id of this hop, if known.
1139+
pub fn target(&self) -> Option<NodeId> {
1140+
match self {
1141+
CandidateRouteHop::FirstHop { details, .. } => Some(details.counterparty.node_id.into()),
1142+
CandidateRouteHop::PublicHop { info, .. } => Some(info.channel.node_two.into()),
1143+
CandidateRouteHop::PrivateHop { target_node_id, .. } => Some(*target_node_id),
1144+
CandidateRouteHop::Blinded { hint, .. } => Some(hint.1.blinding_point.into()),
1145+
CandidateRouteHop::OneHopBlinded { hint, .. } => Some(hint.1.blinding_point.into())
1146+
}
1147+
}
10921148
}
10931149

10941150
#[derive(Clone, Copy, Eq, Hash, Ord, PartialOrd, PartialEq)]
@@ -1132,7 +1188,7 @@ fn iter_equal<I1: Iterator, I2: Iterator>(mut iter_a: I1, mut iter_b: I2)
11321188
/// Fee values should be updated only in the context of the whole path, see update_value_and_recompute_fees.
11331189
/// These fee values are useful to choose hops as we traverse the graph "payee-to-payer".
11341190
#[derive(Clone)]
1135-
struct PathBuildingHop<'a> {
1191+
pub struct PathBuildingHop<'a> {
11361192
// Note that this should be dropped in favor of loading it from CandidateRouteHop, but doing so
11371193
// is a larger refactor and will require careful performance analysis.
11381194
node_id: NodeId,
@@ -1950,7 +2006,7 @@ where L::Target: Logger {
19502006
if !skip_node {
19512007
if let Some(first_channels) = first_hop_targets.get(&$node_id) {
19522008
for details in first_channels {
1953-
let candidate = CandidateRouteHop::FirstHop { details };
2009+
let candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id };
19542010
add_entry!(candidate, our_node_id, $node_id, $fee_to_target_msat,
19552011
$next_hops_value_contribution,
19562012
$next_hops_path_htlc_minimum_msat, $next_hops_path_penalty_msat,
@@ -2005,7 +2061,7 @@ where L::Target: Logger {
20052061
// place where it could be added.
20062062
payee_node_id_opt.map(|payee| first_hop_targets.get(&payee).map(|first_channels| {
20072063
for details in first_channels {
2008-
let candidate = CandidateRouteHop::FirstHop { details };
2064+
let candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id };
20092065
let added = add_entry!(candidate, our_node_id, payee, 0, path_value_msat,
20102066
0, 0u64, 0, 0).is_some();
20112067
log_trace!(logger, "{} direct route to payee via {}",
@@ -2052,7 +2108,7 @@ where L::Target: Logger {
20522108
sort_first_hop_channels(first_channels, &used_liquidities, recommended_value_msat,
20532109
our_node_pubkey);
20542110
for details in first_channels {
2055-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2111+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
20562112
let blinded_path_fee = match compute_fees(path_contribution_msat, candidate.fees()) {
20572113
Some(fee) => fee,
20582114
None => continue
@@ -2098,7 +2154,7 @@ where L::Target: Logger {
20982154
info,
20992155
short_channel_id: hop.short_channel_id,
21002156
})
2101-
.unwrap_or_else(|| CandidateRouteHop::PrivateHop { hint: hop });
2157+
.unwrap_or_else(|| CandidateRouteHop::PrivateHop { hint: hop, target_node_id: target });
21022158

21032159
if let Some(hop_used_msat) = add_entry!(candidate, source, target,
21042160
aggregate_next_hops_fee_msat, aggregate_path_contribution_msat,
@@ -2138,7 +2194,7 @@ where L::Target: Logger {
21382194
sort_first_hop_channels(first_channels, &used_liquidities,
21392195
recommended_value_msat, our_node_pubkey);
21402196
for details in first_channels {
2141-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2197+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
21422198
add_entry!(first_hop_candidate, our_node_id, NodeId::from_pubkey(&prev_hop_id),
21432199
aggregate_next_hops_fee_msat, aggregate_path_contribution_msat,
21442200
aggregate_next_hops_path_htlc_minimum_msat, aggregate_next_hops_path_penalty_msat,
@@ -2179,7 +2235,7 @@ where L::Target: Logger {
21792235
sort_first_hop_channels(first_channels, &used_liquidities,
21802236
recommended_value_msat, our_node_pubkey);
21812237
for details in first_channels {
2182-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2238+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
21832239
add_entry!(first_hop_candidate, our_node_id,
21842240
NodeId::from_pubkey(&hop.src_node_id),
21852241
aggregate_next_hops_fee_msat,

0 commit comments

Comments
 (0)