diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 7647915f247..5f6c5a449f2 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -6443,6 +6443,19 @@ fn get_holder_max_htlc_value_in_flight_msat( channel_value_satoshis * 10 * configured_percent } +fn rescale_max_htlc_value_in_flight_msat( + max_htlc_value_in_flight_msat: u64, old_channel_value_satoshis: u64, + new_channel_value_satoshis: u64, +) -> u64 { + debug_assert_ne!(old_channel_value_satoshis, 0); + if old_channel_value_satoshis == 0 { + return max_htlc_value_in_flight_msat; + } + + ((max_htlc_value_in_flight_msat as u128 * new_channel_value_satoshis as u128) + / old_channel_value_satoshis as u128) 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`] @@ -11185,12 +11198,41 @@ where .find(|funding| funding.get_funding_txid() == Some(splice_txid)) .unwrap(); let prev_funding_txid = self.funding.get_funding_txid(); + let prev_channel_value_satoshis = self.funding.get_value_satoshis(); if let Some(scid) = self.funding.short_channel_id { self.context.historical_scids.push(scid); } core::mem::swap(&mut self.funding, funding); + let new_channel_value_satoshis = self.funding.get_value_satoshis(); + let prev_holder_max_htlc_value_in_flight_msat = + self.context.holder_max_htlc_value_in_flight_msat; + let prev_counterparty_max_htlc_value_in_flight_msat = + self.context.counterparty_max_htlc_value_in_flight_msat; + self.context.holder_max_htlc_value_in_flight_msat = + rescale_max_htlc_value_in_flight_msat( + self.context.holder_max_htlc_value_in_flight_msat, + prev_channel_value_satoshis, + new_channel_value_satoshis, + ); + self.context.counterparty_max_htlc_value_in_flight_msat = + rescale_max_htlc_value_in_flight_msat( + self.context.counterparty_max_htlc_value_in_flight_msat, + prev_channel_value_satoshis, + new_channel_value_satoshis, + ); + log_info!( + logger, + "Splice promotion HTLC caps for channel {}: holder {} -> {}, counterparty {} -> {}, value {} -> {} sats", + &self.context.channel_id, + prev_holder_max_htlc_value_in_flight_msat, + self.context.holder_max_htlc_value_in_flight_msat, + prev_counterparty_max_htlc_value_in_flight_msat, + self.context.counterparty_max_htlc_value_in_flight_msat, + prev_channel_value_satoshis, + new_channel_value_satoshis, + ); // The swap above places the previous `FundingScope` into `pending_funding`. pending_splice diff --git a/lightning/src/ln/splicing_tests.rs b/lightning/src/ln/splicing_tests.rs index e387ac3bfdd..127bdf03e85 100644 --- a/lightning/src/ln/splicing_tests.rs +++ b/lightning/src/ln/splicing_tests.rs @@ -759,15 +759,17 @@ fn test_splice_in() { mine_transaction(&nodes[0], &splice_tx); mine_transaction(&nodes[1], &splice_tx); - let htlc_limit_msat = nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat; - assert!(htlc_limit_msat < initial_channel_value_sat * 1000); - let _ = send_payment(&nodes[0], &[&nodes[1]], htlc_limit_msat); + let pre_splice_htlc_limit_msat = nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat; + assert!(pre_splice_htlc_limit_msat < initial_channel_value_sat * 1000); + let _ = send_payment(&nodes[0], &[&nodes[1]], pre_splice_htlc_limit_msat); lock_splice_after_blocks(&nodes[0], &nodes[1], ANTI_REORG_DELAY - 1); - let htlc_limit_msat = nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat; - assert!(htlc_limit_msat > initial_channel_value_sat); - let _ = send_payment(&nodes[0], &[&nodes[1]], htlc_limit_msat); + let post_splice_htlc_limit_msat = + nodes[0].node.list_channels()[0].next_outbound_htlc_limit_msat; + assert!(post_splice_htlc_limit_msat > pre_splice_htlc_limit_msat); + assert!(post_splice_htlc_limit_msat > initial_channel_value_sat * 1000); + let _ = send_payment(&nodes[0], &[&nodes[1]], post_splice_htlc_limit_msat); } #[test]