Skip to content

Commit 227fd51

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 24b63de commit 227fd51

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
@@ -6620,7 +6620,7 @@ impl Writeable for HTLCSource {
66206620
(1, payment_id_opt, option),
66216621
(2, first_hop_htlc_msat, required),
66226622
(3, payment_secret, option),
6623-
(4, path, vec_type),
6623+
(4, *path, vec_type),
66246624
(5, payment_params, option),
66256625
});
66266626
}

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
@@ -24,7 +24,7 @@ use crate::ln::msgs;
2424
use crate::ln::msgs::DecodeError;
2525
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2626
use crate::routing::gossip::NetworkUpdate;
27-
use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper, OptionDeserWrapper};
27+
use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, WithoutLength, OptionDeserWrapper};
2828
use crate::routing::router::{RouteHop, RouteParameters};
2929

3030
use bitcoin::{PackedLockTime, Transaction};
@@ -785,7 +785,7 @@ impl Writeable for Event {
785785
(1, network_update, option),
786786
(2, payment_failed_permanently, required),
787787
(3, all_paths_failed, required),
788-
(5, path, vec_type),
788+
(5, *path, vec_type),
789789
(7, short_channel_id, option),
790790
(9, retry, option),
791791
(11, payment_id, option),
@@ -799,7 +799,7 @@ impl Writeable for Event {
799799
&Event::SpendableOutputs { ref outputs } => {
800800
5u8.write(writer)?;
801801
write_tlv_fields!(writer, {
802-
(0, VecWriteWrapper(outputs), required),
802+
(0, WithoutLength(outputs), required),
803803
});
804804
},
805805
&Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
@@ -831,7 +831,7 @@ impl Writeable for Event {
831831
write_tlv_fields!(writer, {
832832
(0, payment_id, required),
833833
(2, payment_hash, option),
834-
(4, path, vec_type)
834+
(4, *path, vec_type)
835835
})
836836
},
837837
&Event::PaymentFailed { ref payment_id, ref payment_hash } => {
@@ -859,15 +859,15 @@ impl Writeable for Event {
859859
write_tlv_fields!(writer, {
860860
(0, payment_id, required),
861861
(2, payment_hash, required),
862-
(4, path, vec_type)
862+
(4, *path, vec_type)
863863
})
864864
},
865865
&Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => {
866866
23u8.write(writer)?;
867867
write_tlv_fields!(writer, {
868868
(0, payment_id, required),
869869
(2, payment_hash, required),
870-
(4, path, vec_type),
870+
(4, *path, vec_type),
871871
(6, short_channel_id, option),
872872
})
873873
},
@@ -1007,7 +1007,7 @@ impl MaybeReadable for Event {
10071007
4u8 => Ok(None),
10081008
5u8 => {
10091009
let f = || {
1010-
let mut outputs = VecReadWrapper(Vec::new());
1010+
let mut outputs = WithoutLength(Vec::new());
10111011
read_tlv_fields!(reader, {
10121012
(0, outputs, required),
10131013
});

lightning/src/util/ser.rs

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

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

517+
/// For variable-length values within TLV record where the length is encoded as part of the record.
518+
/// Used to prevent encoding the length twice.
519+
pub(crate) struct WithoutLength<T>(pub T);
520+
521+
impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec<T>> {
522+
#[inline]
523+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
524+
for ref v in self.0.iter() {
525+
v.write(writer)?;
526+
}
527+
Ok(())
528+
}
529+
}
530+
531+
impl<T: MaybeReadable> Readable for WithoutLength<Vec<T>> {
532+
#[inline]
533+
fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
534+
let mut values = Vec::new();
535+
loop {
536+
let mut track_read = ReadTrackingReader::new(&mut reader);
537+
match MaybeReadable::read(&mut track_read) {
538+
Ok(Some(v)) => { values.push(v); },
539+
Ok(None) => { },
540+
// If we failed to read any bytes at all, we reached the end of our TLV
541+
// stream and have simply exhausted all entries.
542+
Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break,
543+
Err(e) => return Err(e),
544+
}
545+
}
546+
Ok(Self(values))
547+
}
548+
}
549+
impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
550+
fn from(v: &'a Vec<T>) -> Self { Self(v) }
551+
}
552+
550553
// HashMap
551554
impl<K, V> Writeable for HashMap<K, V>
552555
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, $crate::util::ser::VecWriteWrapper(&$field), required);
20+
encode_tlv!($stream, $type, $crate::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, $crate::util::ser::VecWriteWrapper(&$field), required);
69+
get_varint_length_prefixed_tlv_length!($len, $type, $crate::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 = $crate::util::ser::Readable::read(&mut $reader)?;
161161
}};
162162
($reader: expr, $field: ident, vec_type) => {{
163-
let f: $crate::util::ser::VecReadWrapper<_> = $crate::util::ser::Readable::read(&mut $reader)?;
163+
let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::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)