+ max_dust_htlc_exposure: MaxDustHTLCExposure::FeeRateMultiplier(5000),
+ force_close_avoidance_max_fee_satoshis: 1000,
+ accept_underpaying_htlcs: false,
+ }
+ }
+}
+
+impl crate::util::ser::Writeable for ChannelConfig {
+ fn write<W: crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), crate::io::Error> {
+ let max_dust_htlc_exposure_msat_fixed_limit = match self.max_dust_htlc_exposure {
+ MaxDustHTLCExposure::FixedLimitMsat(limit) => limit,
+ MaxDustHTLCExposure::FeeRateMultiplier(_) => 5_000_000,
+ };
+ write_tlv_fields!(writer, {
+ (0, self.forwarding_fee_proportional_millionths, required),
+ (1, self.accept_underpaying_htlcs, (default_value, false)),
+ (2, self.forwarding_fee_base_msat, required),
+ (3, self.max_dust_htlc_exposure, required),
+ (4, self.cltv_expiry_delta, required),
+ (6, max_dust_htlc_exposure_msat_fixed_limit, required),
+ // ChannelConfig serialized this field with a required type of 8 prior to the introduction of
+ // LegacyChannelConfig. To make sure that serialization is not compatible with this one, we use
+ // the next required type of 10, which if seen by the old serialization will always fail.
+ (10, self.force_close_avoidance_max_fee_satoshis, required),
+ });
+ Ok(())
+ }
+}
+
+impl crate::util::ser::Readable for ChannelConfig {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ let mut forwarding_fee_proportional_millionths = 0;
+ let mut accept_underpaying_htlcs = false;
+ let mut forwarding_fee_base_msat = 1000;
+ let mut cltv_expiry_delta = 6 * 12;
+ let mut max_dust_htlc_exposure_msat = None;
+ let mut max_dust_htlc_exposure_enum = None;
+ let mut force_close_avoidance_max_fee_satoshis = 1000;
+ read_tlv_fields!(reader, {
+ (0, forwarding_fee_proportional_millionths, required),
+ (1, accept_underpaying_htlcs, (default_value, false)),
+ (2, forwarding_fee_base_msat, required),
+ (3, max_dust_htlc_exposure_enum, option),
+ (4, cltv_expiry_delta, required),
+ // Has always been written, but became optionally read in 0.0.116
+ (6, max_dust_htlc_exposure_msat, option),
+ (10, force_close_avoidance_max_fee_satoshis, required),
+ });
+ let max_dust_htlc_fixed_limit = max_dust_htlc_exposure_msat.unwrap_or(5_000_000);
+ let max_dust_htlc_exposure_msat = max_dust_htlc_exposure_enum
+ .unwrap_or(MaxDustHTLCExposure::FixedLimitMsat(max_dust_htlc_fixed_limit));
+ Ok(Self {
+ forwarding_fee_proportional_millionths,
+ accept_underpaying_htlcs,
+ forwarding_fee_base_msat,
+ cltv_expiry_delta,
+ max_dust_htlc_exposure: max_dust_htlc_exposure_msat,
+ force_close_avoidance_max_fee_satoshis,
+ })
+ }
+}
+
+/// A parallel struct to [`ChannelConfig`] to define partial updates.
+#[allow(missing_docs)]
+pub struct ChannelConfigUpdate {
+ pub forwarding_fee_proportional_millionths: Option<u32>,
+ pub forwarding_fee_base_msat: Option<u32>,
+ pub cltv_expiry_delta: Option<u16>,
+ pub max_dust_htlc_exposure_msat: Option<MaxDustHTLCExposure>,
+ pub force_close_avoidance_max_fee_satoshis: Option<u64>,
+}
+
+impl Default for ChannelConfigUpdate {
+ fn default() -> ChannelConfigUpdate {
+ ChannelConfigUpdate {
+ forwarding_fee_proportional_millionths: None,
+ forwarding_fee_base_msat: None,
+ cltv_expiry_delta: None,
+ max_dust_htlc_exposure_msat: None,
+ force_close_avoidance_max_fee_satoshis: None,
+ }
+ }
+}
+
+impl From<ChannelConfig> for ChannelConfigUpdate {
+ fn from(config: ChannelConfig) -> ChannelConfigUpdate {
+ ChannelConfigUpdate {
+ forwarding_fee_proportional_millionths: Some(config.forwarding_fee_proportional_millionths),
+ forwarding_fee_base_msat: Some(config.forwarding_fee_base_msat),
+ cltv_expiry_delta: Some(config.cltv_expiry_delta),
+ max_dust_htlc_exposure_msat: Some(config.max_dust_htlc_exposure),
+ force_close_avoidance_max_fee_satoshis: Some(config.force_close_avoidance_max_fee_satoshis),
+ }
+ }
+}
+
+/// Legacy version of [`ChannelConfig`] that stored the static
+/// [`ChannelHandshakeConfig::announced_channel`] and
+/// [`ChannelHandshakeConfig::commit_upfront_shutdown_pubkey`] fields.
+#[derive(Copy, Clone, Debug)]
+pub(crate) struct LegacyChannelConfig {
+ pub(crate) options: ChannelConfig,
+ /// Deprecated but may still be read from. See [`ChannelHandshakeConfig::announced_channel`] to
+ /// set this when opening/accepting a channel.
+ pub(crate) announced_channel: bool,
+ /// Deprecated but may still be read from. See
+ /// [`ChannelHandshakeConfig::commit_upfront_shutdown_pubkey`] to set this when
+ /// opening/accepting a channel.
+ pub(crate) commit_upfront_shutdown_pubkey: bool,
+}
+
+impl Default for LegacyChannelConfig {
+ fn default() -> Self {
+ Self {
+ options: ChannelConfig::default(),