@@ -4348,14 +4348,43 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
4348
4348
cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
4349
4349
}
4350
4350
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
+
4351
4379
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
4352
4380
pub(super) fn calculate_our_funding_satoshis(
4353
4381
is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
4354
4382
total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
4355
4383
holder_dust_limit_satoshis: u64,
4356
4384
) -> 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) ;
4358
4386
4387
+ let mut total_input_satoshis = 0u64;
4359
4388
for (idx, input) in funding_inputs.iter().enumerate() {
4360
4389
if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
4361
4390
total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
@@ -4365,26 +4394,8 @@ pub(super) fn calculate_our_funding_satoshis(
4365
4394
input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
4366
4395
}
4367
4396
}
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());
4372
4397
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);
4388
4399
if funding_satoshis < holder_dust_limit_satoshis {
4389
4400
Ok(0)
4390
4401
} else {
@@ -12214,6 +12225,39 @@ mod tests {
12214
12225
assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
12215
12226
}
12216
12227
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
+
12217
12261
fn prepare_input(value: u64) -> (TxIn, TransactionU16LenLimited) {
12218
12262
let input_1_prev_out = TxOut { value: Amount::from_sat(value), script_pubkey: ScriptBuf::default() };
12219
12263
let input_1_prev_tx = Transaction {
@@ -12248,24 +12292,6 @@ mod tests {
12248
12292
298332
12249
12293
);
12250
12294
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
-
12269
12295
// below dust limit
12270
12296
assert_eq!(
12271
12297
calculate_our_funding_satoshis(true, &inputs_1, witness_weight, 2000, 20_000)
0 commit comments