Skip to content

Commit

Permalink
Add option_without_length case to TLV macros
Browse files Browse the repository at this point in the history
This allows us to handle `WithoutLength` fields to prevent the duplicate
encoding of lengths in TLVs for some types that already encode length,
such as `Script` in this case.

This is needed so that we can move `shutdown_scriptpubkey` into the
TLV stream of `OpenChannel` and `AcceptChannel`.
  • Loading branch information
dunxen committed May 1, 2023
1 parent 16d0f2f commit a348209
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
17 changes: 16 additions & 1 deletion lightning/src/util/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SI
use bitcoin::secp256k1::ecdsa;
use bitcoin::secp256k1::schnorr;
use bitcoin::blockdata::constants::ChainHash;
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::script::{Script, self};
use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
use bitcoin::consensus;
use bitcoin::consensus::Encodable;
Expand Down Expand Up @@ -657,6 +657,21 @@ impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
fn from(v: &'a Vec<T>) -> Self { Self(v) }
}

impl Writeable for WithoutLength<&Script> {
#[inline]
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
writer.write_all(self.0.as_bytes())
}
}

impl Readable for WithoutLength<Script> {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let v: WithoutLength<Vec<u8>> = Readable::read(r)?;
Ok(WithoutLength(script::Builder::from(v.0).into_script()))
}
}

#[derive(Debug)]
pub(crate) struct Iterable<'a, I: Iterator<Item = &'a T> + Clone, T: 'a>(pub I);

Expand Down
19 changes: 19 additions & 0 deletions lightning/src/util/ser_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ macro_rules! _encode_tlv {
// Just a read-mapped type
$crate::_encode_tlv!($stream, $type, $field, option);
};
($stream: expr, $type: expr, $field: expr, option_without_length) => {
$crate::_encode_tlv!($stream, $type, $field.as_ref().map(|x| $crate::util::ser::WithoutLength(x)), option);
};
}

/// Panics if the last seen TLV type is not numerically less than the TLV type currently being checked.
Expand Down Expand Up @@ -233,6 +236,9 @@ macro_rules! _check_decoded_tlv_order {
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option) => {{
// no-op
}};
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, option_without_length) => {{
// no-op
}};
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => {{
// no-op
}};
Expand Down Expand Up @@ -284,6 +290,9 @@ macro_rules! _check_missing_tlv {
($last_seen_type: expr, $type: expr, $field: ident, option) => {{
// no-op
}};
($last_seen_type: expr, $type: expr, $field: ident, option_without_length) => {{
// no-op
}};
($last_seen_type: expr, $type: expr, $field: ident, optional_vec) => {{
// no-op
}};
Expand Down Expand Up @@ -324,6 +333,10 @@ macro_rules! _decode_tlv {
($reader: expr, $field: ident, option) => {{
$field = Some($crate::util::ser::Readable::read(&mut $reader)?);
}};
($reader: expr, $field: ident, option_without_length) => {{
let f: $crate::util::ser::WithoutLength<_> = $crate::util::ser::Readable::read(&mut $reader)?;
$field = Some(f.0);
}};
($reader: expr, $field: ident, optional_vec) => {{
$crate::_decode_tlv!($reader, $field, vec_type);
}};
Expand Down Expand Up @@ -679,6 +692,9 @@ macro_rules! _init_tlv_based_struct_field {
($field: ident, option) => {
$field
};
($field: ident, option_without_length) => {
WithoutLength($field)
};
($field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {
$crate::_init_tlv_based_struct_field!($field, option)
};
Expand Down Expand Up @@ -723,6 +739,9 @@ macro_rules! _init_tlv_field_var {
($field: ident, option) => {
let mut $field = None;
};
($field: ident, option_without_length) => {
let mut $field = None;
};
($field: ident, optional_vec) => {
let mut $field = Some(Vec::new());
};
Expand Down

0 comments on commit a348209

Please sign in to comment.