@@ -4469,48 +4469,33 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
4469
4469
cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
4470
4470
}
4471
4471
4472
- #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
4473
- pub(super) fn calculate_our_funding_satoshis(
4474
- is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
4475
- total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
4476
- holder_dust_limit_satoshis: u64,
4477
- ) -> Result<u64, APIError> {
4478
- let mut total_input_satoshis = 0u64;
4479
-
4480
- for (idx, input) in funding_inputs.iter().enumerate() {
4481
- if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
4482
- total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
4483
- } else {
4484
- return Err(APIError::APIMisuseError {
4485
- err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
4486
- input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
4487
- }
4488
- }
4489
- // inputs:
4490
- let mut our_contributed_weight = (funding_inputs.len() as u64) * BASE_INPUT_WEIGHT;
4491
- // witnesses:
4492
- our_contributed_weight = our_contributed_weight.saturating_add(total_witness_weight.to_wu());
4472
+ /// Estimate our part of the fee of the new funding transaction.
4473
+ /// input_count: Number of contributed inputs.
4474
+ /// witness_weight: The witness weight for contributed inputs.
4475
+ #[allow(dead_code)] // TODO(dual_funding): TODO(splicing): Remove allow once used.
4476
+ fn estimate_v2_funding_transaction_fee(
4477
+ is_initiator: bool, input_count: usize, witness_weight: Weight,
4478
+ funding_feerate_sat_per_1000_weight: u32,
4479
+ ) -> u64 {
4480
+ // Inputs
4481
+ let mut weight = (input_count as u64) * BASE_INPUT_WEIGHT;
4482
+
4483
+ // Witnesses
4484
+ weight = weight.saturating_add(witness_weight.to_wu());
4493
4485
4494
4486
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4495
4487
if is_initiator {
4496
- our_contributed_weight = our_contributed_weight
4488
+ weight = weight
4497
4489
.saturating_add(TX_COMMON_FIELDS_WEIGHT)
4498
- // The weight of a P2WSH output to be added later.
4499
- //
4490
+ // The weight of the funding output, a P2WSH output
4500
4491
// NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4501
4492
// to calculate the contributed weight, so we use an all-zero hash.
4502
4493
.saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4503
4494
&WScriptHash::from_raw_hash(Hash::all_zeros())
4504
4495
)).to_wu())
4505
4496
}
4506
4497
4507
- let funding_satoshis = total_input_satoshis
4508
- .saturating_sub(fee_for_weight(funding_feerate_sat_per_1000_weight, our_contributed_weight));
4509
- if funding_satoshis < holder_dust_limit_satoshis {
4510
- Ok(0)
4511
- } else {
4512
- Ok(funding_satoshis)
4513
- }
4498
+ fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
4514
4499
}
4515
4500
4516
4501
/// Context for dual-funded channels.
@@ -9250,27 +9235,23 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9250
9235
9251
9236
/// Creates a new dual-funded channel from a remote side's request for one.
9252
9237
/// Assumes chain_hash has already been checked and corresponds with what we expect!
9238
+ /// TODO(dual_funding): Allow contributions, pass intended amount and inputs
9253
9239
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
9254
9240
pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
9255
9241
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
9256
9242
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
9257
9243
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
9258
- funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, total_witness_weight: Weight,
9259
9244
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
9260
9245
) -> Result<Self, ChannelError>
9261
9246
where ES::Target: EntropySource,
9262
9247
F::Target: FeeEstimator,
9263
9248
L::Target: Logger,
9264
9249
{
9265
- let funding_satoshis = calculate_our_funding_satoshis(
9266
- false, &funding_inputs, total_witness_weight, msg.funding_feerate_sat_per_1000_weight,
9267
- msg.common_fields.dust_limit_satoshis
9268
- ).map_err(|_| ChannelError::Close(
9269
- (
9270
- "Failed to accept channel".to_string(),
9271
- ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
9272
- )))?;
9273
- let channel_value_satoshis = funding_satoshis.saturating_add(msg.common_fields.funding_satoshis);
9250
+ // TODO(dual_funding): Take these as input once supported
9251
+ let our_funding_satoshis = 0u64;
9252
+ let our_funding_inputs = Vec::new();
9253
+
9254
+ let channel_value_satoshis = our_funding_satoshis.saturating_add(msg.common_fields.funding_satoshis);
9274
9255
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
9275
9256
channel_value_satoshis, msg.common_fields.dust_limit_satoshis);
9276
9257
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
@@ -9304,7 +9285,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9304
9285
logger,
9305
9286
false,
9306
9287
9307
- funding_satoshis ,
9288
+ our_funding_satoshis ,
9308
9289
9309
9290
counterparty_pubkeys,
9310
9291
channel_type,
@@ -9319,10 +9300,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9319
9300
context.channel_id = channel_id;
9320
9301
9321
9302
let dual_funding_context = DualFundingChannelContext {
9322
- our_funding_satoshis: funding_satoshis ,
9303
+ our_funding_satoshis: our_funding_satoshis ,
9323
9304
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
9324
9305
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
9325
- our_funding_inputs: funding_inputs .clone(),
9306
+ our_funding_inputs: our_funding_inputs .clone(),
9326
9307
};
9327
9308
9328
9309
let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
@@ -9334,7 +9315,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9334
9315
feerate_sat_per_kw: dual_funding_context.funding_feerate_sat_per_1000_weight,
9335
9316
funding_tx_locktime: dual_funding_context.funding_tx_locktime,
9336
9317
is_initiator: false,
9337
- inputs_to_contribute: funding_inputs ,
9318
+ inputs_to_contribute: our_funding_inputs ,
9338
9319
outputs_to_contribute: Vec::new(),
9339
9320
expected_remote_shared_funding_output: Some((context.get_funding_redeemscript().to_p2wsh(), context.channel_value_satoshis)),
9340
9321
}
@@ -10467,7 +10448,7 @@ mod tests {
10467
10448
use bitcoin::amount::Amount;
10468
10449
use bitcoin::constants::ChainHash;
10469
10450
use bitcoin::script::{ScriptBuf, Builder};
10470
- use bitcoin::transaction::{Transaction, TxIn, TxOut, Version};
10451
+ use bitcoin::transaction::{Transaction, TxOut, Version};
10471
10452
use bitcoin::opcodes;
10472
10453
use bitcoin::network::Network;
10473
10454
use crate::ln::onion_utils::INVALID_ONION_BLINDING;
@@ -10489,7 +10470,7 @@ mod tests {
10489
10470
use crate::routing::router::{Path, RouteHop};
10490
10471
use crate::util::config::UserConfig;
10491
10472
use crate::util::errors::APIError;
10492
- use crate::util::ser::{ReadableArgs, TransactionU16LenLimited, Writeable};
10473
+ use crate::util::ser::{ReadableArgs, Writeable};
10493
10474
use crate::util::test_utils;
10494
10475
use crate::util::test_utils::{OnGetShutdownScriptpubkey, TestKeysInterface};
10495
10476
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
@@ -12240,82 +12221,39 @@ mod tests {
12240
12221
assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
12241
12222
}
12242
12223
12243
- fn funding_input_sats(input_value_sats: u64) -> (TxIn, TransactionU16LenLimited) {
12244
- let input_1_prev_out = TxOut { value: Amount::from_sat(input_value_sats), script_pubkey: ScriptBuf::default() };
12245
- let input_1_prev_tx = Transaction {
12246
- input: vec![], output: vec![input_1_prev_out],
12247
- version: Version::TWO, lock_time: bitcoin::absolute::LockTime::ZERO,
12248
- };
12249
- let input_1_txin = TxIn {
12250
- previous_output: bitcoin::OutPoint { txid: input_1_prev_tx.compute_txid(), vout: 0 },
12251
- ..Default::default()
12252
- };
12253
- (input_1_txin, TransactionU16LenLimited::new(input_1_prev_tx).unwrap())
12254
- }
12255
-
12256
12224
#[test]
12257
- fn test_calculate_our_funding_satoshis () {
12258
- use crate::ln::channel::calculate_our_funding_satoshis ;
12225
+ fn test_estimate_v2_funding_transaction_fee () {
12226
+ use crate::ln::channel::estimate_v2_funding_transaction_fee ;
12259
12227
use bitcoin::Weight;
12260
12228
12261
- // normal use case, output is less than the available inputs
12229
+ // 2 inputs with weight 300, initiator, 2000 sat/kw feerate
12262
12230
assert_eq!(
12263
- calculate_our_funding_satoshis(
12264
- true,
12265
- &[
12266
- funding_input_sats(200_000),
12267
- funding_input_sats(100_000),
12268
- ],
12269
- Weight::from_wu(300),
12270
- 2000,
12271
- 1000,
12272
- ).unwrap(),
12273
- 298332
12231
+ estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 2000),
12232
+ 1668
12274
12233
);
12275
12234
12235
+ // higher feerate
12276
12236
assert_eq!(
12277
- calculate_our_funding_satoshis(
12278
- true,
12279
- &[funding_input_sats(20_000)],
12280
- Weight::from_wu(300),
12281
- 2000,
12282
- 1000,
12283
- ).unwrap(),
12284
- 18652
12237
+ estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 3000),
12238
+ 2502
12285
12239
);
12286
12240
12241
+ // only 1 input
12287
12242
assert_eq!(
12288
- calculate_our_funding_satoshis(
12289
- true,
12290
- &[funding_input_sats(20_000)],
12291
- Weight::from_wu(0),
12292
- 2000,
12293
- 1000,
12294
- ).unwrap(),
12295
- 19252
12243
+ estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(300), 2000),
12244
+ 1348
12296
12245
);
12297
12246
12247
+ // 0 input weight
12298
12248
assert_eq!(
12299
- calculate_our_funding_satoshis(
12300
- false,
12301
- &[funding_input_sats(20_000)],
12302
- Weight::from_wu(0),
12303
- 2000,
12304
- 1000,
12305
- ).unwrap(),
12306
- 19680
12249
+ estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
12250
+ 748
12307
12251
);
12308
12252
12309
- // below dust limit
12253
+ // not initiator
12310
12254
assert_eq!(
12311
- calculate_our_funding_satoshis(
12312
- true,
12313
- &[funding_input_sats(20_000)],
12314
- Weight::from_wu(300),
12315
- 2000,
12316
- 20_000,
12317
- ).unwrap(),
12318
- 0
12255
+ estimate_v2_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
12256
+ 320
12319
12257
);
12320
12258
}
12321
12259
}
0 commit comments