Skip to content

Commit f38244c

Browse files
committed
Properly attribute unreadable failures with a valid hmac
This commit fixes a bug where a node penalty was not applied where it should.
1 parent 00f42de commit f38244c

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

lightning/src/ln/onion_utils.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,17 @@ where
10581058
Err(_) => {
10591059
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
10601060

1061+
let network_update = Some(NetworkUpdate::NodeFailure {
1062+
node_id: route_hop.pubkey,
1063+
is_permanent: true,
1064+
});
1065+
let short_channel_id = Some(route_hop.short_channel_id);
1066+
res = Some(FailureLearnings {
1067+
network_update,
1068+
short_channel_id,
1069+
payment_failed_permanently: is_from_final_node,
1070+
failed_within_blinded_path: false,
1071+
});
10611072
return;
10621073
},
10631074
};
@@ -2176,7 +2187,7 @@ mod tests {
21762187
let packet = vec![1u8; 292];
21772188

21782189
// In the current protocol, it is unfortunately not possible to identify the failure source.
2179-
let logger = TestLogger::new();
2190+
let logger: TestLogger = TestLogger::new();
21802191
let decrypted_failure = test_failure_attribution(&logger, &packet);
21812192
assert_eq!(decrypted_failure.short_channel_id, None);
21822193

@@ -2187,6 +2198,31 @@ mod tests {
21872198
);
21882199
}
21892200

2201+
#[test]
2202+
fn test_unreadable_failure_packet_onion() {
2203+
// Create a failure packet with a valid hmac but unreadable failure message.
2204+
let onion_keys: Vec<OnionKeys> = build_test_onion_keys();
2205+
let shared_secret = onion_keys[0].shared_secret.as_ref();
2206+
let um = gen_um_from_shared_secret(&shared_secret);
2207+
2208+
// The failure message is a single 0 byte.
2209+
let mut packet = [0u8; 33];
2210+
2211+
let mut hmac = HmacEngine::<Sha256>::new(&um);
2212+
hmac.input(&packet[32..]);
2213+
let hmac = Hmac::from_engine(hmac).to_byte_array();
2214+
packet[..32].copy_from_slice(&hmac);
2215+
2216+
let packet = encrypt_failure_packet(shared_secret, &packet);
2217+
2218+
// For the unreadable failure, it is still expected that the failing channel can be identified.
2219+
let logger: TestLogger = TestLogger::new();
2220+
let decrypted_failure = test_failure_attribution(&logger, &packet.data);
2221+
assert_eq!(decrypted_failure.short_channel_id, Some(0));
2222+
2223+
logger.assert_log_contains("lightning::ln::onion_utils", "Unreadable failure", 1);
2224+
}
2225+
21902226
#[test]
21912227
fn test_missing_error_code() {
21922228
// Create a failure packet with a valid hmac and structure, but no error code.

0 commit comments

Comments
 (0)