Skip to content

Commit eb47742

Browse files
committed
Generate TLV write length impls
Add a writeable TLV helper macro that emits both write and serialized_length from the same field list. Reuse the shared TLV length helper from impl_ser_tlv_based so the generated read/write path and the new custom-read path stay aligned. Use the new helper for the hot channel funding and commitment transaction TLV writers while leaving their custom read implementations unchanged.
1 parent f22f509 commit eb47742

3 files changed

Lines changed: 97 additions & 65 deletions

File tree

lightning/src/ln/chan_utils.rs

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,24 +1169,21 @@ impl_ser_tlv_based!(CounterpartyChannelTransactionParameters, {
11691169
(2, selected_contest_delay, required),
11701170
});
11711171

1172-
impl Writeable for ChannelTransactionParameters {
1173-
#[rustfmt::skip]
1174-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1175-
let legacy_deserialization_prevention_marker = legacy_deserialization_prevention_marker_for_channel_type_features(&self.channel_type_features);
1176-
write_tlv_fields!(writer, {
1177-
(0, self.holder_pubkeys, required),
1178-
(2, self.holder_selected_contest_delay, required),
1179-
(4, self.is_outbound_from_holder, required),
1180-
(6, self.counterparty_parameters, option),
1181-
(8, self.funding_outpoint, option),
1182-
(10, legacy_deserialization_prevention_marker, option),
1183-
(11, self.channel_type_features, required),
1184-
(12, self.splice_parent_funding_txid, option),
1185-
(13, self.channel_value_satoshis, required),
1186-
});
1187-
Ok(())
1188-
}
1189-
}
1172+
impl_writeable_tlv_based!(ChannelTransactionParameters, self, {
1173+
(0, self.holder_pubkeys, required),
1174+
(2, self.holder_selected_contest_delay, required),
1175+
(4, self.is_outbound_from_holder, required),
1176+
(6, self.counterparty_parameters, option),
1177+
(8, self.funding_outpoint, option),
1178+
(
1179+
10,
1180+
legacy_deserialization_prevention_marker_for_channel_type_features(&self.channel_type_features),
1181+
option
1182+
),
1183+
(11, self.channel_type_features, required),
1184+
(12, self.splice_parent_funding_txid, option),
1185+
(13, self.channel_value_satoshis, required),
1186+
});
11901187

11911188
impl ReadableArgs<Option<u64>> for ChannelTransactionParameters {
11921189
#[rustfmt::skip]
@@ -1634,25 +1631,22 @@ impl PartialEq for CommitmentTransaction {
16341631
}
16351632
}
16361633

1637-
impl Writeable for CommitmentTransaction {
1638-
#[rustfmt::skip]
1639-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1640-
let legacy_deserialization_prevention_marker = legacy_deserialization_prevention_marker_for_channel_type_features(&self.channel_type_features);
1641-
write_tlv_fields!(writer, {
1642-
(0, self.commitment_number, required),
1643-
(1, self.to_broadcaster_delay, option),
1644-
(2, self.to_broadcaster_value_sat, required),
1645-
(4, self.to_countersignatory_value_sat, required),
1646-
(6, self.feerate_per_kw, required),
1647-
(8, self.keys, required),
1648-
(10, self.built, required),
1649-
(12, self.nondust_htlcs, required_vec),
1650-
(14, legacy_deserialization_prevention_marker, option),
1651-
(15, self.channel_type_features, required),
1652-
});
1653-
Ok(())
1654-
}
1655-
}
1634+
impl_writeable_tlv_based!(CommitmentTransaction, self, {
1635+
(0, self.commitment_number, required),
1636+
(1, self.to_broadcaster_delay, option),
1637+
(2, self.to_broadcaster_value_sat, required),
1638+
(4, self.to_countersignatory_value_sat, required),
1639+
(6, self.feerate_per_kw, required),
1640+
(8, self.keys, required),
1641+
(10, self.built, required),
1642+
(12, self.nondust_htlcs, required_vec),
1643+
(
1644+
14,
1645+
legacy_deserialization_prevention_marker_for_channel_type_features(&self.channel_type_features),
1646+
option
1647+
),
1648+
(15, self.channel_type_features, required),
1649+
});
16561650

16571651
impl Readable for CommitmentTransaction {
16581652
#[rustfmt::skip]

lightning/src/ln/channel.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,22 +2596,17 @@ pub(super) struct FundingScope {
25962596
minimum_depth_override: Option<u32>,
25972597
}
25982598

2599-
impl Writeable for FundingScope {
2600-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
2601-
write_tlv_fields!(writer, {
2602-
(1, self.value_to_self_msat, required),
2603-
(3, self.counterparty_selected_channel_reserve_satoshis, option),
2604-
(5, self.holder_selected_channel_reserve_satoshis, required),
2605-
(7, self.channel_transaction_parameters, (required: ReadableArgs, None)),
2606-
(9, self.funding_transaction, option),
2607-
(11, self.funding_tx_confirmed_in, option),
2608-
(13, self.funding_tx_confirmation_height, required),
2609-
(15, self.short_channel_id, option),
2610-
(17, self.minimum_depth_override, option),
2611-
});
2612-
Ok(())
2613-
}
2614-
}
2599+
impl_writeable_tlv_based!(FundingScope, self, {
2600+
(1, self.value_to_self_msat, required),
2601+
(3, self.counterparty_selected_channel_reserve_satoshis, option),
2602+
(5, self.holder_selected_channel_reserve_satoshis, required),
2603+
(7, self.channel_transaction_parameters, (required: ReadableArgs, None)),
2604+
(9, self.funding_transaction, option),
2605+
(11, self.funding_tx_confirmed_in, option),
2606+
(13, self.funding_tx_confirmation_height, required),
2607+
(15, self.short_channel_id, option),
2608+
(17, self.minimum_depth_override, option),
2609+
});
26152610

26162611
impl Readable for FundingScope {
26172612
#[rustfmt::skip]

lightning/src/util/ser_macros.rs

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,58 @@ macro_rules! write_tlv_fields {
839839
}
840840
}
841841

842+
#[doc(hidden)]
843+
#[macro_export]
844+
macro_rules! _tlv_fields_serialized_length {
845+
({$(($type: expr, $field: expr, $fieldty: tt $(, $self: ident)?)),* $(,)*}) => { {
846+
use $crate::util::ser::BigSize;
847+
let len = {
848+
#[allow(unused_mut)]
849+
let mut len = $crate::util::ser::LengthCalculatingWriter(0);
850+
$(
851+
$crate::_get_varint_length_prefixed_tlv_length!(len, $type, &$field, $fieldty $(, $self)?);
852+
)*
853+
len.0
854+
};
855+
let mut len_calc = $crate::util::ser::LengthCalculatingWriter(0);
856+
BigSize(len as u64).write(&mut len_calc).expect("No in-memory data may fail to serialize");
857+
len + len_calc.0
858+
} }
859+
}
860+
861+
/// Implements [`Writeable`] for a type serialized as a length-prefixed TLV stream.
862+
///
863+
/// This is useful for types that share the TLV-writing format used by
864+
/// [`impl_ser_tlv_based`] but need a custom read implementation. The field list uses the
865+
/// same entries accepted by [`write_tlv_fields`], and the macro derives both `write` and
866+
/// `serialized_length` from that list so the two paths stay aligned.
867+
///
868+
/// The `$self` argument names the generated `self` binding, allowing field expressions to refer
869+
/// to it explicitly.
870+
///
871+
/// [`Writeable`]: crate::util::ser::Writeable
872+
/// [`impl_ser_tlv_based`]: crate::impl_ser_tlv_based
873+
/// [`write_tlv_fields`]: crate::write_tlv_fields
874+
macro_rules! impl_writeable_tlv_based {
875+
($st: ty, $self: ident, {$(($type: expr, $field: expr, $fieldty: tt)),* $(,)*}) => {
876+
impl $crate::util::ser::Writeable for $st {
877+
fn write<W: $crate::util::ser::Writer>(&$self, writer: &mut W) -> Result<(), $crate::io::Error> {
878+
write_tlv_fields!(writer, {
879+
$(($type, $field, $fieldty)),*
880+
});
881+
Ok(())
882+
}
883+
884+
#[inline]
885+
fn serialized_length(&$self) -> usize {
886+
$crate::_tlv_fields_serialized_length!({
887+
$(($type, $field, $fieldty)),*
888+
})
889+
}
890+
}
891+
}
892+
}
893+
842894
/// Reads a prefix added by [`write_ver_prefix`], above. Takes the current version of the
843895
/// serialization logic for this object. This is compared against the
844896
/// `$min_version_that_can_read_this` added by [`write_ver_prefix`].
@@ -1095,18 +1147,9 @@ macro_rules! impl_ser_tlv_based {
10951147

10961148
#[inline]
10971149
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
1150+
$crate::_tlv_fields_serialized_length!({
1151+
$(($type, self.$field, $fieldty, self)),*
1152+
})
11101153
}
11111154
}
11121155

0 commit comments

Comments
 (0)