+
+#[cfg(test)]
+mod tests {
+ use std::io::Cursor;
+ use ln::msgs::DecodeError;
+
+ fn tlv_reader(s: &[u8]) -> Result<(u64, u32, Option<u32>), DecodeError> {
+ let mut s = Cursor::new(s);
+ let mut a: u64 = 0;
+ let mut b: u32 = 0;
+ let mut c: Option<u32> = None;
+ decode_tlv!(&mut s, {(2, a), (3, b)}, {(4, c)});
+ Ok((a, b, c))
+ }
+ #[test]
+ fn test_tlv() {
+ // Value for 3 is longer than we expect, but that's ok...
+ assert_eq!(tlv_reader(&::hex::decode(
+ concat!("0100", "0208deadbeef1badbeef", "0308deadbeef1badf00d")
+ ).unwrap()[..]).unwrap(),
+ (0xdeadbeef1badbeef, 0xdeadbeef, None));
+ // ...even if there's something afterwards
+ assert_eq!(tlv_reader(&::hex::decode(
+ concat!("0100", "0208deadbeef1badbeef", "0308deadbeef1badf00d", "0404ffffffff")
+ ).unwrap()[..]).unwrap(),
+ (0xdeadbeef1badbeef, 0xdeadbeef, Some(0xffffffff)));
+ // ...but not if that extra length is missing
+ if let Err(DecodeError::ShortRead) = tlv_reader(&::hex::decode(
+ concat!("0100", "0208deadbeef1badbeef", "0308deadbeef")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+
+ // If they're out of order that's also bad
+ if let Err(DecodeError::InvalidValue) = tlv_reader(&::hex::decode(
+ concat!("0100", "0304deadbeef", "0208deadbeef1badbeef")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+ // ...even if its some field we don't understand
+ if let Err(DecodeError::InvalidValue) = tlv_reader(&::hex::decode(
+ concat!("0208deadbeef1badbeef", "0100", "0304deadbeef")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+
+ // It's also bad if they included even fields we don't understand
+ if let Err(DecodeError::UnknownRequiredFeature) = tlv_reader(&::hex::decode(
+ concat!("0100", "0208deadbeef1badbeef", "0304deadbeef", "0600")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+ // ... or if they're missing fields we need
+ if let Err(DecodeError::InvalidValue) = tlv_reader(&::hex::decode(
+ concat!("0100", "0208deadbeef1badbeef")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+ // ... even if that field is even
+ if let Err(DecodeError::InvalidValue) = tlv_reader(&::hex::decode(
+ concat!("0304deadbeef", "0500")
+ ).unwrap()[..]) {
+ } else { panic!(); }
+
+ // But usually things are pretty much what we expect:
+ assert_eq!(tlv_reader(&::hex::decode(
+ concat!("0208deadbeef1badbeef", "03041bad1dea")
+ ).unwrap()[..]).unwrap(),
+ (0xdeadbeef1badbeef, 0x1bad1dea, None));
+ assert_eq!(tlv_reader(&::hex::decode(
+ concat!("0208deadbeef1badbeef", "03041bad1dea", "040401020304")
+ ).unwrap()[..]).unwrap(),
+ (0xdeadbeef1badbeef, 0x1bad1dea, Some(0x01020304)));
+ }
+}