From: Matt Corallo Date: Mon, 21 Jun 2021 19:55:45 +0000 (+0000) Subject: Update ChannelConfig serialization to be TLV-based X-Git-Tag: v0.0.99~1^2~5 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commitdiff_plain;h=dac8b7b399d020bc79a6a6c4a119345da0ee8acd Update ChannelConfig serialization to be TLV-based This was missed prior to 0.0.98, so requires a backwards-compatibility wrapper inside the `Channel` serialization logic, but it's not very complicated to do so. --- diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index d8a284fa..356a88dc 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -4460,7 +4460,7 @@ fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh() } -const SERIALIZATION_VERSION: u8 = 1; +const SERIALIZATION_VERSION: u8 = 2; const MIN_SERIALIZATION_VERSION: u8 = 1; impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,; @@ -4502,7 +4502,13 @@ impl Writeable for Channel { write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); self.user_id.write(writer)?; - self.config.write(writer)?; + + // Write out the old serialization for the config object. This is read by version-1 + // deserializers, but we will read the version in the TLV at the end instead. + self.config.fee_proportional_millionths.write(writer)?; + self.config.cltv_expiry_delta.write(writer)?; + self.config.announced_channel.write(writer)?; + self.config.commit_upfront_shutdown_pubkey.write(writer)?; self.channel_id.write(writer)?; (self.channel_state | ChannelState::PeerDisconnected as u32).write(writer)?; @@ -4700,6 +4706,7 @@ impl Writeable for Channel { // override that. (1, self.minimum_depth, option), (3, self.counterparty_selected_channel_reserve_satoshis, option), + (5, self.config, required), }); Ok(()) @@ -4710,10 +4717,21 @@ const MAX_ALLOC_SIZE: usize = 64*1024; impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel where K::Target: KeysInterface { fn read(reader: &mut R, keys_source: &'a K) -> Result { - let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); + let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); let user_id = Readable::read(reader)?; - let config: ChannelConfig = Readable::read(reader)?; + + let mut config = Some(ChannelConfig::default()); + if ver == 1 { + // Read the old serialization of the ChannelConfig from version 0.0.98. + config.as_mut().unwrap().fee_proportional_millionths = Readable::read(reader)?; + config.as_mut().unwrap().cltv_expiry_delta = Readable::read(reader)?; + config.as_mut().unwrap().announced_channel = Readable::read(reader)?; + config.as_mut().unwrap().commit_upfront_shutdown_pubkey = Readable::read(reader)?; + } else { + // Read the 8 bytes of backwards-compatibility ChannelConfig data. + let mut _val: u64 = Readable::read(reader)?; + } let channel_id = Readable::read(reader)?; let channel_state = Readable::read(reader)?; @@ -4887,6 +4905,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel (0, announcement_sigs, option), (1, minimum_depth, option), (3, counterparty_selected_channel_reserve_satoshis, option), + (5, config, option), // Note that if none is provided we will *not* overwrite the existing one. }); let mut secp_ctx = Secp256k1::new(); @@ -4895,7 +4914,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel Ok(Channel { user_id, - config, + config: config.unwrap(), channel_id, channel_state, secp_ctx, diff --git a/lightning/src/util/config.rs b/lightning/src/util/config.rs index 4a66fa37..d5ff2885 100644 --- a/lightning/src/util/config.rs +++ b/lightning/src/util/config.rs @@ -204,12 +204,11 @@ impl Default for ChannelConfig { } } -//Add write and readable traits to channelconfig -impl_writeable!(ChannelConfig, 4+2+1+1, { - fee_proportional_millionths, - cltv_expiry_delta, - announced_channel, - commit_upfront_shutdown_pubkey +impl_writeable_tlv_based!(ChannelConfig, { + (0, fee_proportional_millionths, required), + (2, cltv_expiry_delta, required), + (4, announced_channel, required), + (6, commit_upfront_shutdown_pubkey, required), }); /// Top-level config which holds ChannelHandshakeLimits and ChannelConfig. diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index b93115dc..86149d22 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -173,7 +173,7 @@ macro_rules! decode_tlv_stream { last_seen_type = Some(typ.0); // Finally, read the length and value itself: - let length: ser::BigSize = Readable::read($stream)?; + let length: ser::BigSize = ser::Readable::read($stream)?; let mut s = ser::FixedLengthReader::new($stream, length.0); match typ.0 { $($type => { @@ -503,7 +503,7 @@ mod tests { use prelude::*; use std::io::Cursor; use ln::msgs::DecodeError; - use util::ser::{Readable, Writeable, HighZeroBytesDroppedVarInt, VecWriter}; + use util::ser::{Writeable, HighZeroBytesDroppedVarInt, VecWriter}; use bitcoin::secp256k1::PublicKey; // The BOLT TLV test cases don't include any tests which use our "required-value" logic since