Skip to content

Commit 21822ca

Browse files
ser_macros: encoding wrapper for required_vec
For context, many of our higher level ser macros such as impl_writeable_msg support the syntax: impl_writeable_msg!(StructName, { .. }, { (42, tlv_field, (option, encoding: (Vec<u8>, WithoutLength>), }) i.e. specifying an encoding wrapper around an optional field being serialized. Here we add add similar support for an encoding wrapper around required_vecs that are being serialized, eg (42, tlv_field, (required_vec: (encoding: (..)))). One difficulty here is that some ser macros such as impl_writeable_msg and tlv_stream will call the underlying macro _encode_tlv_stream with each struct field passed in as a reference, whereas others such as impl_writeable_tlv_based will call _encode_tlv_stream with each struct field passed in as a value. This difference led to compilation issues because the WithoutLength ser wrapper expects to wrap a reference to a Vec, not a value. As a result, here we also modify the macros that were previously passing in struct values as values to pass in references instead.
1 parent ffa537e commit 21822ca

File tree

3 files changed

+62
-17
lines changed

3 files changed

+62
-17
lines changed

lightning/src/ln/msgs.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -3144,7 +3144,7 @@ impl<'a> Writeable for OutboundOnionPayload<'a> {
31443144
},
31453145
Self::BlindedForward { encrypted_tlvs, intro_node_blinding_point } => {
31463146
_encode_varint_length_prefixed_tlv!(w, {
3147-
(10, **encrypted_tlvs, required_vec),
3147+
(10, *encrypted_tlvs, required_vec),
31483148
(12, intro_node_blinding_point, option)
31493149
});
31503150
},
@@ -3165,7 +3165,7 @@ impl<'a> Writeable for OutboundOnionPayload<'a> {
31653165
_encode_varint_length_prefixed_tlv!(w, {
31663166
(2, HighZeroBytesDroppedBigSize(*sender_intended_htlc_amt_msat), required),
31673167
(4, HighZeroBytesDroppedBigSize(*cltv_expiry_height), required),
3168-
(10, **encrypted_tlvs, required_vec),
3168+
(10, *encrypted_tlvs, required_vec),
31693169
(12, intro_node_blinding_point, option),
31703170
(18, HighZeroBytesDroppedBigSize(*total_msat), required)
31713171
}, custom_tlvs.iter());
@@ -3206,15 +3206,15 @@ impl<'a> Writeable for OutboundTrampolinePayload<'a> {
32063206
},
32073207
Self::BlindedForward { encrypted_tlvs, intro_node_blinding_point} => {
32083208
_encode_varint_length_prefixed_tlv!(w, {
3209-
(10, **encrypted_tlvs, required_vec),
3209+
(10, *encrypted_tlvs, required_vec),
32103210
(12, intro_node_blinding_point, option)
32113211
});
32123212
},
32133213
Self::BlindedReceive { sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, encrypted_tlvs, intro_node_blinding_point, keysend_preimage, custom_tlvs } => {
32143214
_encode_varint_length_prefixed_tlv!(w, {
32153215
(2, HighZeroBytesDroppedBigSize(*sender_intended_htlc_amt_msat), required),
32163216
(4, HighZeroBytesDroppedBigSize(*cltv_expiry_height), required),
3217-
(10, **encrypted_tlvs, required_vec),
3217+
(10, *encrypted_tlvs, required_vec),
32183218
(12, intro_node_blinding_point, option),
32193219
(18, HighZeroBytesDroppedBigSize(*total_msat), required),
32203220
(20, keysend_preimage, option)
@@ -5592,7 +5592,7 @@ mod tests {
55925592
let test_bytes = vec![42u8; 1000];
55935593
if let msgs::OutboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } = payload {
55945594
_encode_varint_length_prefixed_tlv!(&mut encoded_payload, {
5595-
(1, test_bytes, required_vec),
5595+
(1, &test_bytes, required_vec),
55965596
(2, HighZeroBytesDroppedBigSize(amt_to_forward), required),
55975597
(4, HighZeroBytesDroppedBigSize(outgoing_cltv_value), required),
55985598
(6, short_channel_id, required)

lightning/src/onion_message/packet.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<T: OnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
217217
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
218218
match &self.0 {
219219
Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
220-
_encode_varint_length_prefixed_tlv!(w, { (4, *encrypted_bytes, required_vec) })
220+
_encode_varint_length_prefixed_tlv!(w, { (4, encrypted_bytes, required_vec) })
221221
},
222222
Payload::Receive {
223223
control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes),
@@ -226,7 +226,7 @@ impl<T: OnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
226226
} => {
227227
_encode_varint_length_prefixed_tlv!(w, {
228228
(2, reply_path, option),
229-
(4, *encrypted_bytes, required_vec),
229+
(4, encrypted_bytes, required_vec),
230230
(message.tlv_type(), message, required)
231231
})
232232
},

lightning/src/util/ser_macros.rs

+55-10
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ macro_rules! _encode_tlv {
3333
$crate::_encode_tlv!($stream, $type, $field, required);
3434
};
3535
($stream: expr, $type: expr, $field: expr, required_vec $(, $self: ident)?) => {
36-
$crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
36+
$crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength($field), required);
37+
};
38+
($stream: expr, $type: expr, $field: expr, (required_vec, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
39+
$crate::_encode_tlv!($stream, $type, $encoding($field), required);
3740
};
3841
($stream: expr, $optional_type: expr, $optional_field: expr, option $(, $self: ident)?) => {
3942
if let Some(ref field) = $optional_field {
@@ -166,7 +169,7 @@ macro_rules! _encode_tlv_stream {
166169
)*
167170
for tlv in $extra_tlvs {
168171
let (typ, value): &(u64, Vec<u8>) = tlv;
169-
$crate::_encode_tlv!($stream, *typ, *value, required_vec);
172+
$crate::_encode_tlv!($stream, *typ, value, required_vec);
170173
}
171174

172175
#[allow(unused_mut, unused_variables, unused_assignments)]
@@ -207,11 +210,15 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
207210
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required);
208211
};
209212
($len: expr, $type: expr, $field: expr, required_vec $(, $self: ident)?) => {
210-
let field = $crate::util::ser::WithoutLength(&$field);
213+
let field = $crate::util::ser::WithoutLength($field);
214+
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, field, required);
215+
};
216+
($len: expr, $type: expr, $field: expr, (required_vec, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
217+
let field = $encoding($field);
211218
$crate::_get_varint_length_prefixed_tlv_length!($len, $type, field, required);
212219
};
213220
($len: expr, $optional_type: expr, $optional_field: expr, option $(, $self: ident)?) => {
214-
if let Some(ref field) = $optional_field {
221+
if let Some(ref field) = $optional_field.as_ref() {
215222
BigSize($optional_type)
216223
.write(&mut $len)
217224
.expect("No in-memory data may fail to serialize");
@@ -265,7 +272,7 @@ macro_rules! _encode_varint_length_prefixed_tlv {
265272
)*
266273
for tlv in $extra_tlvs {
267274
let (typ, value): &(u64, Vec<u8>) = tlv;
268-
$crate::_get_varint_length_prefixed_tlv_length!(len, *typ, *value, required_vec);
275+
$crate::_get_varint_length_prefixed_tlv_length!(len, *typ, value, required_vec);
269276
}
270277
len.0
271278
};
@@ -316,6 +323,9 @@ macro_rules! _check_decoded_tlv_order {
316323
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required_vec) => {{
317324
$crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
318325
}};
326+
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required_vec, encoding: $encoding: tt)) => {{
327+
$crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
328+
}};
319329
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, optional_vec) => {{
320330
// no-op
321331
}};
@@ -363,6 +373,9 @@ macro_rules! _check_missing_tlv {
363373
($last_seen_type: expr, $type: expr, $field: ident, required_vec) => {{
364374
$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
365375
}};
376+
($last_seen_type: expr, $type: expr, $field: ident, (required_vec, encoding: $encoding: tt)) => {{
377+
$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
378+
}};
366379
($last_seen_type: expr, $type: expr, $field: ident, option) => {{
367380
// no-op
368381
}};
@@ -412,6 +425,12 @@ macro_rules! _decode_tlv {
412425
let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
413426
$field = f.0;
414427
}};
428+
($outer_reader: expr, $reader: expr, $field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {{
429+
$field = {
430+
let field: $encoding<$fieldty> = ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
431+
$crate::util::ser::RequiredWrapper(Some(field.0))
432+
};
433+
}};
415434
($outer_reader: expr, $reader: expr, $field: ident, option) => {{
416435
$field = Some($crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?);
417436
}};
@@ -762,7 +781,7 @@ macro_rules! write_ver_prefix {
762781
#[macro_export]
763782
macro_rules! write_tlv_fields {
764783
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
765-
$crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty)),*})
784+
$crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, &$field, $fieldty)),*})
766785
}
767786
}
768787

@@ -830,6 +849,9 @@ macro_rules! _init_tlv_based_struct_field {
830849
($field: ident, required_vec) => {
831850
$field
832851
};
852+
($field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {
853+
$crate::_init_tlv_based_struct_field!($field, required)
854+
};
833855
($field: ident, optional_vec) => {
834856
$field.unwrap()
835857
};
@@ -856,6 +878,9 @@ macro_rules! _init_tlv_field_var {
856878
($field: ident, required_vec) => {
857879
let mut $field = Vec::new();
858880
};
881+
($field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {
882+
$crate::_init_tlv_field_var!($field, required);
883+
};
859884
($field: ident, option) => {
860885
let mut $field = None;
861886
};
@@ -983,7 +1008,7 @@ macro_rules! impl_writeable_tlv_based {
9831008
impl $crate::util::ser::Writeable for $st {
9841009
fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
9851010
$crate::_encode_varint_length_prefixed_tlv!(writer, {
986-
$(($type, self.$field, $fieldty, self)),*
1011+
$(($type, &self.$field, $fieldty, self)),*
9871012
});
9881013
Ok(())
9891014
}
@@ -995,7 +1020,7 @@ macro_rules! impl_writeable_tlv_based {
9951020
#[allow(unused_mut)]
9961021
let mut len = $crate::util::ser::LengthCalculatingWriter(0);
9971022
$(
998-
$crate::_get_varint_length_prefixed_tlv_length!(len, $type, self.$field, $fieldty, self);
1023+
$crate::_get_varint_length_prefixed_tlv_length!(len, $type, &self.$field, $fieldty, self);
9991024
)*
10001025
len.0
10011026
};
@@ -1112,7 +1137,7 @@ macro_rules! _impl_writeable_tlv_based_enum_common {
11121137
let id: u8 = $variant_id;
11131138
id.write(writer)?;
11141139
$crate::_encode_varint_length_prefixed_tlv!(writer, {
1115-
$(($type, *$field, $fieldty, self)),*
1140+
$(($type, $field, $fieldty, self)),*
11161141
});
11171142
}),*
11181143
$($st::$tuple_variant_name (ref field) => {
@@ -1370,7 +1395,8 @@ mod tests {
13701395
use crate::io::{self, Cursor};
13711396
use crate::ln::msgs::DecodeError;
13721397
use crate::util::ser::{
1373-
HighZeroBytesDroppedBigSize, LengthReadable, MaybeReadable, Readable, VecWriter, Writeable,
1398+
HighZeroBytesDroppedBigSize, LengthReadable, MaybeReadable, Readable, VecWriter,
1399+
WithoutLength, Writeable,
13741400
};
13751401
use bitcoin::hex::FromHex;
13761402
use bitcoin::secp256k1::PublicKey;
@@ -1879,4 +1905,23 @@ mod tests {
18791905
let read = <ExpandedField as Readable>::read(&mut &encoded[..]).unwrap();
18801906
assert_eq!(read, ExpandedField { new_field: (42, 0) });
18811907
}
1908+
1909+
#[test]
1910+
fn required_vec_with_encoding() {
1911+
// Ensure that serializing a required vec with a specified encoding will survive a ser round
1912+
// trip.
1913+
#[derive(PartialEq, Eq, Debug)]
1914+
struct MyCustomStruct {
1915+
tlv_field: Vec<u8>,
1916+
}
1917+
impl_writeable_tlv_based!(MyCustomStruct, {
1918+
(0, tlv_field, (required_vec, encoding: (Vec<u8>, WithoutLength))),
1919+
});
1920+
1921+
let instance = MyCustomStruct { tlv_field: vec![42; 32] };
1922+
let encoded = instance.encode();
1923+
let decoded: MyCustomStruct =
1924+
LengthReadable::read_from_fixed_length_buffer(&mut &encoded[..]).unwrap();
1925+
assert_eq!(decoded, instance);
1926+
}
18821927
}

0 commit comments

Comments
 (0)