Skip to content

Commit a2f2735

Browse files
committed
Add source reference to BlindedPathCandidate hop
Blinded paths currently contain a node id for the introduction node. However, a compact representation will allow a directed short channel id instead. Update BlindedPathCandidate and OneHopBlindedPathCandidate to store a NodeId reference from either the NetworkGraph or from the user- provided first hops. This approach avoids looking up the introduction node id on demand, which may not be resolvable. Thus, that would require returning an Option from CandidateRouteHop::source and handle None accordingly.
1 parent 69a7bb2 commit a2f2735

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

lightning/src/routing/router.rs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,11 @@ pub struct PrivateHopCandidate<'a> {
11811181
/// A [`CandidateRouteHop::Blinded`] entry.
11821182
#[derive(Clone, Debug)]
11831183
pub struct BlindedPathCandidate<'a> {
1184+
/// The node id of the introduction node, resolved from either the [`NetworkGraph`] or first
1185+
/// hops.
1186+
///
1187+
/// This is not exported to bindings users as lifetimes are not expressable in most languages.
1188+
pub source_node_id: &'a NodeId,
11841189
/// Information about the blinded path including the fee, HTLC amount limits, and
11851190
/// cryptographic material required to build an HTLC through the given path.
11861191
///
@@ -1196,6 +1201,11 @@ pub struct BlindedPathCandidate<'a> {
11961201
/// A [`CandidateRouteHop::OneHopBlinded`] entry.
11971202
#[derive(Clone, Debug)]
11981203
pub struct OneHopBlindedPathCandidate<'a> {
1204+
/// The node id of the introduction node, resolved from either the [`NetworkGraph`] or first
1205+
/// hops.
1206+
///
1207+
/// This is not exported to bindings users as lifetimes are not expressable in most languages.
1208+
pub source_node_id: &'a NodeId,
11991209
/// Information about the blinded path including the fee, HTLC amount limits, and
12001210
/// cryptographic material required to build an HTLC terminating with the given path.
12011211
///
@@ -1409,8 +1419,8 @@ impl<'a> CandidateRouteHop<'a> {
14091419
CandidateRouteHop::FirstHop(hop) => *hop.payer_node_id,
14101420
CandidateRouteHop::PublicHop(hop) => *hop.info.source(),
14111421
CandidateRouteHop::PrivateHop(hop) => hop.hint.src_node_id.into(),
1412-
CandidateRouteHop::Blinded(hop) => hop.hint.1.introduction_node_id.into(),
1413-
CandidateRouteHop::OneHopBlinded(hop) => hop.hint.1.introduction_node_id.into(),
1422+
CandidateRouteHop::Blinded(hop) => *hop.source_node_id,
1423+
CandidateRouteHop::OneHopBlinded(hop) => *hop.source_node_id,
14141424
}
14151425
}
14161426
/// Returns the target node id of this hop, if known.
@@ -2515,26 +2525,38 @@ where L::Target: Logger {
25152525
// earlier than general path finding, they will be somewhat prioritized, although currently
25162526
// it matters only if the fees are exactly the same.
25172527
for (hint_idx, hint) in payment_params.payee.blinded_route_hints().iter().enumerate() {
2518-
let intro_node_id = NodeId::from_pubkey(&hint.1.introduction_node_id);
2519-
let have_intro_node_in_graph =
2520-
// Only add the hops in this route to our candidate set if either
2521-
// we have a direct channel to the first hop or the first hop is
2522-
// in the regular network graph.
2523-
first_hop_targets.get(&intro_node_id).is_some() ||
2524-
network_nodes.get(&intro_node_id).is_some();
2525-
if !have_intro_node_in_graph || our_node_id == intro_node_id { continue }
2528+
// Only add the hops in this route to our candidate set if either
2529+
// we have a direct channel to the first hop or the first hop is
2530+
// in the regular network graph.
2531+
let source_node_id = match hint.1.introduction_node_id(network_graph) {
2532+
Some(node_id) => node_id,
2533+
None => {
2534+
let node_id = NodeId::from_pubkey(&hint.1.introduction_node_id);
2535+
match first_hop_targets.get_key_value(&node_id).map(|(key, _)| key) {
2536+
Some(node_id) => node_id,
2537+
None => continue,
2538+
}
2539+
},
2540+
};
2541+
if our_node_id == *source_node_id { continue }
25262542
let candidate = if hint.1.blinded_hops.len() == 1 {
2527-
CandidateRouteHop::OneHopBlinded(OneHopBlindedPathCandidate { hint, hint_idx })
2528-
} else { CandidateRouteHop::Blinded(BlindedPathCandidate { hint, hint_idx }) };
2543+
CandidateRouteHop::OneHopBlinded(
2544+
OneHopBlindedPathCandidate { source_node_id, hint, hint_idx }
2545+
)
2546+
} else {
2547+
CandidateRouteHop::Blinded(BlindedPathCandidate { source_node_id, hint, hint_idx })
2548+
};
25292549
let mut path_contribution_msat = path_value_msat;
25302550
if let Some(hop_used_msat) = add_entry!(&candidate,
25312551
0, path_contribution_msat, 0, 0_u64, 0, 0)
25322552
{
25332553
path_contribution_msat = hop_used_msat;
25342554
} else { continue }
2535-
if let Some(first_channels) = first_hop_targets.get_mut(&NodeId::from_pubkey(&hint.1.introduction_node_id)) {
2536-
sort_first_hop_channels(first_channels, &used_liquidities, recommended_value_msat,
2537-
our_node_pubkey);
2555+
if let Some(first_channels) = first_hop_targets.get(source_node_id) {
2556+
let mut first_channels = first_channels.clone();
2557+
sort_first_hop_channels(
2558+
&mut first_channels, &used_liquidities, recommended_value_msat, our_node_pubkey
2559+
);
25382560
for details in first_channels {
25392561
let first_hop_candidate = CandidateRouteHop::FirstHop(FirstHopCandidate {
25402562
details, payer_node_id: &our_node_id,
@@ -2630,9 +2652,11 @@ where L::Target: Logger {
26302652
.saturating_add(1);
26312653

26322654
// Searching for a direct channel between last checked hop and first_hop_targets
2633-
if let Some(first_channels) = first_hop_targets.get_mut(target) {
2634-
sort_first_hop_channels(first_channels, &used_liquidities,
2635-
recommended_value_msat, our_node_pubkey);
2655+
if let Some(first_channels) = first_hop_targets.get(target) {
2656+
let mut first_channels = first_channels.clone();
2657+
sort_first_hop_channels(
2658+
&mut first_channels, &used_liquidities, recommended_value_msat, our_node_pubkey
2659+
);
26362660
for details in first_channels {
26372661
let first_hop_candidate = CandidateRouteHop::FirstHop(FirstHopCandidate {
26382662
details, payer_node_id: &our_node_id,
@@ -2677,9 +2701,11 @@ where L::Target: Logger {
26772701
// Note that we *must* check if the last hop was added as `add_entry`
26782702
// always assumes that the third argument is a node to which we have a
26792703
// path.
2680-
if let Some(first_channels) = first_hop_targets.get_mut(&NodeId::from_pubkey(&hop.src_node_id)) {
2681-
sort_first_hop_channels(first_channels, &used_liquidities,
2682-
recommended_value_msat, our_node_pubkey);
2704+
if let Some(first_channels) = first_hop_targets.get(&NodeId::from_pubkey(&hop.src_node_id)) {
2705+
let mut first_channels = first_channels.clone();
2706+
sort_first_hop_channels(
2707+
&mut first_channels, &used_liquidities, recommended_value_msat, our_node_pubkey
2708+
);
26832709
for details in first_channels {
26842710
let first_hop_candidate = CandidateRouteHop::FirstHop(FirstHopCandidate {
26852711
details, payer_node_id: &our_node_id,

0 commit comments

Comments
 (0)