From 2d392f86fdf4f2c390473d852ccaeaa813e78b38 Mon Sep 17 00:00:00 2001 From: Carla Kirk-Cohen Date: Fri, 14 Mar 2025 13:44:38 -0400 Subject: [PATCH 1/4] ln/fix: remove undefined PERM | 1 code from reason method This failure code isn't used anywhere in the codebase and is not defined in BOLT 04. --- lightning/src/ln/onion_utils.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9d528d9dafd..1ef8026f552 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -1431,8 +1431,7 @@ impl HTLCFailReason { const NODE: u16 = 0x2000; const UPDATE: u16 = 0x1000; - if failure_code == 1 | PERM { debug_assert!(data.is_empty()) } - else if failure_code == 2 | NODE { debug_assert!(data.is_empty()) } + if failure_code == 2 | NODE { debug_assert!(data.is_empty()) } else if failure_code == 2 | PERM | NODE { debug_assert!(data.is_empty()) } else if failure_code == 3 | PERM | NODE { debug_assert!(data.is_empty()) } else if failure_code == 4 | BADONION | PERM { debug_assert_eq!(data.len(), 32) } From b7dec5ca0a20c5516326444d3148f17c7e4017a0 Mon Sep 17 00:00:00 2001 From: Carla Kirk-Cohen Date: Fri, 14 Mar 2025 16:01:09 -0400 Subject: [PATCH 2/4] ln/fix: invalid_onion_version code for DecodeError::UnknownVersion Realm is no longer specified in BOLT04, use the specified version error instead. --- lightning/src/ln/onion_utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 1ef8026f552..9a20c2a94aa 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -2037,8 +2037,8 @@ fn decode_next_hop, N: NextPacketBytes>( match R::read(&mut chacha_stream, read_args) { Err(err) => { let error_code = match err { - // Unknown realm byte - msgs::DecodeError::UnknownVersion => 0x4000 | 1, + // Unknown version + msgs::DecodeError::UnknownVersion => 0x8000 | 0x4000 | 4, // invalid_onion_payload msgs::DecodeError::UnknownRequiredFeature | msgs::DecodeError::InvalidValue From 31880955ac4a4a4aa8b64c83108513f23163fe3a Mon Sep 17 00:00:00 2001 From: Carla Kirk-Cohen Date: Wed, 2 Apr 2025 14:34:04 -0400 Subject: [PATCH 3/4] ln/fix: return invalid payload for final hop trampoline with blinding As is, we're returning an `invalid_onion_blinding` error with no associated data, because the calling code does not attach any data when we have a `OnionDecodeErr::Relay` error. This is arguably not the correct error code anyway, as described below, so this commit updates it to `invalid_onion_payload` which does not require additional error data. In this case, we have received a trampoline payload which we believe should contain details of the next trampoline hop. This information is missing, so we've received an invalid payload. When a blinding point point is present in the payload, we're also the introduction node. BOLT04 indicates that if this `current_path_key` is present and we are the final hop we should return a regular error (rather than using `invalid_onion_blinding` when you're the the final hop). Before this commit, this code was considering our node to be non-final and returning an error accordingly. Our role as the final hop is ambiguous here - we are the final hop in the sphinx packet, but the trampoline packet implies that there should be more hops to come. Given that the trampoline packet is invalid, we defer to our position in the sphinx packet and send back an invalid payload error instead. --- lightning/src/ln/blinded_payment_tests.rs | 2 +- lightning/src/ln/onion_utils.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index 17494b06098..c8f13a12bae 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -2160,7 +2160,7 @@ fn do_test_trampoline_single_hop_receive(success: bool) { } { let payment_failed_conditions = PaymentFailedConditions::new() - .expected_htlc_error_data(INVALID_ONION_BLINDING, &[0; 0]); + .expected_htlc_error_data(0x4000 | 22, &[0; 0]); expect_payment_failed_conditions(&nodes[0], payment_hash, true, payment_failed_conditions); } } diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9a20c2a94aa..6b809db10b1 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -1837,7 +1837,7 @@ where if hop_data.intro_node_blinding_point.is_some() { return Err(OnionDecodeErr::Relay { err_msg: "Non-final intro node Trampoline onion data provided to us as last hop", - err_code: INVALID_ONION_BLINDING, + err_code: 0x4000 | 22, shared_secret, trampoline_shared_secret: Some(SharedSecret::from_bytes( trampoline_shared_secret, From 3b2d661c8982b65fd8126df2831ac4f5142b8166 Mon Sep 17 00:00:00 2001 From: Carla Kirk-Cohen Date: Tue, 1 Apr 2025 16:09:49 -0400 Subject: [PATCH 4/4] ln: add length assertion for invalid onion failure code Although the specification allows an all-zero sha256_of_onion for invalid_onion_blinding errors, it still requires that the value is set. --- lightning/src/ln/onion_utils.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 6b809db10b1..d9958029449 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -1458,6 +1458,7 @@ impl HTLCFailReason { else if failure_code == 21 { debug_assert!(data.is_empty()) } else if failure_code == 22 | PERM { debug_assert!(data.len() <= 11) } else if failure_code == 23 { debug_assert!(data.is_empty()) } + else if failure_code == INVALID_ONION_BLINDING { debug_assert_eq!(data.len(), 32) } else if failure_code & BADONION != 0 { // We set some bogus BADONION failure codes in test, so ignore unknown ones. }