X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser_macros.rs;fp=lightning%2Fsrc%2Futil%2Fser_macros.rs;h=8c0a38670b5ad811dffd534721e3980b02fb444d;hb=d6321e6e11b3e1b11e26617d3bab0b8c21da0b5b;hp=94990fcb8a17c8056dfd01d00b18db78d58e466f;hpb=89747dc085ba1e1185e7dd2b0ce6b7cc24b25e2b;p=rust-lightning diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 94990fcb..8c0a3867 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -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 = 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()?; }