Skip to content

Commit ca7b173

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 ca7b173

File tree

1 file changed

+68
-33
lines changed

1 file changed

+68
-33
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -974,14 +974,39 @@ where
974974
const NODE: u16 = 0x2000;
975975
const UPDATE: u16 = 0x1000;
976976

977+
enum ErrorHop {
978+
RouteHop(RouteHop),
979+
}
980+
981+
impl ErrorHop {
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
1009+
.push((route_hop_option.map(|rh| ErrorHop::RouteHop(rh.clone())), shared_secret))
9851010
},
9861011
)
9871012
.expect("Route we used spontaneously grew invalid keys in the middle of it?");
@@ -1048,7 +1073,7 @@ where
10481073
}
10491074
};
10501075

1051-
let amt_to_forward = htlc_msat - route_hop.fee_msat;
1076+
let amt_to_forward = htlc_msat - route_hop.fee_msat();
10521077
htlc_msat = amt_to_forward;
10531078

10541079
crypt_failure_packet(shared_secret.as_ref(), &mut encrypted_packet);
@@ -1065,13 +1090,13 @@ where
10651090
match msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&encrypted_packet.data)) {
10661091
Ok(p) => p,
10671092
Err(_) => {
1068-
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
1093+
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey());
10691094

10701095
let network_update = Some(NetworkUpdate::NodeFailure {
1071-
node_id: route_hop.pubkey,
1096+
node_id: route_hop.pubkey().clone(),
10721097
is_permanent: true,
10731098
});
1074-
let short_channel_id = Some(route_hop.short_channel_id);
1099+
let short_channel_id = route_hop.short_channel_id();
10751100
res = Some(FailureLearnings {
10761101
network_update,
10771102
short_channel_id,
@@ -1087,13 +1112,13 @@ where
10871112
None => {
10881113
// Useless packet that we can't use but it passed HMAC, so it definitely came from the peer
10891114
// in question
1090-
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey);
1115+
log_warn!(logger, "Missing error code in failure from {}", route_hop.pubkey());
10911116

10921117
let network_update = Some(NetworkUpdate::NodeFailure {
1093-
node_id: route_hop.pubkey,
1118+
node_id: route_hop.pubkey().clone(),
10941119
is_permanent: true,
10951120
});
1096-
let short_channel_id = Some(route_hop.short_channel_id);
1121+
let short_channel_id = route_hop.short_channel_id();
10971122
res = Some(FailureLearnings {
10981123
network_update,
10991124
short_channel_id,
@@ -1127,22 +1152,28 @@ where
11271152
// entirely, but we can't be confident in that, as it would allow any node to get us to
11281153
// completely ban one of its counterparties. Instead, we simply remove the channel in
11291154
// question.
1130-
network_update = Some(NetworkUpdate::ChannelFailure {
1131-
short_channel_id: failing_route_hop.short_channel_id,
1132-
is_permanent: true,
1133-
});
1134-
} else if error_code & NODE == NODE {
1135-
let is_permanent = error_code & PERM == PERM;
1136-
network_update =
1137-
Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent });
1138-
short_channel_id = Some(route_hop.short_channel_id);
1139-
} else if error_code & PERM == PERM {
1140-
if !payment_failed {
1155+
if let ErrorHop::RouteHop(failing_route_hop) = failing_route_hop {
11411156
network_update = Some(NetworkUpdate::ChannelFailure {
11421157
short_channel_id: failing_route_hop.short_channel_id,
11431158
is_permanent: true,
11441159
});
1145-
short_channel_id = Some(failing_route_hop.short_channel_id);
1160+
}
1161+
} else if error_code & NODE == NODE {
1162+
let is_permanent = error_code & PERM == PERM;
1163+
network_update = Some(NetworkUpdate::NodeFailure {
1164+
node_id: route_hop.pubkey().clone(),
1165+
is_permanent,
1166+
});
1167+
short_channel_id = route_hop.short_channel_id();
1168+
} else if error_code & PERM == PERM {
1169+
if !payment_failed {
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();
11461177
}
11471178
} else if error_code & UPDATE == UPDATE {
11481179
if let Some(update_len_slice) =
@@ -1155,37 +1186,41 @@ where
11551186
.get(debug_field_size + 4..debug_field_size + 4 + update_len)
11561187
.is_some()
11571188
{
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);
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();
11631196
}
11641197
}
11651198
if network_update.is_none() {
11661199
// They provided an UPDATE which was obviously bogus, not worth
11671200
// trying to relay through them anymore.
11681201
network_update = Some(NetworkUpdate::NodeFailure {
1169-
node_id: route_hop.pubkey,
1202+
node_id: route_hop.pubkey().clone(),
11701203
is_permanent: true,
11711204
});
11721205
}
11731206
if short_channel_id.is_none() {
1174-
short_channel_id = Some(route_hop.short_channel_id);
1207+
short_channel_id = route_hop.short_channel_id();
11751208
}
11761209
} else if payment_failed {
11771210
// Only blame the hop when a value in the HTLC doesn't match the corresponding value in the
11781211
// onion.
11791212
short_channel_id = match error_code & 0xff {
1180-
18 | 19 => Some(route_hop.short_channel_id),
1213+
18 | 19 => route_hop.short_channel_id(),
11811214
_ => None,
11821215
};
11831216
} else {
11841217
// We can't understand their error messages and they failed to forward...they probably can't
11851218
// 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);
1219+
network_update = Some(NetworkUpdate::NodeFailure {
1220+
node_id: route_hop.pubkey().clone(),
1221+
is_permanent: true,
1222+
});
1223+
short_channel_id = route_hop.short_channel_id()
11891224
}
11901225

11911226
res = Some(FailureLearnings {
@@ -1200,7 +1235,7 @@ where
12001235
log_info!(
12011236
logger,
12021237
"Onion Error[from {}: {}({:#x}) {}({})] {}",
1203-
route_hop.pubkey,
1238+
route_hop.pubkey(),
12041239
title,
12051240
error_code,
12061241
debug_field,
@@ -1211,7 +1246,7 @@ where
12111246
log_info!(
12121247
logger,
12131248
"Onion Error[from {}: {}({:#x})] {}",
1214-
route_hop.pubkey,
1249+
route_hop.pubkey(),
12151250
title,
12161251
error_code,
12171252
description

0 commit comments

Comments
 (0)