@@ -4348,14 +4348,43 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
43484348 cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
43494349}
43504350
4351+ /// Estimate our part of the fee of the new funding transaction.
4352+ /// total_witness_weight includes the witness weight for extra outputs (excluding the funding output).
4353+ #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
4354+ fn estimate_funding_transaction_fee(
4355+ is_initiator: bool, funding_input_count: usize,
4356+ total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
4357+ ) -> u64 {
4358+ // Inputs
4359+ let mut weight = (funding_input_count as u64) * BASE_INPUT_WEIGHT;
4360+
4361+ // Witnesses
4362+ weight = weight.saturating_add(total_witness_weight.to_wu());
4363+
4364+ // If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4365+ if is_initiator {
4366+ weight = weight
4367+ .saturating_add(TX_COMMON_FIELDS_WEIGHT)
4368+ // The weight of the funding output, a P2WSH output
4369+ // NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4370+ // to calculate the contributed weight, so we use an all-zero hash.
4371+ .saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4372+ &WScriptHash::from_raw_hash(Hash::all_zeros())
4373+ )).to_wu())
4374+ }
4375+
4376+ fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
4377+ }
4378+
43514379#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
43524380pub(super) fn calculate_our_funding_satoshis(
43534381 is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
43544382 total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
43554383 holder_dust_limit_satoshis: u64,
43564384) -> Result<u64, APIError> {
4357- let mut total_input_satoshis = 0u64 ;
4385+ let estimated_fee = estimate_funding_transaction_fee(is_initiator, funding_inputs.len(), total_witness_weight, funding_feerate_sat_per_1000_weight) ;
43584386
4387+ let mut total_input_satoshis = 0u64;
43594388 for (idx, input) in funding_inputs.iter().enumerate() {
43604389 if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
43614390 total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
@@ -4365,26 +4394,8 @@ pub(super) fn calculate_our_funding_satoshis(
43654394 input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
43664395 }
43674396 }
4368- // inputs:
4369- let mut our_contributed_weight = (funding_inputs.len() as u64) * BASE_INPUT_WEIGHT;
4370- // witnesses:
4371- our_contributed_weight = our_contributed_weight.saturating_add(total_witness_weight.to_wu());
43724397
4373- // If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4374- if is_initiator {
4375- our_contributed_weight = our_contributed_weight
4376- .saturating_add(TX_COMMON_FIELDS_WEIGHT)
4377- // The weight of a P2WSH output to be added later.
4378- //
4379- // NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4380- // to calculate the contributed weight, so we use an all-zero hash.
4381- .saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4382- &WScriptHash::from_raw_hash(Hash::all_zeros())
4383- )).to_wu())
4384- }
4385-
4386- let funding_satoshis = total_input_satoshis
4387- .saturating_sub(fee_for_weight(funding_feerate_sat_per_1000_weight, our_contributed_weight));
4398+ let funding_satoshis = total_input_satoshis.saturating_sub(estimated_fee);
43884399 if funding_satoshis < holder_dust_limit_satoshis {
43894400 Ok(0)
43904401 } else {
@@ -12214,6 +12225,39 @@ mod tests {
1221412225 assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
1221512226 }
1221612227
12228+ #[test]
12229+ fn test_estimate_funding_transaction_fee() {
12230+ use crate::ln::channel::estimate_funding_transaction_fee;
12231+ use bitcoin::Weight;
12232+
12233+ let witness_weight = Weight::from_wu(300);
12234+
12235+ assert_eq!(
12236+ estimate_funding_transaction_fee(true, 2, witness_weight, 2000),
12237+ 1668
12238+ );
12239+
12240+ assert_eq!(
12241+ estimate_funding_transaction_fee(true, 2, witness_weight, 3000),
12242+ 2502
12243+ );
12244+
12245+ assert_eq!(
12246+ estimate_funding_transaction_fee(true, 1, witness_weight, 2000),
12247+ 1348
12248+ );
12249+
12250+ assert_eq!(
12251+ estimate_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
12252+ 748
12253+ );
12254+
12255+ assert_eq!(
12256+ estimate_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
12257+ 320
12258+ );
12259+ }
12260+
1221712261 fn prepare_input(value: u64) -> (TxIn, TransactionU16LenLimited) {
1221812262 let input_1_prev_out = TxOut { value: Amount::from_sat(value), script_pubkey: ScriptBuf::default() };
1221912263 let input_1_prev_tx = Transaction {
@@ -12248,24 +12292,6 @@ mod tests {
1224812292 298332
1224912293 );
1225012294
12251- assert_eq!(
12252- calculate_our_funding_satoshis(true, &inputs_1, witness_weight, 2000, 1000)
12253- .unwrap(),
12254- 18652
12255- );
12256-
12257- assert_eq!(
12258- calculate_our_funding_satoshis(true, &inputs_1, Weight::from_wu(0), 2000, 1000)
12259- .unwrap(),
12260- 19252
12261- );
12262-
12263- assert_eq!(
12264- calculate_our_funding_satoshis(false, &inputs_1, Weight::from_wu(0), 2000, 1000)
12265- .unwrap(),
12266- 19680
12267- );
12268-
1226912295 // below dust limit
1227012296 assert_eq!(
1227112297 calculate_our_funding_satoshis(true, &inputs_1, witness_weight, 2000, 20_000)
0 commit comments