Skip to content

Commit 5684f46

Browse files
Update CandidateRouteHop::short_channel_id to be optional
1 parent 812aaec commit 5684f46

File tree

1 file changed

+51
-33
lines changed

1 file changed

+51
-33
lines changed

lightning/src/routing/router.rs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -938,11 +938,11 @@ enum CandidateRouteHop<'a> {
938938
}
939939

940940
impl<'a> CandidateRouteHop<'a> {
941-
fn short_channel_id(&self) -> u64 {
941+
fn short_channel_id(&self) -> Option<u64> {
942942
match self {
943-
CandidateRouteHop::FirstHop { details } => details.get_outbound_payment_scid().unwrap(),
944-
CandidateRouteHop::PublicHop { short_channel_id, .. } => *short_channel_id,
945-
CandidateRouteHop::PrivateHop { hint } => hint.short_channel_id,
943+
CandidateRouteHop::FirstHop { details } => Some(details.get_outbound_payment_scid().unwrap()),
944+
CandidateRouteHop::PublicHop { short_channel_id, .. } => Some(*short_channel_id),
945+
CandidateRouteHop::PrivateHop { hint } => Some(hint.short_channel_id),
946946
}
947947
}
948948

@@ -994,7 +994,9 @@ impl<'a> CandidateRouteHop<'a> {
994994
}
995995
}
996996
fn id(&self, channel_direction: bool /* src_node_id < target_node_id */) -> CandidateHopId {
997-
CandidateHopId::Clear((self.short_channel_id(), channel_direction))
997+
match self {
998+
_ => CandidateHopId::Clear((self.short_channel_id().unwrap(), channel_direction)),
999+
}
9981000
}
9991001
}
10001002

@@ -1245,6 +1247,18 @@ impl fmt::Display for LoggedPayeePubkey {
12451247
}
12461248
}
12471249

1250+
struct LoggedCandidateHop<'a>(&'a CandidateRouteHop<'a>);
1251+
impl<'a> fmt::Display for LoggedCandidateHop<'a> {
1252+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1253+
match self.0 {
1254+
_ => {
1255+
"SCID ".fmt(f)?;
1256+
self.0.short_channel_id().unwrap().fmt(f)
1257+
},
1258+
}
1259+
}
1260+
}
1261+
12481262
#[inline]
12491263
fn sort_first_hop_channels(
12501264
channels: &mut Vec<&ChannelDetails>, used_liquidities: &HashMap<CandidateHopId, u64>,
@@ -1549,7 +1563,7 @@ where L::Target: Logger {
15491563
// - for regular channels at channel announcement (TODO)
15501564
// - for first and last hops early in get_route
15511565
if $src_node_id != $dest_node_id {
1552-
let short_channel_id = $candidate.short_channel_id();
1566+
let scid_opt = $candidate.short_channel_id();
15531567
let effective_capacity = $candidate.effective_capacity();
15541568
let htlc_maximum_msat = max_htlc_from_capacity(effective_capacity, channel_saturation_pow_half);
15551569

@@ -1604,8 +1618,8 @@ where L::Target: Logger {
16041618
(amount_to_transfer_over_msat < $next_hops_path_htlc_minimum_msat &&
16051619
recommended_value_msat > $next_hops_path_htlc_minimum_msat));
16061620

1607-
let payment_failed_on_this_channel =
1608-
payment_params.previously_failed_channels.contains(&short_channel_id);
1621+
let payment_failed_on_this_channel = scid_opt.map_or(false,
1622+
|scid| payment_params.previously_failed_channels.contains(&scid));
16091623

16101624
// If HTLC minimum is larger than the amount we're going to transfer, we shouldn't
16111625
// bother considering this channel. If retrying with recommended_value_msat may
@@ -1674,9 +1688,9 @@ where L::Target: Logger {
16741688
inflight_htlc_msat: used_liquidity_msat,
16751689
effective_capacity,
16761690
};
1677-
let channel_penalty_msat = scorer.channel_penalty_msat(
1678-
short_channel_id, &$src_node_id, &$dest_node_id, channel_usage, score_params
1679-
);
1691+
let channel_penalty_msat = scid_opt.map_or(0,
1692+
|scid| scorer.channel_penalty_msat(scid, &$src_node_id, &$dest_node_id,
1693+
channel_usage, score_params));
16801694
let path_penalty_msat = $next_hops_path_penalty_msat
16811695
.saturating_add(channel_penalty_msat);
16821696
let new_graph_node = RouteGraphNode {
@@ -1846,8 +1860,8 @@ where L::Target: Logger {
18461860
let candidate = CandidateRouteHop::FirstHop { details };
18471861
let added = add_entry!(candidate, our_node_id, payee, 0, path_value_msat,
18481862
0, 0u64, 0, 0).is_some();
1849-
log_trace!(logger, "{} direct route to payee via SCID {}",
1850-
if added { "Added" } else { "Skipped" }, candidate.short_channel_id());
1863+
log_trace!(logger, "{} direct route to payee via {}",
1864+
if added { "Added" } else { "Skipped" }, LoggedCandidateHop(&candidate));
18511865
}
18521866
}));
18531867

@@ -2028,10 +2042,12 @@ where L::Target: Logger {
20282042
let mut features_set = false;
20292043
if let Some(first_channels) = first_hop_targets.get(&ordered_hops.last().unwrap().0.node_id) {
20302044
for details in first_channels {
2031-
if details.get_outbound_payment_scid().unwrap() == ordered_hops.last().unwrap().0.candidate.short_channel_id() {
2032-
ordered_hops.last_mut().unwrap().1 = details.counterparty.features.to_context();
2033-
features_set = true;
2034-
break;
2045+
if let Some(scid) = ordered_hops.last().unwrap().0.candidate.short_channel_id() {
2046+
if details.get_outbound_payment_scid().unwrap() == scid {
2047+
ordered_hops.last_mut().unwrap().1 = details.counterparty.features.to_context();
2048+
features_set = true;
2049+
break;
2050+
}
20352051
}
20362052
}
20372053
}
@@ -2117,11 +2133,12 @@ where L::Target: Logger {
21172133
// If we weren't capped by hitting a liquidity limit on a channel in the path,
21182134
// we'll probably end up picking the same path again on the next iteration.
21192135
// Decrease the available liquidity of a hop in the middle of the path.
2120-
let victim_scid = payment_path.hops[(payment_path.hops.len()) / 2].0.candidate.short_channel_id();
2136+
let victim_candidate = &payment_path.hops[(payment_path.hops.len()) / 2].0.candidate;
21212137
let exhausted = u64::max_value();
2122-
log_trace!(logger, "Disabling channel {} for future path building iterations to avoid duplicates.", victim_scid);
2123-
*used_liquidities.entry(CandidateHopId::Clear((victim_scid, false))).or_default() = exhausted;
2124-
*used_liquidities.entry(CandidateHopId::Clear((victim_scid, true))).or_default() = exhausted;
2138+
log_trace!(logger, "Disabling route candidate {} for future path building iterations to
2139+
avoid duplicates.", LoggedCandidateHop(victim_candidate));
2140+
*used_liquidities.entry(victim_candidate.id(false)).or_default() = exhausted;
2141+
*used_liquidities.entry(victim_candidate.id(true)).or_default() = exhausted;
21252142
}
21262143

21272144
// Track the total amount all our collected paths allow to send so that we know
@@ -2251,9 +2268,9 @@ where L::Target: Logger {
22512268
selected_route.sort_unstable_by_key(|path| {
22522269
let mut key = [0u64; MAX_PATH_LENGTH_ESTIMATE as usize];
22532270
debug_assert!(path.hops.len() <= key.len());
2254-
for (scid, key) in path.hops.iter().map(|h| h.0.candidate.short_channel_id()).zip(key.iter_mut()) {
2255-
*key = scid;
2256-
}
2271+
for (scid, key) in path.hops.iter().filter(|h| h.0.candidate.short_channel_id().is_some())
2272+
.map(|h| h.0.candidate.short_channel_id().unwrap()).zip(key.iter_mut())
2273+
{ *key = scid; }
22572274
key
22582275
});
22592276
for idx in 0..(selected_route.len() - 1) {
@@ -2268,15 +2285,16 @@ where L::Target: Logger {
22682285

22692286
let mut selected_paths = Vec::<Vec<Result<RouteHop, LightningError>>>::new();
22702287
for payment_path in selected_route {
2271-
let mut path = payment_path.hops.iter().map(|(payment_hop, node_features)| {
2272-
Ok(RouteHop {
2273-
pubkey: PublicKey::from_slice(payment_hop.node_id.as_slice()).map_err(|_| LightningError{err: format!("Public key {:?} is invalid", &payment_hop.node_id), action: ErrorAction::IgnoreAndLog(Level::Trace)})?,
2274-
node_features: node_features.clone(),
2275-
short_channel_id: payment_hop.candidate.short_channel_id(),
2276-
channel_features: payment_hop.candidate.features(),
2277-
fee_msat: payment_hop.fee_msat,
2278-
cltv_expiry_delta: payment_hop.candidate.cltv_expiry_delta(),
2279-
})
2288+
let mut path = payment_path.hops.iter().filter(|(h, _)| h.candidate.short_channel_id().is_some())
2289+
.map(|(payment_hop, node_features)| {
2290+
Ok(RouteHop {
2291+
pubkey: PublicKey::from_slice(payment_hop.node_id.as_slice()).map_err(|_| LightningError{err: format!("Public key {:?} is invalid", &payment_hop.node_id), action: ErrorAction::IgnoreAndLog(Level::Trace)})?,
2292+
node_features: node_features.clone(),
2293+
short_channel_id: payment_hop.candidate.short_channel_id().unwrap(),
2294+
channel_features: payment_hop.candidate.features(),
2295+
fee_msat: payment_hop.fee_msat,
2296+
cltv_expiry_delta: payment_hop.candidate.cltv_expiry_delta(),
2297+
})
22802298
}).collect::<Vec<_>>();
22812299
// Propagate the cltv_expiry_delta one hop backwards since the delta from the current hop is
22822300
// applicable for the previous hop.

0 commit comments

Comments
 (0)