Skip to content

Commit 7641788

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 2157773 commit 7641788

File tree

1 file changed

+67
-35
lines changed

1 file changed

+67
-35
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 67 additions & 35 deletions
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,14 +974,38 @@ 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 mut onion_keys = Vec::with_capacity(path.hops.len());
9781002
construct_onion_keys_generic_callback(
9791003
secp_ctx,
9801004
&path.hops,
9811005
path.blinded_tail.as_ref(),
9821006
session_priv,
9831007
|shared_secret, _, _, route_hop_option: Option<&RouteHop>, _| {
984-
onion_keys.push((route_hop_option.cloned(), shared_secret))
1008+
onion_keys.push((route_hop_option.map(|rh| ErrorHop::RouteHop(rh)), shared_secret))
9851009
},
9861010
)
9871011
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
@@ -1048,7 +1072,7 @@ where
10481072
}
10491073
};
10501074

1051-
let amt_to_forward = htlc_msat - route_hop.fee_msat;
1075+
let amt_to_forward = htlc_msat - route_hop.fee_msat();
10521076
htlc_msat = amt_to_forward;
10531077

10541078
crypt_failure_packet(shared_secret.as_ref(), &mut encrypted_packet);
@@ -1065,13 +1089,13 @@ where
10651089
match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&encrypted_packet.data)) {
10661090
Ok(p) => p,
10671091
Err(_) => {
1068-
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
1092+
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey());
10691093

10701094
let network_update = Some(NetworkUpdate::NodeFailure {
1071-
node_id: route_hop.pubkey,
1095+
node_id: *route_hop.pubkey(),
10721096
is_permanent: true,
10731097
});
1074-
let short_channel_id = Some(route_hop.short_channel_id);
1098+
let short_channel_id = route_hop.short_channel_id();
10751099
res = Some(FailureLearnings {
10761100
network_update,
10771101
short_channel_id,
@@ -1087,13 +1111,13 @@ where
10871111
None => {
10881112
// Useless packet that we can't use but it passed HMAC, so it definitely came from the peer
10891113
// in question
1090-
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey);
1114+
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey());
10911115

10921116
let network_update = Some(NetworkUpdate::NodeFailure {
1093-
node_id: route_hop.pubkey,
1117+
node_id: *route_hop.pubkey(),
10941118
is_permanent: true,
10951119
});
1096-
let short_channel_id = Some(route_hop.short_channel_id);
1120+
let short_channel_id = route_hop.short_channel_id();
10971121
res = Some(FailureLearnings {
10981122
network_update,
10991123
short_channel_id,
@@ -1127,22 +1151,26 @@ where
11271151
// entirely, but we can't be confident in that, as it would allow any node to get us to
11281152
// completely ban one of its counterparties. Instead, we simply remove the channel in
11291153
// question.
1130-
network_update = Some(NetworkUpdate::ChannelFailure {
1131-
short_channel_id: failing_route_hop.short_channel_id,
1132-
is_permanent: true,
1133-
});
1154+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1155+
network_update = Some(NetworkUpdate::ChannelFailure {
1156+
short_channel_id: failing_route_hop.short_channel_id,
1157+
is_permanent: true,
1158+
});
1159+
}
11341160
} else if error_code & NODE == NODE {
11351161
let is_permanent = error_code & PERM == PERM;
11361162
network_update =
1137-
Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent });
1138-
short_channel_id = Some(route_hop.short_channel_id);
1163+
Some(NetworkUpdate::NodeFailure { node_id: *route_hop.pubkey(), is_permanent });
1164+
short_channel_id = route_hop.short_channel_id();
11391165
} else if error_code & PERM == PERM {
11401166
if !payment_failed {
1141-
network_update = Some(NetworkUpdate::ChannelFailure {
1142-
short_channel_id: failing_route_hop.short_channel_id,
1143-
is_permanent: true,
1144-
});
1145-
short_channel_id = Some(failing_route_hop.short_channel_id);
1167+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1168+
network_update = Some(NetworkUpdate::ChannelFailure {
1169+
short_channel_id: failing_route_hop.short_channel_id,
1170+
is_permanent: true,
1171+
});
1172+
}
1173+
short_channel_id = failing_route_hop.short_channel_id();
11461174
}
11471175
} else if error_code & UPDATE == UPDATE {
11481176
if let Some(update_len_slice) =
@@ -1155,37 +1183,41 @@ where
11551183
.get(debug_field_size + 4..debug_field_size + 4 + update_len)
11561184
.is_some()
11571185
{
1158-
network_update = Some(NetworkUpdate::ChannelFailure {
1159-
short_channel_id: failing_route_hop.short_channel_id,
1160-
is_permanent: false,
1161-
});
1162-
short_channel_id = Some(failing_route_hop.short_channel_id);
1186+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
1187+
network_update = Some(NetworkUpdate::ChannelFailure {
1188+
short_channel_id: failing_route_hop.short_channel_id,
1189+
is_permanent: false,
1190+
});
1191+
}
1192+
short_channel_id = failing_route_hop.short_channel_id();
11631193
}
11641194
}
11651195
if network_update.is_none() {
11661196
// They provided an UPDATE which was obviously bogus, not worth
11671197
// trying to relay through them anymore.
11681198
network_update = Some(NetworkUpdate::NodeFailure {
1169-
node_id: route_hop.pubkey,
1199+
node_id: *route_hop.pubkey(),
11701200
is_permanent: true,
11711201
});
11721202
}
11731203
if short_channel_id.is_none() {
1174-
short_channel_id = Some(route_hop.short_channel_id);
1204+
short_channel_id = route_hop.short_channel_id();
11751205
}
11761206
} else if payment_failed {
11771207
// Only blame the hop when a value in the HTLC doesn't match the corresponding value in the
11781208
// onion.
11791209
short_channel_id = match error_code & 0xff {
1180-
18 | 19 => Some(route_hop.short_channel_id),
1210+
18 | 19 => route_hop.short_channel_id(),
11811211
_ => None,
11821212
};
11831213
} else {
11841214
// We can't understand their error messages and they failed to forward...they probably can't
11851215
// understand our forwards so it's really not worth trying any further.
1186-
network_update =
1187-
Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true });
1188-
short_channel_id = Some(route_hop.short_channel_id);
1216+
network_update = Some(NetworkUpdate::NodeFailure {
1217+
node_id: *route_hop.pubkey(),
1218+
is_permanent: true,
1219+
});
1220+
short_channel_id = route_hop.short_channel_id()
11891221
}
11901222

11911223
res = Some(FailureLearnings {
@@ -1200,7 +1232,7 @@ where
12001232
log_info!(
12011233
logger,
12021234
"Onion Error[from {}: {}({:#x}) {}({})] {}",
1203-
route_hop.pubkey,
1235+
route_hop.pubkey(),
12041236
title,
12051237
error_code,
12061238
debug_field,
@@ -1211,7 +1243,7 @@ where
12111243
log_info!(
12121244
logger,
12131245
"Onion Error[from {}: {}({:#x})] {}",
1214-
route_hop.pubkey,
1246+
route_hop.pubkey(),
12151247
title,
12161248
error_code,
12171249
description

0 commit comments

Comments
 (0)