diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 4faafbfc4ef..d37ee1cd99e 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -10518,9 +10518,20 @@ fn test_max_dust_htlc_exposure() { } #[test] -fn test_nondust_htlc_fees_are_dust() { - // Test that the transaction fees paid in nondust HTLCs count towards our dust limit +fn test_nondust_htlc_excess_fees_are_dust() { + // Test that the excess transaction fees paid in nondust HTLCs count towards our dust limit + const DEFAULT_FEERATE: u32 = 253; + const HIGH_FEERATE: u32 = 275; + const EXCESS_FEERATE: u32 = HIGH_FEERATE - DEFAULT_FEERATE; let chanmon_cfgs = create_chanmon_cfgs(3); + { + // Set the feerate of the channel funder above the `dust_exposure_limiting_feerate` of + // the fundee. This delta means that the fundee will add the mining fees of the commitment and + // htlc transactions in excess of its `dust_exposure_limiting_feerate` to its total dust htlc + // exposure. + let mut feerate_lock = chanmon_cfgs[1].fee_estimator.sat_per_kw.lock().unwrap(); + *feerate_lock = HIGH_FEERATE; + } let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let mut config = test_default_channel_config(); @@ -10528,18 +10539,16 @@ fn test_nondust_htlc_fees_are_dust() { config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FeeRateMultiplier(10_000); // Make sure the HTLC limits don't get in the way - config.channel_handshake_limits.min_max_accepted_htlcs = 400; - config.channel_handshake_config.our_max_accepted_htlcs = 400; + config.channel_handshake_limits.min_max_accepted_htlcs = chan_utils::MAX_HTLCS; + config.channel_handshake_config.our_max_accepted_htlcs = chan_utils::MAX_HTLCS; config.channel_handshake_config.our_htlc_minimum_msat = 1; + config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100; let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(config), Some(config), Some(config)]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); - // Create a channel from 1 -> 0 but immediately push all of the funds towards 0 - let chan_id_1 = create_announced_chan_between_nodes(&nodes, 1, 0).2; - while nodes[1].node.list_channels()[0].next_outbound_htlc_limit_msat > 0 { - send_payment(&nodes[1], &[&nodes[0]], nodes[1].node.list_channels()[0].next_outbound_htlc_limit_msat); - } + // Leave enough on the funder side to let it pay the mining fees for a commit tx with tons of htlcs + let chan_id_1 = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1_000_000, 750_000_000).2; // First get the channel one HTLC_VALUE HTLC away from the dust limit by sending dust HTLCs // repeatedly until we run out of space. @@ -10561,14 +10570,13 @@ fn test_nondust_htlc_fees_are_dust() { // At this point we have somewhere between dust_limit and dust_limit * 2 left in our dust // exposure limit, and we want to max that out using non-dust HTLCs. - let commitment_tx_per_htlc_cost = - htlc_success_tx_weight(&ChannelTypeFeatures::empty()) * 253; + let commitment_tx_per_htlc_cost = chan_utils::per_outbound_htlc_counterparty_commit_tx_fee_msat(EXCESS_FEERATE, &ChannelTypeFeatures::empty()); let max_htlcs_remaining = dust_limit * 2 / commitment_tx_per_htlc_cost; - assert!(max_htlcs_remaining < 30, + assert!(max_htlcs_remaining < chan_utils::MAX_HTLCS.into(), "We should be able to fill our dust limit without too many HTLCs"); for i in 0..max_htlcs_remaining + 1 { assert_ne!(i, max_htlcs_remaining); - if nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat < dust_limit { + if nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat <= dust_limit { // We found our limit, and it was less than max_htlcs_remaining! // At this point we can only send dust HTLCs as any non-dust HTLCs will overuse our // remaining dust exposure.