Skip to content

Commit 0beaaa7

Browse files
Make our in-flight limit percentage configurable
Add a config field `ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel` which sets the percentage of the channel value we cap the total value of outstanding inbound HTLCs to. This field can be set to a value between 1-100, where the value corresponds to the percent of the channel value in whole percentages. Note that: * If configured to another value than the default value 10, any new channels created with the non default value will cause versions of LDK prior to 0.0.104 to refuse to read the `ChannelManager`. * This caps the total value for inbound HTLCs in-flight only, and there's currently no way to configure the cap for the total value of outbound HTLCs in-flight. * The requirements for your node being online to ensure the safety of HTLC-encumbered funds are different from the non-HTLC-encumbered funds. This makes this an important knob to restrict exposure to loss due to being offline for too long. See `ChannelHandshakeConfig::our_to_self_delay` and `ChannelConfig::cltv_expiry_delta` for more information. Default value: 10. Minimum value: 1, any values less than 1 will be treated as 1 instead. Maximum value: 100, any values larger than 100 will be treated as 100 instead.
1 parent dc8479a commit 0beaaa7

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

lightning/src/ln/channel.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use util::events::ClosureReason;
3939
use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
4040
use util::logger::Logger;
4141
use util::errors::APIError;
42-
use util::config::{UserConfig, ChannelConfig, ChannelHandshakeLimits};
42+
use util::config::{UserConfig, ChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits};
4343
use util::scid_utils::scid_from_parts;
4444

4545
use io;
@@ -745,6 +745,12 @@ pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
745745

746746
pub const ANCHOR_OUTPUT_VALUE_SATOSHI: u64 = 330;
747747

748+
/// The percentage of the channel value `holder_max_htlc_value_in_flight_msat` used to be set to,
749+
/// before this was made configurable. The percentage was made configurable in LDK 0.0.107,
750+
/// although LDK 0.0.104+ enabled serialization of channels with a different value set for
751+
/// `holder_max_htlc_value_in_flight_msat`.
752+
pub const MAX_IN_FLIGHT_PERCENT_LEGACY: u8 = 10;
753+
748754
/// Maximum `funding_satoshis` value according to the BOLT #2 specification, if
749755
/// `option_support_large_channel` (aka wumbo channels) is not supported.
750756
/// It's 2^24 - 1.
@@ -803,9 +809,22 @@ macro_rules! secp_check {
803809
}
804810

805811
impl<Signer: Sign> Channel<Signer> {
806-
// Convert constants + channel value to limits:
807-
fn get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis: u64) -> u64 {
808-
channel_value_satoshis * 1000 / 10 //TODO
812+
/// Returns the value to use for `holder_max_htlc_value_in_flight_msat` as a percentage of the
813+
/// `channel_value_satoshis` in msat, set through
814+
/// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`]
815+
///
816+
/// The effective percentage is lower bounded by 1% and upper bounded by 100%.
817+
///
818+
/// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`]: crate::util::config::ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel
819+
fn get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis: u64, config: &ChannelHandshakeConfig) -> u64 {
820+
let configured_percent = if config.max_inbound_htlc_value_in_flight_percent_of_channel < 1 {
821+
1
822+
} else if config.max_inbound_htlc_value_in_flight_percent_of_channel > 100 {
823+
100
824+
} else {
825+
config.max_inbound_htlc_value_in_flight_percent_of_channel as u64
826+
};
827+
channel_value_satoshis * 10 * configured_percent
809828
}
810829

811830
/// Returns a minimum channel reserve value the remote needs to maintain,
@@ -964,7 +983,7 @@ impl<Signer: Sign> Channel<Signer> {
964983
counterparty_dust_limit_satoshis: 0,
965984
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
966985
counterparty_max_htlc_value_in_flight_msat: 0,
967-
holder_max_htlc_value_in_flight_msat: Self::get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis),
986+
holder_max_htlc_value_in_flight_msat: Self::get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis, &config.own_channel_config),
968987
counterparty_selected_channel_reserve_satoshis: None, // Filled in in accept_channel
969988
holder_selected_channel_reserve_satoshis,
970989
counterparty_htlc_minimum_msat: 0,
@@ -1282,7 +1301,7 @@ impl<Signer: Sign> Channel<Signer> {
12821301
counterparty_dust_limit_satoshis: msg.dust_limit_satoshis,
12831302
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
12841303
counterparty_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
1285-
holder_max_htlc_value_in_flight_msat: Self::get_holder_max_htlc_value_in_flight_msat(msg.funding_satoshis),
1304+
holder_max_htlc_value_in_flight_msat: Self::get_holder_max_htlc_value_in_flight_msat(msg.funding_satoshis, &config.own_channel_config),
12861305
counterparty_selected_channel_reserve_satoshis: Some(msg.channel_reserve_satoshis),
12871306
holder_selected_channel_reserve_satoshis,
12881307
counterparty_htlc_minimum_msat: msg.htlc_minimum_msat,
@@ -5877,13 +5896,18 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
58775896
let chan_type = if self.channel_type != ChannelTypeFeatures::only_static_remote_key() {
58785897
Some(&self.channel_type) } else { None };
58795898

5880-
// The same logic applies for `holder_selected_channel_reserve_satoshis` and
5881-
// `holder_max_htlc_value_in_flight_msat` values other than the defaults.
5899+
// The same logic applies for `holder_selected_channel_reserve_satoshis` values other than
5900+
// the default, and when `holder_max_htlc_value_in_flight_msat` is configured to be set to
5901+
// a different percentage of the channel value then 10%, which older versions of LDK used
5902+
// to set it to before the percentage was made configurable.
58825903
let serialized_holder_selected_reserve =
58835904
if self.holder_selected_channel_reserve_satoshis != Self::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis)
58845905
{ Some(self.holder_selected_channel_reserve_satoshis) } else { None };
5906+
5907+
let mut old_max_in_flight_percent_config = UserConfig::default().own_channel_config;
5908+
old_max_in_flight_percent_config.max_inbound_htlc_value_in_flight_percent_of_channel = MAX_IN_FLIGHT_PERCENT_LEGACY;
58855909
let serialized_holder_htlc_max_in_flight =
5886-
if self.holder_max_htlc_value_in_flight_msat != Self::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis)
5910+
if self.holder_max_htlc_value_in_flight_msat != Self::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis, &old_max_in_flight_percent_config)
58875911
{ Some(self.holder_max_htlc_value_in_flight_msat) } else { None };
58885912

58895913
write_tlv_fields!(writer, {
@@ -6153,7 +6177,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
61536177
let mut target_closing_feerate_sats_per_kw = None;
61546178
let mut monitor_pending_finalized_fulfills = Some(Vec::new());
61556179
let mut holder_selected_channel_reserve_satoshis = Some(Self::get_holder_selected_channel_reserve_satoshis(channel_value_satoshis));
6156-
let mut holder_max_htlc_value_in_flight_msat = Some(Self::get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis));
6180+
let mut holder_max_htlc_value_in_flight_msat = Some(Self::get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis, &UserConfig::default().own_channel_config));
61576181
// Prior to supporting channel type negotiation, all of our channels were static_remotekey
61586182
// only, so we default to that if none was written.
61596183
let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());

lightning/src/util/config.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ pub struct ChannelHandshakeConfig {
4848
/// Default value: 1. If the value is less than 1, it is ignored and set to 1, as is required
4949
/// by the protocol.
5050
pub our_htlc_minimum_msat: u64,
51+
/// Sets the percentage of the channel value we will cap the total value of outstanding inbound
52+
/// HTLCs to.
53+
///
54+
/// This can be set to a value between 1-100, where the value corresponds to the percent of the
55+
/// channel value in whole percentages.
56+
///
57+
/// Note that:
58+
/// * If configured to another value than the default value 10, any new channels created with
59+
/// the non default value will cause versions of LDK prior to 0.0.104 to refuse to read the
60+
/// `ChannelManager`.
61+
///
62+
/// * This caps the total value for inbound HTLCs in-flight only, and there's currently
63+
/// no way to configure the cap for the total value of outbound HTLCs in-flight.
64+
///
65+
/// * The requirements for your node being online to ensure the safety of HTLC-encumbered funds
66+
/// are different from the non-HTLC-encumbered funds. This makes this an important knob to
67+
/// restrict exposure to loss due to being offline for too long.
68+
/// See [`ChannelHandshakeConfig::our_to_self_delay`] and [`ChannelConfig::cltv_expiry_delta`]
69+
/// for more information.
70+
///
71+
/// Default value: 10.
72+
/// Minimum value: 1, any values less than 1 will be treated as 1 instead.
73+
/// Maximum value: 100, any values larger than 100 will be treated as 100 instead.
74+
pub max_inbound_htlc_value_in_flight_percent_of_channel: u8,
5175
/// If set, we attempt to negotiate the `scid_privacy` (referred to as `scid_alias` in the
5276
/// BOLTs) option for outbound private channels. This provides better privacy by not including
5377
/// our real on-chain channel UTXO in each invoice and requiring that our counterparty only
@@ -78,6 +102,7 @@ impl Default for ChannelHandshakeConfig {
78102
minimum_depth: 6,
79103
our_to_self_delay: BREAKDOWN_TIMEOUT,
80104
our_htlc_minimum_msat: 1,
105+
max_inbound_htlc_value_in_flight_percent_of_channel: 10,
81106
negotiate_scid_privacy: false,
82107
}
83108
}

0 commit comments

Comments
 (0)