Skip to content

Commit cdda315

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 b3882b4 commit cdda315

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,22 @@ where
10561056

10571057
let err_packet = match decrypt_result {
10581058
Ok(p) => p,
1059-
Err(_) => return,
1059+
Err(_) => {
1060+
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
1061+
1062+
let network_update = Some(NetworkUpdate::NodeFailure {
1063+
node_id: route_hop.pubkey,
1064+
is_permanent: true,
1065+
});
1066+
let short_channel_id = Some(route_hop.short_channel_id);
1067+
res = Some(FailureLearnings {
1068+
network_update,
1069+
short_channel_id,
1070+
payment_failed_permanently: is_from_final_node,
1071+
failed_within_blinded_path: false,
1072+
});
1073+
return;
1074+
},
10601075
};
10611076

10621077
let error_code_slice = match err_packet.failuremsg.get(0..2) {
@@ -2177,6 +2192,28 @@ mod tests {
21772192
assert_eq!(decrypted_failure.short_channel_id, None);
21782193
}
21792194

2195+
#[test]
2196+
fn test_unreadable_failure_packet_onion() {
2197+
// Create a failure packet with a valid hmac but unreadable failure message.
2198+
let onion_keys: Vec<OnionKeys> = build_test_onion_keys();
2199+
let shared_secret = onion_keys[0].shared_secret.as_ref();
2200+
let um = gen_um_from_shared_secret(&shared_secret);
2201+
2202+
// The failure message is a single 0 byte.
2203+
let mut packet = [0u8; 33];
2204+
2205+
let mut hmac = HmacEngine::<Sha256>::new(&um);
2206+
hmac.input(&packet[32..]);
2207+
let hmac = Hmac::from_engine(hmac).to_byte_array();
2208+
packet[..32].copy_from_slice(&hmac);
2209+
2210+
let packet = encrypt_failure_packet(shared_secret, &packet);
2211+
2212+
// For the unreadable failure, it is still expected that the failing channel can be identified.
2213+
let decrypted_failure = test_failure_attribution(&packet.data);
2214+
assert_eq!(decrypted_failure.short_channel_id, Some(0));
2215+
}
2216+
21802217
#[test]
21812218
fn test_missing_error_code() {
21822219
// Create a failure packet with a valid hmac and structure, but no error code.

0 commit comments

Comments
 (0)