Skip to content

Commit 222e545

Browse files
TheBlueMattAntoine Riard
authored and
Antoine Riard
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 afae12e commit 222e545

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
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
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
'tlv_read: loop {
@@ -168,7 +191,7 @@ macro_rules! decode_tlv_stream {
168191
}
169192
// As we read types, make sure we hit every required type:
170193
$({
171-
check_tlv_order!(last_seen_type, typ, $type, $fieldty);
194+
check_tlv_order!(last_seen_type, typ, $type, $field, $fieldty);
172195
})*
173196
last_seen_type = Some(typ.0);
174197

@@ -192,7 +215,7 @@ macro_rules! decode_tlv_stream {
192215
}
193216
// Make sure we got to each required type after we've read every TLV:
194217
$({
195-
check_missing_tlv!(last_seen_type, $type, $fieldty);
218+
check_missing_tlv!(last_seen_type, $type, $field, $fieldty);
196219
})*
197220
} }
198221
}
@@ -326,7 +349,7 @@ macro_rules! write_ver_prefix {
326349
/// This is the preferred method of adding new fields that old nodes can ignore and still function
327350
/// correctly.
328351
macro_rules! write_tlv_fields {
329-
($stream: expr, {$(($type: expr, $field: expr, $fieldty: ident)),* $(,)*}) => {
352+
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
330353
encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*});
331354
}
332355
}
@@ -347,7 +370,7 @@ macro_rules! read_ver_prefix {
347370

348371
/// Reads a suffix added by write_tlv_fields.
349372
macro_rules! read_tlv_fields {
350-
($stream: expr, {$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}) => { {
373+
($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
351374
let tlv_len = ::util::ser::BigSize::read($stream)?;
352375
let mut rd = ::util::ser::FixedLengthReader::new($stream, tlv_len.0);
353376
decode_tlv_stream!(&mut rd, {$(($type, $field, $fieldty)),*});
@@ -356,6 +379,9 @@ macro_rules! read_tlv_fields {
356379
}
357380

358381
macro_rules! init_tlv_based_struct_field {
382+
($field: ident, (default_value, $default: expr)) => {
383+
$field
384+
};
359385
($field: ident, option) => {
360386
$field
361387
};
@@ -368,6 +394,9 @@ macro_rules! init_tlv_based_struct_field {
368394
}
369395

370396
macro_rules! init_tlv_field_var {
397+
($field: ident, (default_value, $default: expr)) => {
398+
let mut $field = $default;
399+
};
371400
($field: ident, required) => {
372401
let mut $field = ::util::ser::OptionDeserWrapper(None);
373402
};
@@ -385,7 +414,7 @@ macro_rules! init_tlv_field_var {
385414
/// if $fieldty is `vec_type`, then $field is a Vec, which needs to have its individual elements
386415
/// serialized.
387416
macro_rules! impl_writeable_tlv_based {
388-
($st: ident, {$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}) => {
417+
($st: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
389418
impl ::util::ser::Writeable for $st {
390419
fn write<W: ::util::ser::Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
391420
write_tlv_fields!(writer, {
@@ -441,7 +470,7 @@ macro_rules! impl_writeable_tlv_based {
441470
/// Attempts to read an unknown type byte result in DecodeError::UnknownRequiredFeature.
442471
macro_rules! impl_writeable_tlv_based_enum {
443472
($st: ident, $(($variant_id: expr, $variant_name: ident) =>
444-
{$(($type: expr, $field: ident, $fieldty: ident)),* $(,)*}
473+
{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
445474
),* $(,)*;
446475
$(($tuple_variant_id: expr, $tuple_variant_name: ident)),* $(,)*) => {
447476
impl ::util::ser::Writeable for $st {

0 commit comments

Comments
 (0)