Skip to content

Commit 7ded4c3

Browse files
committed
Introduce ErrorHop enum
When we start handling Trampoline, the hops in our error decryption path could be either `RouteHop`s or `TrampolineHop`s. To avoid excessive code duplication, we introduce an enum with some methods for common accessors.
1 parent 3e14896 commit 7ded4c3

File tree

1 file changed

+67
-35
lines changed

1 file changed

+67
-35
lines changed

lightning/src/ln/onion_utils.rs

+67-35
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,14 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
297297
}
298298

299299
#[inline]
300-
fn construct_onion_keys_generic_callback<T, H, FType>(
301-
secp_ctx: &Secp256k1<T>, hops: &[H], blinded_tail: Option<&BlindedTail>,
300+
fn construct_onion_keys_generic_callback<'a, T, H, FType>(
301+
secp_ctx: &Secp256k1<T>, hops: &'a [H], blinded_tail: Option<&BlindedTail>,
302302
session_priv: &SecretKey, mut callback: FType,
303303
) -> Result<(), secp256k1::Error>
304304
where
305305
T: secp256k1::Signing,
306306
H: HopInfo,
307-
FType: FnMut(SharedSecret, [u8; 32], PublicKey, Option<&H>, usize),
307+
FType: FnMut(SharedSecret, [u8; 32], PublicKey, Option<&'a H>, usize),
308308
{
309309
let mut blinded_priv = session_priv.clone();
310310
let mut blinded_pub = PublicKey::from_secret_key(secp_ctx, &blinded_priv);
@@ -974,6 +974,30 @@ where
974974
const NODE: u16 = 0x2000;
975975
const UPDATE: u16 = 0x1000;
976976

977+
enum ErrorHop<'a> {
978+
RouteHop(&'a RouteHop),
979+
}
980+
981+
impl<'a> ErrorHop<'a> {
982+
fn fee_msat(&self) -> u64 {
983+
match self {
984+
ErrorHop::RouteHop(rh) => rh.fee_msat,
985+
}
986+
}
987+
988+
fn pubkey(&self) -> &PublicKey {
989+
match self {
990+
ErrorHop::RouteHop(rh) => rh.node_pubkey(),
991+
}
992+
}
993+
994+
fn short_channel_id(&self) -> Option<u64> {
995+
match self {
996+
ErrorHop::RouteHop(rh) => Some(rh.short_channel_id),
997+
}
998+
}
999+
}
1000+
9771001
let num_blinded_hops = path.blinded_tail.as_ref().map_or(0, |bt| bt.hops.len());
9781002
let mut onion_keys = Vec::with_capacity(path.hops.len() + num_blinded_hops);
9791003
construct_onion_keys_generic_callback(
@@ -982,7 +1006,7 @@ where
9821006
path.blinded_tail.as_ref(),
9831007
session_priv,
9841008
|shared_secret, _, _, route_hop_option: Option<&RouteHop>, _| {
985-
onion_keys.push((route_hop_option.cloned(), shared_secret))
1009+
onion_keys.push((route_hop_option.map(|rh| ErrorHop::RouteHop(rh)), shared_secret))
9861010
},
9871011
)
9881012
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
@@ -1051,7 +1075,7 @@ where
10511075
}
10521076
};
10531077

1054-
let amt_to_forward = htlc_msat - route_hop.fee_msat;
1078+
let amt_to_forward = htlc_msat - route_hop.fee_msat();
10551079
htlc_msat = amt_to_forward;
10561080

10571081
crypt_failure_packet(shared_secret.as_ref(), &mut encrypted_packet);
@@ -1068,13 +1092,13 @@ where
10681092
match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&encrypted_packet.data)) {
10691093
Ok(p) => p,
10701094
Err(_) => {
1071-
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
1095+
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey());
10721096

10731097
let network_update = Some(NetworkUpdate::NodeFailure {
1074-
node_id: route_hop.pubkey,
1098+
node_id: *route_hop.pubkey(),
10751099
is_permanent: true,
10761100
});
1077-
let short_channel_id = Some(route_hop.short_channel_id);
1101+
let short_channel_id = route_hop.short_channel_id();
10781102
res = Some(FailureLearnings {
10791103
network_update,
10801104
short_channel_id,
@@ -1090,13 +1114,13 @@ where
10901114
None => {
10911115
// Useless packet that we can't use but it passed HMAC, so it definitely came from the peer
10921116
// in question
1093-
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey);
1117+
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey());
10941118

10951119
let network_update = Some(NetworkUpdate::NodeFailure {
1096-
node_id: route_hop.pubkey,
1120+
node_id: *route_hop.pubkey(),
10971121
is_permanent: true,
10981122
});
1099-
let short_channel_id = Some(route_hop.short_channel_id);
1123+
let short_channel_id = route_hop.short_channel_id();
11001124
res = Some(FailureLearnings {
11011125
network_update,
11021126
short_channel_id,
@@ -1130,22 +1154,26 @@ where
11301154
// entirely, but we can't be confident in that, as it would allow any node to get us to
11311155
// completely ban one of its counterparties. Instead, we simply remove the channel in
11321156
// question.
1133-
network_update = Some(NetworkUpdate::ChannelFailure {
1134-
short_channel_id: failing_route_hop.short_channel_id,
1135-
is_permanent: true,
1136-
});
1157+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1158+
network_update = Some(NetworkUpdate::ChannelFailure {
1159+
short_channel_id: failing_route_hop.short_channel_id,
1160+
is_permanent: true,
1161+
});
1162+
}
11371163
} else if error_code & NODE == NODE {
11381164
let is_permanent = error_code & PERM == PERM;
11391165
network_update =
1140-
Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent });
1141-
short_channel_id = Some(route_hop.short_channel_id);
1166+
Some(NetworkUpdate::NodeFailure { node_id: *route_hop.pubkey(), is_permanent });
1167+
short_channel_id = route_hop.short_channel_id();
11421168
} else if error_code & PERM == PERM {
11431169
if !payment_failed {
1144-
network_update = Some(NetworkUpdate::ChannelFailure {
1145-
short_channel_id: failing_route_hop.short_channel_id,
1146-
is_permanent: true,
1147-
});
1148-
short_channel_id = Some(failing_route_hop.short_channel_id);
1170+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1171+
network_update = Some(NetworkUpdate::ChannelFailure {
1172+
short_channel_id: failing_route_hop.short_channel_id,
1173+
is_permanent: true,
1174+
});
1175+
}
1176+
short_channel_id = failing_route_hop.short_channel_id();
11491177
}
11501178
} else if error_code & UPDATE == UPDATE {
11511179
if let Some(update_len_slice) =
@@ -1158,37 +1186,41 @@ where
11581186
.get(debug_field_size + 4..debug_field_size + 4 + update_len)
11591187
.is_some()
11601188
{
1161-
network_update = Some(NetworkUpdate::ChannelFailure {
1162-
short_channel_id: failing_route_hop.short_channel_id,
1163-
is_permanent: false,
1164-
});
1165-
short_channel_id = Some(failing_route_hop.short_channel_id);
1189+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1190+
network_update = Some(NetworkUpdate::ChannelFailure {
1191+
short_channel_id: failing_route_hop.short_channel_id,
1192+
is_permanent: false,
1193+
});
1194+
}
1195+
short_channel_id = failing_route_hop.short_channel_id();
11661196
}
11671197
}
11681198
if network_update.is_none() {
11691199
// They provided an UPDATE which was obviously bogus, not worth
11701200
// trying to relay through them anymore.
11711201
network_update = Some(NetworkUpdate::NodeFailure {
1172-
node_id: route_hop.pubkey,
1202+
node_id: *route_hop.pubkey(),
11731203
is_permanent: true,
11741204
});
11751205
}
11761206
if short_channel_id.is_none() {
1177-
short_channel_id = Some(route_hop.short_channel_id);
1207+
short_channel_id = route_hop.short_channel_id();
11781208
}
11791209
} else if payment_failed {
11801210
// Only blame the hop when a value in the HTLC doesn't match the corresponding value in the
11811211
// onion.
11821212
short_channel_id = match error_code & 0xff {
1183-
18 | 19 => Some(route_hop.short_channel_id),
1213+
18 | 19 => route_hop.short_channel_id(),
11841214
_ => None,
11851215
};
11861216
} else {
11871217
// We can't understand their error messages and they failed to forward...they probably can't
11881218
// understand our forwards so it's really not worth trying any further.
1189-
network_update =
1190-
Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true });
1191-
short_channel_id = Some(route_hop.short_channel_id);
1219+
network_update = Some(NetworkUpdate::NodeFailure {
1220+
node_id: *route_hop.pubkey(),
1221+
is_permanent: true,
1222+
});
1223+
short_channel_id = route_hop.short_channel_id()
11921224
}
11931225

11941226
res = Some(FailureLearnings {
@@ -1203,7 +1235,7 @@ where
12031235
log_info!(
12041236
logger,
12051237
"Onion Error[from {}: {}({:#x}) {}({})] {}",
1206-
route_hop.pubkey,
1238+
route_hop.pubkey(),
12071239
title,
12081240
error_code,
12091241
debug_field,
@@ -1214,7 +1246,7 @@ where
12141246
log_info!(
12151247
logger,
12161248
"Onion Error[from {}: {}({:#x})] {}",
1217-
route_hop.pubkey,
1249+
route_hop.pubkey(),
12181250
title,
12191251
error_code,
12201252
description

0 commit comments

Comments
 (0)