Skip to content

Commit 195c206

Browse files
committed
Suggestions from matt
1 parent 541c943 commit 195c206

File tree

2 files changed

+92
-5
lines changed

2 files changed

+92
-5
lines changed

lightning/src/onion_message/packet.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ impl<H: CustomOnionMessageHandler> ReadableArgs<(SharedSecret, &H)> for Payload<
209209
let rho = onion_utils::gen_rho_from_shared_secret(&encrypted_tlvs_ss.secret_bytes());
210210
let mut message_type: Option<u64> = None;
211211
let mut message = None;
212-
decode_tlv_stream!(&mut rd, {
212+
decode_tlv_stream_with_custom_tlv_decode!(&mut rd, {
213213
(2, reply_path, option),
214214
(4, read_adapter, (option: LengthReadableArgs, rho)),
215215
}, |msg_type, msg_reader| {

lightning/src/util/ser_macros.rs

+91-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
/// Implements serialization for a single TLV record.
1414
/// This is exported for use by other exported macros, do not use directly.
15+
#[doc(hidden)]
1516
#[macro_export]
1617
macro_rules! _encode_tlv {
1718
($stream: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
@@ -41,6 +42,42 @@ macro_rules! _encode_tlv {
4142
}
4243

4344
/// Implements the TLVs serialization part in a Writeable implementation of a struct.
45+
///
46+
/// This should be called inside a method which returns `Result<_, `[`io::Error`]`>`, such as
47+
/// [`Writeable::write`]. It will only return an `Err` if the stream `Err`s or [`Writeable::write`]
48+
/// on one of the fields `Err`s.
49+
///
50+
/// `$stream` must be a `&mut `[`Writer`] which will receive the bytes for each TLV in the stream.
51+
///
52+
/// Fields MUST be sorted in `$type`-order.
53+
///
54+
/// Note that the lightning TLV requirements require that a single type not appear more than once,
55+
/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
56+
/// decoder.
57+
///
58+
/// Any `option` fields which have a value of `None` will not be serialized at all.
59+
///
60+
/// For example,
61+
/// ```
62+
/// # use lightning::encode_tlv_stream;
63+
/// # fn write<W: lightning::util::ser::Writer> (stream: &mut W) -> Result<(), lightning::io::Error> {
64+
/// let mut required_value = 0u64;
65+
/// let mut optional_value: Option<u64> = None;
66+
/// encode_tlv_stream!(stream, {
67+
/// (0, required_value, required),
68+
/// (1, Some(42u64), option),
69+
/// (2, optional_value, option),
70+
/// });
71+
/// // At this point `required_value` has been written as a TLV of type 0, `42u64` has been written
72+
/// // as a TLV of type 1 (indicating the reader may ignore it if it is not understood), and *no*
73+
/// // TLV is written with type 2.
74+
/// # Ok(())
75+
/// # }
76+
/// ```
77+
///
78+
/// [`io::Error`]: crate::io::Error
79+
/// [`Writeable::write`]: crate::util::ser::Writeable::write
80+
/// [`Writer`]: crate::util::ser::Writer
4481
#[macro_export]
4582
macro_rules! encode_tlv_stream {
4683
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => { {
@@ -72,6 +109,7 @@ macro_rules! encode_tlv_stream {
72109

73110
/// Adds the length of the serialized field to a LengthCalculatingWriter.
74111
/// This is exported for use by other exported macros, do not use directly.
112+
#[doc(hidden)]
75113
#[macro_export]
76114
macro_rules! _get_varint_length_prefixed_tlv_length {
77115
($len: expr, $type: expr, $field: expr, (default_value, $default: expr)) => {
@@ -98,6 +136,7 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
98136

99137
/// See the documentation of write_tlv_fields!().
100138
/// This is exported for use by other exported macros, do not use directly.
139+
#[doc(hidden)]
101140
#[macro_export]
102141
macro_rules! _encode_varint_length_prefixed_tlv {
103142
($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),*}) => { {
@@ -117,6 +156,7 @@ macro_rules! _encode_varint_length_prefixed_tlv {
117156

118157
/// Errors if there are missing required TLV types between the last seen type and the type currently being processed.
119158
/// This is exported for use by other exported macros, do not use directly.
159+
#[doc(hidden)]
120160
#[macro_export]
121161
macro_rules! _check_tlv_order {
122162
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
@@ -152,6 +192,7 @@ macro_rules! _check_tlv_order {
152192

153193
/// Errors if there are missing required TLV types after the last seen type.
154194
/// This is exported for use by other exported macros, do not use directly.
195+
#[doc(hidden)]
155196
#[macro_export]
156197
macro_rules! _check_missing_tlv {
157198
($last_seen_type: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
@@ -187,6 +228,7 @@ macro_rules! _check_missing_tlv {
187228

188229
/// Implements deserialization for a single TLV record.
189230
/// This is exported for use by other exported macros, do not use directly.
231+
#[doc(hidden)]
190232
#[macro_export]
191233
macro_rules! _decode_tlv {
192234
($reader: expr, $field: ident, (default_value, $default: expr)) => {{
@@ -221,17 +263,59 @@ macro_rules! _decode_tlv {
221263

222264
/// Implements the TLVs deserialization part in a Readable implementation of a struct.
223265
///
266+
/// This should be called inside a method which returns `Result<_, `[`DecodeError`]`>`, such as
267+
/// [`Readable::read`]. It will either return an `Err` or ensure all `required` fields have been
268+
/// read and optionally read `optional` fields.
269+
///
270+
/// `$stream` must be a [`Read`] and will be fully consumed, reading until no more bytes remain
271+
/// (i.e. it returns [`DecodeError::ShortRead`]).
272+
///
273+
/// Fields MUST be sorted in `$type`-order.
274+
///
275+
/// Note that the lightning TLV requirements require that a single type not appear more than once,
276+
/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
277+
/// decoder.
278+
///
279+
/// For example,
280+
/// ```
281+
/// # use lightning::decode_tlv_stream;
282+
/// # fn read<R: lightning::io::Read> (stream: R) -> Result<(), lightning::ln::msgs::DecodeError> {
283+
/// let mut required_value = 0u64;
284+
/// let mut optional_value: Option<u64> = None;
285+
/// decode_tlv_stream!(stream, {
286+
/// (0, required_value, required),
287+
/// (2, optional_value, option),
288+
/// });
289+
/// // At this point, `required_value` has been overwritten with the TLV with type 0.
290+
/// // `optional_value` may have been overwritten, setting it to `Some` if a TLV with type 2 was
291+
/// // present.
292+
/// # Ok(())
293+
/// # }
294+
/// ```
295+
///
296+
/// [`DecodeError`]: crate::ln::msgs::DecodeError
297+
/// [`Readable::read`]: crate::util::ser::Readable::read
298+
/// [`Read`]: crate::io::Read
299+
/// [`DecodeError::ShortRead`]: crate::ln::msgs::DecodeError::ShortRead
300+
#[macro_export]
301+
macro_rules! decode_tlv_stream {
302+
($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
303+
let rewind = |_, _| { unreachable!() };
304+
$crate::_decode_tlv_stream_range!($stream, .., rewind, {$(($type, $field, $fieldty)),*});
305+
}
306+
}
307+
308+
/// Similar to [`decode_tlv_stream`] with a custom TLV decoding capabilities.
309+
///
224310
/// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
225311
/// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
226312
/// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
227313
/// `Ok(false)` if the message type is unknown, and `Err(DecodeError)` if parsing fails.
228-
#[macro_export]
229-
macro_rules! decode_tlv_stream {
314+
macro_rules! decode_tlv_stream_with_custom_tlv_decode {
230315
($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
231316
$(, $decode_custom_tlv: expr)?) => { {
232317
let rewind = |_, _| { unreachable!() };
233-
use core::ops::RangeBounds;
234-
$crate::_decode_tlv_stream_range!(
318+
_decode_tlv_stream_range!(
235319
$stream, .., rewind, {$(($type, $field, $fieldty)),*} $(, $decode_custom_tlv)?
236320
);
237321
} }
@@ -242,6 +326,7 @@ macro_rules! decode_tlv_stream {
242326
macro_rules! _decode_tlv_stream_range {
243327
($stream: expr, $range: expr, $rewind: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
244328
$(, $decode_custom_tlv: expr)?) => { {
329+
use core::ops::RangeBounds;
245330
use $crate::ln::msgs::DecodeError;
246331
let mut last_seen_type: Option<u64> = None;
247332
let mut stream_ref = $stream;
@@ -434,6 +519,7 @@ macro_rules! read_tlv_fields {
434519

435520
/// Initializes the struct fields.
436521
/// This is exported for use by other exported macros, do not use directly.
522+
#[doc(hidden)]
437523
#[macro_export]
438524
macro_rules! _init_tlv_based_struct_field {
439525
($field: ident, (default_value, $default: expr)) => {
@@ -452,6 +538,7 @@ macro_rules! _init_tlv_based_struct_field {
452538

453539
/// Initializes the variable we are going to read the TLV into.
454540
/// This is exported for use by other exported macros, do not use directly.
541+
#[doc(hidden)]
455542
#[macro_export]
456543
macro_rules! _init_tlv_field_var {
457544
($field: ident, (default_value, $default: expr)) => {

0 commit comments

Comments
 (0)