From 2cc49bc7db4e577d605a8618897c7561f3e925a0 Mon Sep 17 00:00:00 2001 From: optout <13562139+optout21@users.noreply.github.com> Date: Sat, 25 Jan 2025 00:00:59 +0100 Subject: [PATCH] Include input weight in splice_channel; test util to return weight as well --- lightning/src/ln/channel.rs | 16 ++++++++++------ lightning/src/ln/channelmanager.rs | 6 ++++-- lightning/src/ln/dual_funding_tests.rs | 4 ++-- lightning/src/ln/functional_test_utils.rs | 15 ++++++++++----- lightning/src/ln/functional_tests_splice.rs | 3 ++- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index e378b7e052f..e17507866bc 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -54,7 +54,9 @@ use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBounde use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; use crate::sign::ecdsa::EcdsaChannelSigner; -use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient, P2WPKH_WITNESS_WEIGHT}; +use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient}; +#[cfg(splicing)] +use crate::sign::P2WPKH_WITNESS_WEIGHT; use crate::events::{ClosureReason, Event}; use crate::events::bump_transaction::BASE_INPUT_WEIGHT; use crate::routing::gossip::NodeId; @@ -8128,10 +8130,12 @@ impl FundedChannel where } } - /// Initiate splicing + /// Initiate splicing. + /// - witness_weight: The witness weight for contributed inputs. #[cfg(splicing)] pub fn splice_channel(&mut self, our_funding_contribution_satoshis: i64, - our_funding_inputs: Vec<(TxIn, Transaction)>, funding_feerate_per_kw: u32, locktime: u32, + our_funding_inputs: Vec<(TxIn, Transaction)>, witness_weight: Weight, + funding_feerate_per_kw: u32, locktime: u32, ) -> Result { // Check if a splice has been initiated already. // Note: only a single outstanding splice is supported (per spec) @@ -8174,10 +8178,10 @@ impl FundedChannel where // The +1 is to include the input of the old funding let funding_input_count = our_funding_inputs.len() + 1; - // Add weight for inputs (estimated as P2WPKH) *and* spending old funding + // Input witness weight, extended with weight for spending old funding let total_witness_weight = Weight::from_wu( - our_funding_inputs.len() as u64 * P2WPKH_WITNESS_WEIGHT + - 2 * P2WPKH_WITNESS_WEIGHT + witness_weight.to_wu() + .saturating_add(2 * P2WPKH_WITNESS_WEIGHT) ); let estimated_fee = estimate_funding_transaction_fee(true, funding_input_count, total_witness_weight, funding_feerate_per_kw); let available_input = sum_input.saturating_sub(estimated_fee); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 9c2720112e4..5e3b3408020 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4213,10 +4213,12 @@ where /// Note: Currently only splice-in is supported (increase in channel capacity), splice-out is not. /// - our_funding_contribution_satoshis: the amount contributed by us to the channel. This will increase our channel balance. /// - our_funding_inputs: the funding inputs provided by us. If our contribution is positive, our funding inputs must cover at least that amount. + /// - witness_weight: The witness weight for contributed inputs. #[cfg(splicing)] pub fn splice_channel( &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64, - our_funding_inputs: Vec<(TxIn, Transaction)>, funding_feerate_per_kw: u32, locktime: u32, + our_funding_inputs: Vec<(TxIn, Transaction)>, witness_weight: Weight, + funding_feerate_per_kw: u32, locktime: u32, ) -> Result<(), APIError> { let per_peer_state = self.per_peer_state.read().unwrap(); @@ -4230,7 +4232,7 @@ where match peer_state.channel_by_id.entry(*channel_id) { hash_map::Entry::Occupied(mut chan_phase_entry) => { if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() { - let msg = chan.splice_channel(our_funding_contribution_satoshis, our_funding_inputs, funding_feerate_per_kw, locktime) + let msg = chan.splice_channel(our_funding_contribution_satoshis, our_funding_inputs, witness_weight, funding_feerate_per_kw, locktime) .map_err(|err| APIError::APIMisuseError { err: format!( "Cannot initiate Splicing, {}, channel ID {}", err, channel_id diff --git a/lightning/src/ln/dual_funding_tests.rs b/lightning/src/ln/dual_funding_tests.rs index 8cd47ad1765..ee5b5ea080f 100644 --- a/lightning/src/ln/dual_funding_tests.rs +++ b/lightning/src/ln/dual_funding_tests.rs @@ -51,7 +51,7 @@ fn do_test_v2_channel_establishment( let logger_a = test_utils::TestLogger::with_id("node a".to_owned()); // Create a funding input for the new channel along with its previous transaction. - let initiator_funding_inputs: Vec<_> = create_dual_funding_utxos_with_prev_txs( + let (initiator_funding_inputs, total_weight) = create_dual_funding_utxos_with_prev_txs( &nodes[0], &[session.initiator_input_value_satoshis], ) @@ -66,7 +66,7 @@ fn do_test_v2_channel_establishment( let funding_satoshis = calculate_our_funding_satoshis( true, &initiator_funding_inputs[..], - Weight::from_wu(P2WPKH_WITNESS_WEIGHT), + total_weight, funding_feerate, MIN_CHAN_DUST_LIMIT_SATOSHIS, ) diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index a3b38709215..1315d86f62b 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -38,7 +38,7 @@ use crate::util::test_utils; use crate::util::test_utils::{TestChainMonitor, TestScorer, TestKeysInterface}; use crate::util::ser::{ReadableArgs, Writeable}; -use bitcoin::WPubkeyHash; +use bitcoin::{Weight, WPubkeyHash}; use bitcoin::amount::Amount; use bitcoin::block::{Block, Header, Version as BlockVersion}; use bitcoin::locktime::absolute::{LockTime, LOCK_TIME_THRESHOLD}; @@ -60,6 +60,7 @@ use core::mem; use core::ops::Deref; use crate::io; use crate::prelude::*; +use crate::sign::P2WPKH_WITNESS_WEIGHT; use crate::sync::{Arc, Mutex, LockTestExt, RwLock}; pub const CHAN_CONFIRM_DEPTH: u32 = 10; @@ -1243,9 +1244,11 @@ fn internal_create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, } } +/// Create test inputs for a funding transaction. +/// Return the inputs (with prev tx), and the total witness weight for these inputs pub fn create_dual_funding_utxos_with_prev_txs( node: &Node<'_, '_, '_>, utxo_values_in_satoshis: &[u64], -) -> Vec<(TxIn, Transaction)> { +) -> (Vec<(TxIn, Transaction)>, Weight) { // Ensure we have unique transactions per node by using the locktime. let tx = Transaction { version: TxVersion::TWO, @@ -1258,9 +1261,9 @@ pub fn create_dual_funding_utxos_with_prev_txs( }).collect() }; - let mut result = vec![]; + let mut inputs = vec![]; for i in 0..utxo_values_in_satoshis.len() { - result.push( + inputs.push( (TxIn { previous_output: OutPoint { txid: tx.compute_txid(), @@ -1271,7 +1274,9 @@ pub fn create_dual_funding_utxos_with_prev_txs( witness: Witness::new(), }, tx.clone())); } - result + let total_weight = Weight::from_wu(utxo_values_in_satoshis.len() as u64 * P2WPKH_WITNESS_WEIGHT); + + (inputs, total_weight) } pub fn sign_funding_transaction<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, expected_temporary_channel_id: ChannelId) -> Transaction { diff --git a/lightning/src/ln/functional_tests_splice.rs b/lightning/src/ln/functional_tests_splice.rs index 6c9fa111454..07fb125aade 100644 --- a/lightning/src/ln/functional_tests_splice.rs +++ b/lightning/src/ln/functional_tests_splice.rs @@ -231,7 +231,7 @@ fn test_v1_splice_in() { // Create additional inputs let extra_splice_funding_input_sats = 35_000; - let funding_inputs = create_dual_funding_utxos_with_prev_txs( + let (funding_inputs, total_weight) = create_dual_funding_utxos_with_prev_txs( &initiator_node, &[extra_splice_funding_input_sats], ); @@ -243,6 +243,7 @@ fn test_v1_splice_in() { &acceptor_node.node.get_our_node_id(), splice_in_sats as i64, funding_inputs, + total_weight, funding_feerate_per_kw, locktime, )