From: Matt Corallo Date: Mon, 6 Feb 2023 21:56:39 +0000 (+0000) Subject: Support `ReadableArgs` types across in the TLV struct serialization X-Git-Tag: v0.0.114-beta~1^2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=6aa5ebb1aac21f65462bbd747627ae58e2949ae3;p=rust-lightning Support `ReadableArgs` types across in the TLV struct serialization This adds `required` support for trait-wrapped reading (e.g. for objects read via `ReadableArgs`) as well as support for the trait-wrapped reading syntax across the TLV struct/enum serialization macros. --- diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 5adf57581..14c257751 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -289,17 +289,23 @@ impl MaybeReadable for T { } /// Wrapper to read a required (non-optional) TLV record. -pub struct RequiredWrapper(pub Option); +pub struct RequiredWrapper(pub Option); impl Readable for RequiredWrapper { #[inline] fn read(reader: &mut R) -> Result { Ok(Self(Some(Readable::read(reader)?))) } } +impl> ReadableArgs for RequiredWrapper { + #[inline] + fn read(reader: &mut R, args: A) -> Result { + Ok(Self(Some(ReadableArgs::read(reader, args)?))) + } +} /// When handling `default_values`, we want to map the default-value T directly /// to a `RequiredWrapper` in a way that works for `field: T = t;` as /// well. Thus, we assume `Into for T` does nothing and use that. -impl From for RequiredWrapper { +impl From for RequiredWrapper { fn from(t: T) -> RequiredWrapper { RequiredWrapper(Some(t)) } } diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 5e55ab1d3..59402f6ac 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); @@ -644,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() }; @@ -673,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); };