From: Matt Corallo Date: Thu, 1 Dec 2022 20:31:52 +0000 (+0000) Subject: Assert that all onion error messages are correct len in tests X-Git-Tag: v0.0.113~13^2~3 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=8ec148072437b3a64ddddee89088a77db271312e;p=rust-lightning Assert that all onion error messages are correct len in tests When we're constructing an HTLCFailReason, we should check that we set the data to at least the correct length for the given failure code, which we do here. --- diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index c12c63d5..5f55714a 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -642,11 +642,49 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr, impl HTLCFailReason { pub(super) fn reason(failure_code: u16, data: Vec) -> Self { + const BADONION: u16 = 0x8000; + const PERM: u16 = 0x4000; + 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()) } + 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) } + else if failure_code == 5 | BADONION | PERM { debug_assert_eq!(data.len(), 32) } + else if failure_code == 6 | BADONION | PERM { debug_assert_eq!(data.len(), 32) } + else if failure_code == 7 | UPDATE { + debug_assert_eq!(data.len() - 2, u16::from_be_bytes(data[0..2].try_into().unwrap()) as usize) } + else if failure_code == 8 | PERM { debug_assert!(data.is_empty()) } + else if failure_code == 9 | PERM { debug_assert!(data.is_empty()) } + else if failure_code == 10 | PERM { debug_assert!(data.is_empty()) } + else if failure_code == 11 | UPDATE { + debug_assert_eq!(data.len() - 2 - 8, u16::from_be_bytes(data[8..10].try_into().unwrap()) as usize) } + else if failure_code == 12 | UPDATE { + debug_assert_eq!(data.len() - 2 - 8, u16::from_be_bytes(data[8..10].try_into().unwrap()) as usize) } + else if failure_code == 13 | UPDATE { + debug_assert_eq!(data.len() - 2 - 4, u16::from_be_bytes(data[4..6].try_into().unwrap()) as usize) } + else if failure_code == 14 | UPDATE { + debug_assert_eq!(data.len() - 2, u16::from_be_bytes(data[0..2].try_into().unwrap()) as usize) } + else if failure_code == 15 | PERM { debug_assert_eq!(data.len(), 12) } + else if failure_code == 18 { debug_assert_eq!(data.len(), 4) } + else if failure_code == 19 { debug_assert_eq!(data.len(), 8) } + else if failure_code == 20 | UPDATE { + debug_assert_eq!(data.len() - 2 - 2, u16::from_be_bytes(data[2..4].try_into().unwrap()) as usize) } + 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 & BADONION != 0 { + // We set some bogus BADONION failure codes in test, so ignore unknown ones. + } + else { debug_assert!(false, "Unknown failure code: {}", failure_code) } + Self(HTLCFailReasonRepr::Reason { failure_code, data }) } pub(super) fn from_failure_code(failure_code: u16) -> Self { - Self(HTLCFailReasonRepr::Reason { failure_code, data: Vec::new() }) + Self::reason(failure_code, Vec::new()) } pub(super) fn from_msg(msg: &msgs::UpdateFailHTLC) -> Self {