diff --git a/lightning/src/ln/async_payments_tests.rs b/lightning/src/ln/async_payments_tests.rs index 25522346d9c..341bd5d7269 100644 --- a/lightning/src/ln/async_payments_tests.rs +++ b/lightning/src/ln/async_payments_tests.rs @@ -504,6 +504,9 @@ fn often_offline_node_cfg() -> UserConfig { cfg.channel_handshake_config.announce_for_forwarding = false; cfg.channel_handshake_limits.force_announced_channel_preference = true; cfg.hold_outbound_htlcs_at_next_hop = true; + // Use the setting that matches the default at the time these tests were written + cfg.channel_handshake_config.unannounced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; cfg } @@ -1310,6 +1313,10 @@ fn async_receive_mpp() { let mut allow_priv_chan_fwds_cfg = test_default_channel_config(); allow_priv_chan_fwds_cfg.accept_forwards_to_priv_channels = true; + // Set the percentage to the default value at the time this test was written + allow_priv_chan_fwds_cfg + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; let node_chanmgrs = create_node_chanmgrs( 4, diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index e148ce2c474..d62f79957eb 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -269,7 +269,11 @@ fn one_hop_blinded_path_with_dummy_hops() { fn mpp_to_one_hop_blinded_path() { let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); let mut secp_ctx = Secp256k1::new(); @@ -349,7 +353,11 @@ fn mpp_to_one_hop_blinded_path() { fn mpp_to_three_hop_blinded_paths() { let chanmon_cfgs = create_chanmon_cfgs(6); let node_cfgs = create_node_cfgs(6, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(6, &node_cfgs, &[None, None, None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; + let configs: [Option; 6] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(6, &node_cfgs, &configs); let nodes = create_network(6, &node_cfgs, &node_chanmgrs); // Create this network topology so node 0 MPP's over 2 3-hop blinded paths: diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index dd799c2c27c..af4d1569d0c 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -4656,6 +4656,7 @@ fn test_claim_to_closed_channel_blocks_claimed_event() { #[test] #[cfg(all(feature = "std", not(target_os = "windows")))] fn test_single_channel_multiple_mpp() { + use crate::util::config::UserConfig; use std::sync::atomic::{AtomicBool, Ordering}; // Test what happens when we attempt to claim an MPP with many parts that came to us through @@ -4667,7 +4668,11 @@ fn test_single_channel_multiple_mpp() { // for more info. let chanmon_cfgs = create_chanmon_cfgs(9); let node_cfgs = create_node_cfgs(9, &chanmon_cfgs); - let configs = [None, None, None, None, None, None, None, None, None]; + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let configs: [Option; 9] = core::array::from_fn(|_| Some(config.clone())); let node_chanmgrs = create_node_chanmgrs(9, &node_cfgs, &configs); let mut nodes = create_network(9, &node_cfgs, &node_chanmgrs); diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 03f78dc82b4..5579c119e05 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -4102,6 +4102,7 @@ impl ChannelContext { ), holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat( channel_value_satoshis, + announce_for_forwarding, &config.channel_handshake_config, ), counterparty_htlc_minimum_msat: open_channel_fields.htlc_minimum_msat, @@ -4405,6 +4406,7 @@ impl ChannelContext { // receive `accept_channel2`. holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat( channel_value_satoshis, + config.channel_handshake_config.announce_for_forwarding, &config.channel_handshake_config, ), counterparty_htlc_minimum_msat: 0, @@ -6678,24 +6680,41 @@ impl ChannelContext { /// Returns the value to use for `holder_max_htlc_value_in_flight_msat` as a percentage of the /// `channel_value_satoshis` in msat, set through -/// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`] +/// [`ChannelHandshakeConfig::announced_channel_max_inbound_htlc_value_in_flight_percentage`] +/// or [`ChannelHandshakeConfig::unannounced_channel_max_inbound_htlc_value_in_flight_percentage`] +/// depending on the value of [`ChannelHandshakeConfig::announce_for_forwarding`]. /// /// The effective percentage is lower bounded by 1% and upper bounded by 100%. /// -/// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`]: crate::util::config::ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel +/// [`ChannelHandshakeConfig::announced_channel_max_inbound_htlc_value_in_flight_percentage`]: crate::util::config::ChannelHandshakeConfig::announced_channel_max_inbound_htlc_value_in_flight_percentage +/// [`ChannelHandshakeConfig::unannounced_channel_max_inbound_htlc_value_in_flight_percentage`]: crate::util::config::ChannelHandshakeConfig::unannounced_channel_max_inbound_htlc_value_in_flight_percentage +/// [`ChannelHandshakeConfig::announce_for_forwarding`]: crate::util::config::ChannelHandshakeConfig::announce_for_forwarding fn get_holder_max_htlc_value_in_flight_msat( - channel_value_satoshis: u64, config: &ChannelHandshakeConfig, + channel_value_satoshis: u64, is_announced_channel: bool, config: &ChannelHandshakeConfig, ) -> u64 { - let configured_percent = if config.max_inbound_htlc_value_in_flight_percent_of_channel < 1 { + let config_setting = if is_announced_channel { + config.announced_channel_max_inbound_htlc_value_in_flight_percentage + } else { + config.unannounced_channel_max_inbound_htlc_value_in_flight_percentage + }; + let configured_percent = if config_setting < 1 { 1 - } else if config.max_inbound_htlc_value_in_flight_percent_of_channel > 100 { + } else if config_setting > 100 { 100 } else { - config.max_inbound_htlc_value_in_flight_percent_of_channel as u64 + config_setting as u64 }; channel_value_satoshis * 10 * configured_percent } +/// This is for legacy reasons, present for forward-compatibility. +/// LDK versions older than 0.0.104 don't know how read/handle values other than the legacy +/// percentage from storage. Hence, we use this function to not persist legacy values of +/// `holder_max_htlc_value_in_flight_msat` for channels into storage. +fn get_legacy_default_holder_max_htlc_value_in_flight_msat(channel_value_satoshis: u64) -> u64 { + channel_value_satoshis * 10 * MAX_IN_FLIGHT_PERCENT_LEGACY as u64 +} + /// Returns a minimum channel reserve value the remote needs to maintain, /// required by us according to the configured or default /// [`ChannelHandshakeConfig::their_channel_reserve_proportional_millionths`] @@ -15691,15 +15710,11 @@ impl Writeable for FundedChannel { None }; - let mut old_max_in_flight_percent_config = UserConfig::default().channel_handshake_config; - old_max_in_flight_percent_config.max_inbound_htlc_value_in_flight_percent_of_channel = - MAX_IN_FLIGHT_PERCENT_LEGACY; - let max_in_flight_msat = get_holder_max_htlc_value_in_flight_msat( + let legacy_max_in_flight_msat = get_legacy_default_holder_max_htlc_value_in_flight_msat( self.funding.get_value_satoshis(), - &old_max_in_flight_percent_config, ); let serialized_holder_htlc_max_in_flight = - if self.context.holder_max_htlc_value_in_flight_msat != max_in_flight_msat { + if self.context.holder_max_htlc_value_in_flight_msat != legacy_max_in_flight_msat { Some(self.context.holder_max_htlc_value_in_flight_msat) } else { None @@ -16131,11 +16146,9 @@ impl<'a, 'b, 'c, ES: EntropySource, SP: SignerProvider> let mut holder_selected_channel_reserve_satoshis = Some( get_legacy_default_holder_selected_channel_reserve_satoshis(channel_value_satoshis), ); + let mut holder_max_htlc_value_in_flight_msat = - Some(get_holder_max_htlc_value_in_flight_msat( - channel_value_satoshis, - &UserConfig::default().channel_handshake_config, - )); + Some(get_legacy_default_holder_max_htlc_value_in_flight_msat(channel_value_satoshis)); // Prior to supporting channel type negotiation, all of our channels were static_remotekey // only, so we default to that if none was written. let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key()); @@ -17141,8 +17154,13 @@ mod tests { } #[test] - #[rustfmt::skip] fn test_configured_holder_max_htlc_value_in_flight() { + do_test_configured_holder_max_htlc_value_in_flight(true); + do_test_configured_holder_max_htlc_value_in_flight(false); + } + + #[rustfmt::skip] + fn do_test_configured_holder_max_htlc_value_in_flight(announce_channel: bool) { let test_est = TestFeeEstimator::new(15000); let feeest = LowerBoundedFeeEstimator::new(&test_est); let logger = TestLogger::new(); @@ -17154,13 +17172,49 @@ mod tests { let inbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); let mut config_2_percent = UserConfig::default(); - config_2_percent.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 2; + config_2_percent.channel_handshake_config.announce_for_forwarding = announce_channel; + if announce_channel { + config_2_percent + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 2; + } else { + config_2_percent + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 2; + } let mut config_99_percent = UserConfig::default(); - config_99_percent.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 99; + config_99_percent.channel_handshake_config.announce_for_forwarding = announce_channel; + if announce_channel { + config_99_percent + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 99; + } else { + config_99_percent + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 99; + } let mut config_0_percent = UserConfig::default(); - config_0_percent.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 0; + config_0_percent.channel_handshake_config.announce_for_forwarding = announce_channel; + if announce_channel { + config_0_percent + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 0; + } else { + config_0_percent + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 0; + } let mut config_101_percent = UserConfig::default(); - config_101_percent.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 101; + config_101_percent.channel_handshake_config.announce_for_forwarding = announce_channel; + if announce_channel { + config_101_percent + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 101; + } else { + config_101_percent + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 101; + } // Test that `OutboundV1Channel::new` creates a channel with the correct value for // `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value, @@ -17189,26 +17243,26 @@ mod tests { assert_eq!(chan_4.context.holder_max_htlc_value_in_flight_msat, (chan_4_value_msat as f64 * 0.99) as u64); // Test that `OutboundV1Channel::new` uses the lower bound of the configurable percentage values (1%) - // if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a value less than 1. + // if `(un)announced_channel_max_inbound_htlc_value_in_flight_percentage` is set to a value less than 1. let chan_5 = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_0_percent), 10000000, 100000, 42, &config_0_percent, 0, 42, None, &logger, None).unwrap(); let chan_5_value_msat = chan_5.funding.get_value_satoshis() * 1000; assert_eq!(chan_5.context.holder_max_htlc_value_in_flight_msat, (chan_5_value_msat as f64 * 0.01) as u64); // Test that `OutboundV1Channel::new` uses the upper bound of the configurable percentage values - // (100%) if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a larger value + // (100%) if `(un)announced_channel_max_inbound_htlc_value_in_flight_percentage` is set to a larger value // than 100. let chan_6 = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_101_percent), 10000000, 100000, 42, &config_101_percent, 0, 42, None, &logger, None).unwrap(); let chan_6_value_msat = chan_6.funding.get_value_satoshis() * 1000; assert_eq!(chan_6.context.holder_max_htlc_value_in_flight_msat, chan_6_value_msat); // Test that `InboundV1Channel::new` uses the lower bound of the configurable percentage values (1%) - // if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a value less than 1. + // if `(un)announced_channel_max_inbound_htlc_value_in_flight_percentage` is set to a value less than 1. let chan_7 = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_0_percent), &channelmanager::provided_init_features(&config_0_percent), &chan_1_open_channel_msg, 7, &config_0_percent, 0, &&logger, None).unwrap(); let chan_7_value_msat = chan_7.funding.get_value_satoshis() * 1000; assert_eq!(chan_7.context.holder_max_htlc_value_in_flight_msat, (chan_7_value_msat as f64 * 0.01) as u64); // Test that `InboundV1Channel::new` uses the upper bound of the configurable percentage values - // (100%) if `max_inbound_htlc_value_in_flight_percent_of_channel` is set to a larger value + // (100%) if `(un)announced_channel_max_inbound_htlc_value_in_flight_percentage` is set to a larger value // than 100. let chan_8 = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, inbound_node_id, &channelmanager::provided_channel_type_features(&config_101_percent), &channelmanager::provided_init_features(&config_101_percent), &chan_1_open_channel_msg, 7, &config_101_percent, 0, &&logger, None).unwrap(); let chan_8_value_msat = chan_8.funding.get_value_satoshis() * 1000; diff --git a/lightning/src/ln/channel_open_tests.rs b/lightning/src/ln/channel_open_tests.rs index d28d157488d..ac4a1b67994 100644 --- a/lightning/src/ln/channel_open_tests.rs +++ b/lightning/src/ln/channel_open_tests.rs @@ -182,7 +182,8 @@ fn test_inbound_anchors_manual_acceptance() { fn test_inbound_anchors_config_overridden() { let overrides = ChannelConfigOverrides { handshake_overrides: Some(ChannelHandshakeConfigUpdate { - max_inbound_htlc_value_in_flight_percent_of_channel: Some(5), + announced_channel_max_inbound_htlc_value_in_flight_percentage: Some(5), + unannounced_channel_max_inbound_htlc_value_in_flight_percentage: None, htlc_minimum_msat: Some(1000), minimum_depth: Some(2), to_self_delay: Some(200), @@ -1070,7 +1071,8 @@ pub fn test_accept_inbound_channel_config_override() { let config_overrides = ChannelConfigOverrides { handshake_overrides: Some(ChannelHandshakeConfigUpdate { - max_inbound_htlc_value_in_flight_percent_of_channel: None, + announced_channel_max_inbound_htlc_value_in_flight_percentage: None, + unannounced_channel_max_inbound_htlc_value_in_flight_percentage: None, htlc_minimum_msat: None, minimum_depth: None, to_self_delay: None, diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 7ed46922d8a..32a07be4d2b 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -6903,22 +6903,22 @@ pub fn test_channel_update_has_correct_htlc_maximum_msat() { config_30_percent.channel_handshake_config.announce_for_forwarding = true; config_30_percent .channel_handshake_config - .max_inbound_htlc_value_in_flight_percent_of_channel = 30; + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 30; let mut config_50_percent = UserConfig::default(); config_50_percent.channel_handshake_config.announce_for_forwarding = true; config_50_percent .channel_handshake_config - .max_inbound_htlc_value_in_flight_percent_of_channel = 50; + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 50; let mut config_95_percent = UserConfig::default(); config_95_percent.channel_handshake_config.announce_for_forwarding = true; config_95_percent .channel_handshake_config - .max_inbound_htlc_value_in_flight_percent_of_channel = 95; + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 95; let mut config_100_percent = UserConfig::default(); config_100_percent.channel_handshake_config.announce_for_forwarding = true; config_100_percent .channel_handshake_config - .max_inbound_htlc_value_in_flight_percent_of_channel = 100; + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 100; let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); @@ -8436,7 +8436,12 @@ pub fn test_inconsistent_mpp_params() { // such HTLC and allow the second to stay. let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); let node_a_id = nodes[0].node.get_our_node_id(); @@ -8580,7 +8585,12 @@ pub fn test_double_partial_claim() { // amount. let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); let node_b_id = nodes[1].node.get_our_node_id(); @@ -9067,7 +9077,8 @@ pub fn test_nondust_htlc_excess_fees_are_dust() { config.channel_handshake_limits.min_max_accepted_htlcs = chan_utils::max_htlcs(&chan_ty); config.channel_handshake_config.our_max_accepted_htlcs = chan_utils::max_htlcs(&chan_ty); config.channel_handshake_config.our_htlc_minimum_msat = 1; - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs( 3, @@ -10039,7 +10050,8 @@ pub fn test_dust_exposure_holding_cell_assertion() { // Use a fixed dust exposure limit to make the test simpler const DUST_HTLC_VALUE_MSAT: u64 = 500_000; config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FixedLimitMsat(5_000_000); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let configs = [Some(config.clone()), Some(config.clone()), Some(config.clone())]; let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs); diff --git a/lightning/src/ln/htlc_reserve_unit_tests.rs b/lightning/src/ln/htlc_reserve_unit_tests.rs index 608ac143c8d..aaf81b87be7 100644 --- a/lightning/src/ln/htlc_reserve_unit_tests.rs +++ b/lightning/src/ln/htlc_reserve_unit_tests.rs @@ -2376,7 +2376,8 @@ fn test_create_channel_to_trusted_peer_0reserve() { fn do_test_create_channel_to_trusted_peer_0reserve(mut config: UserConfig) -> ChannelTypeFeatures { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -2465,7 +2466,8 @@ fn do_test_accept_inbound_channel_from_trusted_peer_0reserve( ) -> ChannelTypeFeatures { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -2679,7 +2681,8 @@ fn do_test_0reserve_no_outputs_legacy(no_outputs_case: LegacyChannelsNoOutputs) let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let channel_type = ChannelTypeFeatures::only_static_remote_key(); @@ -2979,7 +2982,8 @@ fn do_test_0reserve_no_outputs_keyed_anchors(payment_success: bool) { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let channel_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies(); @@ -3112,7 +3116,8 @@ fn do_test_0reserve_no_outputs_p2a_anchor() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let channel_type = ChannelTypeFeatures::anchors_zero_fee_commitments(); @@ -3170,7 +3175,8 @@ fn do_test_0reserve_force_close_with_single_p2a_output(high_feerate: bool) { *feerate_lock = 2500; } let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let channel_type = ChannelTypeFeatures::anchors_zero_fee_commitments(); @@ -3276,7 +3282,8 @@ fn test_0reserve_zero_conf_combined() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index efd2084a38e..f52f093917b 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -2724,6 +2724,8 @@ fn do_test_anchors_aggregated_revoked_htlc_tx(p2a_anchor: bool) { anchors_config.channel_handshake_config.announce_for_forwarding = true; anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; anchors_config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = p2a_anchor; + // Set the percentage to the default value at the time this test was written + anchors_config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config.clone()), Some(anchors_config.clone())]); let bob_deserialized; diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index be52459a872..807d1a1af39 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -45,7 +45,7 @@ use crate::sign::EntropySource; use crate::types::features::{Bolt11InvoiceFeatures, ChannelTypeFeatures}; use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; use crate::types::string::UntrustedString; -use crate::util::config::HTLCInterceptionFlags; +use crate::util::config::{HTLCInterceptionFlags, UserConfig}; use crate::util::errors::APIError; use crate::util::ser::Writeable; use bitcoin::hashes::sha256::Hash as Sha256; @@ -212,7 +212,9 @@ fn mpp_retry_overpay() { let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); let mut user_config = test_legacy_channel_config(); - user_config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + user_config + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 100; let mut limited_1 = user_config.clone(); limited_1.channel_handshake_config.our_htlc_minimum_msat = 35_000_000; let mut limited_2 = user_config.clone(); @@ -487,7 +489,12 @@ fn do_test_keysend_payments(public_node: bool) { fn test_mpp_keysend() { let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); let node_b_id = nodes[1].node.get_our_node_id(); @@ -1702,7 +1709,8 @@ fn preflight_probes_yield_event_skip_private_hop() { // We alleviate the HTLC max-in-flight limit, as otherwise we'd always be limited through that. let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let config = Some(config); let configs = [config.clone(), config.clone(), config.clone(), config.clone(), config]; @@ -1749,7 +1757,8 @@ fn preflight_probes_yield_event() { // We alleviate the HTLC max-in-flight limit, as otherwise we'd always be limited through that. let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let config = Some(config); let configs = [config.clone(), config.clone(), config.clone(), config]; @@ -1800,7 +1809,8 @@ fn preflight_probes_yield_event_and_skip() { // We alleviate the HTLC max-in-flight limit, as otherwise we'd always be limited through that. let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let config = Some(config); let configs = @@ -2429,11 +2439,12 @@ fn do_accept_underpaying_htlcs_config(num_mpp_parts: usize) { HTLCInterceptionFlags::ToInterceptSCIDs as u8; intercept_forwards_config .channel_handshake_config - .max_inbound_htlc_value_in_flight_percent_of_channel = max_in_flight_percent; + .announced_channel_max_inbound_htlc_value_in_flight_percentage = max_in_flight_percent; let mut underpay_config = test_default_channel_config(); underpay_config.channel_config.accept_underpaying_htlcs = true; - underpay_config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = - max_in_flight_percent; + underpay_config + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = max_in_flight_percent; let configs = [None, Some(intercept_forwards_config), Some(underpay_config)]; let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs); @@ -3220,7 +3231,12 @@ fn retry_multi_path_single_failed_payment() { // Tests that we can/will retry after a single path of an MPP payment failed immediately let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let node_chanmgrs = + create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config.clone())]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let node_b_id = nodes[1].node.get_our_node_id(); @@ -3339,7 +3355,12 @@ fn immediate_retry_on_failure() { // Tests that we can/will retry immediately after a failure let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let node_chanmgrs = + create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config.clone())]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let node_b_id = nodes[1].node.get_our_node_id(); @@ -4240,17 +4261,13 @@ fn do_claim_from_closed_chan(fail_payment: bool) { // CLTVs on the paths to different value resulting in a different claim deadline. let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let legacy_cfg = test_legacy_channel_config(); - let node_chanmgrs = create_node_chanmgrs( - 4, - &node_cfgs, - &[ - Some(legacy_cfg.clone()), - Some(legacy_cfg.clone()), - Some(legacy_cfg.clone()), - Some(legacy_cfg), - ], - ); + let mut legacy_cfg = test_legacy_channel_config(); + // Set the percentage to the default value at the time this test was written + legacy_cfg + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(legacy_cfg.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs); let node_a_id = nodes[0].node.get_our_node_id(); @@ -4635,7 +4652,12 @@ fn do_test_custom_tlvs_consistency( ) { let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); let node_a_id = nodes[0].node.get_our_node_id(); @@ -4788,7 +4810,8 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) { let chain_mon; let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 50; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 50; let configs = [None, Some(config.clone()), Some(config.clone()), Some(config.clone())]; let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let node_d_reload; @@ -5147,7 +5170,8 @@ fn test_non_strict_forwarding() { let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let mut config = test_legacy_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let configs = [Some(config.clone()), Some(config.clone()), Some(config)]; let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs); @@ -5386,11 +5410,15 @@ fn max_out_mpp_path() { let mut user_cfg = test_default_channel_config(); user_cfg.channel_config.forwarding_fee_base_msat = 0; - user_cfg.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + user_cfg + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 100; let mut lsp_cfg = test_default_channel_config(); lsp_cfg.channel_config.forwarding_fee_base_msat = 0; lsp_cfg.channel_config.forwarding_fee_proportional_millionths = 3000; - lsp_cfg.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + lsp_cfg + .channel_handshake_config + .unannounced_channel_max_inbound_htlc_value_in_flight_percentage = 100; let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); diff --git a/lightning/src/ln/reload_tests.rs b/lightning/src/ln/reload_tests.rs index 892a6c62d8f..9e992467ecd 100644 --- a/lightning/src/ln/reload_tests.rs +++ b/lightning/src/ln/reload_tests.rs @@ -745,7 +745,11 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool, double_rest let (persist_d_1, persist_d_2); let (chain_d_1, chain_d_2); - let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; + let configs: [Option; 4] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs); let (node_d_1, node_d_2); let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs); @@ -2107,7 +2111,11 @@ fn test_reload_with_mpp_claims_on_same_channel() { let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let persister; let new_chain_monitor; - let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); + let mut config = test_default_channel_config(); + // Set the percentage to the default value at the time this test was written + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10; + let configs: [Option; 3] = core::array::from_fn(|_| Some(config.clone())); + let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs); let nodes_1_deserialized; let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); diff --git a/lightning/src/ln/splicing_tests.rs b/lightning/src/ln/splicing_tests.rs index 5279f2dfcc0..e4c4c10dbbd 100644 --- a/lightning/src/ln/splicing_tests.rs +++ b/lightning/src/ln/splicing_tests.rs @@ -1122,7 +1122,8 @@ fn test_splice_in() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -1172,7 +1173,8 @@ fn test_splice_out() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -1215,7 +1217,8 @@ fn test_splice_in_and_out() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -3546,7 +3549,8 @@ fn test_splice_balance_falls_below_reserve() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); @@ -4066,19 +4070,22 @@ fn test_funding_contributed_unfunded_channel() { #[test] fn test_splice_pending_htlcs() { let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false; config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false; do_test_splice_pending_htlcs(config); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false; do_test_splice_pending_htlcs(config); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false; config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true; do_test_splice_pending_htlcs(config); @@ -6298,7 +6305,8 @@ fn test_splice_revalidation_at_quiescence() { let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let mut config = test_default_channel_config(); - config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); diff --git a/lightning/src/ln/update_fee_tests.rs b/lightning/src/ln/update_fee_tests.rs index fc80059bbd3..b1f8257088e 100644 --- a/lightning/src/ln/update_fee_tests.rs +++ b/lightning/src/ln/update_fee_tests.rs @@ -1031,7 +1031,8 @@ pub fn do_cannot_afford_on_holding_cell_release( let chanmon_cfgs = create_chanmon_cfgs(2); let mut cfg = test_legacy_channel_config(); - cfg.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + cfg.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = + 100; if channel_type_features.supports_anchors_zero_fee_htlc_tx() { cfg.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; } @@ -1225,7 +1226,9 @@ pub fn do_can_afford_given_trimmed_htlcs(inequality_regions: core::cmp::Ordering let chanmon_cfgs = create_chanmon_cfgs(2); let mut legacy_cfg = test_legacy_channel_config(); - legacy_cfg.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; + legacy_cfg + .channel_handshake_config + .announced_channel_max_inbound_htlc_value_in_flight_percentage = 100; let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let node_chanmgrs = diff --git a/lightning/src/util/config.rs b/lightning/src/util/config.rs index 14c507184ac..ebef8c27bca 100644 --- a/lightning/src/util/config.rs +++ b/lightning/src/util/config.rs @@ -62,17 +62,35 @@ pub struct ChannelHandshakeConfig { /// Default value: `1` (If the value is less than `1`, it is ignored and set to `1`, as is /// required by the protocol. pub our_htlc_minimum_msat: u64, - /// Sets the percentage of the channel value we will cap the total value of outstanding inbound - /// HTLCs to. + /// Sets the maximum percentage of the total channel value that can be allocated to inbound + /// HTLCs in announced channels. /// /// This 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: `25` /// + /// Minimum value: `1` (Any values less will be treated as `1` instead.) + /// + /// Maximum value: `100` (Any values larger will be treated as `100` instead.) + pub announced_channel_max_inbound_htlc_value_in_flight_percentage: u8, + /// Sets the maximum percentage of the total channel value that can be allocated to inbound + /// HTLCs in unannounced channels. + /// + /// This 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: /// * 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. /// @@ -82,12 +100,12 @@ pub struct ChannelHandshakeConfig { /// See [`ChannelHandshakeConfig::our_to_self_delay`] and [`ChannelConfig::cltv_expiry_delta`] /// for more information. /// - /// Default value: `10` + /// Default value: `100` /// /// Minimum value: `1` (Any values less will be treated as `1` instead.) /// /// Maximum value: `100` (Any values larger will be treated as `100` instead.) - pub max_inbound_htlc_value_in_flight_percent_of_channel: u8, + pub unannounced_channel_max_inbound_htlc_value_in_flight_percentage: u8, /// If set, we attempt to negotiate the `scid_privacy` (referred to as `scid_alias` in the /// BOLTs) option for outbound private channels. This provides better privacy by not including /// our real on-chain channel UTXO in each invoice and requiring that our counterparty only @@ -246,7 +264,8 @@ impl Default for ChannelHandshakeConfig { minimum_depth: 6, our_to_self_delay: BREAKDOWN_TIMEOUT, our_htlc_minimum_msat: 1, - max_inbound_htlc_value_in_flight_percent_of_channel: 10, + announced_channel_max_inbound_htlc_value_in_flight_percentage: 25, + unannounced_channel_max_inbound_htlc_value_in_flight_percentage: 100, negotiate_scid_privacy: false, announce_for_forwarding: false, commit_upfront_shutdown_pubkey: true, @@ -264,11 +283,21 @@ impl Default for ChannelHandshakeConfig { #[cfg(fuzzing)] impl Readable for ChannelHandshakeConfig { fn read(reader: &mut R) -> Result { + let minimum_depth = Readable::read(reader)?; + let our_to_self_delay = Readable::read(reader)?; + let our_htlc_minimum_msat = Readable::read(reader)?; + // Apply the same byte to both the announced and the unannounced maximums so as to + // not invalidate the existing fuzz corpus + let max_inbound_htlc_value_in_flight_percentage = Readable::read(reader)?; + Ok(Self { - minimum_depth: Readable::read(reader)?, - our_to_self_delay: Readable::read(reader)?, - our_htlc_minimum_msat: Readable::read(reader)?, - max_inbound_htlc_value_in_flight_percent_of_channel: Readable::read(reader)?, + minimum_depth, + our_to_self_delay, + our_htlc_minimum_msat, + announced_channel_max_inbound_htlc_value_in_flight_percentage: + max_inbound_htlc_value_in_flight_percentage, + unannounced_channel_max_inbound_htlc_value_in_flight_percentage: + max_inbound_htlc_value_in_flight_percentage, negotiate_scid_privacy: Readable::read(reader)?, announce_for_forwarding: Readable::read(reader)?, commit_upfront_shutdown_pubkey: Readable::read(reader)?, @@ -1171,9 +1200,15 @@ impl UserConfig { /// Config structure for overriding channel handshake parameters. #[derive(Default)] pub struct ChannelHandshakeConfigUpdate { - /// Overrides the percentage of the channel value we will cap the total value of outstanding inbound HTLCs to. See - /// [`ChannelHandshakeConfig::max_inbound_htlc_value_in_flight_percent_of_channel`]. - pub max_inbound_htlc_value_in_flight_percent_of_channel: Option, + /// Overrides the maximum percentage of the total channel value that can be allocated to inbound + /// HTLCs in announced channels. See + /// [`ChannelHandshakeConfig::announced_channel_max_inbound_htlc_value_in_flight_percentage`]. + pub announced_channel_max_inbound_htlc_value_in_flight_percentage: Option, + + /// Overrides the maximum percentage of the total channel value that can be allocated to inbound + /// HTLCs in unannounced channels. See + /// [`ChannelHandshakeConfig::unannounced_channel_max_inbound_htlc_value_in_flight_percentage`]. + pub unannounced_channel_max_inbound_htlc_value_in_flight_percentage: Option, /// Overrides the smallest value HTLC we will accept to process. See [`ChannelHandshakeConfig::our_htlc_minimum_msat`]. pub htlc_minimum_msat: Option, @@ -1199,9 +1234,17 @@ impl ChannelHandshakeConfig { /// Applies the provided handshake config update. pub fn apply(&mut self, config: &ChannelHandshakeConfigUpdate) { if let Some(max_in_flight_percent) = - config.max_inbound_htlc_value_in_flight_percent_of_channel + config.announced_channel_max_inbound_htlc_value_in_flight_percentage + { + self.announced_channel_max_inbound_htlc_value_in_flight_percentage = + max_in_flight_percent; + } + + if let Some(max_in_flight_percent) = + config.unannounced_channel_max_inbound_htlc_value_in_flight_percentage { - self.max_inbound_htlc_value_in_flight_percent_of_channel = max_in_flight_percent; + self.unannounced_channel_max_inbound_htlc_value_in_flight_percentage = + max_in_flight_percent; } if let Some(htlc_minimum_msat) = config.htlc_minimum_msat {