@@ -4348,14 +4348,44 @@ 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+ /// input_count: Number of contributed inputs.
4353+ /// witness_weight: The witness weight for contributed inputs.
4354+ #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
4355+ fn estimate_funding_transaction_fee(
4356+ is_initiator: bool, input_count: usize, witness_weight: Weight,
4357+ funding_feerate_sat_per_1000_weight: u32,
4358+ ) -> u64 {
4359+ // Inputs
4360+ let mut weight = (input_count as u64) * BASE_INPUT_WEIGHT;
4361+
4362+ // Witnesses
4363+ weight = weight.saturating_add(witness_weight.to_wu());
4364+
4365+ // If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4366+ if is_initiator {
4367+ weight = weight
4368+ .saturating_add(TX_COMMON_FIELDS_WEIGHT)
4369+ // The weight of the funding output, a P2WSH output
4370+ // NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4371+ // to calculate the contributed weight, so we use an all-zero hash.
4372+ .saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4373+ &WScriptHash::from_raw_hash(Hash::all_zeros())
4374+ )).to_wu())
4375+ }
4376+
4377+ fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
4378+ }
4379+
43514380#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
43524381pub(super) fn calculate_our_funding_satoshis(
43534382 is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
43544383 total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
43554384 holder_dust_limit_satoshis: u64,
43564385) -> Result<u64, APIError> {
4357- let mut total_input_satoshis = 0u64 ;
4386+ let estimated_fee = estimate_funding_transaction_fee(is_initiator, funding_inputs.len(), total_witness_weight, funding_feerate_sat_per_1000_weight) ;
43584387
4388+ let mut total_input_satoshis = 0u64;
43594389 for (idx, input) in funding_inputs.iter().enumerate() {
43604390 if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
43614391 total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
@@ -4365,26 +4395,8 @@ pub(super) fn calculate_our_funding_satoshis(
43654395 input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
43664396 }
43674397 }
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());
43724398
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));
4399+ let funding_satoshis = total_input_satoshis.saturating_sub(estimated_fee);
43884400 if funding_satoshis < holder_dust_limit_satoshis {
43894401 Ok(0)
43904402 } else {
@@ -12214,6 +12226,39 @@ mod tests {
1221412226 assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
1221512227 }
1221612228
12229+ #[test]
12230+ fn test_estimate_funding_transaction_fee() {
12231+ use crate::ln::channel::estimate_funding_transaction_fee;
12232+ use bitcoin::Weight;
12233+
12234+ let witness_weight = Weight::from_wu(300);
12235+
12236+ assert_eq!(
12237+ estimate_funding_transaction_fee(true, 2, witness_weight, 2000),
12238+ 1668
12239+ );
12240+
12241+ assert_eq!(
12242+ estimate_funding_transaction_fee(true, 2, witness_weight, 3000),
12243+ 2502
12244+ );
12245+
12246+ assert_eq!(
12247+ estimate_funding_transaction_fee(true, 1, witness_weight, 2000),
12248+ 1348
12249+ );
12250+
12251+ assert_eq!(
12252+ estimate_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
12253+ 748
12254+ );
12255+
12256+ assert_eq!(
12257+ estimate_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
12258+ 320
12259+ );
12260+ }
12261+
1221712262 fn prepare_input(value: u64) -> (TxIn, TransactionU16LenLimited) {
1221812263 let input_1_prev_out = TxOut { value: Amount::from_sat(value), script_pubkey: ScriptBuf::default() };
1221912264 let input_1_prev_tx = Transaction {
@@ -12248,24 +12293,6 @@ mod tests {
1224812293 298332
1224912294 );
1225012295
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-
1226912296 // below dust limit
1227012297 assert_eq!(
1227112298 calculate_our_funding_satoshis(true, &inputs_1, witness_weight, 2000, 20_000)
0 commit comments