Skip to content

Commit 4f5e64a

Browse files
authored
Merge pull request #4507 from carlaKC/default-vec-macro
util: add default_value_vec for defaults without LengthReadable
2 parents 6c94e5d + 5330f9f commit 4f5e64a

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

lightning/src/util/ser_macros.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ macro_rules! _encode_tlv {
2121
($stream: expr, $type: expr, $field: expr, (default_value, $default: expr) $(, $self: ident)?) => {
2222
$crate::_encode_tlv!($stream, $type, $field, required)
2323
};
24+
($stream: expr, $type: expr, $field: expr, (default_value_vec, $default: expr) $(, $self: ident)?) => {
25+
$crate::_encode_tlv!($stream, $type, $field, required_vec)
26+
};
2427
($stream: expr, $type: expr, $field: expr, (static_value, $value: expr) $(, $self: ident)?) => {
2528
let _ = &$field; // Ensure we "use" the $field
2629
};
@@ -200,6 +203,9 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
200203
($len: expr, $type: expr, $field: expr, (default_value, $default: expr) $(, $self: ident)?) => {
201204
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required)
202205
};
206+
($len: expr, $type: expr, $field: expr, (default_value_vec, $default: expr) $(, $self: ident)?) => {
207+
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required_vec)
208+
};
203209
($len: expr, $type: expr, $field: expr, (static_value, $value: expr) $(, $self: ident)?) => {};
204210
($len: expr, $type: expr, $field: expr, required $(, $self: ident)?) => {
205211
BigSize($type).write(&mut $len).expect("No in-memory data may fail to serialize");
@@ -301,6 +307,15 @@ macro_rules! _check_decoded_tlv_order {
301307
$field = $default.into();
302308
}
303309
}};
310+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value_vec, $default: expr)) => {{
311+
$crate::_check_decoded_tlv_order!(
312+
$last_seen_type,
313+
$typ,
314+
$type,
315+
$field,
316+
(default_value, $default)
317+
);
318+
}};
304319
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (static_value, $value: expr)) => {};
305320
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => {{
306321
// Note that $type may be 0 making the second comparison always false
@@ -372,6 +387,9 @@ macro_rules! _check_missing_tlv {
372387
$field = $default.into();
373388
}
374389
}};
390+
($last_seen_type: expr, $type: expr, $field: ident, (default_value_vec, $default: expr)) => {{
391+
$crate::_check_missing_tlv!($last_seen_type, $type, $field, (default_value, $default));
392+
}};
375393
($last_seen_type: expr, $type: expr, $field: expr, (static_value, $value: expr)) => {
376394
$field = $value;
377395
};
@@ -440,6 +458,10 @@ macro_rules! _decode_tlv {
440458
($outer_reader: expr, $reader: expr, $field: ident, (default_value, $default: expr)) => {{
441459
$crate::_decode_tlv!($outer_reader, $reader, $field, required)
442460
}};
461+
($outer_reader: expr, $reader: expr, $field: ident, (default_value_vec, $default: expr)) => {{
462+
let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
463+
$field = $crate::util::ser::RequiredWrapper(Some(f.0));
464+
}};
443465
($outer_reader: expr, $reader: expr, $field: ident, (static_value, $value: expr)) => {{
444466
}};
445467
($outer_reader: expr, $reader: expr, $field: ident, required) => {{
@@ -854,6 +876,9 @@ macro_rules! _init_tlv_based_struct_field {
854876
($field: ident, (default_value, $default: expr)) => {
855877
$field.0.unwrap()
856878
};
879+
($field: ident, (default_value_vec, $default: expr)) => {
880+
$crate::_init_tlv_based_struct_field!($field, (default_value, $default))
881+
};
857882
($field: ident, (static_value, $value: expr)) => {
858883
$field
859884
};
@@ -905,6 +930,9 @@ macro_rules! _init_tlv_field_var {
905930
($field: ident, (default_value, $default: expr)) => {
906931
let mut $field = $crate::util::ser::RequiredWrapper(None);
907932
};
933+
($field: ident, (default_value_vec, $default: expr)) => {
934+
$crate::_init_tlv_field_var!($field, (default_value, $default));
935+
};
908936
($field: ident, (static_value, $value: expr)) => {
909937
let $field;
910938
};
@@ -1007,6 +1035,9 @@ macro_rules! _decode_and_build {
10071035
///
10081036
/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
10091037
/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
1038+
/// If `$fieldty` is `(default_value_vec, $default)`, then `$field` is a [`Vec`] which will be set to `$default`
1039+
/// if not present. Elements are serialized individually without a count prefix (like `required_vec`).
1040+
/// The TLV is always written, even if the vec is empty (matching `default_value` behavior).
10101041
/// If `$fieldty` is `(static_value, $static)`, then `$field` will be set to `$static`.
10111042
/// If `$fieldty` is `option`, then `$field` is optional field.
10121043
/// If `$fieldty` is `upgradable_option`, then `$field` is optional and read via [`MaybeReadable`].
@@ -1019,7 +1050,7 @@ macro_rules! _decode_and_build {
10191050
/// `Some`. When reading, an optional field of type `$ty` is read, and after all TLV fields are
10201051
/// read, the `$read` closure is called with the `Option<&$ty>` value. The `$read` closure should
10211052
/// return a `Result<(), DecodeError>`. Legacy field values can be used in later
1022-
/// `default_value` or `static_value` fields by referring to the value by name.
1053+
/// `default_value`, `default_value_vec`, or `static_value` fields by referring to the value by name.
10231054
/// If `$fieldty` is `(custom, $ty, $read, $write)` then, when writing, the same behavior as
10241055
/// `legacy`, above is used. When reading, if a TLV is present, it is read as `$ty` and the
10251056
/// `$read` method is called with `Some(decoded_$ty_object)`. If no TLV is present, the field
@@ -1956,6 +1987,59 @@ mod tests {
19561987
assert_eq!(read, ExpandedField { new_field: (42, 0) });
19571988
}
19581989

1990+
#[derive(Debug, PartialEq, Eq)]
1991+
struct DefaultValueVecStruct {
1992+
items: Vec<u32>,
1993+
}
1994+
impl_writeable_tlv_based!(DefaultValueVecStruct, {
1995+
(1, items, (default_value_vec, vec![4, 5, 6])),
1996+
});
1997+
1998+
#[test]
1999+
fn test_default_value_vec() {
2000+
// Non-empty vec round-trips correctly.
2001+
let instance = DefaultValueVecStruct { items: vec![1, 2, 3] };
2002+
let encoded = instance.encode();
2003+
let decoded: DefaultValueVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2004+
assert_eq!(decoded, instance);
2005+
2006+
// Empty TLV stream falls back to the default.
2007+
let empty_encoded = <Vec<u8>>::from_hex("00").unwrap(); // zero-length TLV stream
2008+
let decoded: DefaultValueVecStruct = Readable::read(&mut &empty_encoded[..]).unwrap();
2009+
assert_eq!(decoded, DefaultValueVecStruct { items: vec![4, 5, 6] });
2010+
2011+
// Empty vec round-trips to empty vec (TLV is always written).
2012+
let empty_vec = DefaultValueVecStruct { items: vec![] };
2013+
let encoded = empty_vec.encode();
2014+
let decoded: DefaultValueVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2015+
assert_eq!(decoded, DefaultValueVecStruct { items: vec![] });
2016+
}
2017+
2018+
#[derive(Debug, PartialEq, Eq)]
2019+
struct LegacyToVecStruct {
2020+
new_items: Vec<u32>,
2021+
}
2022+
impl_writeable_tlv_based!(LegacyToVecStruct, {
2023+
(0, old_item, (legacy, u32, |_| Ok(()),
2024+
|us: &LegacyToVecStruct| us.new_items.first().copied())),
2025+
(1, new_items, (default_value_vec,
2026+
old_item.map(|v| vec![v]).unwrap_or_default())),
2027+
});
2028+
2029+
#[test]
2030+
fn test_default_value_vec_with_legacy_fallback() {
2031+
// New format: round-trips via the new TLV.
2032+
let instance = LegacyToVecStruct { new_items: vec![10, 20, 30] };
2033+
let encoded = instance.encode();
2034+
let decoded: LegacyToVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2035+
assert_eq!(decoded, instance);
2036+
2037+
// Old format: only the legacy type-0 field is present, falls back via default expression.
2038+
let old_encoded = <Vec<u8>>::from_hex("0600040000002a").unwrap(); // TLV len 6, type 0, len 4, value 42u32
2039+
let decoded: LegacyToVecStruct = Readable::read(&mut &old_encoded[..]).unwrap();
2040+
assert_eq!(decoded, LegacyToVecStruct { new_items: vec![42] });
2041+
}
2042+
19592043
#[test]
19602044
fn required_vec_with_encoding() {
19612045
// Ensure that serializing a required vec with a specified encoding will survive a ser round

0 commit comments

Comments
 (0)