use std::ops::Deref;
use chain;
+// Maximum size of a serialized HTLCOutputInCommitment
const HTLC_OUTPUT_IN_COMMITMENT_SIZE: usize = 1 + 8 + 4 + 32 + 5;
pub(crate) const MAX_HTLCS: u16 = 483;
/// Broadcaster's Payment Key (which isn't allowed to be spent from for some delay)
pub broadcaster_delayed_payment_key: PublicKey,
}
-impl_writeable!(TxCreationKeys, 33*6,
+
+impl_writeable!(TxCreationKeys, 33*5,
{ per_commitment_point, revocation_key, broadcaster_htlc_key, countersignatory_htlc_key, broadcaster_delayed_payment_key });
/// One counterparty's public keys which do not change over the life of a channel.
pub transaction_output_index: Option<u32>,
}
-impl_writeable!(HTLCOutputInCommitment, HTLC_OUTPUT_IN_COMMITMENT_SIZE, {
+impl_writeable_len_match!(HTLCOutputInCommitment, {
+ { HTLCOutputInCommitment { transaction_output_index: None, .. }, HTLC_OUTPUT_IN_COMMITMENT_SIZE - 4 },
+ { _, HTLC_OUTPUT_IN_COMMITMENT_SIZE }
+ }, {
offered,
amount_msat,
cltv_expiry,
impl Writeable for UnsignedChannelAnnouncement {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
- w.size_hint(2 + 2*32 + 4*33 + self.features.byte_count() + self.excess_data.len());
+ w.size_hint(2 + 32 + 8 + 4*33 + self.features.byte_count() + self.excess_data.len());
self.features.write(w)?;
self.chain_hash.write(w)?;
self.short_channel_id.write(w)?;
impl_writeable_len_match!(ChannelAnnouncement, {
{ ChannelAnnouncement { contents: UnsignedChannelAnnouncement {ref features, ref excess_data, ..}, .. },
- 2 + 2*32 + 4*33 + features.byte_count() + excess_data.len() + 4*64 }
+ 2 + 32 + 8 + 4*33 + features.byte_count() + excess_data.len() + 4*64 }
}, {
node_signature_1,
node_signature_2,
}
impl_writeable_len_match!(ChannelUpdate, {
- { ChannelUpdate { contents: UnsignedChannelUpdate {ref excess_data, ..}, .. },
- 64 + excess_data.len() + 64 }
+ { ChannelUpdate { contents: UnsignedChannelUpdate {ref excess_data, ref htlc_maximum_msat, ..}, .. },
+ 64 + 64 + excess_data.len() + if let OptionalField::Present(_) = htlc_maximum_msat { 8 } else { 0 } }
}, {
signature,
contents
impl Writeable for UnsignedNodeAnnouncement {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
- w.size_hint(64 + 76 + self.features.byte_count() + self.addresses.len()*38 + self.excess_address_data.len() + self.excess_data.len());
+ w.size_hint(76 + self.features.byte_count() + self.addresses.len()*38 + self.excess_address_data.len() + self.excess_data.len());
self.features.write(w)?;
self.timestamp.write(w)?;
self.node_id.write(w)?;
}
}
-impl_writeable_len_match!(NodeAnnouncement, {
+impl_writeable_len_match!(NodeAnnouncement, <=, {
{ NodeAnnouncement { contents: UnsignedNodeAnnouncement { ref features, ref addresses, ref excess_address_data, ref excess_data, ..}, .. },
64 + 76 + features.byte_count() + addresses.len()*(NetAddress::MAX_LEN as usize + 1) + excess_address_data.len() + excess_data.len() }
}, {
}
//Add write and readable traits to channelconfig
-impl_writeable!(ChannelConfig, 8+2+1+1, {
+impl_writeable!(ChannelConfig, 4+2+1+1, {
fee_proportional_millionths,
cltv_expiry_delta,
announced_channel,
if $len != 0 {
w.size_hint($len);
}
+ #[cfg(any(test, feature = "fuzztarget"))]
+ {
+ // In tests, assert that the hard-coded length matches the actual one
+ if $len != 0 {
+ use util::ser::LengthCalculatingWriter;
+ let mut len_calc = LengthCalculatingWriter(0);
+ $( self.$field.write(&mut len_calc)?; )*
+ assert_eq!(len_calc.0, $len);
+ }
+ }
$( self.$field.write(w)?; )*
Ok(())
}
}
}
macro_rules! impl_writeable_len_match {
- ($st:ident, {$({$m: pat, $l: expr}),*}, {$($field:ident),*}) => {
+ ($st:ident, $cmp: tt, {$({$m: pat, $l: expr}),*}, {$($field:ident),*}) => {
impl Writeable for $st {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
- w.size_hint(match *self {
+ let len = match *self {
$($m => $l,)*
- });
+ };
+ w.size_hint(len);
+ #[cfg(any(test, feature = "fuzztarget"))]
+ {
+ // In tests, assert that the hard-coded length matches the actual one
+ use util::ser::LengthCalculatingWriter;
+ let mut len_calc = LengthCalculatingWriter(0);
+ $( self.$field.write(&mut len_calc)?; )*
+ assert!(len_calc.0 $cmp len);
+ }
$( self.$field.write(w)?; )*
Ok(())
}
})
}
}
+ };
+ ($st:ident, {$({$m: pat, $l: expr}),*}, {$($field:ident),*}) => {
+ impl_writeable_len_match!($st, ==, { $({ $m, $l }),* }, { $($field),* });
}
}