Skip to content

Commit 4f5e17b

Browse files
committed
Move blinded path introduction point resolution to a helper method
This marginally reduces the size of `get_route` by moving a the blinded path introduction point resolution and blinded path checks into a helper method.
1 parent 5fb6637 commit 4f5e17b

File tree

1 file changed

+76
-61
lines changed

1 file changed

+76
-61
lines changed

lightning/src/routing/router.rs

Lines changed: 76 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,79 @@ impl<'a> NodeCounters<'a> {
16351635
}
16361636
}
16371637

1638+
/// Calculates the introduction point for each blinded path in the given [`PaymentParameters`], if
1639+
/// they can be found.
1640+
fn calculate_blinded_path_intro_points<'a, L: Deref>(
1641+
payment_params: &PaymentParameters, node_counters: &'a NodeCounters,
1642+
network_graph: &ReadOnlyNetworkGraph, logger: &L, our_node_id: NodeId,
1643+
first_hop_targets: &HashMap<NodeId, (Vec<&ChannelDetails>, u32)>,
1644+
) -> Result<Vec<Option<(&'a NodeId, u32)>>, LightningError>
1645+
where L::Target: Logger {
1646+
let introduction_node_id_cache = payment_params.payee.blinded_route_hints().iter()
1647+
.map(|(_, path)| {
1648+
match &path.introduction_node {
1649+
IntroductionNode::NodeId(pubkey) => {
1650+
// Note that this will only return `Some` if the `pubkey` is somehow known to
1651+
// us (i.e. a channel counterparty or in the network graph).
1652+
node_counters.node_counter_from_id(&NodeId::from_pubkey(&pubkey))
1653+
},
1654+
IntroductionNode::DirectedShortChannelId(direction, scid) => {
1655+
path.public_introduction_node_id(network_graph)
1656+
.map(|node_id_ref| *node_id_ref)
1657+
.or_else(|| {
1658+
first_hop_targets.iter().find(|(_, (channels, _))|
1659+
channels
1660+
.iter()
1661+
.any(|details| Some(*scid) == details.get_outbound_payment_scid())
1662+
).map(|(cp, _)| direction.select_node_id(our_node_id, *cp))
1663+
})
1664+
.and_then(|node_id| node_counters.node_counter_from_id(&node_id))
1665+
},
1666+
}
1667+
})
1668+
.collect::<Vec<_>>();
1669+
match &payment_params.payee {
1670+
Payee::Clear { route_hints, node_id, .. } => {
1671+
for route in route_hints.iter() {
1672+
for hop in &route.0 {
1673+
if hop.src_node_id == *node_id {
1674+
return Err(LightningError {
1675+
err: "Route hint cannot have the payee as the source.".to_owned(),
1676+
action: ErrorAction::IgnoreError
1677+
});
1678+
}
1679+
}
1680+
}
1681+
},
1682+
Payee::Blinded { route_hints, .. } => {
1683+
if introduction_node_id_cache.iter().all(|info_opt| info_opt.map(|(a, _)| a) == Some(&our_node_id)) {
1684+
return Err(LightningError{err: "Cannot generate a route to blinded paths if we are the introduction node to all of them".to_owned(), action: ErrorAction::IgnoreError});
1685+
}
1686+
for ((_, blinded_path), info_opt) in route_hints.iter().zip(introduction_node_id_cache.iter()) {
1687+
if blinded_path.blinded_hops.len() == 0 {
1688+
return Err(LightningError{err: "0-hop blinded path provided".to_owned(), action: ErrorAction::IgnoreError});
1689+
}
1690+
let introduction_node_id = match info_opt {
1691+
None => continue,
1692+
Some(info) => info.0,
1693+
};
1694+
if *introduction_node_id == our_node_id {
1695+
log_info!(logger, "Got blinded path with ourselves as the introduction node, ignoring");
1696+
} else if blinded_path.blinded_hops.len() == 1 &&
1697+
route_hints
1698+
.iter().zip(introduction_node_id_cache.iter())
1699+
.filter(|((_, p), _)| p.blinded_hops.len() == 1)
1700+
.any(|(_, iter_info_opt)| iter_info_opt.is_some() && iter_info_opt != info_opt)
1701+
{
1702+
return Err(LightningError{err: format!("1-hop blinded paths must all have matching introduction node ids"), action: ErrorAction::IgnoreError});
1703+
}
1704+
}
1705+
}
1706+
}
1707+
1708+
Ok(introduction_node_id_cache)
1709+
}
1710+
16381711
#[inline]
16391712
fn max_htlc_from_capacity(capacity: EffectiveCapacity, max_channel_saturation_power_of_half: u8) -> u64 {
16401713
let saturation_shift: u32 = max_channel_saturation_power_of_half as u32;
@@ -2183,67 +2256,9 @@ where L::Target: Logger {
21832256

21842257
let node_counters = node_counter_builder.build();
21852258

2186-
let introduction_node_id_cache = payment_params.payee.blinded_route_hints().iter()
2187-
.map(|(_, path)| {
2188-
match &path.introduction_node {
2189-
IntroductionNode::NodeId(pubkey) => {
2190-
// Note that this will only return `Some` if the `pubkey` is somehow known to
2191-
// us (i.e. a channel counterparty or in the network graph).
2192-
node_counters.node_counter_from_id(&NodeId::from_pubkey(&pubkey))
2193-
},
2194-
IntroductionNode::DirectedShortChannelId(direction, scid) => {
2195-
path.public_introduction_node_id(network_graph)
2196-
.map(|node_id_ref| *node_id_ref)
2197-
.or_else(|| {
2198-
first_hop_targets.iter().find(|(_, (channels, _))|
2199-
channels
2200-
.iter()
2201-
.any(|details| Some(*scid) == details.get_outbound_payment_scid())
2202-
).map(|(cp, _)| direction.select_node_id(our_node_id, *cp))
2203-
})
2204-
.and_then(|node_id| node_counters.node_counter_from_id(&node_id))
2205-
},
2206-
}
2207-
})
2208-
.collect::<Vec<_>>();
2209-
match &payment_params.payee {
2210-
Payee::Clear { route_hints, node_id, .. } => {
2211-
for route in route_hints.iter() {
2212-
for hop in &route.0 {
2213-
if hop.src_node_id == *node_id {
2214-
return Err(LightningError {
2215-
err: "Route hint cannot have the payee as the source.".to_owned(),
2216-
action: ErrorAction::IgnoreError
2217-
});
2218-
}
2219-
}
2220-
}
2221-
},
2222-
Payee::Blinded { route_hints, .. } => {
2223-
if introduction_node_id_cache.iter().all(|info_opt| info_opt.map(|(a, _)| a) == Some(&our_node_id)) {
2224-
return Err(LightningError{err: "Cannot generate a route to blinded paths if we are the introduction node to all of them".to_owned(), action: ErrorAction::IgnoreError});
2225-
}
2226-
for ((_, blinded_path), info_opt) in route_hints.iter().zip(introduction_node_id_cache.iter()) {
2227-
if blinded_path.blinded_hops.len() == 0 {
2228-
return Err(LightningError{err: "0-hop blinded path provided".to_owned(), action: ErrorAction::IgnoreError});
2229-
}
2230-
let introduction_node_id = match info_opt {
2231-
None => continue,
2232-
Some(info) => info.0,
2233-
};
2234-
if *introduction_node_id == our_node_id {
2235-
log_info!(logger, "Got blinded path with ourselves as the introduction node, ignoring");
2236-
} else if blinded_path.blinded_hops.len() == 1 &&
2237-
route_hints
2238-
.iter().zip(introduction_node_id_cache.iter())
2239-
.filter(|((_, p), _)| p.blinded_hops.len() == 1)
2240-
.any(|(_, iter_info_opt)| iter_info_opt.is_some() && iter_info_opt != info_opt)
2241-
{
2242-
return Err(LightningError{err: format!("1-hop blinded paths must all have matching introduction node ids"), action: ErrorAction::IgnoreError});
2243-
}
2244-
}
2245-
}
2246-
}
2259+
let introduction_node_id_cache = calculate_blinded_path_intro_points(
2260+
&payment_params, &node_counters, network_graph, &logger, our_node_id, &first_hop_targets,
2261+
)?;
22472262

22482263
// The main heap containing all candidate next-hops sorted by their score (max(fee,
22492264
// htlc_minimum)). Ideally this would be a heap which allowed cheap score reduction instead of

0 commit comments

Comments
 (0)