+impl crate::util::ser::Writeable for LegacyChannelConfig {
+ 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.options.max_dust_htlc_exposure {
+ MaxDustHTLCExposure::FixedLimitMsat(limit) => limit,
+ MaxDustHTLCExposure::FeeRateMultiplier(_) => 5_000_000,
+ };
+ write_tlv_fields!(writer, {
+ (0, self.options.forwarding_fee_proportional_millionths, required),
+ (1, max_dust_htlc_exposure_msat_fixed_limit, required),
+ (2, self.options.cltv_expiry_delta, required),
+ (3, self.options.force_close_avoidance_max_fee_satoshis, (default_value, 1000)),
+ (4, self.announced_channel, required),
+ (5, self.options.max_dust_htlc_exposure, required),
+ (6, self.commit_upfront_shutdown_pubkey, required),
+ (8, self.options.forwarding_fee_base_msat, required),
+ });
+ Ok(())
+ }
+}
+
+impl crate::util::ser::Readable for LegacyChannelConfig {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ let mut forwarding_fee_proportional_millionths = 0;
+ let mut max_dust_htlc_exposure_msat_fixed_limit = None;
+ let mut cltv_expiry_delta = 0;
+ let mut force_close_avoidance_max_fee_satoshis = 1000;
+ let mut announced_channel = false;
+ let mut commit_upfront_shutdown_pubkey = false;
+ let mut forwarding_fee_base_msat = 0;
+ let mut max_dust_htlc_exposure_enum = None;
+ read_tlv_fields!(reader, {
+ (0, forwarding_fee_proportional_millionths, required),
+ // Has always been written, but became optionally read in 0.0.116
+ (1, max_dust_htlc_exposure_msat_fixed_limit, option),
+ (2, cltv_expiry_delta, required),
+ (3, force_close_avoidance_max_fee_satoshis, (default_value, 1000u64)),
+ (4, announced_channel, required),
+ (5, max_dust_htlc_exposure_enum, option),
+ (6, commit_upfront_shutdown_pubkey, required),
+ (8, forwarding_fee_base_msat, required),
+ });
+ let max_dust_htlc_exposure_msat_fixed_limit =
+ max_dust_htlc_exposure_msat_fixed_limit.unwrap_or(5_000_000);
+ let max_dust_htlc_exposure_msat = max_dust_htlc_exposure_enum
+ .unwrap_or(MaxDustHTLCExposure::FixedLimitMsat(max_dust_htlc_exposure_msat_fixed_limit));
+ Ok(Self {
+ options: ChannelConfig {
+ forwarding_fee_proportional_millionths,
+ max_dust_htlc_exposure: max_dust_htlc_exposure_msat,
+ cltv_expiry_delta,
+ force_close_avoidance_max_fee_satoshis,
+ forwarding_fee_base_msat,
+ accept_underpaying_htlcs: false,
+ },
+ announced_channel,
+ commit_upfront_shutdown_pubkey,
+ })
+ }
+}
+
+/// Top-level config which holds ChannelHandshakeLimits and ChannelConfig.
+///
+/// Default::default() provides sane defaults for most configurations
+/// (but currently with 0 relay fees!)
+#[derive(Copy, Clone, Debug)]
+pub struct UserConfig {
+ /// Channel handshake config that we propose to our counterparty.
+ pub channel_handshake_config: ChannelHandshakeConfig,
+ /// Limits applied to our counterparty's proposed channel handshake config settings.
+ pub channel_handshake_limits: ChannelHandshakeLimits,
+ /// Channel config which affects behavior during channel lifetime.
+ pub channel_config: ChannelConfig,
+ /// If this is set to false, we will reject any HTLCs which were to be forwarded over private
+ /// channels. This prevents us from taking on HTLC-forwarding risk when we intend to run as a
+ /// node which is not online reliably.
+ ///
+ /// For nodes which are not online reliably, you should set all channels to *not* be announced
+ /// (using [`ChannelHandshakeConfig::announced_channel`] and
+ /// [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
+ /// ensure you are not exposed to any forwarding risk.
+ ///
+ /// Note that because you cannot change a channel's announced state after creation, there is no
+ /// way to disable forwarding on public channels retroactively. Thus, in order to change a node
+ /// from a publicly-announced forwarding node to a private non-forwarding node you must close
+ /// all your channels and open new ones. For privacy, you should also change your node_id
+ /// (swapping all private and public key material for new ones) at that time.
+ ///
+ /// Default value: false.
+ pub accept_forwards_to_priv_channels: bool,
+ /// If this is set to false, we do not accept inbound requests to open a new channel.
+ /// Default value: true.
+ pub accept_inbound_channels: bool,
+ /// If this is set to true, the user needs to manually accept inbound requests to open a new
+ /// channel.
+ ///
+ /// When set to true, [`Event::OpenChannelRequest`] will be triggered once a request to open a
+ /// new inbound channel is received through a [`msgs::OpenChannel`] message. In that case, a
+ /// [`msgs::AcceptChannel`] message will not be sent back to the counterparty node unless the
+ /// user explicitly chooses to accept the request.
+ ///
+ /// Default value: false.
+ ///
+ /// [`Event::OpenChannelRequest`]: crate::events::Event::OpenChannelRequest
+ /// [`msgs::OpenChannel`]: crate::ln::msgs::OpenChannel
+ /// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
+ pub manually_accept_inbound_channels: bool,
+ /// If this is set to true, LDK will intercept HTLCs that are attempting to be forwarded over
+ /// fake short channel ids generated via [`ChannelManager::get_intercept_scid`]. Upon HTLC
+ /// intercept, LDK will generate an [`Event::HTLCIntercepted`] which MUST be handled by the user.
+ ///
+ /// Setting this to true may break backwards compatibility with LDK versions < 0.0.113.
+ ///
+ /// Default value: false.
+ ///
+ /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid
+ /// [`Event::HTLCIntercepted`]: crate::events::Event::HTLCIntercepted
+ pub accept_intercept_htlcs: bool,
+ /// If this is set to false, when receiving a keysend payment we'll fail it if it has multiple
+ /// parts. If this is set to true, we'll accept the payment.
+ ///
+ /// Setting this to true will break backwards compatibility upon downgrading to an LDK
+ /// version < 0.0.116 while receiving an MPP keysend. If we have already received an MPP
+ /// keysend, downgrading will cause us to fail to deserialize [`ChannelManager`].
+ ///
+ /// Default value: false.
+ ///
+ /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
+ pub accept_mpp_keysend: bool,
+}
+
+impl Default for UserConfig {
+ fn default() -> Self {
+ UserConfig {
+ channel_handshake_config: ChannelHandshakeConfig::default(),
+ channel_handshake_limits: ChannelHandshakeLimits::default(),
+ channel_config: ChannelConfig::default(),
+ accept_forwards_to_priv_channels: false,
+ accept_inbound_channels: true,
+ manually_accept_inbound_channels: false,
+ accept_intercept_htlcs: false,
+ accept_mpp_keysend: false,
+ }
+ }
+}
+
+// When fuzzing, we want to allow the fuzzer to pick any configuration parameters. Thus, we
+// implement Readable here in a naive way (which is a bit easier for the fuzzer to handle). We
+// don't really want to ever expose this to users (if we did we'd want to use TLVs).
+#[cfg(fuzzing)]
+impl Readable for UserConfig {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ Ok(Self {
+ channel_handshake_config: Readable::read(reader)?,
+ channel_handshake_limits: Readable::read(reader)?,
+ channel_config: Readable::read(reader)?,
+ accept_forwards_to_priv_channels: Readable::read(reader)?,
+ accept_inbound_channels: Readable::read(reader)?,
+ manually_accept_inbound_channels: Readable::read(reader)?,
+ accept_intercept_htlcs: Readable::read(reader)?,
+ accept_mpp_keysend: Readable::read(reader)?,
+ })
+ }
+}