Merge pull request #1748 from valentinewallace/2022-10-custom-oms
[rust-lightning] / lightning / src / util / ser_macros.rs
index 94990fcb8a17c8056dfd01d00b18db78d58e466f..8c0a38670b5ad811dffd534721e3980b02fb444d 100644 (file)
@@ -157,25 +157,30 @@ macro_rules! decode_tlv {
                decode_tlv!($reader, $field, required)
        }};
        ($reader: expr, $field: ident, required) => {{
-               $field = ser::Readable::read(&mut $reader)?;
+               $field = ::util::ser::Readable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, vec_type) => {{
-               let f: ::util::ser::VecReadWrapper<_> = ser::Readable::read(&mut $reader)?;
+               let f: ::util::ser::VecReadWrapper<_> = ::util::ser::Readable::read(&mut $reader)?;
                $field = Some(f.0);
        }};
        ($reader: expr, $field: ident, option) => {{
-               $field = Some(ser::Readable::read(&mut $reader)?);
+               $field = Some(::util::ser::Readable::read(&mut $reader)?);
        }};
        ($reader: expr, $field: ident, ignorable) => {{
-               $field = ser::MaybeReadable::read(&mut $reader)?;
+               $field = ::util::ser::MaybeReadable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = Some($trait::read(&mut $reader $(, $read_arg)*)?);
        }};
 }
 
+// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
+// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
+// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
+// `Ok(false)` if the message type is unknown, and `Err(DecodeError)` if parsing fails.
 macro_rules! decode_tlv_stream {
-       ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
+       ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
+        $(, $decode_custom_tlv: expr)?) => { {
                use ln::msgs::DecodeError;
                let mut last_seen_type: Option<u64> = None;
                let mut stream_ref = $stream;
@@ -226,10 +231,19 @@ macro_rules! decode_tlv_stream {
                                                return Err(DecodeError::InvalidValue);
                                        }
                                },)*
-                               x if x % 2 == 0 => {
-                                       return Err(DecodeError::UnknownRequiredFeature);
-                               },
-                               _ => {},
+                               t => {
+                                       $(
+                                               if $decode_custom_tlv(t, &mut s)? {
+                                                       // If a custom TLV was successfully read (i.e. decode_custom_tlv returns true),
+                                                       // continue to the next TLV read.
+                                                       s.eat_remaining()?;
+                                                       continue 'tlv_read;
+                                               }
+                                       )?
+                                       if t % 2 == 0 {
+                                               return Err(DecodeError::UnknownRequiredFeature);
+                                       }
+                               }
                        }
                        s.eat_remaining()?;
                }