Skip to content

Commit b9d561a

Browse files
Update CandidateRouteHop::short_channel_id to be optional
1 parent 8f4f3b7 commit b9d561a

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
@@ -949,11 +949,11 @@ enum CandidateRouteHop<'a> {
949949
}
950950

951951
impl<'a> CandidateRouteHop<'a> {
952-
fn short_channel_id(&self) -> u64 {
952+
fn short_channel_id(&self) -> Option<u64> {
953953
match self {
954-
CandidateRouteHop::FirstHop { details } => details.get_outbound_payment_scid().unwrap(),
955-
CandidateRouteHop::PublicHop { short_channel_id, .. } => *short_channel_id,
956-
CandidateRouteHop::PrivateHop { hint } => hint.short_channel_id,
954+
CandidateRouteHop::FirstHop { details } => Some(details.get_outbound_payment_scid().unwrap()),
955+
CandidateRouteHop::PublicHop { short_channel_id, .. } => Some(*short_channel_id),
956+
CandidateRouteHop::PrivateHop { hint } => Some(hint.short_channel_id),
957957
}
958958
}
959959

@@ -1005,7 +1005,9 @@ impl<'a> CandidateRouteHop<'a> {
10051005
}
10061006
}
10071007
fn id(&self, channel_direction: bool /* src_node_id < target_node_id */) -> CandidateHopId {
1008-
CandidateHopId::Clear((self.short_channel_id(), channel_direction))
1008+
match self {
1009+
_ => CandidateHopId::Clear((self.short_channel_id().unwrap(), channel_direction)),
1010+
}
10091011
}
10101012
}
10111013

@@ -1256,6 +1258,18 @@ impl fmt::Display for LoggedPayeePubkey {
12561258
}
12571259
}
12581260

1261+
struct LoggedCandidateHop<'a>(&'a CandidateRouteHop<'a>);
1262+
impl<'a> fmt::Display for LoggedCandidateHop<'a> {
1263+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1264+
match self.0 {
1265+
_ => {
1266+
"SCID ".fmt(f)?;
1267+
self.0.short_channel_id().unwrap().fmt(f)
1268+
},
1269+
}
1270+
}
1271+
}
1272+
12591273
#[inline]
12601274
fn sort_first_hop_channels(
12611275
channels: &mut Vec<&ChannelDetails>, used_liquidities: &HashMap<CandidateHopId, u64>,
@@ -1560,7 +1574,7 @@ where L::Target: Logger {
15601574
// - for regular channels at channel announcement (TODO)
15611575
// - for first and last hops early in get_route
15621576
if $src_node_id != $dest_node_id {
1563-
let short_channel_id = $candidate.short_channel_id();
1577+
let scid_opt = $candidate.short_channel_id();
15641578
let effective_capacity = $candidate.effective_capacity();
15651579
let htlc_maximum_msat = max_htlc_from_capacity(effective_capacity, channel_saturation_pow_half);
15661580

@@ -1615,8 +1629,8 @@ where L::Target: Logger {
16151629
(amount_to_transfer_over_msat < $next_hops_path_htlc_minimum_msat &&
16161630
recommended_value_msat > $next_hops_path_htlc_minimum_msat));
16171631

1618-
let payment_failed_on_this_channel =
1619-
payment_params.previously_failed_channels.contains(&short_channel_id);
1632+
let payment_failed_on_this_channel = scid_opt.map_or(false,
1633+
|scid| payment_params.previously_failed_channels.contains(&scid));
16201634

16211635
// If HTLC minimum is larger than the amount we're going to transfer, we shouldn't
16221636
// bother considering this channel. If retrying with recommended_value_msat may
@@ -1685,9 +1699,9 @@ where L::Target: Logger {
16851699
inflight_htlc_msat: used_liquidity_msat,
16861700
effective_capacity,
16871701
};
1688-
let channel_penalty_msat = scorer.channel_penalty_msat(
1689-
short_channel_id, &$src_node_id, &$dest_node_id, channel_usage, score_params
1690-
);
1702+
let channel_penalty_msat = scid_opt.map_or(0,
1703+
|scid| scorer.channel_penalty_msat(scid, &$src_node_id, &$dest_node_id,
1704+
channel_usage, score_params));
16911705
let path_penalty_msat = $next_hops_path_penalty_msat
16921706
.saturating_add(channel_penalty_msat);
16931707
let new_graph_node = RouteGraphNode {
@@ -1857,8 +1871,8 @@ where L::Target: Logger {
18571871
let candidate = CandidateRouteHop::FirstHop { details };
18581872
let added = add_entry!(candidate, our_node_id, payee, 0, path_value_msat,
18591873
0, 0u64, 0, 0).is_some();
1860-
log_trace!(logger, "{} direct route to payee via SCID {}",
1861-
if added { "Added" } else { "Skipped" }, candidate.short_channel_id());
1874+
log_trace!(logger, "{} direct route to payee via {}",
1875+
if added { "Added" } else { "Skipped" }, LoggedCandidateHop(&candidate));
18621876
}
18631877
}));
18641878

@@ -2039,10 +2053,12 @@ where L::Target: Logger {
20392053
let mut features_set = false;
20402054
if let Some(first_channels) = first_hop_targets.get(&ordered_hops.last().unwrap().0.node_id) {
20412055
for details in first_channels {
2042-
if details.get_outbound_payment_scid().unwrap() == ordered_hops.last().unwrap().0.candidate.short_channel_id() {
2043-
ordered_hops.last_mut().unwrap().1 = details.counterparty.features.to_context();
2044-
features_set = true;
2045-
break;
2056+
if let Some(scid) = ordered_hops.last().unwrap().0.candidate.short_channel_id() {
2057+
if details.get_outbound_payment_scid().unwrap() == scid {
2058+
ordered_hops.last_mut().unwrap().1 = details.counterparty.features.to_context();
2059+
features_set = true;
2060+
break;
2061+
}
20462062
}
20472063
}
20482064
}
@@ -2128,11 +2144,12 @@ where L::Target: Logger {
21282144
// If we weren't capped by hitting a liquidity limit on a channel in the path,
21292145
// we'll probably end up picking the same path again on the next iteration.
21302146
// Decrease the available liquidity of a hop in the middle of the path.
2131-
let victim_scid = payment_path.hops[(payment_path.hops.len()) / 2].0.candidate.short_channel_id();
2147+
let victim_candidate = &payment_path.hops[(payment_path.hops.len()) / 2].0.candidate;
21322148
let exhausted = u64::max_value();
2133-
log_trace!(logger, "Disabling channel {} for future path building iterations to avoid duplicates.", victim_scid);
2134-
*used_liquidities.entry(CandidateHopId::Clear((victim_scid, false))).or_default() = exhausted;
2135-
*used_liquidities.entry(CandidateHopId::Clear((victim_scid, true))).or_default() = exhausted;
2149+
log_trace!(logger, "Disabling route candidate {} for future path building iterations to
2150+
avoid duplicates.", LoggedCandidateHop(victim_candidate));
2151+
*used_liquidities.entry(victim_candidate.id(false)).or_default() = exhausted;
2152+
*used_liquidities.entry(victim_candidate.id(true)).or_default() = exhausted;
21362153
}
21372154

21382155
// Track the total amount all our collected paths allow to send so that we know
@@ -2262,9 +2279,9 @@ where L::Target: Logger {
22622279
selected_route.sort_unstable_by_key(|path| {
22632280
let mut key = [0u64; MAX_PATH_LENGTH_ESTIMATE as usize];
22642281
debug_assert!(path.hops.len() <= key.len());
2265-
for (scid, key) in path.hops.iter().map(|h| h.0.candidate.short_channel_id()).zip(key.iter_mut()) {
2266-
*key = scid;
2267-
}
2282+
for (scid, key) in path.hops.iter().filter(|h| h.0.candidate.short_channel_id().is_some())
2283+
.map(|h| h.0.candidate.short_channel_id().unwrap()).zip(key.iter_mut())
2284+
{ *key = scid; }
22682285
key
22692286
});
22702287
for idx in 0..(selected_route.len() - 1) {
@@ -2279,15 +2296,16 @@ where L::Target: Logger {
22792296

22802297
let mut selected_paths = Vec::<Vec<Result<RouteHop, LightningError>>>::new();
22812298
for payment_path in selected_route {
2282-
let mut path = payment_path.hops.iter().map(|(payment_hop, node_features)| {
2283-
Ok(RouteHop {
2284-
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)})?,
2285-
node_features: node_features.clone(),
2286-
short_channel_id: payment_hop.candidate.short_channel_id(),
2287-
channel_features: payment_hop.candidate.features(),
2288-
fee_msat: payment_hop.fee_msat,
2289-
cltv_expiry_delta: payment_hop.candidate.cltv_expiry_delta(),
2290-
})
2299+
let mut path = payment_path.hops.iter().filter(|(h, _)| h.candidate.short_channel_id().is_some())
2300+
.map(|(payment_hop, node_features)| {
2301+
Ok(RouteHop {
2302+
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)})?,
2303+
node_features: node_features.clone(),
2304+
short_channel_id: payment_hop.candidate.short_channel_id().unwrap(),
2305+
channel_features: payment_hop.candidate.features(),
2306+
fee_msat: payment_hop.fee_msat,
2307+
cltv_expiry_delta: payment_hop.candidate.cltv_expiry_delta(),
2308+
})
22912309
}).collect::<Vec<_>>();
22922310
// Propagate the cltv_expiry_delta one hop backwards since the delta from the current hop is
22932311
// applicable for the previous hop.

0 commit comments

Comments
 (0)