Skip to main content

lightning/util/
ser_macros.rs

1// This file is Copyright its original authors, visible in version control
2// history.
3//
4// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7// You may not use this file except in accordance with one or both of these
8// licenses.
9
10//! Some macros that implement [`Readable`]/[`Writeable`] traits for lightning messages.
11//! They also handle serialization and deserialization of TLVs.
12//!
13//! [`Readable`]: crate::util::ser::Readable
14//! [`Writeable`]: crate::util::ser::Writeable
15
16/// Implements serialization for a single TLV record.
17/// This is exported for use by other exported macros, do not use directly.
18#[doc(hidden)]
19#[macro_export]
20macro_rules! _encode_tlv {
21	($stream: expr, $type: expr, $field: expr, (default_value, $default: expr) $(, $self: ident)?) => {
22		$crate::_encode_tlv!($stream, $type, $field, required)
23	};
24	($stream: expr, $type: expr, $field: expr, (default_value_vec, $default: expr) $(, $self: ident)?) => {
25		$crate::_encode_tlv!($stream, $type, $field, required_vec)
26	};
27	($stream: expr, $type: expr, $field: expr, (static_value, $value: expr) $(, $self: ident)?) => {
28		let _ = &$field; // Ensure we "use" the $field
29	};
30	($stream: expr, $type: expr, $field: expr, required $(, $self: ident)?) => {
31		BigSize($type).write($stream)?;
32		BigSize($field.serialized_length() as u64).write($stream)?;
33		$field.write($stream)?;
34	};
35	($stream: expr, $type: expr, $field: expr, (required: $trait: ident $(, $read_arg: expr)?) $(, $self: ident)?) => {
36		$crate::_encode_tlv!($stream, $type, $field, required);
37	};
38	($stream: expr, $type: expr, $field: expr, required_vec $(, $self: ident)?) => {
39		$crate::_encode_tlv!($stream, $type, $crate::util::ser::WithoutLength($field), required);
40	};
41	($stream: expr, $type: expr, $field: expr, (required_vec, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
42		$crate::_encode_tlv!($stream, $type, $encoding($field), required);
43	};
44	($stream: expr, $optional_type: expr, $optional_field: expr, option $(, $self: ident)?) => {
45		if let Some(ref field) = $optional_field {
46			BigSize($optional_type).write($stream)?;
47			BigSize(field.serialized_length() as u64).write($stream)?;
48			field.write($stream)?;
49		}
50	};
51	($stream: expr, $optional_type: expr, $optional_field: expr, (legacy, $fieldty: ty, $read: expr, $write: expr) $(, $self: ident)?) => { {
52		let value: Option<_> = $write($($self)?);
53		#[cfg(debug_assertions)]
54		{
55			// The value we write may be either an Option<$fieldty> or an Option<&$fieldty>.
56			// Either way, it should decode just fine as a $fieldty, so we check that here.
57			// This is useful in that it checks that we aren't accidentally writing, for example,
58			// Option<Option<$fieldty>>.
59			if let Some(v) = &value {
60				let encoded_value = v.encode();
61				let mut read_slice = &encoded_value[..];
62				let _: $fieldty = $crate::util::ser::Readable::read(&mut read_slice)
63					.expect("Failed to read written TLV, check types");
64				assert!(read_slice.is_empty(), "Reading written TLV was short, check types");
65			}
66		}
67		$crate::_encode_tlv!($stream, $optional_type, value, option);
68	} };
69	($stream: expr, $optional_type: expr, $optional_field: expr, (custom, $fieldty: ty, $read: expr, $write: expr) $(, $self: ident)?) => { {
70		$crate::_encode_tlv!($stream, $optional_type, $optional_field, (legacy, $fieldty, $read, $write) $(, $self)?);
71	} };
72	($stream: expr, $type: expr, $field: expr, optional_vec $(, $self: ident)?) => {
73		if !$field.is_empty() {
74			$crate::_encode_tlv!($stream, $type, $field, required_vec);
75		}
76	};
77	($stream: expr, $type: expr, $field: expr, upgradable_required $(, $self: ident)?) => {
78		$crate::_encode_tlv!($stream, $type, $field, required);
79	};
80	($stream: expr, $type: expr, $field: expr, upgradable_option $(, $self: ident)?) => {
81		$crate::_encode_tlv!($stream, $type, $field, option);
82	};
83	($stream: expr, $type: expr, $field: expr, (option, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
84		$crate::_encode_tlv!($stream, $type, $field.as_ref().map(|f| $encoding(f)), option);
85	};
86	($stream: expr, $type: expr, $field: expr, (option, encoding: $fieldty: ty) $(, $self: ident)?) => {
87		$crate::_encode_tlv!($stream, $type, $field, option);
88	};
89	($stream: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?) $(, $self: ident)?) => {
90		// Just a read-mapped type
91		$crate::_encode_tlv!($stream, $type, $field, option);
92	};
93}
94
95/// Panics if the last seen TLV type is not numerically less than the TLV type currently being checked.
96/// This is exported for use by other exported macros, do not use directly.
97#[doc(hidden)]
98#[macro_export]
99macro_rules! _check_encoded_tlv_order {
100	($last_type: expr, $type: expr, (static_value, $value: expr)) => {};
101	($last_type: expr, $type: expr, $fieldty: tt) => {
102		if let Some(t) = $last_type {
103			// Note that $type may be 0 making the following comparison always false
104			#[allow(unused_comparisons)]
105			(debug_assert!(t < $type))
106		}
107		$last_type = Some($type);
108	};
109}
110
111/// Implements the TLVs serialization part in a [`Writeable`] implementation of a struct.
112///
113/// This should be called inside a method which returns `Result<_, `[`io::Error`]`>`, such as
114/// [`Writeable::write`]. It will only return an `Err` if the stream `Err`s or [`Writeable::write`]
115/// on one of the fields `Err`s.
116///
117/// `$stream` must be a `&mut `[`Writer`] which will receive the bytes for each TLV in the stream.
118///
119/// Fields MUST be sorted in `$type`-order.
120///
121/// Note that the lightning TLV requirements require that a single type not appear more than once,
122/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
123/// decoder.
124///
125/// Any `option` fields which have a value of `None` will not be serialized at all.
126///
127/// For example,
128/// ```
129/// # use lightning::encode_tlv_stream;
130/// # fn write<W: lightning::util::ser::Writer> (stream: &mut W) -> Result<(), lightning::io::Error> {
131/// let mut required_value = 0u64;
132/// let mut optional_value: Option<u64> = None;
133/// encode_tlv_stream!(stream, {
134///     (0, required_value, required),
135///     (1, Some(42u64), option),
136///     (2, optional_value, option),
137/// });
138/// // At this point `required_value` has been written as a TLV of type 0, `42u64` has been written
139/// // as a TLV of type 1 (indicating the reader may ignore it if it is not understood), and *no*
140/// // TLV is written with type 2.
141/// # Ok(())
142/// # }
143/// ```
144///
145/// [`Writeable`]: crate::util::ser::Writeable
146/// [`io::Error`]: crate::io::Error
147/// [`Writeable::write`]: crate::util::ser::Writeable::write
148/// [`Writer`]: crate::util::ser::Writer
149#[macro_export]
150macro_rules! encode_tlv_stream {
151	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
152		$crate::_encode_tlv_stream!($stream, {$(($type, $field, $fieldty)),*})
153	}
154}
155
156/// Implementation of [`encode_tlv_stream`].
157/// This is exported for use by other exported macros, do not use directly.
158#[doc(hidden)]
159#[macro_export]
160macro_rules! _encode_tlv_stream {
161	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt $(, $self: ident)?)),* $(,)*}) => { {
162		$crate::_encode_tlv_stream!($stream, { $(($type, $field, $fieldty $(, $self)?)),* }, &[])
163	} };
164	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt $(, $self: ident)?)),* $(,)*}, $extra_tlvs: expr) => { {
165		#[allow(unused_imports)]
166		use $crate::{
167			ln::msgs::DecodeError,
168			util::ser,
169			util::ser::BigSize,
170			util::ser::Writeable,
171		};
172
173		$(
174			$crate::_encode_tlv!($stream, $type, $field, $fieldty $(, $self)?);
175		)*
176		for tlv in $extra_tlvs {
177			let (typ, value): &(u64, Vec<u8>) = tlv;
178			$crate::_encode_tlv!($stream, *typ, value, required_vec);
179		}
180
181		#[allow(unused_mut, unused_variables, unused_assignments)]
182		#[cfg(debug_assertions)]
183		{
184			let mut last_seen: Option<u64> = None;
185			$(
186				$crate::_check_encoded_tlv_order!(last_seen, $type, $fieldty);
187			)*
188			for tlv in $extra_tlvs {
189				let (typ, _): &(u64, Vec<u8>) = tlv;
190				$crate::_check_encoded_tlv_order!(last_seen, *typ, required_vec);
191			}
192		}
193	} };
194}
195
196/// Adds the length of the serialized field to a [`LengthCalculatingWriter`].
197/// This is exported for use by other exported macros, do not use directly.
198///
199/// [`LengthCalculatingWriter`]: crate::util::ser::LengthCalculatingWriter
200#[doc(hidden)]
201#[macro_export]
202macro_rules! _get_varint_length_prefixed_tlv_length {
203	($len: expr, $type: expr, $field: expr, (default_value, $default: expr) $(, $self: ident)?) => {
204		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required)
205	};
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	};
209	($len: expr, $type: expr, $field: expr, (static_value, $value: expr) $(, $self: ident)?) => {};
210	($len: expr, $type: expr, $field: expr, required $(, $self: ident)?) => {
211		BigSize($type).write(&mut $len).expect("No in-memory data may fail to serialize");
212		let field_len = $field.serialized_length();
213		BigSize(field_len as u64)
214			.write(&mut $len)
215			.expect("No in-memory data may fail to serialize");
216		$len.0 += field_len;
217	};
218	($len: expr, $type: expr, $field: expr, (required: $trait: ident $(, $read_arg: expr)?) $(, $self: ident)?) => {
219		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required);
220	};
221	($len: expr, $type: expr, $field: expr, required_vec $(, $self: ident)?) => {
222		let field = $crate::util::ser::WithoutLength($field);
223		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, field, required);
224	};
225	($len: expr, $type: expr, $field: expr, (required_vec, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
226		let field = $encoding($field);
227		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, field, required);
228	};
229	($len: expr, $optional_type: expr, $optional_field: expr, option $(, $self: ident)?) => {
230		if let Some(ref field) = $optional_field.as_ref() {
231			BigSize($optional_type)
232				.write(&mut $len)
233				.expect("No in-memory data may fail to serialize");
234			let field_len = field.serialized_length();
235			BigSize(field_len as u64)
236				.write(&mut $len)
237				.expect("No in-memory data may fail to serialize");
238			$len.0 += field_len;
239		}
240	};
241	($len: expr, $optional_type: expr, $optional_field: expr, (legacy, $fieldty: ty, $read: expr, $write: expr) $(, $self: ident)?) => {
242		$crate::_get_varint_length_prefixed_tlv_length!($len, $optional_type, $write($($self)?), option);
243	};
244	($len: expr, $optional_type: expr, $optional_field: expr, (custom, $fieldty: ty, $read: expr, $write: expr) $(, $self: ident)?) => {
245		$crate::_get_varint_length_prefixed_tlv_length!($len, $optional_type, $optional_field, (legacy, $fieldty, $read, $write) $(, $self)?);
246	};
247	($len: expr, $type: expr, $field: expr, optional_vec $(, $self: ident)?) => {
248		if !$field.is_empty() {
249			$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required_vec);
250		}
251	};
252	($len: expr, $type: expr, $field: expr, (option: $trait: ident $(, $read_arg: expr)?) $(, $self: ident)?) => {
253		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, option);
254	};
255	($len: expr, $type: expr, $field: expr, (option, encoding: ($fieldty: ty, $encoding: ident)) $(, $self: ident)?) => {
256		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field.as_ref().map(|f| $encoding(f)), option);
257	};
258	($len: expr, $type: expr, $field: expr, upgradable_required $(, $self: ident)?) => {
259		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, required);
260	};
261	($len: expr, $type: expr, $field: expr, upgradable_option $(, $self: ident)?) => {
262		$crate::_get_varint_length_prefixed_tlv_length!($len, $type, $field, option);
263	};
264}
265
266/// See the documentation of [`write_tlv_fields`].
267/// This is exported for use by other exported macros, do not use directly.
268#[doc(hidden)]
269#[macro_export]
270macro_rules! _encode_varint_length_prefixed_tlv {
271	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt $(, $self: ident)?)),*}) => { {
272		$crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, $field, $fieldty $(, $self)?)),*}, &[])
273	} };
274	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt $(, $self: ident)?)),*}, $extra_tlvs: expr) => { {
275		extern crate alloc;
276		use $crate::util::ser::BigSize;
277		use alloc::vec::Vec;
278		let len = {
279			#[allow(unused_mut)]
280			let mut len = $crate::util::ser::LengthCalculatingWriter(0);
281			$(
282				$crate::_get_varint_length_prefixed_tlv_length!(len, $type, $field, $fieldty $(, $self)?);
283			)*
284			for tlv in $extra_tlvs {
285				let (typ, value): &(u64, Vec<u8>) = tlv;
286				$crate::_get_varint_length_prefixed_tlv_length!(len, *typ, value, required_vec);
287			}
288			len.0
289		};
290		BigSize(len as u64).write($stream)?;
291		$crate::_encode_tlv_stream!($stream, { $(($type, $field, $fieldty $(, $self)?)),* }, $extra_tlvs);
292	} };
293}
294
295/// Errors if there are missing required TLV types between the last seen type and the type currently being processed.
296/// This is exported for use by other exported macros, do not use directly.
297#[doc(hidden)]
298#[macro_export]
299macro_rules! _check_decoded_tlv_order {
300	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
301		// Note that $type may be 0 making the second comparison always false
302		#[allow(unused_comparisons)]
303		let invalid_order =
304			($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
305		if invalid_order {
306			$field = $default.into();
307		}
308	}};
309	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (default_value_vec, $default: expr)) => {{
310		$crate::_check_decoded_tlv_order!(
311			$last_seen_type,
312			$typ,
313			$type,
314			$field,
315			(default_value, $default)
316		);
317	}};
318	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (static_value, $value: expr)) => {};
319	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => {{
320		// Note that $type may be 0 making the second comparison always false
321		#[allow(unused_comparisons)]
322		let invalid_order =
323			($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
324		if invalid_order {
325			return Err(DecodeError::InvalidValue);
326		}
327	}};
328	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
329		$crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
330	}};
331	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
332		// no-op
333	}};
334	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option, explicit_type: $fieldty: ty)) => {{
335		// no-op
336	}};
337	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (legacy, $fieldty: ty, $read: expr, $write: expr)) => {{
338		// no-op
339	}};
340	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (custom, $fieldty: ty, $read: expr, $write: expr) $(, $self: ident)?) => {{
341		// Note that $type may be 0 making the second comparison always false
342		#[allow(unused_comparisons)]
343		let invalid_order =
344			($last_seen_type.is_none() || $last_seen_type.unwrap() < $type) && $typ.0 > $type;
345		if invalid_order {
346			let read_result: Result<_, DecodeError> = $read(None);
347			$field = read_result?.into();
348		}
349	}};
350	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required, explicit_type: $fieldty: ty)) => {{
351		_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
352	}};
353	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required_vec) => {{
354		$crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
355	}};
356	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (required_vec, encoding: $encoding: tt)) => {{
357		$crate::_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required);
358	}};
359	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, optional_vec) => {{
360		// no-op
361	}};
362	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_required) => {{
363		_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required)
364	}};
365	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_option) => {{
366		// no-op
367	}};
368	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
369		// no-op
370	}};
371	($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option, encoding: $encoding: tt)) => {{
372		// no-op
373	}};
374}
375
376/// Errors if there are missing required TLV types after the last seen type.
377/// This is exported for use by other exported macros, do not use directly.
378#[doc(hidden)]
379#[macro_export]
380macro_rules! _check_missing_tlv {
381	($last_seen_type: expr, $type: expr, $field: ident, (default_value, $default: expr)) => {{
382		// Note that $type may be 0 making the second comparison always false
383		#[allow(unused_comparisons)]
384		let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
385		if missing_req_type {
386			$field = $default.into();
387		}
388	}};
389	($last_seen_type: expr, $type: expr, $field: ident, (default_value_vec, $default: expr)) => {{
390		$crate::_check_missing_tlv!($last_seen_type, $type, $field, (default_value, $default));
391	}};
392	($last_seen_type: expr, $type: expr, $field: expr, (static_value, $value: expr)) => {
393		$field = $value;
394	};
395	($last_seen_type: expr, $type: expr, $field: ident, required) => {{
396		// Note that $type may be 0 making the second comparison always false
397		#[allow(unused_comparisons)]
398		let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
399		if missing_req_type {
400			return Err(DecodeError::InvalidValue);
401		}
402	}};
403	($last_seen_type: expr, $type: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
404		$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
405	}};
406	($last_seen_type: expr, $type: expr, $field: ident, required_vec) => {{
407		$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
408	}};
409	($last_seen_type: expr, $type: expr, $field: ident, (required_vec, encoding: $encoding: tt)) => {{
410		$crate::_check_missing_tlv!($last_seen_type, $type, $field, required);
411	}};
412	($last_seen_type: expr, $type: expr, $field: ident, option) => {{
413		// no-op
414	}};
415	($last_seen_type: expr, $type: expr, $field: ident, (option, explicit_type: $fieldty: ty)) => {{
416		// no-op
417	}};
418	($last_seen_type: expr, $type: expr, $field: ident, (legacy, $fieldty: ty, $read: expr, $write: expr)) => {{
419		use $crate::ln::msgs::DecodeError;
420		let read_result: Result<(), DecodeError> = $read($field.as_ref());
421		read_result?;
422	}};
423	($last_seen_type: expr, $type: expr, $field: ident, (custom, $fieldty: ty, $read: expr, $write: expr)) => {{
424		// Note that $type may be 0 making the second comparison always false
425		#[allow(unused_comparisons)]
426		let missing_req_type = $last_seen_type.is_none() || $last_seen_type.unwrap() < $type;
427		if missing_req_type {
428			let read_result: Result<_, DecodeError> = $read(None);
429			$field = read_result?.into();
430		}
431	}};
432	($last_seen_type: expr, $type: expr, $field: ident, (required, explicit_type: $fieldty: ty)) => {{
433		_check_missing_tlv!($last_seen_type, $type, $field, required);
434	}};
435	($last_seen_type: expr, $type: expr, $field: ident, optional_vec) => {{
436		// no-op
437	}};
438	($last_seen_type: expr, $type: expr, $field: ident, upgradable_required) => {{
439		_check_missing_tlv!($last_seen_type, $type, $field, required)
440	}};
441	($last_seen_type: expr, $type: expr, $field: ident, upgradable_option) => {{
442		// no-op
443	}};
444	($last_seen_type: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
445		// no-op
446	}};
447	($last_seen_type: expr, $type: expr, $field: ident, (option, encoding: $encoding: tt)) => {{
448		// no-op
449	}};
450}
451
452/// Implements deserialization for a single TLV record.
453/// This is exported for use by other exported macros, do not use directly.
454#[doc(hidden)]
455#[macro_export]
456macro_rules! _decode_tlv {
457	($outer_reader: expr, $reader: expr, $field: ident, (default_value, $default: expr)) => {{
458		$crate::_decode_tlv!($outer_reader, $reader, $field, required)
459	}};
460	($outer_reader: expr, $reader: expr, $field: ident, (default_value_vec, $default: expr)) => {{
461		let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
462		$field = $crate::util::ser::RequiredWrapper(Some(f.0));
463	}};
464	($outer_reader: expr, $reader: expr, $field: ident, (static_value, $value: expr)) => {{
465	}};
466	($outer_reader: expr, $reader: expr, $field: ident, required) => {{
467		$field = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
468	}};
469	($outer_reader: expr, $reader: expr, $field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {{
470		$field = $trait::read(&mut $reader $(, $read_arg)*)?;
471	}};
472	($outer_reader: expr, $reader: expr, $field: ident, required_vec) => {{
473		let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
474		$field = f.0;
475	}};
476	($outer_reader: expr, $reader: expr, $field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {{
477		$field = {
478			let field: $encoding<$fieldty> = ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
479			$crate::util::ser::RequiredWrapper(Some(field.0))
480		};
481	}};
482	($outer_reader: expr, $reader: expr, $field: ident, option) => {{
483		$field = Some($crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?);
484	}};
485	($outer_reader: expr, $reader: expr, $field: ident, (option, explicit_type: $fieldty: ty)) => {{
486		let _field: &Option<$fieldty> = &$field;
487		$crate::_decode_tlv!($outer_reader, $reader, $field, option);
488	}};
489	($outer_reader: expr, $reader: expr, $field: ident, (legacy, $fieldty: ty, $read: expr, $write: expr)) => {{
490		$crate::_decode_tlv!($outer_reader, $reader, $field, (option, explicit_type: $fieldty));
491	}};
492	($outer_reader: expr, $reader: expr, $field: ident, (custom, $fieldty: ty, $read: expr, $write: expr)) => {{
493		let read_field: $fieldty;
494		$crate::_decode_tlv!($outer_reader, $reader, read_field, required);
495		let read_result: Result<_, DecodeError> = $read(Some(read_field));
496		$field = read_result?.into();
497	}};
498	($outer_reader: expr, $reader: expr, $field: ident, (required, explicit_type: $fieldty: ty)) => {{
499		let _field: &$fieldty = &$field;
500		_decode_tlv!($outer_reader, $reader, $field, required);
501	}};
502	($outer_reader: expr, $reader: expr, $field: ident, optional_vec) => {{
503		let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
504		$field = Some(f.0);
505	}};
506	// `upgradable_required` indicates we're reading a required TLV that may have been upgraded
507	// without backwards compat. We'll error if the field is missing, and return `Ok(None)` if the
508	// field is present but we can no longer understand it.
509	// Note that this variant can only be used within a `MaybeReadable` read.
510	($outer_reader: expr, $reader: expr, $field: ident, upgradable_required) => {{
511		$field = match $crate::util::ser::MaybeReadable::read(&mut $reader)? {
512			Some(res) => res,
513			None => {
514				// If we successfully read a value but we don't know how to parse it, we give up
515				// and immediately return `None`. However, we need to make sure we read the correct
516				// number of bytes for this TLV stream, which is implicitly the end of the stream.
517				// Thus, we consume everything left in the `$outer_reader` here, ensuring that if
518				// we're being read as a part of another TLV stream we don't spuriously fail to
519				// deserialize the outer object due to a TLV length mismatch.
520				$crate::io_extras::copy($outer_reader, &mut $crate::io_extras::sink()).unwrap();
521				return Ok(None)
522			},
523		};
524	}};
525	// `upgradable_option` indicates we're reading an Option-al TLV that may have been upgraded
526	// without backwards compat. $field will be None if the TLV is missing or if the field is present
527	// but we can no longer understand it.
528	($outer_reader: expr, $reader: expr, $field: ident, upgradable_option) => {{
529		$field = $crate::util::ser::MaybeReadable::read(&mut $reader)?;
530		if $field.is_none() {
531			#[cfg(not(debug_assertions))] {
532				// In general, MaybeReadable implementations are required to consume all the bytes
533				// of the object even if they don't understand it, but due to a bug in the
534				// serialization format for `impl_writeable_tlv_based_enum_upgradable` we sometimes
535				// don't know how many bytes that is. In such cases, we'd like to spuriously allow
536				// TLV length mismatches, which we do here by calling `eat_remaining` so that the
537				// `s.bytes_remain()` check in `_decode_tlv_stream_range` doesn't fail.
538				$reader.eat_remaining()?;
539			}
540		}
541	}};
542	($outer_reader: expr, $reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
543		$field = Some($trait::read(&mut $reader $(, $read_arg)*)?);
544	}};
545	($outer_reader: expr, $reader: expr, $field: ident, (option, encoding: ($fieldty: ty, $encoding: ident, $encoder:ty))) => {{
546		$crate::_decode_tlv!($outer_reader, $reader, $field, (option, encoding: ($fieldty, $encoding)));
547	}};
548	($outer_reader: expr, $reader: expr, $field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {{
549		$field = {
550			let field: $encoding<$fieldty> = ser::LengthReadable::read_from_fixed_length_buffer(&mut $reader)?;
551			Some(field.0)
552		};
553	}};
554	($outer_reader: expr, $reader: expr, $field: ident, (option, encoding: $fieldty: ty)) => {{
555		$crate::_decode_tlv!($outer_reader, $reader, $field, option);
556	}};
557}
558
559/// Checks if `$val` matches `$type`.
560/// This is exported for use by other exported macros, do not use directly.
561#[doc(hidden)]
562#[macro_export]
563macro_rules! _decode_tlv_stream_match_check {
564	($val: ident, $type: expr, (static_value, $value: expr)) => {
565		false
566	};
567	($val: ident, $type: expr, $fieldty: tt) => {
568		$val == $type
569	};
570}
571
572/// Implements the TLVs deserialization part in a [`Readable`] implementation of a struct.
573///
574/// This should be called inside a method which returns `Result<_, `[`DecodeError`]`>`, such as
575/// [`Readable::read`]. It will either return an `Err` or ensure all `required` fields have been
576/// read and optionally read `optional` fields.
577///
578/// `$stream` must be a [`Read`] and will be fully consumed, reading until no more bytes remain
579/// (i.e. it returns [`DecodeError::ShortRead`]).
580///
581/// Fields MUST be sorted in `$type`-order.
582///
583/// Note that the lightning TLV requirements require that a single type not appear more than once,
584/// that TLVs are sorted in type-ascending order, and that any even types be understood by the
585/// decoder.
586///
587/// For example,
588/// ```
589/// # use lightning::decode_tlv_stream;
590/// # fn read<R: lightning::io::Read> (stream: &mut R) -> Result<(), lightning::ln::msgs::DecodeError> {
591/// let mut required_value = 0u64;
592/// let mut optional_value: Option<u64> = None;
593/// decode_tlv_stream!(stream, {
594///     (0, required_value, required),
595///     (2, optional_value, option),
596/// });
597/// // At this point, `required_value` has been overwritten with the TLV with type 0.
598/// // `optional_value` may have been overwritten, setting it to `Some` if a TLV with type 2 was
599/// // present.
600/// # Ok(())
601/// # }
602/// ```
603///
604/// [`Readable`]: crate::util::ser::Readable
605/// [`DecodeError`]: crate::ln::msgs::DecodeError
606/// [`Readable::read`]: crate::util::ser::Readable::read
607/// [`Read`]: crate::io::Read
608/// [`DecodeError::ShortRead`]: crate::ln::msgs::DecodeError::ShortRead
609#[macro_export]
610macro_rules! decode_tlv_stream {
611	($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
612		let rewind = |_, _| { unreachable!() };
613		$crate::_decode_tlv_stream_range!($stream, .., rewind, {$(($type, $field, $fieldty)),*});
614	}
615}
616
617/// Similar to [`decode_tlv_stream`] with a custom TLV decoding capabilities.
618///
619/// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
620/// If it is provided, it will be called with the custom type and the [`FixedLengthReader`] containing
621/// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
622/// `Ok(false)` if the message type is unknown, and `Err(`[`DecodeError`]`)` if parsing fails.
623///
624/// [`FixedLengthReader`]: crate::util::ser::FixedLengthReader
625/// [`DecodeError`]: crate::ln::msgs::DecodeError
626macro_rules! decode_tlv_stream_with_custom_tlv_decode {
627	($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
628	 $(, $decode_custom_tlv: expr)?) => { {
629		let rewind = |_, _| { unreachable!() };
630		_decode_tlv_stream_range!(
631			$stream, .., rewind, {$(($type, $field, $fieldty)),*} $(, $decode_custom_tlv)?
632		);
633	} }
634}
635
636#[doc(hidden)]
637#[macro_export]
638macro_rules! _decode_tlv_stream_range {
639	($stream: expr, $range: expr, $rewind: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
640	 $(, $decode_custom_tlv: expr)?) => { {
641		use $crate::ln::msgs::DecodeError;
642		let mut last_seen_type: Option<u64> = None;
643		let stream_ref = $stream;
644		'tlv_read: loop {
645			use $crate::util::ser;
646
647			// First decode the type of this TLV:
648			let typ: ser::BigSize = {
649				// We track whether any bytes were read during the consensus_decode call to
650				// determine whether we should break or return ShortRead if we get an
651				// UnexpectedEof. This should in every case be largely cosmetic, but its nice to
652				// pass the TLV test vectors exactly, which require this distinction.
653				let mut tracking_reader = ser::ReadTrackingReader::new(stream_ref);
654				match <$crate::util::ser::BigSize as $crate::util::ser::Readable>::read(&mut tracking_reader) {
655					Err(DecodeError::ShortRead) => {
656						if !tracking_reader.have_read {
657							break 'tlv_read;
658						} else {
659							return Err(DecodeError::ShortRead);
660						}
661					},
662					Err(e) => return Err(e),
663					Ok(t) => if core::ops::RangeBounds::contains(&$range, &t.0) { t } else {
664						drop(tracking_reader);
665
666						// Assumes the type id is minimally encoded, which is enforced on read.
667						use $crate::util::ser::Writeable;
668						let bytes_read = t.serialized_length();
669						$rewind(stream_ref, bytes_read);
670						break 'tlv_read;
671					},
672				}
673			};
674
675			// Types must be unique and monotonically increasing:
676			match last_seen_type {
677				Some(t) if typ.0 <= t => {
678					return Err(DecodeError::InvalidValue);
679				},
680				_ => {},
681			}
682			// As we read types, make sure we hit every required type between `last_seen_type` and `typ`:
683			$({
684				$crate::_check_decoded_tlv_order!(last_seen_type, typ, $type, $field, $fieldty);
685			})*
686			last_seen_type = Some(typ.0);
687
688			// Finally, read the length and value itself:
689			let length: ser::BigSize = $crate::util::ser::Readable::read(stream_ref)?;
690			let mut s = ser::FixedLengthReader::new(stream_ref, length.0);
691			match typ.0 {
692				$(_t if $crate::_decode_tlv_stream_match_check!(_t, $type, $fieldty) => {
693					$crate::_decode_tlv!($stream, s, $field, $fieldty);
694					if s.bytes_remain() {
695						s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
696						return Err(DecodeError::InvalidValue);
697					}
698				},)*
699				t => {
700					$(
701						if $decode_custom_tlv(t, &mut s)? {
702							// If a custom TLV was successfully read (i.e. decode_custom_tlv returns true),
703							// continue to the next TLV read.
704							s.eat_remaining()?;
705							continue 'tlv_read;
706						}
707					)?
708					if t % 2 == 0 {
709						return Err(DecodeError::UnknownRequiredFeature);
710					}
711				}
712			}
713			s.eat_remaining()?;
714		}
715		// Make sure we got to each required type after we've read every TLV:
716		$({
717			$crate::_check_missing_tlv!(last_seen_type, $type, $field, $fieldty);
718		})*
719	} }
720}
721
722/// Implements [`LengthReadable`]/[`Writeable`] for a message struct that may include non-TLV and
723/// TLV-encoded parts.
724///
725/// This is useful to implement a [`CustomMessageReader`].
726///
727/// Currently `$fieldty` may only be `option`, i.e., `$tlvfield` is optional field.
728///
729/// For example,
730/// ```
731/// # use lightning::impl_writeable_msg;
732/// struct MyCustomMessage {
733/// 	pub field_1: u32,
734/// 	pub field_2: bool,
735/// 	pub field_3: String,
736/// 	pub tlv_optional_integer: Option<u32>,
737/// }
738///
739/// impl_writeable_msg!(MyCustomMessage, {
740/// 	field_1,
741/// 	field_2,
742/// 	field_3
743/// }, {
744/// 	(1, tlv_optional_integer, option),
745/// });
746/// ```
747///
748/// [`LengthReadable`]: crate::util::ser::LengthReadable
749/// [`Writeable`]: crate::util::ser::Writeable
750/// [`CustomMessageReader`]: crate::ln::wire::CustomMessageReader
751#[macro_export]
752macro_rules! impl_writeable_msg {
753	($st:ident, {$($field:ident),* $(,)*}, {$(($type: expr, $tlvfield: ident, $fieldty: tt)),* $(,)*}) => {
754		impl $crate::util::ser::Writeable for $st {
755			fn write<W: $crate::util::ser::Writer>(&self, w: &mut W) -> Result<(), $crate::io::Error> {
756				$( self.$field.write(w)?; )*
757				$crate::encode_tlv_stream!(w, {$(($type, &self.$tlvfield, $fieldty)),*});
758				Ok(())
759			}
760		}
761		impl $crate::util::ser::LengthReadable for $st {
762			fn read_from_fixed_length_buffer<R: $crate::util::ser::LengthLimitedRead>(
763				r: &mut R
764			) -> Result<Self, $crate::ln::msgs::DecodeError> {
765				$(let $field = $crate::util::ser::Readable::read(r)?;)*
766				$($crate::_init_tlv_field_var!($tlvfield, $fieldty);)*
767				$crate::decode_tlv_stream!(r, {$(($type, $tlvfield, $fieldty)),*});
768				Ok(Self {
769					$($field,)*
770					$($tlvfield: $crate::_init_tlv_based_struct_field!($tlvfield, $fieldty)),*
771				})
772			}
773		}
774	}
775}
776
777macro_rules! impl_writeable {
778	($st:ident, {$($field:ident),*}) => {
779		impl $crate::util::ser::Writeable for $st {
780			fn write<W: $crate::util::ser::Writer>(&self, w: &mut W) -> Result<(), $crate::io::Error> {
781				$( self.$field.write(w)?; )*
782				Ok(())
783			}
784
785			#[inline]
786			fn serialized_length(&self) -> usize {
787				let mut len_calc = 0;
788				$( len_calc += self.$field.serialized_length(); )*
789				return len_calc;
790			}
791		}
792
793		impl $crate::util::ser::Readable for $st {
794			fn read<R: $crate::io::Read>(r: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
795				Ok(Self {
796					$($field: $crate::util::ser::Readable::read(r)?),*
797				})
798			}
799		}
800	}
801}
802
803/// Write out two bytes to indicate the version of an object.
804///
805/// $this_version represents a unique version of a type. Incremented whenever the type's
806/// serialization format has changed or has a new interpretation. Used by a type's reader to
807/// determine how to interpret fields or if it can understand a serialized object.
808///
809/// $min_version_that_can_read_this is the minimum reader version which can understand this
810/// serialized object. Previous versions will simply err with a [`DecodeError::UnknownVersion`].
811///
812/// Updates to either `$this_version` or `$min_version_that_can_read_this` should be included in
813/// release notes.
814///
815/// Both version fields can be specific to this type of object.
816///
817/// [`DecodeError::UnknownVersion`]: crate::ln::msgs::DecodeError::UnknownVersion
818macro_rules! write_ver_prefix {
819	($stream: expr, $this_version: expr, $min_version_that_can_read_this: expr) => {
820		$stream.write_all(&[$this_version; 1])?;
821		$stream.write_all(&[$min_version_that_can_read_this; 1])?;
822	};
823}
824
825/// Writes out a suffix to an object as a length-prefixed TLV stream which contains potentially
826/// backwards-compatible, optional fields which old nodes can happily ignore.
827///
828/// It is written out in TLV format and, as with all TLV fields, unknown even fields cause a
829/// [`DecodeError::UnknownRequiredFeature`] error, with unknown odd fields ignored.
830///
831/// This is the preferred method of adding new fields that old nodes can ignore and still function
832/// correctly.
833///
834/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
835#[macro_export]
836macro_rules! write_tlv_fields {
837	($stream: expr, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
838		$crate::_encode_varint_length_prefixed_tlv!($stream, {$(($type, &$field, $fieldty)),*})
839	}
840}
841
842/// Reads a prefix added by [`write_ver_prefix`], above. Takes the current version of the
843/// serialization logic for this object. This is compared against the
844/// `$min_version_that_can_read_this` added by [`write_ver_prefix`].
845macro_rules! read_ver_prefix {
846	($stream: expr, $this_version: expr) => {{
847		let ver: u8 = Readable::read($stream)?;
848		let min_ver: u8 = Readable::read($stream)?;
849		if min_ver > $this_version {
850			return Err(DecodeError::UnknownVersion);
851		}
852		ver
853	}};
854}
855
856/// Reads a suffix added by [`write_tlv_fields`].
857///
858/// [`write_tlv_fields`]: crate::write_tlv_fields
859#[macro_export]
860macro_rules! read_tlv_fields {
861	($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
862		let tlv_len: $crate::util::ser::BigSize = $crate::util::ser::Readable::read($stream)?;
863		let mut rd = $crate::util::ser::FixedLengthReader::new($stream, tlv_len.0);
864		$crate::decode_tlv_stream!(&mut rd, {$(($type, $field, $fieldty)),*});
865		rd.eat_remaining().map_err(|_| $crate::ln::msgs::DecodeError::ShortRead)?;
866	} }
867}
868
869/// Initializes the struct fields.
870///
871/// This is exported for use by other exported macros, do not use directly.
872#[doc(hidden)]
873#[macro_export]
874macro_rules! _init_tlv_based_struct_field {
875	($field: ident, (default_value, $default: expr)) => {
876		$field.0.unwrap()
877	};
878	($field: ident, (default_value_vec, $default: expr)) => {
879		$crate::_init_tlv_based_struct_field!($field, (default_value, $default))
880	};
881	($field: ident, (static_value, $value: expr)) => {
882		$field
883	};
884	($field: ident, option) => {
885		$field
886	};
887	($field: ident, (legacy, $fieldty: ty, $read: expr, $write: expr)) => {
888		$crate::_init_tlv_based_struct_field!($field, option)
889	};
890	($field: ident, (custom, $fieldty: ty, $read: expr, $write: expr)) => {
891		$crate::_init_tlv_based_struct_field!($field, required)
892	};
893	($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
894		$crate::_init_tlv_based_struct_field!($field, option)
895	};
896	// Note that legacy TLVs are eaten by `drop_legacy_field_definition`
897	($field: ident, upgradable_required) => {
898		$field.0.unwrap()
899	};
900	($field: ident, upgradable_option) => {
901		$field
902	};
903	($field: ident, required) => {
904		$field.0.unwrap()
905	};
906	($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {
907		$crate::_init_tlv_based_struct_field!($field, required)
908	};
909	($field: ident, required_vec) => {
910		$field
911	};
912	($field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {
913		$crate::_init_tlv_based_struct_field!($field, required)
914	};
915	($field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
916		$crate::_init_tlv_based_struct_field!($field, option)
917	};
918	($field: ident, optional_vec) => {
919		$field.unwrap()
920	};
921}
922
923/// Initializes the variable we are going to read the TLV into.
924///
925/// This is exported for use by other exported macros, do not use directly.
926#[doc(hidden)]
927#[macro_export]
928macro_rules! _init_tlv_field_var {
929	($field: ident, (default_value, $default: expr)) => {
930		let mut $field = $crate::util::ser::RequiredWrapper(None);
931	};
932	($field: ident, (default_value_vec, $default: expr)) => {
933		$crate::_init_tlv_field_var!($field, (default_value, $default));
934	};
935	($field: ident, (static_value, $value: expr)) => {
936		let $field;
937	};
938	($field: ident, required) => {
939		let mut $field = $crate::util::ser::RequiredWrapper(None);
940	};
941	($field: ident, (required: $trait: ident $(, $read_arg: expr)?)) => {
942		$crate::_init_tlv_field_var!($field, required);
943	};
944	($field: ident, required_vec) => {
945		let mut $field = Vec::new();
946	};
947	($field: ident, (required_vec, encoding: ($fieldty: ty, $encoding: ident))) => {
948		$crate::_init_tlv_field_var!($field, required);
949	};
950	($field: ident, option) => {
951		let mut $field = None;
952	};
953	($field: ident, optional_vec) => {
954		let mut $field = Some(Vec::new());
955	};
956	($field: ident, (option, explicit_type: $fieldty: ty)) => {
957		let mut $field: Option<$fieldty> = None;
958	};
959	($field: ident, (legacy, $fieldty: ty, $read: expr, $write: expr)) => {
960		$crate::_init_tlv_field_var!($field, (option, explicit_type: $fieldty));
961	};
962	($field: ident, (custom, $fieldty: ty, $read: expr, $write: expr)) => {
963		$crate::_init_tlv_field_var!($field, required);
964	};
965	($field: ident, (required, explicit_type: $fieldty: ty)) => {
966		let mut $field = $crate::util::ser::RequiredWrapper::<$fieldty>(None);
967	};
968	($field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
969		$crate::_init_tlv_field_var!($field, option);
970	};
971	($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
972		$crate::_init_tlv_field_var!($field, option);
973	};
974	($field: ident, upgradable_required) => {
975		let mut $field = $crate::util::ser::UpgradableRequired(None);
976	};
977	($field: ident, upgradable_option) => {
978		let mut $field = None;
979	};
980}
981
982/// Equivalent to running [`_init_tlv_field_var`] then [`read_tlv_fields`].
983///
984/// If any unused values are read, their type MUST be specified or else `rustc` will read them as an
985/// `i64`.
986///
987/// This is exported for use by other exported macros, do not use directly.
988#[doc(hidden)]
989#[macro_export]
990macro_rules! _init_and_read_len_prefixed_tlv_fields {
991	($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
992		$(
993			$crate::_init_tlv_field_var!($field, $fieldty);
994		)*
995
996		$crate::read_tlv_fields!($reader, {
997			$(($type, $field, $fieldty)),*
998		});
999	}
1000}
1001
1002/// Equivalent to running [`_init_tlv_field_var`] then [`decode_tlv_stream`].
1003///
1004/// If any unused values are read, their type MUST be specified or else `rustc` will read them as an
1005/// `i64`.
1006macro_rules! _init_and_read_tlv_stream {
1007	($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
1008		$(
1009			$crate::_init_tlv_field_var!($field, $fieldty);
1010		)*
1011		$crate::decode_tlv_stream!($reader, {
1012			$(($type, $field, $fieldty)),*
1013		});
1014	}
1015}
1016
1017/// Reads a TLV stream with the given fields to build a struct/enum variant of type `$thing`
1018#[doc(hidden)]
1019#[macro_export]
1020macro_rules! _decode_and_build {
1021	($stream: ident, $thing: path, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
1022		$crate::_init_and_read_len_prefixed_tlv_fields!($stream, {
1023			$(($type, $field, $fieldty)),*
1024		});
1025		::lightning_macros::drop_legacy_field_definition!($thing {
1026			$($field: $crate::_init_tlv_based_struct_field!($field, $fieldty)),*
1027		})
1028	} }
1029}
1030
1031/// Implements [`Readable`]/[`Writeable`] for a struct storing it as a set of TLVs. Each TLV is
1032/// read/written in the order they appear and contains a type number, a field name, and a
1033/// de/serialization method, from the following:
1034///
1035/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
1036/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
1037/// If `$fieldty` is `(default_value_vec, $default)`, then `$field` is a [`Vec`] which will be set to `$default`
1038///    if not present. Elements are serialized individually without a count prefix (like `required_vec`).
1039///    The TLV is always written, even if the vec is empty (matching `default_value` behavior).
1040/// If `$fieldty` is `(static_value, $static)`, then `$field` will be set to `$static`.
1041/// If `$fieldty` is `option`, then `$field` is optional field.
1042/// If `$fieldty` is `upgradable_option`, then `$field` is optional and read via [`MaybeReadable`].
1043/// If `$fieldty` is `upgradable_required`, then `$field` is stored as an [`Option`] and read via
1044///    [`MaybeReadable`], requiring the TLV to be present.
1045/// If `$fieldty` is `optional_vec`, then `$field` is a [`Vec`], which needs to have its individual elements serialized.
1046///    Note that for `optional_vec` no bytes are written if the vec is empty
1047/// If `$fieldty` is `(legacy, $ty, $read, $write)` then, when writing, the function $write will be
1048///    called with the object being serialized and a returned `Option` and is written as a TLV if
1049///    `Some`. When reading, an optional field of type `$ty` is read, and after all TLV fields are
1050///    read, the `$read` closure is called with the `Option<&$ty>` value. The `$read` closure should
1051///    return a `Result<(), DecodeError>`. Legacy field values can be used in later
1052///    `default_value`, `default_value_vec`, or `static_value` fields by referring to the value by name.
1053/// If `$fieldty` is `(custom, $ty, $read, $write)` then, when writing, the same behavior as
1054///    `legacy`, above is used. When reading, if a TLV is present, it is read as `$ty` and the
1055///    `$read` method is called with `Some(decoded_$ty_object)`. If no TLV is present, the field
1056///    will be initialized by calling `$read(None)`. `$read` should return a
1057///    `Result<field type, DecodeError>` (note that the processed field type may differ from `$ty`;
1058///    `$ty` is the type as de/serialized, not necessarily the actual field type).
1059///
1060/// For example,
1061/// ```
1062/// # use lightning::impl_writeable_tlv_based;
1063/// struct LightningMessage {
1064/// 	tlv_integer: u32,
1065/// 	tlv_default_integer: u32,
1066/// 	tlv_optional_integer: Option<u32>,
1067/// 	tlv_vec_type_integer: Vec<u32>,
1068///		tlv_upgraded_integer: u32,
1069/// }
1070///
1071/// impl_writeable_tlv_based!(LightningMessage, {
1072/// 	(0, tlv_integer, required),
1073/// 	(1, tlv_default_integer, (default_value, 7)),
1074/// 	(2, tlv_optional_integer, option),
1075/// 	(3, tlv_vec_type_integer, optional_vec),
1076/// 	(4, unwritten_type, (legacy, u32, |_| Ok(()), |us: &LightningMessage| Some(us.tlv_integer))),
1077/// 	(_unused, tlv_upgraded_integer, (static_value, unwritten_type.unwrap_or(0) * 2))
1078/// });
1079/// ```
1080///
1081/// [`Readable`]: crate::util::ser::Readable
1082/// [`MaybeReadable`]: crate::util::ser::MaybeReadable
1083/// [`Writeable`]: crate::util::ser::Writeable
1084/// [`Vec`]: crate::prelude::Vec
1085#[macro_export]
1086macro_rules! impl_writeable_tlv_based {
1087	($st: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
1088		impl $crate::util::ser::Writeable for $st {
1089			fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
1090				$crate::_encode_varint_length_prefixed_tlv!(writer, {
1091					$(($type, &self.$field, $fieldty, self)),*
1092				});
1093				Ok(())
1094			}
1095
1096			#[inline]
1097			fn serialized_length(&self) -> usize {
1098				use $crate::util::ser::BigSize;
1099				let len = {
1100					#[allow(unused_mut)]
1101					let mut len = $crate::util::ser::LengthCalculatingWriter(0);
1102					$(
1103						$crate::_get_varint_length_prefixed_tlv_length!(len, $type, &self.$field, $fieldty, self);
1104					)*
1105					len.0
1106				};
1107				let mut len_calc = $crate::util::ser::LengthCalculatingWriter(0);
1108				BigSize(len as u64).write(&mut len_calc).expect("No in-memory data may fail to serialize");
1109				len + len_calc.0
1110			}
1111		}
1112
1113		impl $crate::util::ser::Readable for $st {
1114			fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
1115				Ok($crate::_decode_and_build!(reader, Self, {$(($type, $field, $fieldty)),*}))
1116			}
1117		}
1118	}
1119}
1120
1121/// Defines a struct for a TLV stream and a similar struct using references for non-primitive types,
1122/// implementing [`Readable`] for the former and [`Writeable`] for the latter. Useful as an
1123/// intermediary format when reading or writing a type encoded as a TLV stream. Note that each field
1124/// representing a TLV record has its type wrapped with an [`Option`]. A tuple consisting of a type
1125/// and a serialization wrapper may be given in place of a type when custom serialization is
1126/// required.
1127///
1128/// [`Readable`]: crate::util::ser::Readable
1129/// [`Writeable`]: crate::util::ser::Writeable
1130macro_rules! tlv_stream {
1131	($name:ident, $nameref:ident $(<$lifetime:lifetime>)?, $range:expr, {
1132		$(($type:expr, $field:ident : $fieldty:tt)),* $(,)*
1133	}) => {
1134		#[derive(Debug)]
1135		pub(super) struct $name {
1136			$(
1137				pub(super) $field: Option<tlv_record_type!($fieldty)>,
1138			)*
1139		}
1140
1141		#[cfg_attr(test, derive(PartialEq))]
1142		#[derive(Debug)]
1143		pub(crate) struct $nameref<$($lifetime)*> {
1144			$(
1145				pub(super) $field: Option<tlv_record_ref_type!($fieldty)>,
1146			)*
1147		}
1148
1149		impl<$($lifetime)*> $crate::util::ser::Writeable for $nameref<$($lifetime)*> {
1150			fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
1151				encode_tlv_stream!(writer, {
1152					$(($type, self.$field, (option, encoding: $fieldty))),*
1153				});
1154				Ok(())
1155			}
1156		}
1157
1158		impl $crate::util::ser::CursorReadable for $name {
1159			fn read<R: AsRef<[u8]>>(reader: &mut crate::io::Cursor<R>) -> Result<Self, $crate::ln::msgs::DecodeError> {
1160				$(
1161					_init_tlv_field_var!($field, option);
1162				)*
1163				let rewind = |cursor: &mut crate::io::Cursor<R>, offset: usize| {
1164					cursor.set_position(cursor.position().checked_sub(offset as u64).expect("Cannot rewind past 0."));
1165				};
1166				_decode_tlv_stream_range!(reader, $range, rewind, {
1167					$(($type, $field, (option, encoding: $fieldty))),*
1168				});
1169
1170				Ok(Self {
1171					$(
1172						$field: $field
1173					),*
1174				})
1175			}
1176		}
1177	}
1178}
1179
1180macro_rules! tlv_record_type {
1181	(($type:ty, $wrapper:ident)) => {
1182		$type
1183	};
1184	(($type:ty, $wrapper:ident, $encoder:ty)) => {
1185		$type
1186	};
1187	($type:ty) => {
1188		$type
1189	};
1190}
1191
1192macro_rules! tlv_record_ref_type {
1193	(char) => { char };
1194	(u8) => { u8 };
1195	((u16, $wrapper: ident)) => { u16 };
1196	((u32, $wrapper: ident)) => { u32 };
1197	((u64, $wrapper: ident)) => { u64 };
1198	(($type:ty, $wrapper:ident)) => { &'a $type };
1199	(($type:ty, $wrapper:ident, $encoder:ty)) => { $encoder };
1200	($type:ty) => { &'a $type };
1201}
1202
1203#[doc(hidden)]
1204#[macro_export]
1205macro_rules! _impl_writeable_tlv_based_enum_common {
1206	($st: ident, $(($variant_id: expr, $variant_name: ident) =>
1207		{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
1208	),* $(,)?;
1209	// $tuple_variant_* are only passed from `impl_writeable_tlv_based_enum_*_legacy`
1210	$(($tuple_variant_id: expr, $tuple_variant_name: ident)),* $(,)?;
1211	// $length_prefixed_* are only passed from `impl_writeable_tlv_based_enum_*` non-`legacy`
1212	$(($length_prefixed_tuple_variant_id: expr, $length_prefixed_tuple_variant_name: ident)),* $(,)?) => {
1213		impl $crate::util::ser::Writeable for $st {
1214			fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
1215				lightning_macros::skip_legacy_fields!(match self {
1216					$($st::$variant_name { $(ref $field: $fieldty, )* .. } => {
1217						let id: u8 = $variant_id;
1218						id.write(writer)?;
1219						$crate::_encode_varint_length_prefixed_tlv!(writer, {
1220							$(($type, $field, $fieldty, self)),*
1221						});
1222					}),*
1223					$($st::$tuple_variant_name (ref field) => {
1224						let id: u8 = $tuple_variant_id;
1225						id.write(writer)?;
1226						field.write(writer)?;
1227					}),*
1228					$($st::$length_prefixed_tuple_variant_name (ref field) => {
1229						let id: u8 = $length_prefixed_tuple_variant_id;
1230						id.write(writer)?;
1231						$crate::util::ser::BigSize(field.serialized_length() as u64).write(writer)?;
1232						field.write(writer)?;
1233					}),*
1234				});
1235				Ok(())
1236			}
1237		}
1238	}
1239}
1240
1241/// Implement [`Readable`] and [`Writeable`] for an enum, with struct variants stored as TLVs and tuple
1242/// variants stored directly.
1243///
1244/// The format is, for example,
1245/// ```
1246/// enum EnumName {
1247///   StructVariantA {
1248///     required_variant_field: u64,
1249///     optional_variant_field: Option<u8>,
1250///   },
1251///   StructVariantB {
1252///     variant_field_a: bool,
1253///     variant_field_b: u32,
1254///     variant_vec_field: Vec<u32>,
1255///   },
1256///   TupleVariantA(),
1257///   TupleVariantB(Vec<u8>),
1258/// }
1259/// # use lightning::impl_writeable_tlv_based_enum;
1260/// impl_writeable_tlv_based_enum!(EnumName,
1261///   (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
1262///   (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, optional_vec)},
1263///   (2, TupleVariantA) => {}, // Note that empty tuple variants have to use the struct syntax due to rust limitations
1264///   {3, TupleVariantB} => (),
1265/// );
1266/// ```
1267///
1268/// The type is written as a single byte, followed by length-prefixed variant data.
1269///
1270/// Attempts to read an unknown type byte result in [`DecodeError::UnknownRequiredFeature`].
1271///
1272/// Note that the serialization for tuple variants (as well as the call format) was changed in LDK
1273/// 0.0.124.
1274///
1275/// [`Readable`]: crate::util::ser::Readable
1276/// [`Writeable`]: crate::util::ser::Writeable
1277/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
1278#[macro_export]
1279macro_rules! impl_writeable_tlv_based_enum {
1280	($st: ident,
1281		$(($variant_id: expr, $variant_name: ident) =>
1282			{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
1283		),*
1284		$($(,)? {$tuple_variant_id: expr, $tuple_variant_name: ident} => ()),*
1285		$(,)?
1286	) => {
1287		$crate::_impl_writeable_tlv_based_enum_common!($st,
1288			$(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*
1289			;;
1290			$(($tuple_variant_id, $tuple_variant_name)),*);
1291
1292		impl $crate::util::ser::Readable for $st {
1293			#[allow(unused_mut)]
1294			fn read<R: $crate::io::Read>(mut reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
1295				let id: u8 = $crate::util::ser::Readable::read(reader)?;
1296				match id {
1297					$($variant_id => {
1298						// Because read_tlv_fields creates a labeled loop, we cannot call it twice
1299						// in the same function body. Instead, we define a closure and call it.
1300						let mut f = || {
1301							Ok($crate::_decode_and_build!(reader, $st::$variant_name, {$(($type, $field, $fieldty)),*}))
1302						};
1303						f()
1304					}),*
1305					$($tuple_variant_id => {
1306						let length: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?;
1307						let mut s = $crate::util::ser::FixedLengthReader::new(reader, length.0);
1308						let res = $crate::util::ser::LengthReadable::read_from_fixed_length_buffer(&mut s)?;
1309						if s.bytes_remain() {
1310							s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
1311							return Err($crate::ln::msgs::DecodeError::InvalidValue);
1312						}
1313						Ok($st::$tuple_variant_name(res))
1314					}),*
1315					_ => {
1316						Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature)
1317					},
1318				}
1319			}
1320		}
1321	}
1322}
1323
1324/// See [`impl_writeable_tlv_based_enum`] and use that unless backwards-compatibility with tuple
1325/// variants is required.
1326macro_rules! impl_writeable_tlv_based_enum_legacy {
1327	($st: ident, $(($variant_id: expr, $variant_name: ident) =>
1328		{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
1329	),* $(,)*;
1330	$(($tuple_variant_id: expr, $tuple_variant_name: ident)),+  $(,)?) => {
1331		$crate::_impl_writeable_tlv_based_enum_common!($st,
1332			$(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*;
1333			$(($tuple_variant_id, $tuple_variant_name)),+;);
1334
1335		impl $crate::util::ser::Readable for $st {
1336			fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
1337				let id: u8 = $crate::util::ser::Readable::read(reader)?;
1338				match id {
1339					$($variant_id => {
1340						// Because read_tlv_fields creates a labeled loop, we cannot call it twice
1341						// in the same function body. Instead, we define a closure and call it.
1342						let mut f = || {
1343							Ok($crate::_decode_and_build!(reader, $st::$variant_name, {$(($type, $field, $fieldty)),*}))
1344						};
1345						f()
1346					}),*
1347					$($tuple_variant_id => {
1348						Ok($st::$tuple_variant_name($crate::util::ser::Readable::read(reader)?))
1349					}),+
1350					_ => {
1351						Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature)
1352					},
1353				}
1354			}
1355		}
1356	}
1357}
1358
1359/// Implement [`MaybeReadable`] and [`Writeable`] for an enum, with struct variants stored as TLVs and
1360/// tuple variants stored directly.
1361///
1362/// This is largely identical to [`impl_writeable_tlv_based_enum`], except that odd variants will
1363/// return `Ok(None)` instead of `Err(`[`DecodeError::UnknownRequiredFeature`]`)`. It should generally be preferred
1364/// when [`MaybeReadable`] is practical instead of just [`Readable`] as it provides an upgrade path for
1365/// new variants to be added which are simply ignored by existing clients.
1366///
1367/// Note that the serialization for tuple variants (as well as the call format) was changed in LDK
1368/// 0.0.124.
1369///
1370/// [`MaybeReadable`]: crate::util::ser::MaybeReadable
1371/// [`Writeable`]: crate::util::ser::Writeable
1372/// [`DecodeError::UnknownRequiredFeature`]: crate::ln::msgs::DecodeError::UnknownRequiredFeature
1373/// [`Readable`]: crate::util::ser::Readable
1374#[macro_export]
1375macro_rules! impl_writeable_tlv_based_enum_upgradable {
1376	($st: ident,
1377		$(($variant_id: expr, $variant_name: ident) =>
1378			{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
1379		),*
1380		$(, {$tuple_variant_id: expr, $tuple_variant_name: ident} => ())*
1381		$(, unread_variants: $($unread_variant: ident),*)?
1382		$(,)?
1383	) => {
1384		$crate::_impl_writeable_tlv_based_enum_common!($st,
1385			$(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*
1386			$(, $((255, $unread_variant) => {}),*)?
1387			;;
1388			$(($tuple_variant_id, $tuple_variant_name)),*);
1389
1390		impl $crate::util::ser::MaybeReadable for $st {
1391			#[allow(unused_mut)]
1392			fn read<R: $crate::io::Read>(mut reader: &mut R) -> Result<Option<Self>, $crate::ln::msgs::DecodeError> {
1393				let id: u8 = $crate::util::ser::Readable::read(reader)?;
1394				match id {
1395					$($variant_id => {
1396						// Because read_tlv_fields creates a labeled loop, we cannot call it twice
1397						// in the same function body. Instead, we define a closure and call it.
1398						let mut f = || {
1399							Ok(Some($crate::_decode_and_build!(reader, $st::$variant_name, {$(($type, $field, $fieldty)),*})))
1400						};
1401						f()
1402					}),*
1403					$($tuple_variant_id => {
1404						let length: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?;
1405						let mut s = $crate::util::ser::FixedLengthReader::new(reader, length.0);
1406						let res = $crate::util::ser::Readable::read(&mut s)?;
1407						if s.bytes_remain() {
1408							s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
1409							return Err($crate::ln::msgs::DecodeError::InvalidValue);
1410						}
1411						Ok(Some($st::$tuple_variant_name(res)))
1412					}),*
1413					// Note that we explicitly match 255 here to reserve it for use in
1414					// `unread_variants`.
1415					255|_ if id % 2 == 1 => {
1416						let tlv_len: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?;
1417						let mut rd = $crate::util::ser::FixedLengthReader::new(reader, tlv_len.0);
1418						rd.eat_remaining().map_err(|_| $crate::ln::msgs::DecodeError::ShortRead)?;
1419						Ok(None)
1420					},
1421					_ => Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature),
1422				}
1423			}
1424		}
1425	}
1426}
1427
1428/// See [`impl_writeable_tlv_based_enum_upgradable`] and use that unless backwards-compatibility
1429/// with tuple variants is required.
1430macro_rules! impl_writeable_tlv_based_enum_upgradable_legacy {
1431	($st: ident, $(($variant_id: expr, $variant_name: ident) =>
1432		{$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
1433	),* $(,)?
1434	;
1435	$(($tuple_variant_id: expr, $tuple_variant_name: ident)),+  $(,)?) => {
1436		$crate::_impl_writeable_tlv_based_enum_common!($st,
1437			$(($variant_id, $variant_name) => {$(($type, $field, $fieldty)),*}),*;
1438			$(($tuple_variant_id, $tuple_variant_name)),+;);
1439
1440		impl $crate::util::ser::MaybeReadable for $st {
1441			fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Option<Self>, $crate::ln::msgs::DecodeError> {
1442				let id: u8 = $crate::util::ser::Readable::read(reader)?;
1443				match id {
1444					$($variant_id => {
1445						// Because read_tlv_fields creates a labeled loop, we cannot call it twice
1446						// in the same function body. Instead, we define a closure and call it.
1447						let mut f = || {
1448							Ok(Some($crate::_decode_and_build!(reader, $st::$variant_name, {$(($type, $field, $fieldty)),*})))
1449						};
1450						f()
1451					}),*
1452					$($tuple_variant_id => {
1453						Ok(Some($st::$tuple_variant_name(Readable::read(reader)?)))
1454					}),+
1455					_ if id % 2 == 1 => {
1456						// Assume that a $variant_id was written, not a $tuple_variant_id, and read
1457						// the length prefix and discard the correct number of bytes.
1458						let tlv_len: $crate::util::ser::BigSize = $crate::util::ser::Readable::read(reader)?;
1459						let mut rd = $crate::util::ser::FixedLengthReader::new(reader, tlv_len.0);
1460						rd.eat_remaining().map_err(|_| $crate::ln::msgs::DecodeError::ShortRead)?;
1461						Ok(None)
1462					},
1463					_ => Err($crate::ln::msgs::DecodeError::UnknownRequiredFeature),
1464				}
1465			}
1466		}
1467	}
1468}
1469
1470#[cfg(test)]
1471mod tests {
1472	#[allow(unused_imports)]
1473	use crate::prelude::*;
1474
1475	use crate::io::{self, Cursor};
1476	use crate::ln::msgs::DecodeError;
1477	use crate::util::ser::{
1478		HighZeroBytesDroppedBigSize, LengthReadable, MaybeReadable, Readable, VecWriter,
1479		WithoutLength, Writeable,
1480	};
1481	use bitcoin::hex::FromHex;
1482	use bitcoin::secp256k1::PublicKey;
1483
1484	// The BOLT TLV test cases don't include any tests which use our "required-value" logic since
1485	// the encoding layer in the BOLTs has no such concept, though it makes our macros easier to
1486	// work with so they're baked into the decoder. Thus, we have a few additional tests below
1487	fn tlv_reader(s: &[u8]) -> Result<(u64, u32, Option<u32>), DecodeError> {
1488		let mut s = Cursor::new(s);
1489		let mut a: u64 = 0;
1490		let mut b: u32 = 0;
1491		let mut c: Option<u32> = None;
1492		decode_tlv_stream!(&mut s, {(2, a, required), (3, b, required), (4, c, option)});
1493		Ok((a, b, c))
1494	}
1495
1496	#[test]
1497	fn tlv_v_short_read() {
1498		// We only expect a u32 for type 3 (which we are given), but the L says its 8 bytes.
1499		let buf =
1500			<Vec<u8>>::from_hex(concat!("0100", "0208deadbeef1badbeef", "0308deadbeef")).unwrap();
1501		if let Err(DecodeError::ShortRead) = tlv_reader(&buf[..]) {
1502		} else {
1503			panic!();
1504		}
1505	}
1506
1507	#[test]
1508	fn tlv_types_out_of_order() {
1509		let buf =
1510			<Vec<u8>>::from_hex(concat!("0100", "0304deadbeef", "0208deadbeef1badbeef")).unwrap();
1511		if let Err(DecodeError::InvalidValue) = tlv_reader(&buf[..]) {
1512		} else {
1513			panic!();
1514		}
1515		// ...even if its some field we don't understand
1516		let buf =
1517			<Vec<u8>>::from_hex(concat!("0208deadbeef1badbeef", "0100", "0304deadbeef")).unwrap();
1518		if let Err(DecodeError::InvalidValue) = tlv_reader(&buf[..]) {
1519		} else {
1520			panic!();
1521		}
1522	}
1523
1524	#[test]
1525	fn tlv_req_type_missing_or_extra() {
1526		// It's also bad if they included even fields we don't understand
1527		let buf =
1528			<Vec<u8>>::from_hex(concat!("0100", "0208deadbeef1badbeef", "0304deadbeef", "0600"))
1529				.unwrap();
1530		if let Err(DecodeError::UnknownRequiredFeature) = tlv_reader(&buf[..]) {
1531		} else {
1532			panic!();
1533		}
1534		// ... or if they're missing fields we need
1535		let buf = <Vec<u8>>::from_hex(concat!("0100", "0208deadbeef1badbeef")).unwrap();
1536		if let Err(DecodeError::InvalidValue) = tlv_reader(&buf[..]) {
1537		} else {
1538			panic!();
1539		}
1540		// ... even if that field is even
1541		let buf = <Vec<u8>>::from_hex(concat!("0304deadbeef", "0500")).unwrap();
1542		if let Err(DecodeError::InvalidValue) = tlv_reader(&buf[..]) {
1543		} else {
1544			panic!();
1545		}
1546	}
1547
1548	#[test]
1549	fn tlv_simple_good_cases() {
1550		let buf = <Vec<u8>>::from_hex(concat!("0208deadbeef1badbeef", "03041bad1dea")).unwrap();
1551		assert_eq!(tlv_reader(&buf[..]).unwrap(), (0xdeadbeef1badbeef, 0x1bad1dea, None));
1552		let buf =
1553			<Vec<u8>>::from_hex(concat!("0208deadbeef1badbeef", "03041bad1dea", "040401020304"))
1554				.unwrap();
1555		assert_eq!(
1556			tlv_reader(&buf[..]).unwrap(),
1557			(0xdeadbeef1badbeef, 0x1bad1dea, Some(0x01020304))
1558		);
1559	}
1560
1561	#[derive(Debug, PartialEq)]
1562	struct TestUpgradable {
1563		a: u32,
1564		b: u32,
1565		c: Option<u32>,
1566	}
1567
1568	fn upgradable_tlv_reader(s: &[u8]) -> Result<Option<TestUpgradable>, DecodeError> {
1569		let mut s = Cursor::new(s);
1570		let mut a = 0;
1571		let mut b = 0;
1572		let mut c: Option<u32> = None;
1573		decode_tlv_stream!(&mut s, {(2, a, upgradable_required), (3, b, upgradable_required), (4, c, upgradable_option)});
1574		Ok(Some(TestUpgradable { a, b, c }))
1575	}
1576
1577	#[test]
1578	fn upgradable_tlv_simple_good_cases() {
1579		let buf =
1580			<Vec<u8>>::from_hex(concat!("0204deadbeef", "03041bad1dea", "0404deadbeef")).unwrap();
1581		assert_eq!(
1582			upgradable_tlv_reader(&buf[..]).unwrap(),
1583			Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: Some(0xdeadbeef) })
1584		);
1585
1586		let buf = <Vec<u8>>::from_hex(concat!("0204deadbeef", "03041bad1dea")).unwrap();
1587		assert_eq!(
1588			upgradable_tlv_reader(&buf[..]).unwrap(),
1589			Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: None })
1590		);
1591	}
1592
1593	#[test]
1594	fn missing_required_upgradable() {
1595		let buf = <Vec<u8>>::from_hex(concat!("0100", "0204deadbeef")).unwrap();
1596		if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&buf[..]) {
1597		} else {
1598			panic!();
1599		}
1600		let buf = <Vec<u8>>::from_hex(concat!("0100", "03041bad1dea")).unwrap();
1601		if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&buf[..]) {
1602		} else {
1603			panic!();
1604		}
1605	}
1606
1607	/// A "V1" enum with only one variant
1608	enum InnerEnumV1 {
1609		StructVariantA { field: u32 },
1610	}
1611
1612	impl_writeable_tlv_based_enum_upgradable!(InnerEnumV1,
1613		(0, StructVariantA) => {
1614			(0, field, required),
1615		},
1616	);
1617
1618	struct OuterStructOptionalEnumV1 {
1619		inner_enum: Option<InnerEnumV1>,
1620		other_field: u32,
1621	}
1622
1623	impl_writeable_tlv_based!(OuterStructOptionalEnumV1, {
1624		(0, inner_enum, upgradable_option),
1625		(2, other_field, required),
1626	});
1627
1628	/// An upgraded version of [`InnerEnumV1`] that added a second variant
1629	enum InnerEnumV2 {
1630		StructVariantA { field: u32 },
1631		StructVariantB { field2: u64 },
1632	}
1633
1634	impl_writeable_tlv_based_enum_upgradable!(InnerEnumV2,
1635		(0, StructVariantA) => {
1636			(0, field, required),
1637		},
1638		(1, StructVariantB) => {
1639			(0, field2, required),
1640		},
1641	);
1642
1643	struct OuterStructOptionalEnumV2 {
1644		inner_enum: Option<InnerEnumV2>,
1645		other_field: u32,
1646	}
1647
1648	impl_writeable_tlv_based!(OuterStructOptionalEnumV2, {
1649		(0, inner_enum, upgradable_option),
1650		(2, other_field, required),
1651	});
1652
1653	#[test]
1654	fn upgradable_enum_option() {
1655		// Test downgrading from `OuterStructOptionalEnumV2` to `OuterStructOptionalEnumV1` and
1656		// ensure we still read the `other_field` just fine.
1657		let serialized_bytes = OuterStructOptionalEnumV2 {
1658			inner_enum: Some(InnerEnumV2::StructVariantB { field2: 64 }),
1659			other_field: 0x1bad1dea,
1660		}
1661		.encode();
1662		let mut s = Cursor::new(serialized_bytes);
1663
1664		let outer_struct: OuterStructOptionalEnumV1 = Readable::read(&mut s).unwrap();
1665		assert!(outer_struct.inner_enum.is_none());
1666		assert_eq!(outer_struct.other_field, 0x1bad1dea);
1667	}
1668
1669	/// A struct that is read with an [`InnerEnumV1`] but is written with an [`InnerEnumV2`].
1670	struct OuterStructRequiredEnum {
1671		#[allow(unused)]
1672		inner_enum: InnerEnumV1,
1673	}
1674
1675	impl MaybeReadable for OuterStructRequiredEnum {
1676		fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
1677			let mut inner_enum = crate::util::ser::UpgradableRequired(None);
1678			read_tlv_fields!(reader, {
1679				(0, inner_enum, upgradable_required),
1680			});
1681			Ok(Some(Self { inner_enum: inner_enum.0.unwrap() }))
1682		}
1683	}
1684
1685	impl Writeable for OuterStructRequiredEnum {
1686		fn write<W: crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1687			write_tlv_fields!(writer, {
1688				(0, InnerEnumV2::StructVariantB { field2: 0xdeadbeef }, required),
1689			});
1690			Ok(())
1691		}
1692	}
1693
1694	struct OuterOuterStruct {
1695		outer_struct: Option<OuterStructRequiredEnum>,
1696		other_field: u32,
1697	}
1698
1699	impl_writeable_tlv_based!(OuterOuterStruct, {
1700		(0, outer_struct, upgradable_option),
1701		(2, other_field, required),
1702	});
1703
1704	#[test]
1705	fn upgradable_enum_required() {
1706		// Test downgrading from an `OuterOuterStruct` (i.e. test downgrading an
1707		// `upgradable_required` `InnerEnumV2` to an `InnerEnumV1`).
1708		//
1709		// Note that `OuterStructRequiredEnum` has a split write/read implementation that writes an
1710		// `InnerEnumV2::StructVariantB` irrespective of the value of `inner_enum`.
1711
1712		let dummy_inner_enum = InnerEnumV1::StructVariantA { field: 42 };
1713		let serialized_bytes = OuterOuterStruct {
1714			outer_struct: Some(OuterStructRequiredEnum { inner_enum: dummy_inner_enum }),
1715			other_field: 0x1bad1dea,
1716		}
1717		.encode();
1718		let mut s = Cursor::new(serialized_bytes);
1719
1720		let outer_outer_struct: OuterOuterStruct = Readable::read(&mut s).unwrap();
1721		assert!(outer_outer_struct.outer_struct.is_none());
1722		assert_eq!(outer_outer_struct.other_field, 0x1bad1dea);
1723	}
1724
1725	// BOLT TLV test cases
1726	fn tlv_reader_n1(
1727		s: &[u8],
1728	) -> Result<
1729		(
1730			Option<HighZeroBytesDroppedBigSize<u64>>,
1731			Option<u64>,
1732			Option<(PublicKey, u64, u64)>,
1733			Option<u16>,
1734		),
1735		DecodeError,
1736	> {
1737		let mut s = Cursor::new(s);
1738		let mut tlv1: Option<HighZeroBytesDroppedBigSize<u64>> = None;
1739		let mut tlv2: Option<u64> = None;
1740		let mut tlv3: Option<(PublicKey, u64, u64)> = None;
1741		let mut tlv4: Option<u16> = None;
1742		decode_tlv_stream!(&mut s, {(1, tlv1, option), (2, tlv2, option), (3, tlv3, option), (254, tlv4, option)});
1743		Ok((tlv1, tlv2, tlv3, tlv4))
1744	}
1745
1746	#[test]
1747	fn bolt_tlv_bogus_stream() {
1748		macro_rules! do_test {
1749			($stream: expr, $reason: ident) => {
1750				if let Err(DecodeError::$reason) =
1751					tlv_reader_n1(&<Vec<u8>>::from_hex($stream).unwrap()[..])
1752				{
1753				} else {
1754					panic!();
1755				}
1756			};
1757		}
1758
1759		// TLVs from the BOLT test cases which should not decode as either n1 or n2
1760		do_test!("fd01", ShortRead);
1761		do_test!(concat!("fd0001", "00"), InvalidValue);
1762		do_test!("fd0101", ShortRead);
1763		do_test!(concat!("0f", "fd"), ShortRead);
1764		do_test!(concat!("0f", "fd26"), ShortRead);
1765		do_test!(concat!("0f", "fd2602"), ShortRead);
1766		do_test!(concat!("0f", "fd0001", "00"), InvalidValue);
1767		do_test!(concat!("0f", "fd0201", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), ShortRead);
1768
1769		do_test!(concat!("12", "00"), UnknownRequiredFeature);
1770		do_test!(concat!("fd0102", "00"), UnknownRequiredFeature);
1771		do_test!(concat!("fe01000002", "00"), UnknownRequiredFeature);
1772		do_test!(concat!("ff0100000000000002", "00"), UnknownRequiredFeature);
1773	}
1774
1775	#[test]
1776	fn bolt_tlv_bogus_n1_stream() {
1777		macro_rules! do_test {
1778			($stream: expr, $reason: ident) => {
1779				if let Err(DecodeError::$reason) =
1780					tlv_reader_n1(&<Vec<u8>>::from_hex($stream).unwrap()[..])
1781				{
1782				} else {
1783					panic!();
1784				}
1785			};
1786		}
1787
1788		// TLVs from the BOLT test cases which should not decode as n1
1789		do_test!(concat!("01", "09", "ffffffffffffffffff"), InvalidValue);
1790		do_test!(concat!("01", "01", "00"), InvalidValue);
1791		do_test!(concat!("01", "02", "0001"), InvalidValue);
1792		do_test!(concat!("01", "03", "000100"), InvalidValue);
1793		do_test!(concat!("01", "04", "00010000"), InvalidValue);
1794		do_test!(concat!("01", "05", "0001000000"), InvalidValue);
1795		do_test!(concat!("01", "06", "000100000000"), InvalidValue);
1796		do_test!(concat!("01", "07", "00010000000000"), InvalidValue);
1797		do_test!(concat!("01", "08", "0001000000000000"), InvalidValue);
1798		do_test!(concat!("02", "07", "01010101010101"), ShortRead);
1799		do_test!(concat!("02", "09", "010101010101010101"), InvalidValue);
1800		do_test!(
1801			concat!(
1802				"03",
1803				"21",
1804				"023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"
1805			),
1806			ShortRead
1807		);
1808		do_test!(concat!("03", "29", "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001"), ShortRead);
1809		do_test!(concat!("03", "30", "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001"), ShortRead);
1810		do_test!(concat!("03", "31", "043da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002"), InvalidValue);
1811		do_test!(concat!("03", "32", "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001"), InvalidValue);
1812		do_test!(concat!("fd00fe", "00"), ShortRead);
1813		do_test!(concat!("fd00fe", "01", "01"), ShortRead);
1814		do_test!(concat!("fd00fe", "03", "010101"), InvalidValue);
1815		do_test!(concat!("00", "00"), UnknownRequiredFeature);
1816
1817		do_test!(concat!("02", "08", "0000000000000226", "01", "01", "2a"), InvalidValue);
1818		do_test!(
1819			concat!("02", "08", "0000000000000231", "02", "08", "0000000000000451"),
1820			InvalidValue
1821		);
1822		do_test!(concat!("1f", "00", "0f", "01", "2a"), InvalidValue);
1823		do_test!(concat!("1f", "00", "1f", "01", "2a"), InvalidValue);
1824
1825		// The last BOLT test modified to not require creating a new decoder for one trivial test.
1826		do_test!(concat!("ffffffffffffffffff", "00", "01", "00"), InvalidValue);
1827	}
1828
1829	#[test]
1830	fn bolt_tlv_valid_n1_stream() {
1831		macro_rules! do_test {
1832			($stream: expr, $tlv1: expr, $tlv2: expr, $tlv3: expr, $tlv4: expr) => {
1833				if let Ok((tlv1, tlv2, tlv3, tlv4)) =
1834					tlv_reader_n1(&<Vec<u8>>::from_hex($stream).unwrap()[..])
1835				{
1836					assert_eq!(tlv1.map(|v| v.0), $tlv1);
1837					assert_eq!(tlv2, $tlv2);
1838					assert_eq!(tlv3, $tlv3);
1839					assert_eq!(tlv4, $tlv4);
1840				} else {
1841					panic!();
1842				}
1843			};
1844		}
1845
1846		do_test!("", None, None, None, None);
1847		do_test!(concat!("21", "00"), None, None, None, None);
1848		do_test!(concat!("fd0201", "00"), None, None, None, None);
1849		do_test!(concat!("fd00fd", "00"), None, None, None, None);
1850		do_test!(concat!("fd00ff", "00"), None, None, None, None);
1851		do_test!(concat!("fe02000001", "00"), None, None, None, None);
1852		do_test!(concat!("ff0200000000000001", "00"), None, None, None, None);
1853
1854		do_test!(concat!("01", "00"), Some(0), None, None, None);
1855		do_test!(concat!("01", "01", "01"), Some(1), None, None, None);
1856		do_test!(concat!("01", "02", "0100"), Some(256), None, None, None);
1857		do_test!(concat!("01", "03", "010000"), Some(65536), None, None, None);
1858		do_test!(concat!("01", "04", "01000000"), Some(16777216), None, None, None);
1859		do_test!(concat!("01", "05", "0100000000"), Some(4294967296), None, None, None);
1860		do_test!(concat!("01", "06", "010000000000"), Some(1099511627776), None, None, None);
1861		do_test!(concat!("01", "07", "01000000000000"), Some(281474976710656), None, None, None);
1862		do_test!(
1863			concat!("01", "08", "0100000000000000"),
1864			Some(72057594037927936),
1865			None,
1866			None,
1867			None
1868		);
1869		do_test!(
1870			concat!("02", "08", "0000000000000226"),
1871			None,
1872			Some((0 << 30) | (0 << 5) | (550 << 0)),
1873			None,
1874			None
1875		);
1876		do_test!(concat!("03", "31", "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002"),
1877			None, None, Some((
1878				PublicKey::from_slice(&<Vec<u8>>::from_hex("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]).unwrap(), 1, 2)),
1879			None);
1880		do_test!(concat!("fd00fe", "02", "0226"), None, None, None, Some(550));
1881	}
1882
1883	fn do_simple_test_tlv_write() -> Result<(), io::Error> {
1884		let mut stream = VecWriter(Vec::new());
1885
1886		stream.0.clear();
1887		_encode_varint_length_prefixed_tlv!(&mut stream, {(1, 1u8, required), (42, None::<u64>, option)});
1888		assert_eq!(stream.0, <Vec<u8>>::from_hex("03010101").unwrap());
1889
1890		stream.0.clear();
1891		_encode_varint_length_prefixed_tlv!(&mut stream, { (1, Some(1u8), option) });
1892		assert_eq!(stream.0, <Vec<u8>>::from_hex("03010101").unwrap());
1893
1894		stream.0.clear();
1895		_encode_varint_length_prefixed_tlv!(&mut stream, {(4, 0xabcdu16, required), (42, None::<u64>, option)});
1896		assert_eq!(stream.0, <Vec<u8>>::from_hex("040402abcd").unwrap());
1897
1898		stream.0.clear();
1899		_encode_varint_length_prefixed_tlv!(&mut stream, {(42, None::<u64>, option), (0xff, 0xabcdu16, required)});
1900		assert_eq!(stream.0, <Vec<u8>>::from_hex("06fd00ff02abcd").unwrap());
1901
1902		stream.0.clear();
1903		_encode_varint_length_prefixed_tlv!(&mut stream, {(0, 1u64, required), (42, None::<u64>, option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
1904		assert_eq!(stream.0, <Vec<u8>>::from_hex("0e00080000000000000001fd00ff00").unwrap());
1905
1906		stream.0.clear();
1907		_encode_varint_length_prefixed_tlv!(&mut stream, {(0, Some(1u64), option), (0xff, HighZeroBytesDroppedBigSize(0u64), required)});
1908		assert_eq!(stream.0, <Vec<u8>>::from_hex("0e00080000000000000001fd00ff00").unwrap());
1909
1910		Ok(())
1911	}
1912
1913	#[test]
1914	fn simple_test_tlv_write() {
1915		do_simple_test_tlv_write().unwrap();
1916	}
1917
1918	#[derive(Debug, Eq, PartialEq)]
1919	struct EmptyMsg {}
1920	impl_writeable_msg!(EmptyMsg, {}, {});
1921
1922	#[test]
1923	fn impl_writeable_msg_empty() {
1924		let msg = EmptyMsg {};
1925		let encoded_msg = msg.encode();
1926		assert!(encoded_msg.is_empty());
1927		let decoded_msg: EmptyMsg =
1928			LengthReadable::read_from_fixed_length_buffer(&mut &encoded_msg[..]).unwrap();
1929		assert_eq!(msg, decoded_msg);
1930	}
1931
1932	#[derive(Debug, PartialEq, Eq)]
1933	enum TuplesOnly {
1934		A(),
1935		B(u64),
1936	}
1937	impl_writeable_tlv_based_enum_upgradable!(TuplesOnly, (2, A) => {}, {3, B} => ());
1938
1939	#[test]
1940	fn test_impl_writeable_enum() {
1941		let a = TuplesOnly::A().encode();
1942		assert_eq!(TuplesOnly::read(&mut Cursor::new(&a)).unwrap(), Some(TuplesOnly::A()));
1943		let b42 = TuplesOnly::B(42).encode();
1944		assert_eq!(TuplesOnly::read(&mut Cursor::new(&b42)).unwrap(), Some(TuplesOnly::B(42)));
1945
1946		// Test unknown variants with 0-length data
1947		let unknown_variant = vec![41, 0];
1948		let mut none_read = Cursor::new(&unknown_variant);
1949		assert_eq!(TuplesOnly::read(&mut none_read).unwrap(), None);
1950		assert_eq!(none_read.position(), unknown_variant.len() as u64);
1951
1952		TuplesOnly::read(&mut Cursor::new(&vec![42, 0])).unwrap_err();
1953
1954		// Test unknown variants with data
1955		let unknown_data_variant = vec![41, 3, 42, 52, 62];
1956		let mut none_data_read = Cursor::new(&unknown_data_variant);
1957		assert_eq!(TuplesOnly::read(&mut none_data_read).unwrap(), None);
1958		assert_eq!(none_data_read.position(), unknown_data_variant.len() as u64);
1959	}
1960
1961	#[derive(Debug, PartialEq, Eq)]
1962	struct ExpandedField {
1963		// Old versions of LDK are presumed to have had something like:
1964		// old_field: u8,
1965		new_field: (u8, u8),
1966	}
1967	impl_writeable_tlv_based!(ExpandedField, {
1968		(0, old_field, (legacy, u8, |_| Ok(()), |us: &ExpandedField| Some(us.new_field.0))),
1969		(1, new_field, (default_value, (old_field.ok_or(DecodeError::InvalidValue)?, 0))),
1970	});
1971
1972	#[test]
1973	fn test_legacy_conversion() {
1974		let mut encoded = ExpandedField { new_field: (43, 42) }.encode();
1975		assert_eq!(encoded, <Vec<u8>>::from_hex("0700012b01022b2a").unwrap());
1976
1977		// On read, we'll read a `new_field` which means we won't bother looking at `old_field`.
1978		encoded[3] = 10;
1979		let read = <ExpandedField as Readable>::read(&mut &encoded[..]).unwrap();
1980		assert_eq!(read, ExpandedField { new_field: (43, 42) });
1981
1982		// On read, if we read an old `ExpandedField` that just has a type-0 `old_field` entry,
1983		// we'll copy that into the first position of `new_field`.
1984		let encoded = <Vec<u8>>::from_hex("0300012a").unwrap();
1985		let read = <ExpandedField as Readable>::read(&mut &encoded[..]).unwrap();
1986		assert_eq!(read, ExpandedField { new_field: (42, 0) });
1987	}
1988
1989	#[derive(Debug, PartialEq, Eq)]
1990	struct DefaultValueVecStruct {
1991		items: Vec<u32>,
1992	}
1993	impl_writeable_tlv_based!(DefaultValueVecStruct, {
1994		(1, items, (default_value_vec, vec![4, 5, 6])),
1995	});
1996
1997	#[test]
1998	fn test_default_value_vec() {
1999		// Non-empty vec round-trips correctly.
2000		let instance = DefaultValueVecStruct { items: vec![1, 2, 3] };
2001		let encoded = instance.encode();
2002		let decoded: DefaultValueVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2003		assert_eq!(decoded, instance);
2004
2005		// Empty TLV stream falls back to the default.
2006		let empty_encoded = <Vec<u8>>::from_hex("00").unwrap(); // zero-length TLV stream
2007		let decoded: DefaultValueVecStruct = Readable::read(&mut &empty_encoded[..]).unwrap();
2008		assert_eq!(decoded, DefaultValueVecStruct { items: vec![4, 5, 6] });
2009
2010		// Empty vec round-trips to empty vec (TLV is always written).
2011		let empty_vec = DefaultValueVecStruct { items: vec![] };
2012		let encoded = empty_vec.encode();
2013		let decoded: DefaultValueVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2014		assert_eq!(decoded, DefaultValueVecStruct { items: vec![] });
2015	}
2016
2017	#[derive(Debug, PartialEq, Eq)]
2018	struct LegacyToVecStruct {
2019		new_items: Vec<u32>,
2020	}
2021	impl_writeable_tlv_based!(LegacyToVecStruct, {
2022		(0, old_item, (legacy, u32, |_| Ok(()),
2023			|us: &LegacyToVecStruct| us.new_items.first().copied())),
2024		(1, new_items, (default_value_vec,
2025			old_item.map(|v| vec![v]).unwrap_or_default())),
2026	});
2027
2028	#[test]
2029	fn test_default_value_vec_with_legacy_fallback() {
2030		// New format: round-trips via the new TLV.
2031		let instance = LegacyToVecStruct { new_items: vec![10, 20, 30] };
2032		let encoded = instance.encode();
2033		let decoded: LegacyToVecStruct = Readable::read(&mut &encoded[..]).unwrap();
2034		assert_eq!(decoded, instance);
2035
2036		// Old format: only the legacy type-0 field is present, falls back via default expression.
2037		let old_encoded = <Vec<u8>>::from_hex("0600040000002a").unwrap(); // TLV len 6, type 0, len 4, value 42u32
2038		let decoded: LegacyToVecStruct = Readable::read(&mut &old_encoded[..]).unwrap();
2039		assert_eq!(decoded, LegacyToVecStruct { new_items: vec![42] });
2040	}
2041
2042	#[test]
2043	fn required_vec_with_encoding() {
2044		// Ensure that serializing a required vec with a specified encoding will survive a ser round
2045		// trip.
2046		#[derive(PartialEq, Eq, Debug)]
2047		struct MyCustomStruct {
2048			tlv_field: Vec<u8>,
2049		}
2050		impl_writeable_tlv_based!(MyCustomStruct, {
2051			(0, tlv_field, (required_vec, encoding: (Vec<u8>, WithoutLength))),
2052		});
2053
2054		let instance = MyCustomStruct { tlv_field: vec![42; 32] };
2055		let encoded = instance.encode();
2056		let decoded: MyCustomStruct =
2057			LengthReadable::read_from_fixed_length_buffer(&mut &encoded[..]).unwrap();
2058		assert_eq!(decoded, instance);
2059	}
2060
2061	#[test]
2062	fn test_option_with_encoding() {
2063		// Ensure that serializing an option with a specified encoding will survive a ser round
2064		// trip for Some and None options.
2065		#[derive(PartialEq, Eq, Debug)]
2066		struct MyCustomStruct {
2067			tlv_field: Option<u64>,
2068		}
2069
2070		impl_writeable_msg!(MyCustomStruct, {}, {
2071			(1, tlv_field, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
2072		});
2073
2074		for tlv_field in [None, Some(0u64), Some(255u64)] {
2075			let instance = MyCustomStruct { tlv_field };
2076			let encoded = instance.encode();
2077			let decoded: MyCustomStruct =
2078				LengthReadable::read_from_fixed_length_buffer(&mut &encoded[..]).unwrap();
2079			assert_eq!(
2080				decoded,
2081				MyCustomStruct { tlv_field },
2082				"option custom encoding failed for: {:?}",
2083				tlv_field
2084			);
2085		}
2086	}
2087}