diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 6267e234a78..6c84584e963 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -1059,8 +1059,19 @@ where Err(_) => { log_warn!(logger, "Unreadable failure from {}", route_hop.pubkey); + let network_update = Some(NetworkUpdate::NodeFailure { + node_id: route_hop.pubkey, + is_permanent: true, + }); + let short_channel_id = Some(route_hop.short_channel_id); + res = Some(FailureLearnings { + network_update, + short_channel_id, + payment_failed_permanently: is_from_final_node, + failed_within_blinded_path: false, + }); return; - } + }, }; let error_code_slice = match err_packet.failuremsg.get(0..2) { @@ -2181,6 +2192,28 @@ mod tests { assert_eq!(decrypted_failure.short_channel_id, None); } + #[test] + fn test_unreadable_failure_packet_onion() { + // Create a failure packet with a valid hmac but unreadable failure message. + let onion_keys: Vec = build_test_onion_keys(); + let shared_secret = onion_keys[0].shared_secret.as_ref(); + let um = gen_um_from_shared_secret(&shared_secret); + + // The failure message is a single 0 byte. + let mut packet = [0u8; 33]; + + let mut hmac = HmacEngine::::new(&um); + hmac.input(&packet[32..]); + let hmac = Hmac::from_engine(hmac).to_byte_array(); + packet[..32].copy_from_slice(&hmac); + + let packet = encrypt_failure_packet(shared_secret, &packet); + + // For the unreadable failure, it is still expected that the failing channel can be identified. + let decrypted_failure = test_failure_attribution(&packet.data); + assert_eq!(decrypted_failure.short_channel_id, Some(0)); + } + #[test] fn test_missing_error_code() { // Create a failure packet with a valid hmac and structure, but no error code.