Skip to content

Commit aeb9140

Browse files
committed
Add additional TLV serialization type of (default_value, N)
This allows TLV serialization macros to read non-Option-wrapped types but allow them to be missing, filling them in with the provided default value as needed.
1 parent e1ee622 commit aeb9140

File tree

1 file changed

+44
-15
lines changed

1 file changed

+44
-15
lines changed

lightning/src/util/ser_macros.rs

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// licenses.
99

1010
macro_rules! encode_tlv {
11+
($stream: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
12+
encode_tlv!($stream, $type, $field, required)
13+
};
1114
($stream: expr, $type: expr, $field: expr, required) => {
1215
BigSize($type).write($stream)?;
1316
BigSize($field.serialized_length() as u64).write($stream)?;
@@ -26,7 +29,7 @@ macro_rules! encode_tlv {
2629
}
2730

2831
macro_rules! encode_tlv_stream {
29-
($stream: expr, {$(($type: expr, $field: expr, $fieldty: ident)),* $(,)*}) => { {
32+
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => { {
3033
#[allow(unused_imports)]
3134
use {
3235
ln::msgs::DecodeError,
@@ -53,6 +56,9 @@ macro_rules! encode_tlv_stream {
5356
}
5457

5558
macro_rules! get_varint_length_prefixed_tlv_length {
59+
($len: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
60+
get_varint_length_prefixed_tlv_length!($len, $type, $field, required)
61+
};
5662
($len: expr, $type: expr, $field: expr, required) => {
5763
BigSize($type).write(&mut $len).expect("No in-memory data may fail to serialize");
5864
let field_len = $field.serialized_length();
@@ -73,7 +79,7 @@ macro_rules! get_varint_length_prefixed_tlv_length {
7379
}
7480

7581
macro_rules! encode_varint_length_prefixed_tlv {
76-
($stream: expr, {$(($type: expr, $field: expr, $fieldty: ident)),*}) => { {
82+
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),*}) => { {
7783
use util::ser::BigSize;
7884
let len = {
7985
#[allow(unused_mut)]
@@ -89,38 +95,55 @@ macro_rules! encode_varint_length_prefixed_tlv {
8995
}
9096

9197
macro_rules! check_tlv_order {
92-
($last_seen_type: expr, $typ: expr, $type: expr, required) => {{
98+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
99+
#[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
100+
let invalid_order = ($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
101+
if invalid_order {
102+
$field = $default;
103+
}
104+
}};
105+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => {{
93106
#[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
94107
let invalid_order = ($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
95108
if invalid_order {
96109
return Err(DecodeError::InvalidValue);
97110
}
98111
}};
99-
($last_seen_type: expr, $typ: expr, $type: expr, option) => {{
112+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
100113
// no-op
101114
}};
102-
($last_seen_type: expr, $typ: expr, $type: expr, vec_type) => {{
115+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
103116
// no-op
104117
}};
105118
}
106119

107120
macro_rules! check_missing_tlv {
108-
($last_seen_type: expr, $type: expr, required) => {{
121+
($last_seen_type: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
122+
#[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
123+
let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
124+
if missing_req_type {
125+
$field = $default;
126+
}
127+
}};
128+
($last_seen_type: expr, $type: expr, $field: ident, required) => {{
109129
#[allow(unused_comparisons)] // Note that $type may be 0 making the second comparison always true
110130
let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
111131
if missing_req_type {
112132
return Err(DecodeError::InvalidValue);
113133
}
114134
}};
115-
($last_seen_type: expr, $type: expr, vec_type) => {{
135+
($last_seen_type: expr, $type: expr, $field: ident, vec_type) => {{
116136
// no-op
117137
}};
118-
($last_seen_type: expr, $type: expr, option) => {{
138+
($last_seen_type: expr, $type: expr, $field: ident, option) => {{
119139
// no-op
120140
}};
121141
}
122142

123143
macro_rules! decode_tlv {
144+
($reader: expr, $field: ident, (default_value, $default: expr)) => {{
145+
decode_tlv!($reader, $field, required)
146+
}};
124147
($reader: expr, $field: ident, required) => {{
125148
$field = ser::Readable::read(&mut $reader)?;
126149
}};
@@ -133,7 +156,7 @@ macro_rules! decode_tlv {
133156
}
134157

135158
macro_rules! decode_tlv_stream {
136-
($stream: expr, {$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}) => { {
159+
($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
137160
use ln::msgs::DecodeError;
138161
let mut last_seen_type: Option<u64> = None;
139162
let mut stream_ref = $stream;
@@ -169,7 +192,7 @@ macro_rules! decode_tlv_stream {
169192
}
170193
// As we read types, make sure we hit every required type:
171194
$({
172-
check_tlv_order!(last_seen_type, typ, $type, $fieldty);
195+
check_tlv_order!(last_seen_type, typ, $type, $field, $fieldty);
173196
})*
174197
last_seen_type = Some(typ.0);
175198

@@ -193,7 +216,7 @@ macro_rules! decode_tlv_stream {
193216
}
194217
// Make sure we got to each required type after we've read every TLV:
195218
$({
196-
check_missing_tlv!(last_seen_type, $type, $fieldty);
219+
check_missing_tlv!(last_seen_type, $type, $field, $fieldty);
197220
})*
198221
} }
199222
}
@@ -327,7 +350,7 @@ macro_rules! write_ver_prefix {
327350
/// This is the preferred method of adding new fields that old nodes can ignore and still function
328351
/// correctly.
329352
macro_rules! write_tlv_fields {
330-
($stream: expr, {$(($type: expr, $field: expr, $fieldty: ident)),* $(,)*}) => {
353+
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
331354
encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*});
332355
}
333356
}
@@ -348,7 +371,7 @@ macro_rules! read_ver_prefix {
348371

349372
/// Reads a suffix added by write_tlv_fields.
350373
macro_rules! read_tlv_fields {
351-
($stream: expr, {$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}) => { {
374+
($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
352375
let tlv_len = ::util::ser::BigSize::read($stream)?;
353376
let mut rd = ::util::ser::FixedLengthReader::new($stream, tlv_len.0);
354377
decode_tlv_stream!(&mut rd, {$(($type, $field, $fieldty)),*});
@@ -357,6 +380,9 @@ macro_rules! read_tlv_fields {
357380
}
358381

359382
macro_rules! init_tlv_based_struct_field {
383+
($field: ident, (default_value, $default: expr)) => {
384+
$field
385+
};
360386
($field: ident, option) => {
361387
$field
362388
};
@@ -369,6 +395,9 @@ macro_rules! init_tlv_based_struct_field {
369395
}
370396

371397
macro_rules! init_tlv_field_var {
398+
($field: ident, (default_value, $default: expr)) => {
399+
let mut $field = $default;
400+
};
372401
($field: ident, required) => {
373402
let mut $field = ::util::ser::OptionDeserWrapper(None);
374403
};
@@ -386,7 +415,7 @@ macro_rules! init_tlv_field_var {
386415
/// if $fieldty is `vec_type`, then $field is a Vec, which needs to have its individual elements
387416
/// serialized.
388417
macro_rules! impl_writeable_tlv_based {
389-
($st: ident, {$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}) => {
418+
($st: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
390419
impl ::util::ser::Writeable for $st {
391420
fn write<W: ::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
392421
write_tlv_fields!(writer, {
@@ -442,7 +471,7 @@ macro_rules! impl_writeable_tlv_based {
442471
/// Attempts to read an unknown type byte result in DecodeError::UnknownRequiredFeature.
443472
macro_rules! impl_writeable_tlv_based_enum {
444473
($st: ident, $(($variant_id: expr, $variant_name: ident) =>
445-
{$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}
474+
{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
446475
),* $(,)*;
447476
$(($tuple_variant_id: expr, $tuple_variant_name: ident)),* $(,)*) => {
448477
impl ::util::ser::Writeable for $st {

0 commit comments

Comments
 (0)