Skip to content

Commit f360c00

Browse files
committed
Add WithoutLength wrapper
When serializing variable-length types as part of a TLV stream, the length does not need to be serialized as it is already encoded in TLV records. Add a WithoutLength wrapper for this encoding. Replace VecReadWrapper and VecWriteWrapper with this single type to avoid redundant encoders.
1 parent 827217a commit f360c00

File tree

5 files changed

+50
-47
lines changed

5 files changed

+50
-47
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6523,7 +6523,7 @@ impl Writeable for HTLCSource {
65236523
(1, payment_id_opt, option),
65246524
(2, first_hop_htlc_msat, required),
65256525
(3, payment_secret, option),
6526-
(4, path, vec_type),
6526+
(4, *path, vec_type),
65276527
(5, payment_params, option),
65286528
});
65296529
}

lightning/src/onion_message/packet.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,15 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
164164
match &self.0 {
165165
Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
166166
encode_varint_length_prefixed_tlv!(w, {
167-
(4, encrypted_bytes, vec_type)
167+
(4, *encrypted_bytes, vec_type)
168168
})
169169
},
170170
Payload::Receive {
171171
control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), reply_path, message,
172172
} => {
173173
encode_varint_length_prefixed_tlv!(w, {
174174
(2, reply_path, option),
175-
(4, encrypted_bytes, vec_type),
175+
(4, *encrypted_bytes, vec_type),
176176
(message.tlv_type(), message, required)
177177
})
178178
},

lightning/src/util/events.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use ln::msgs;
2323
use ln::msgs::DecodeError;
2424
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2525
use routing::gossip::NetworkUpdate;
26-
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
26+
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, WithoutLength};
2727
use routing::router::{RouteHop, RouteParameters};
2828

2929
use bitcoin::{PackedLockTime, Transaction, OutPoint};
@@ -754,7 +754,7 @@ impl Writeable for Event {
754754
(1, network_update, option),
755755
(2, payment_failed_permanently, required),
756756
(3, all_paths_failed, required),
757-
(5, path, vec_type),
757+
(5, *path, vec_type),
758758
(7, short_channel_id, option),
759759
(9, retry, option),
760760
(11, payment_id, option),
@@ -768,7 +768,7 @@ impl Writeable for Event {
768768
&Event::SpendableOutputs { ref outputs } => {
769769
5u8.write(writer)?;
770770
write_tlv_fields!(writer, {
771-
(0, VecWriteWrapper(outputs), required),
771+
(0, WithoutLength(outputs), required),
772772
});
773773
},
774774
&Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
@@ -800,7 +800,7 @@ impl Writeable for Event {
800800
write_tlv_fields!(writer, {
801801
(0, payment_id, required),
802802
(2, payment_hash, option),
803-
(4, path, vec_type)
803+
(4, *path, vec_type)
804804
})
805805
},
806806
&Event::PaymentFailed { ref payment_id, ref payment_hash } => {
@@ -828,15 +828,15 @@ impl Writeable for Event {
828828
write_tlv_fields!(writer, {
829829
(0, payment_id, required),
830830
(2, payment_hash, required),
831-
(4, path, vec_type)
831+
(4, *path, vec_type)
832832
})
833833
},
834834
&Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => {
835835
23u8.write(writer)?;
836836
write_tlv_fields!(writer, {
837837
(0, payment_id, required),
838838
(2, payment_hash, required),
839-
(4, path, vec_type),
839+
(4, *path, vec_type),
840840
(6, short_channel_id, option),
841841
})
842842
},
@@ -967,7 +967,7 @@ impl MaybeReadable for Event {
967967
4u8 => Ok(None),
968968
5u8 => {
969969
let f = || {
970-
let mut outputs = VecReadWrapper(Vec::new());
970+
let mut outputs = WithoutLength(Vec::new());
971971
read_tlv_fields!(reader, {
972972
(0, outputs, required),
973973
});

lightning/src/util/ser.rs

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -292,39 +292,6 @@ impl<T: Readable> From<T> for OptionDeserWrapper<T> {
292292
fn from(t: T) -> OptionDeserWrapper<T> { OptionDeserWrapper(Some(t)) }
293293
}
294294

295-
/// Wrapper to write each element of a Vec with no length prefix
296-
pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec<T>);
297-
impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> {
298-
#[inline]
299-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
300-
for ref v in self.0.iter() {
301-
v.write(writer)?;
302-
}
303-
Ok(())
304-
}
305-
}
306-
307-
/// Wrapper to read elements from a given stream until it reaches the end of the stream.
308-
pub(crate) struct VecReadWrapper<T>(pub Vec<T>);
309-
impl<T: MaybeReadable> Readable for VecReadWrapper<T> {
310-
#[inline]
311-
fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
312-
let mut values = Vec::new();
313-
loop {
314-
let mut track_read = ReadTrackingReader::new(&mut reader);
315-
match MaybeReadable::read(&mut track_read) {
316-
Ok(Some(v)) => { values.push(v); },
317-
Ok(None) => { },
318-
// If we failed to read any bytes at all, we reached the end of our TLV
319-
// stream and have simply exhausted all entries.
320-
Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break,
321-
Err(e) => return Err(e),
322-
}
323-
}
324-
Ok(Self(values))
325-
}
326-
}
327-
328295
pub(crate) struct U48(pub u64);
329296
impl Writeable for U48 {
330297
#[inline]
@@ -556,6 +523,42 @@ impl Readable for [u16; 8] {
556523
}
557524
}
558525

526+
/// For variable-length values within TLV record where the length is encoded as part of the record.
527+
/// Used to prevent encoding the length twice.
528+
pub(crate) struct WithoutLength<T>(pub T);
529+
530+
impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec<T>> {
531+
#[inline]
532+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
533+
for ref v in self.0.iter() {
534+
v.write(writer)?;
535+
}
536+
Ok(())
537+
}
538+
}
539+
540+
impl<T: MaybeReadable> Readable for WithoutLength<Vec<T>> {
541+
#[inline]
542+
fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
543+
let mut values = Vec::new();
544+
loop {
545+
let mut track_read = ReadTrackingReader::new(&mut reader);
546+
match MaybeReadable::read(&mut track_read) {
547+
Ok(Some(v)) => { values.push(v); },
548+
Ok(None) => { },
549+
// If we failed to read any bytes at all, we reached the end of our TLV
550+
// stream and have simply exhausted all entries.
551+
Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break,
552+
Err(e) => return Err(e),
553+
}
554+
}
555+
Ok(Self(values))
556+
}
557+
}
558+
impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
559+
fn from(v: &'a Vec<T>) -> Self { Self(v) }
560+
}
561+
559562
// HashMap
560563
impl<K, V> Writeable for HashMap<K, V>
561564
where K: Writeable + Eq + Hash,

lightning/src/util/ser_macros.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ macro_rules! encode_tlv {
1717
$field.write($stream)?;
1818
};
1919
($stream: expr, $type: expr, $field: expr, vec_type) => {
20-
encode_tlv!($stream, $type, ::util::ser::VecWriteWrapper(&$field), required);
20+
encode_tlv!($stream, $type, ::util::ser::WithoutLength(&$field), required);
2121
};
2222
($stream: expr, $optional_type: expr, $optional_field: expr, option) => {
2323
if let Some(ref field) = $optional_field {
@@ -66,7 +66,7 @@ macro_rules! get_varint_length_prefixed_tlv_length {
6666
$len.0 += field_len;
6767
};
6868
($len: expr, $type: expr, $field: expr, vec_type) => {
69-
get_varint_length_prefixed_tlv_length!($len, $type, ::util::ser::VecWriteWrapper(&$field), required);
69+
get_varint_length_prefixed_tlv_length!($len, $type, ::util::ser::WithoutLength(&$field), required);
7070
};
7171
($len: expr, $optional_type: expr, $optional_field: expr, option) => {
7272
if let Some(ref field) = $optional_field {
@@ -160,7 +160,7 @@ macro_rules! decode_tlv {
160160
$field = ::util::ser::Readable::read(&mut $reader)?;
161161
}};
162162
($reader: expr, $field: ident, vec_type) => {{
163-
let f: ::util::ser::VecReadWrapper<_> = ::util::ser::Readable::read(&mut $reader)?;
163+
let f: ::util::ser::WithoutLength<Vec<_>> = ser::Readable::read(&mut $reader)?;
164164
$field = Some(f.0);
165165
}};
166166
($reader: expr, $field: ident, option) => {{
@@ -453,7 +453,7 @@ macro_rules! _impl_writeable_tlv_based_enum_common {
453453
let id: u8 = $variant_id;
454454
id.write(writer)?;
455455
write_tlv_fields!(writer, {
456-
$(($type, $field, $fieldty)),*
456+
$(($type, *$field, $fieldty)),*
457457
});
458458
}),*
459459
$($st::$tuple_variant_name (ref field) => {

0 commit comments

Comments
 (0)