@@ -4348,14 +4348,41 @@ 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+ #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
4352+ fn estimate_funding_transaction_fee(
4353+ is_initiator: bool, funding_input_count: usize,
4354+ total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
4355+ ) -> u64 {
4356+ // Inputs
4357+ let mut weight = (funding_input_count as u64) * BASE_INPUT_WEIGHT;
4358+
4359+ // Witnesses
4360+ weight = weight.saturating_add(total_witness_weight.to_wu());
4361+
4362+ // If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4363+ if is_initiator {
4364+ weight = weight
4365+ .saturating_add(TX_COMMON_FIELDS_WEIGHT)
4366+ // The weight of the funding output, a P2WSH output
4367+ // NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4368+ // to calculate the contributed weight, so we use an all-zero hash.
4369+ .saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4370+ &WScriptHash::from_raw_hash(Hash::all_zeros())
4371+ )).to_wu())
4372+ }
4373+
4374+ fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
4375+ }
4376+
43514377#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
43524378pub(super) fn calculate_our_funding_satoshis(
43534379 is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
43544380 total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
43554381 holder_dust_limit_satoshis: u64,
43564382) -> Result<u64, APIError> {
4357- let mut total_input_satoshis = 0u64 ;
4383+ let estimated_fee = estimate_funding_transaction_fee(is_initiator, funding_inputs.len(), total_witness_weight, funding_feerate_sat_per_1000_weight) ;
43584384
4385+ let mut total_input_satoshis = 0u64;
43594386 for (idx, input) in funding_inputs.iter().enumerate() {
43604387 if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
43614388 total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
@@ -4365,26 +4392,8 @@ pub(super) fn calculate_our_funding_satoshis(
43654392 input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
43664393 }
43674394 }
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());
43724395
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));
4396+ let funding_satoshis = total_input_satoshis.saturating_sub(estimated_fee);
43884397 if funding_satoshis < holder_dust_limit_satoshis {
43894398 Ok(0)
43904399 } else {
@@ -12214,6 +12223,39 @@ mod tests {
1221412223 assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
1221512224 }
1221612225
12226+ #[test]
12227+ fn test_estimate_funding_transaction_fee() {
12228+ use crate::ln::channel::estimate_funding_transaction_fee;
12229+ use bitcoin::Weight;
12230+
12231+ let witness_weight = Weight::from_wu(300);
12232+
12233+ assert_eq!(
12234+ estimate_funding_transaction_fee(true, 2, witness_weight, 2000),
12235+ 1668
12236+ );
12237+
12238+ assert_eq!(
12239+ estimate_funding_transaction_fee(true, 2, witness_weight, 3000),
12240+ 2502
12241+ );
12242+
12243+ assert_eq!(
12244+ estimate_funding_transaction_fee(true, 1, witness_weight, 2000),
12245+ 1348
12246+ );
12247+
12248+ assert_eq!(
12249+ estimate_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
12250+ 748
12251+ );
12252+
12253+ assert_eq!(
12254+ estimate_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
12255+ 320
12256+ );
12257+ }
12258+
1221712259 fn prepare_input(value: u64) -> (TxIn, TransactionU16LenLimited) {
1221812260 let input_1_prev_out = TxOut { value: Amount::from_sat(value), script_pubkey: ScriptBuf::default() };
1221912261 let input_1_prev_tx = Transaction {
@@ -12248,24 +12290,6 @@ mod tests {
1224812290 298332
1224912291 );
1225012292
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-
1226912293 // below dust limit
1227012294 assert_eq!(
1227112295 calculate_our_funding_satoshis(true, &inputs_1, witness_weight, 2000, 20_000)
0 commit comments