X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser_macros.rs;h=92a43b3fde5282fb4420d4981c1e23b3d9bd0e81;hb=3d479c9de62665214e8589699cdbb8a797b77188;hp=1f617de40b3ced31491cd8deedc6cf11a9b83dab;hpb=5d0ee867ea6c9670ebfe6004614e9ebaa7502c64;p=rust-lightning diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 1f617de4..92a43b3f 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -51,6 +51,10 @@ macro_rules! _encode_tlv { ($stream: expr, $type: expr, $field: expr, (option, encoding: $fieldty: ty)) => { $crate::_encode_tlv!($stream, $type, $field, option); }; + ($stream: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => { + // Just a read-mapped type + $crate::_encode_tlv!($stream, $type, $field, option); + }; } /// Panics if the last seen TLV type is not numerically less than the TLV type currently being checked. @@ -161,6 +165,9 @@ macro_rules! _get_varint_length_prefixed_tlv_length { $len.0 += field_len; } }; + ($len: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?)) => { + $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, option); + }; ($len: expr, $type: expr, $field: expr, upgradable_required) => { $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required); }; @@ -210,6 +217,9 @@ macro_rules! _check_decoded_tlv_order { return Err(DecodeError::InvalidValue); } }}; + ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{ + $crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required); + }}; ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{ // no-op }}; @@ -252,6 +262,9 @@ macro_rules! _check_missing_tlv { return Err(DecodeError::InvalidValue); } }}; + ($last_seen_type: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{ + $crate::_check_missing_tlv!($last_seen_type, $type, $field, required); + }}; ($last_seen_type: expr, $type: expr, $field: ident, vec_type) => {{ // no-op }}; @@ -285,6 +298,9 @@ macro_rules! _decode_tlv { ($reader: expr, $field: ident, required) => {{ $field = $crate::util::ser::Readable::read(&mut $reader)?; }}; + ($reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{ + $field = $trait::read(&mut $reader $(, $read_arg)*)?; + }}; ($reader: expr, $field: ident, vec_type) => {{ let f: $crate::util::ser::WithoutLength> = $crate::util::ser::Readable::read(&mut $reader)?; $field = Some(f.0); @@ -292,12 +308,19 @@ macro_rules! _decode_tlv { ($reader: expr, $field: ident, option) => {{ $field = Some($crate::util::ser::Readable::read(&mut $reader)?); }}; + // `upgradable_required` indicates we're reading a required TLV that may have been upgraded + // without backwards compat. We'll error if the field is missing, and return `Ok(None)` if the + // field is present but we can no longer understand it. + // Note that this variant can only be used within a `MaybeReadable` read. ($reader: expr, $field: ident, upgradable_required) => {{ $field = match $crate::util::ser::MaybeReadable::read(&mut $reader)? { Some(res) => res, _ => return Ok(None) }; }}; + // `upgradable_option` indicates we're reading an Option-al TLV that may have been upgraded + // without backwards compat. $field will be None if the TLV is missing or if the field is present + // but we can no longer understand it. ($reader: expr, $field: ident, upgradable_option) => {{ $field = $crate::util::ser::MaybeReadable::read(&mut $reader)?; }}; @@ -396,7 +419,6 @@ macro_rules! decode_tlv_stream_with_custom_tlv_decode { macro_rules! _decode_tlv_stream_range { ($stream: expr, $range: expr, $rewind: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*} $(, $decode_custom_tlv: expr)?) => { { - use core::ops::RangeBounds; use $crate::ln::msgs::DecodeError; let mut last_seen_type: Option = None; let mut stream_ref = $stream; @@ -419,7 +441,7 @@ macro_rules! _decode_tlv_stream_range { } }, Err(e) => return Err(e), - Ok(t) => if $range.contains(&t.0) { t } else { + Ok(t) => if core::ops::RangeBounds::contains(&$range, &t.0) { t } else { drop(tracking_reader); // Assumes the type id is minimally encoded, which is enforced on read. @@ -638,6 +660,9 @@ macro_rules! _init_tlv_based_struct_field { ($field: ident, option) => { $field }; + ($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => { + $crate::_init_tlv_based_struct_field!($field, option) + }; ($field: ident, upgradable_required) => { $field.0.unwrap() }; @@ -667,12 +692,18 @@ macro_rules! _init_tlv_field_var { ($field: ident, required) => { let mut $field = $crate::util::ser::RequiredWrapper(None); }; + ($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => { + $crate::_init_tlv_field_var!($field, required); + }; ($field: ident, vec_type) => { let mut $field = Some(Vec::new()); }; ($field: ident, option) => { let mut $field = None; }; + ($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => { + $crate::_init_tlv_field_var!($field, option); + }; ($field: ident, upgradable_required) => { let mut $field = $crate::util::ser::UpgradableRequired(None); }; @@ -843,6 +874,8 @@ macro_rules! tlv_record_ref_type { ($type:ty) => { &'a $type }; } +#[doc(hidden)] +#[macro_export] macro_rules! _impl_writeable_tlv_based_enum_common { ($st: ident, $(($variant_id: expr, $variant_name: ident) => {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*} @@ -854,7 +887,7 @@ macro_rules! _impl_writeable_tlv_based_enum_common { $($st::$variant_name { $(ref $field),* } => { let id: u8 = $variant_id; id.write(writer)?; - write_tlv_fields!(writer, { + $crate::write_tlv_fields!(writer, { $(($type, *$field, $fieldty)),* }); }),* @@ -892,7 +925,7 @@ macro_rules! impl_writeable_tlv_based_enum { {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*} ),* $(,)*; $(($tuple_variant_id: expr, $tuple_variant_name: ident)),* $(,)*) => { - _impl_writeable_tlv_based_enum_common!($st, + $crate::_impl_writeable_tlv_based_enum_common!($st, $(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*; $(($tuple_variant_id, $tuple_variant_name)),*); @@ -904,12 +937,12 @@ macro_rules! impl_writeable_tlv_based_enum { // Because read_tlv_fields creates a labeled loop, we cannot call it twice // in the same function body. Instead, we define a closure and call it. let f = || { - _init_and_read_tlv_fields!(reader, { + $crate::_init_and_read_tlv_fields!(reader, { $(($type, $field, $fieldty)),* }); Ok($st::$variant_name { $( - $field: _init_tlv_based_struct_field!($field, $fieldty) + $field: $crate::_init_tlv_based_struct_field!($field, $fieldty) ),* }) }; @@ -946,7 +979,7 @@ macro_rules! impl_writeable_tlv_based_enum_upgradable { ),* $(,)* $(; $(($tuple_variant_id: expr, $tuple_variant_name: ident)),* $(,)*)*) => { - _impl_writeable_tlv_based_enum_common!($st, + $crate::_impl_writeable_tlv_based_enum_common!($st, $(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*; $($(($tuple_variant_id, $tuple_variant_name)),*)*); @@ -958,12 +991,12 @@ macro_rules! impl_writeable_tlv_based_enum_upgradable { // Because read_tlv_fields creates a labeled loop, we cannot call it twice // in the same function body. Instead, we define a closure and call it. let f = || { - _init_and_read_tlv_fields!(reader, { + $crate::_init_and_read_tlv_fields!(reader, { $(($type, $field, $fieldty)),* }); Ok(Some($st::$variant_name { $( - $field: _init_tlv_based_struct_field!($field, $fieldty) + $field: $crate::_init_tlv_based_struct_field!($field, $fieldty) ),* })) };