Merge pull request #2128 from valentinewallace/2023-03-route-blinding-groundwork
[rust-lightning] / lightning / src / util / ser_macros.rs
index 92a43b3fde5282fb4420d4981c1e23b3d9bd0e81..1744b923d5e92589eee665c5a1ef1e263b6cfd8b 100644 (file)
 //! [`Readable`]: crate::util::ser::Readable
 //! [`Writeable`]: crate::util::ser::Writeable
 
+// There are quite a few TLV serialization "types" which behave differently. We currently only
+// publicly document the `optional` and `required` types, not supporting anything else publicly and
+// changing them at will.
+//
+// Some of the other types include:
+//  * (default_value, $default) - reads optionally, reading $default if no TLV is present
+//  * (static_value, $value) - ignores any TLVs, always using $value
+//  * required_vec - reads into a Vec without a length prefix, failing if no TLV is present.
+//  * optional_vec - reads into an Option<Vec> without a length prefix, continuing if no TLV is
+//                   present. Writes from a Vec directly, only if any elements are present. Note
+//                   that the struct deserialization macros return a Vec, not an Option.
+//  * upgradable_option - reads via MaybeReadable.
+//  * upgradable_required - reads via MaybeReadable, requiring a TLV be present but may return None
+//                          if MaybeReadable::read() returns None.
+
 /// Implements serialization for a single TLV record.
 /// This is exported for use by other exported macros, do not use directly.
 #[doc(hidden)]
@@ -29,7 +44,7 @@ macro_rules! _encode_tlv {
                BigSize($field.serialized_length() as u64).write($stream)?;
                $field.write($stream)?;
        };
-       ($stream: expr, $type: expr, $field: expr, vec_type) => {
+       ($stream: expr, $type: expr, $field: expr, required_vec) => {
                $crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($stream: expr, $optional_type: expr, $optional_field: expr, option) => {
@@ -39,6 +54,11 @@ macro_rules! _encode_tlv {
                        field.write($stream)?;
                }
        };
+       ($stream: expr, $type: expr, $field: expr, optional_vec) => {
+               if !$field.is_empty() {
+                       $crate::_encode_tlv!($stream, $type, $field, required_vec);
+               }
+       };
        ($stream: expr, $type: expr, $field: expr, upgradable_required) => {
                $crate::_encode_tlv!($stream, $type, $field, required);
        };
@@ -154,7 +174,7 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
                BigSize(field_len as u64).write(&mut $len).expect("No in-memory data may fail to serialize");
                $len.0 += field_len;
        };
-       ($len: expr, $type: expr, $field: expr, vec_type) => {
+       ($len: expr, $type: expr, $field: expr, required_vec) => {
                $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($len: expr, $optional_type: expr, $optional_field: expr, option) => {
@@ -165,9 +185,17 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
                        $len.0 += field_len;
                }
        };
+       ($len: expr, $type: expr, $field: expr, optional_vec) => {
+               if !$field.is_empty() {
+                       $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required_vec);
+               }
+       };
        ($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, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
+               $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field.map(|f| $encoding(f)), option);
+       };
        ($len: expr, $type: expr, $field: expr, upgradable_required) => {
                $crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required);
        };
@@ -223,7 +251,10 @@ macro_rules! _check_decoded_tlv_order {
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
                // no-op
        }};
-       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
+       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required_vec) => {{
+               $crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
+       }};
+       ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, optional_vec) => {{
                // no-op
        }};
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_required) => {{
@@ -265,12 +296,15 @@ macro_rules! _check_missing_tlv {
        ($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
+       ($last_seen_type: expr, $type: expr, $field: ident, required_vec) => {{
+               $crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
        }};
        ($last_seen_type: expr, $type: expr, $field: ident, option) => {{
                // no-op
        }};
+       ($last_seen_type: expr, $type: expr, $field: ident, optional_vec) => {{
+               // no-op
+       }};
        ($last_seen_type: expr, $type: expr, $field: ident, upgradable_required) => {{
                _check_missing_tlv!($last_seen_type, $type, $field, required)
        }};
@@ -301,13 +335,17 @@ macro_rules! _decode_tlv {
        ($reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = $trait::read(&mut $reader $(, $read_arg)*)?;
        }};
-       ($reader: expr, $field: ident, vec_type) => {{
+       ($reader: expr, $field: ident, required_vec) => {{
                let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
-               $field = Some(f.0);
+               $field = f.0;
        }};
        ($reader: expr, $field: ident, option) => {{
                $field = Some($crate::util::ser::Readable::read(&mut $reader)?);
        }};
+       ($reader: expr, $field: ident, optional_vec) => {{
+               let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
+               $field = Some(f.0);
+       }};
        // `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.
@@ -535,7 +573,7 @@ macro_rules! impl_writeable_msg {
                impl $crate::util::ser::Writeable for $st {
                        fn write<W: $crate::util::ser::Writer>(&self, w: &mut W) -> Result<(), $crate::io::Error> {
                                $( self.$field.write(w)?; )*
-                               $crate::encode_tlv_stream!(w, {$(($type, self.$tlvfield, $fieldty)),*});
+                               $crate::encode_tlv_stream!(w, {$(($type, self.$tlvfield.as_ref(), $fieldty)),*});
                                Ok(())
                        }
                }
@@ -672,7 +710,10 @@ macro_rules! _init_tlv_based_struct_field {
        ($field: ident, required) => {
                $field.0.unwrap()
        };
-       ($field: ident, vec_type) => {
+       ($field: ident, required_vec) => {
+               $field
+       };
+       ($field: ident, optional_vec) => {
                $field.unwrap()
        };
 }
@@ -695,12 +736,18 @@ macro_rules! _init_tlv_field_var {
        ($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, required_vec) => {
+               let mut $field = Vec::new();
        };
        ($field: ident, option) => {
                let mut $field = None;
        };
+       ($field: ident, optional_vec) => {
+               let mut $field = Some(Vec::new());
+       };
+       ($field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
+               $crate::_init_tlv_field_var!($field, option);
+       };
        ($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
                $crate::_init_tlv_field_var!($field, option);
        };
@@ -733,7 +780,8 @@ macro_rules! _init_and_read_tlv_fields {
 /// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
 /// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
 /// If `$fieldty` is `option`, then `$field` is optional field.
-/// If `$fieldty` is `vec_type`, then `$field` is a [`Vec`], which needs to have its individual elements serialized.
+/// If `$fieldty` is `optional_vec`, then `$field` is a [`Vec`], which needs to have its individual elements serialized.
+///    Note that for `optional_vec` no bytes are written if the vec is empty
 ///
 /// For example,
 /// ```
@@ -749,7 +797,7 @@ macro_rules! _init_and_read_tlv_fields {
 ///    (0, tlv_integer, required),
 ///    (1, tlv_default_integer, (default_value, 7)),
 ///    (2, tlv_optional_integer, option),
-///    (3, tlv_vec_type_integer, vec_type),
+///    (3, tlv_vec_type_integer, optional_vec),
 /// });
 /// ```
 ///
@@ -909,7 +957,7 @@ macro_rules! _impl_writeable_tlv_based_enum_common {
 /// ```ignore
 /// impl_writeable_tlv_based_enum!(EnumName,
 ///   (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
-///   (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, vec_type)};
+///   (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, optional_vec)};
 ///   (2, TupleVariantA), (3, TupleVariantB),
 /// );
 /// ```
@@ -949,7 +997,7 @@ macro_rules! impl_writeable_tlv_based_enum {
                                                f()
                                        }),*
                                        $($tuple_variant_id => {
-                                               Ok($st::$tuple_variant_name(Readable::read(reader)?))
+                                               Ok($st::$tuple_variant_name($crate::util::ser::Readable::read(reader)?))
                                        }),*
                                        _ => {
                                                Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature)