Skip to content

Commit 9f16e69

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 94be75f commit 9f16e69

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,17 @@ where
10601060
Err(_) => {
10611061
log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey);
10621062

1063+
let network_update = Some(NetworkUpdate::NodeFailure {
1064+
node_id: route_hop.pubkey,
1065+
is_permanent: true,
1066+
});
1067+
let short_channel_id = Some(route_hop.short_channel_id);
1068+
res = Some(FailureLearnings {
1069+
network_update,
1070+
short_channel_id,
1071+
payment_failed_permanently: is_from_final_node,
1072+
failed_within_blinded_path: false,
1073+
});
10631074
return;
10641075
},
10651076
};
@@ -2178,7 +2189,7 @@ mod tests {
21782189
let packet = vec![1u8; 292];
21792190

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

@@ -2189,6 +2200,31 @@ mod tests {
21892200
);
21902201
}
21912202

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

0 commit comments

Comments
 (0)