Skip to content

Commit 0c62e8c

Browse files
Blame outbound channel on UPDATE onion failure with 0-len update
We've run into this several times in the wild, likely due to ElementsProject/lightning#6200 wherein a node on the path will error with 0x1000 but not provide a channel update (a spec violation). Previously, we would blame the inbound edge even though the buggy peer wanted us to blame the outbound edge. Since this issue seems to be recurring and our blaming the inbound edge is causing us to punish innocent channels, trust the peer that the outbound edge is the one to blame.
1 parent aa3387e commit 0c62e8c

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

lightning/src/ln/onion_route_tests.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,34 @@ fn test_onion_failure() {
645645
}, || nodes[2].node.fail_htlc_backwards(&payment_hash), false, None,
646646
Some(NetworkUpdate::NodeFailure { node_id: route.paths[0].hops[1].pubkey, is_permanent: true }),
647647
Some(channels[1].0.contents.short_channel_id));
648-
run_onion_failure_test_with_fail_intercept("0-length channel update in UPDATE onion failure", 200, &nodes,
649-
&route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
648+
run_onion_failure_test_with_fail_intercept("0-length channel update in intermediate node UPDATE onion failure",
649+
100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
650+
msg.amount_msat -= 1;
651+
}, |msg| {
652+
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
653+
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
654+
let mut decoded_err_packet = msgs::DecodedOnionErrorPacket {
655+
failuremsg: vec![
656+
0x10, 0x7, // UPDATE|7
657+
0x0, 0x0 // 0-len channel update
658+
],
659+
pad: vec![0; 255 - 4 /* 4-byte error message */],
660+
hmac: [0; 32],
661+
};
662+
let um = onion_utils::gen_um_from_shared_secret(&onion_keys[0].shared_secret.as_ref());
663+
let mut hmac = HmacEngine::<Sha256>::new(&um);
664+
hmac.input(&decoded_err_packet.encode()[32..]);
665+
decoded_err_packet.hmac = Hmac::from_engine(hmac).into_inner();
666+
msg.reason = onion_utils::encrypt_failure_packet(
667+
&onion_keys[0].shared_secret.as_ref(), &decoded_err_packet.encode()[..])
668+
}, || {}, true, Some(0x1000|7),
669+
Some(NetworkUpdate::ChannelFailure {
670+
short_channel_id: channels[1].0.contents.short_channel_id,
671+
is_permanent: false,
672+
}),
673+
Some(channels[1].0.contents.short_channel_id));
674+
run_onion_failure_test_with_fail_intercept("0-length channel update in final node UPDATE onion failure",
675+
200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
650676
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
651677
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
652678
let mut decoded_err_packet = msgs::DecodedOnionErrorPacket {

lightning/src/ln/onion_utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,9 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(
641641
} else {
642642
// The node in question intentionally encoded a 0-length channel update. This is
643643
// likely due to https://github.com/ElementsProject/lightning/issues/6200.
644+
short_channel_id = Some(failing_route_hop.short_channel_id);
644645
network_update = Some(NetworkUpdate::ChannelFailure {
645-
short_channel_id: route_hop.short_channel_id,
646+
short_channel_id: failing_route_hop.short_channel_id,
646647
is_permanent: false,
647648
});
648649
}

0 commit comments

Comments
 (0)