Skip to content

Commit 2d0c66b

Browse files
committed
Add source and target functions to CandidateRouteHop
- Make methods public and add docs
1 parent a7e3575 commit 2d0c66b

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
@@ -978,42 +978,78 @@ impl cmp::PartialOrd for RouteGraphNode {
978978
///
979979
/// Used to construct a [`PathBuildingHop`] and to estimate [`EffectiveCapacity`].
980980
#[derive(Clone, Debug)]
981-
enum CandidateRouteHop<'a> {
981+
pub enum CandidateRouteHop<'a> {
982982
/// A hop from the payer, where the outbound liquidity is known.
983983
FirstHop {
984+
/// The channel details of the first hop.
985+
/// `get_outbound_payment_scid` is assumed to always return Some(scid) - this assumption is checked in
986+
/// `find_route` method.
984987
details: &'a ChannelDetails,
988+
/// The node id of the payer.
989+
/// Can be accessed via `source` method.
990+
node_id: NodeId
985991
},
986992
/// A hop found in the [`ReadOnlyNetworkGraph`], where the channel capacity may be unknown.
987993
PublicHop {
994+
/// The channel info of the hop.
988995
info: DirectedChannelInfo<'a>,
996+
/// The short_channel_id of the channel.
989997
short_channel_id: u64,
998+
/// The node id of the current hop in route.
999+
source_node_id: NodeId,
1000+
/// The node id of next hop in route.
1001+
target_node_id: NodeId,
9901002
},
9911003
/// A hop to the payee found in the BOLT 11 payment invoice, though not necessarily a direct
9921004
/// channel.
9931005
PrivateHop {
1006+
/// Hint provides information about a private hop, needed while routing through a private
1007+
/// channel.
9941008
hint: &'a RouteHintHop,
1009+
/// The node id of the next hop in route.
1010+
target_node_id: NodeId
9951011
},
9961012
/// The payee's identity is concealed behind blinded paths provided in a BOLT 12 invoice.
9971013
Blinded {
1014+
/// Hint provides information about a blinded hop, needed while routing through a blinded
1015+
/// channel.
1016+
/// `BlindedPayInfo` provides information needed about the
1017+
/// payment while routing through a blinded
1018+
/// path.
1019+
/// `BlindedPath` is the blinded path to the destination.
9981020
hint: &'a (BlindedPayInfo, BlindedPath),
1021+
/// The index of the hint in the original list of blinded hints.
1022+
/// Provided to uniquely identify a hop as we are
1023+
/// route building.
9991024
hint_idx: usize,
10001025
},
10011026
/// Similar to [`Self::Blinded`], but the path here has 1 blinded hop. `BlindedPayInfo` provided
10021027
/// for 1-hop blinded paths is ignored because it is meant to apply to the hops *between* the
10031028
/// introduction node and the destination. Useful for tracking that we need to include a blinded
10041029
/// path at the end of our [`Route`].
10051030
OneHopBlinded {
1031+
/// Hint provides information about a single blinded hop, needed while routing through a blinded
1032+
/// channel.
1033+
/// `BlindedPayInfo` is ignored here.
1034+
/// `BlindedPath` is the blinded path to the destination.
10061035
hint: &'a (BlindedPayInfo, BlindedPath),
1036+
/// The index of the hint in the original list of blinded hints.
1037+
/// Provided to uniquely identify a hop as we are
1038+
/// route building.
10071039
hint_idx: usize,
10081040
},
10091041
}
10101042

10111043
impl<'a> CandidateRouteHop<'a> {
1012-
fn short_channel_id(&self) -> Option<u64> {
1044+
/// Returns short_channel_id if known.
1045+
/// For `FirstHop` we assume `get_outbound_payment_scid` is always set, this assumption is checked in
1046+
/// `find_route` method.
1047+
/// For `Blinded` and `OneHopBlinded` we return None because we don't know the channel id.
1048+
pub fn short_channel_id(&self) -> Option<u64> {
10131049
match self {
1014-
CandidateRouteHop::FirstHop { details } => Some(details.get_outbound_payment_scid().unwrap()),
1050+
CandidateRouteHop::FirstHop { details, .. } => Some(details.get_outbound_payment_scid().unwrap()),
10151051
CandidateRouteHop::PublicHop { short_channel_id, .. } => Some(*short_channel_id),
1016-
CandidateRouteHop::PrivateHop { hint } => Some(hint.short_channel_id),
1052+
CandidateRouteHop::PrivateHop { hint, .. } => Some(hint.short_channel_id),
10171053
CandidateRouteHop::Blinded { .. } => None,
10181054
CandidateRouteHop::OneHopBlinded { .. } => None,
10191055
}
@@ -1022,7 +1058,7 @@ impl<'a> CandidateRouteHop<'a> {
10221058
// NOTE: This may alloc memory so avoid calling it in a hot code path.
10231059
fn features(&self) -> ChannelFeatures {
10241060
match self {
1025-
CandidateRouteHop::FirstHop { details } => details.counterparty.features.to_context(),
1061+
CandidateRouteHop::FirstHop { details, .. } => details.counterparty.features.to_context(),
10261062
CandidateRouteHop::PublicHop { info, .. } => info.channel().features.clone(),
10271063
CandidateRouteHop::PrivateHop { .. } => ChannelFeatures::empty(),
10281064
CandidateRouteHop::Blinded { .. } => ChannelFeatures::empty(),
@@ -1034,17 +1070,17 @@ impl<'a> CandidateRouteHop<'a> {
10341070
match self {
10351071
CandidateRouteHop::FirstHop { .. } => 0,
10361072
CandidateRouteHop::PublicHop { info, .. } => info.direction().cltv_expiry_delta as u32,
1037-
CandidateRouteHop::PrivateHop { hint } => hint.cltv_expiry_delta as u32,
1073+
CandidateRouteHop::PrivateHop { hint, .. } => hint.cltv_expiry_delta as u32,
10381074
CandidateRouteHop::Blinded { hint, .. } => hint.0.cltv_expiry_delta as u32,
10391075
CandidateRouteHop::OneHopBlinded { .. } => 0,
10401076
}
10411077
}
10421078

10431079
fn htlc_minimum_msat(&self) -> u64 {
10441080
match self {
1045-
CandidateRouteHop::FirstHop { details } => details.next_outbound_htlc_minimum_msat,
1081+
CandidateRouteHop::FirstHop { details, .. } => details.next_outbound_htlc_minimum_msat,
10461082
CandidateRouteHop::PublicHop { info, .. } => info.direction().htlc_minimum_msat,
1047-
CandidateRouteHop::PrivateHop { hint } => hint.htlc_minimum_msat.unwrap_or(0),
1083+
CandidateRouteHop::PrivateHop { hint, .. } => hint.htlc_minimum_msat.unwrap_or(0),
10481084
CandidateRouteHop::Blinded { hint, .. } => hint.0.htlc_minimum_msat,
10491085
CandidateRouteHop::OneHopBlinded { .. } => 0,
10501086
}
@@ -1056,7 +1092,7 @@ impl<'a> CandidateRouteHop<'a> {
10561092
base_msat: 0, proportional_millionths: 0,
10571093
},
10581094
CandidateRouteHop::PublicHop { info, .. } => info.direction().fees,
1059-
CandidateRouteHop::PrivateHop { hint } => hint.fees,
1095+
CandidateRouteHop::PrivateHop { hint, .. } => hint.fees,
10601096
CandidateRouteHop::Blinded { hint, .. } => {
10611097
RoutingFees {
10621098
base_msat: hint.0.fee_base_msat,
@@ -1070,13 +1106,13 @@ impl<'a> CandidateRouteHop<'a> {
10701106

10711107
fn effective_capacity(&self) -> EffectiveCapacity {
10721108
match self {
1073-
CandidateRouteHop::FirstHop { details } => EffectiveCapacity::ExactLiquidity {
1109+
CandidateRouteHop::FirstHop { details, .. } => EffectiveCapacity::ExactLiquidity {
10741110
liquidity_msat: details.next_outbound_htlc_limit_msat,
10751111
},
10761112
CandidateRouteHop::PublicHop { info, .. } => info.effective_capacity(),
1077-
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: Some(max), .. }} =>
1113+
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: Some(max), .. }, ..} =>
10781114
EffectiveCapacity::HintMaxHTLC { amount_msat: *max },
1079-
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: None, .. }} =>
1115+
CandidateRouteHop::PrivateHop { hint: RouteHintHop { htlc_maximum_msat: None, .. }, ..} =>
10801116
EffectiveCapacity::Infinite,
10811117
CandidateRouteHop::Blinded { hint, .. } =>
10821118
EffectiveCapacity::HintMaxHTLC { amount_msat: hint.0.htlc_maximum_msat },
@@ -1099,6 +1135,26 @@ impl<'a> CandidateRouteHop<'a> {
10991135
_ => None,
11001136
}
11011137
}
1138+
/// Returns the source node id of this hop.
1139+
pub fn source(&self) -> NodeId {
1140+
match self {
1141+
CandidateRouteHop::FirstHop { node_id, .. } => *node_id,
1142+
CandidateRouteHop::PublicHop { info, .. } => info.channel.node_one.into(),
1143+
CandidateRouteHop::PrivateHop { hint, .. } => hint.src_node_id.into(),
1144+
CandidateRouteHop::Blinded { hint, .. } => hint.1.introduction_node_id.into(),
1145+
CandidateRouteHop::OneHopBlinded { hint, .. } => hint.1.introduction_node_id.into()
1146+
}
1147+
}
1148+
/// Returns the target node id of this hop, if known.
1149+
pub fn target(&self) -> Option<NodeId> {
1150+
match self {
1151+
CandidateRouteHop::FirstHop { details, .. } => Some(details.counterparty.node_id.into()),
1152+
CandidateRouteHop::PublicHop { info, .. } => Some(info.channel.node_two.into()),
1153+
CandidateRouteHop::PrivateHop { target_node_id, .. } => Some(*target_node_id),
1154+
CandidateRouteHop::Blinded { hint, .. } => Some(hint.1.blinding_point.into()),
1155+
CandidateRouteHop::OneHopBlinded { hint, .. } => Some(hint.1.blinding_point.into())
1156+
}
1157+
}
11021158
}
11031159

11041160
#[derive(Clone, Copy, Eq, Hash, Ord, PartialOrd, PartialEq)]
@@ -1142,7 +1198,7 @@ fn iter_equal<I1: Iterator, I2: Iterator>(mut iter_a: I1, mut iter_b: I2)
11421198
/// Fee values should be updated only in the context of the whole path, see update_value_and_recompute_fees.
11431199
/// These fee values are useful to choose hops as we traverse the graph "payee-to-payer".
11441200
#[derive(Clone)]
1145-
struct PathBuildingHop<'a> {
1201+
pub struct PathBuildingHop<'a> {
11461202
// Note that this should be dropped in favor of loading it from CandidateRouteHop, but doing so
11471203
// is a larger refactor and will require careful performance analysis.
11481204
node_id: NodeId,
@@ -1960,7 +2016,7 @@ where L::Target: Logger {
19602016
if !skip_node {
19612017
if let Some(first_channels) = first_hop_targets.get(&$node_id) {
19622018
for details in first_channels {
1963-
let candidate = CandidateRouteHop::FirstHop { details };
2019+
let candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id };
19642020
add_entry!(candidate, our_node_id, $node_id, $fee_to_target_msat,
19652021
$next_hops_value_contribution,
19662022
$next_hops_path_htlc_minimum_msat, $next_hops_path_penalty_msat,
@@ -2015,7 +2071,7 @@ where L::Target: Logger {
20152071
// place where it could be added.
20162072
payee_node_id_opt.map(|payee| first_hop_targets.get(&payee).map(|first_channels| {
20172073
for details in first_channels {
2018-
let candidate = CandidateRouteHop::FirstHop { details };
2074+
let candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id };
20192075
let added = add_entry!(candidate, our_node_id, payee, 0, path_value_msat,
20202076
0, 0u64, 0, 0).is_some();
20212077
log_trace!(logger, "{} direct route to payee via {}",
@@ -2062,7 +2118,7 @@ where L::Target: Logger {
20622118
sort_first_hop_channels(first_channels, &used_liquidities, recommended_value_msat,
20632119
our_node_pubkey);
20642120
for details in first_channels {
2065-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2121+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
20662122
let blinded_path_fee = match compute_fees(path_contribution_msat, candidate.fees()) {
20672123
Some(fee) => fee,
20682124
None => continue
@@ -2108,7 +2164,7 @@ where L::Target: Logger {
21082164
info,
21092165
short_channel_id: hop.short_channel_id,
21102166
})
2111-
.unwrap_or_else(|| CandidateRouteHop::PrivateHop { hint: hop });
2167+
.unwrap_or_else(|| CandidateRouteHop::PrivateHop { hint: hop, target_node_id: target });
21122168

21132169
if let Some(hop_used_msat) = add_entry!(candidate, source, target,
21142170
aggregate_next_hops_fee_msat, aggregate_path_contribution_msat,
@@ -2148,7 +2204,7 @@ where L::Target: Logger {
21482204
sort_first_hop_channels(first_channels, &used_liquidities,
21492205
recommended_value_msat, our_node_pubkey);
21502206
for details in first_channels {
2151-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2207+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
21522208
add_entry!(first_hop_candidate, our_node_id, NodeId::from_pubkey(&prev_hop_id),
21532209
aggregate_next_hops_fee_msat, aggregate_path_contribution_msat,
21542210
aggregate_next_hops_path_htlc_minimum_msat, aggregate_next_hops_path_penalty_msat,
@@ -2189,7 +2245,7 @@ where L::Target: Logger {
21892245
sort_first_hop_channels(first_channels, &used_liquidities,
21902246
recommended_value_msat, our_node_pubkey);
21912247
for details in first_channels {
2192-
let first_hop_candidate = CandidateRouteHop::FirstHop { details };
2248+
let first_hop_candidate = CandidateRouteHop::FirstHop { details, node_id: our_node_id};
21932249
add_entry!(first_hop_candidate, our_node_id,
21942250
NodeId::from_pubkey(&hop.src_node_id),
21952251
aggregate_next_hops_fee_msat,

0 commit comments

Comments
 (0)