@@ -4469,48 +4469,33 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
44694469 cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
44704470}
44714471
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());
44934485
44944486 // If we are the initiator, we must pay for weight of all common fields in the funding transaction.
44954487 if is_initiator {
4496- our_contributed_weight = our_contributed_weight
4488+ weight = weight
44974489 .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
45004491 // NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
45014492 // to calculate the contributed weight, so we use an all-zero hash.
45024493 .saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
45034494 &WScriptHash::from_raw_hash(Hash::all_zeros())
45044495 )).to_wu())
45054496 }
45064497
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)
45144499}
45154500
45164501/// Context for dual-funded channels.
@@ -9250,27 +9235,23 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
92509235
92519236 /// Creates a new dual-funded channel from a remote side's request for one.
92529237 /// Assumes chain_hash has already been checked and corresponds with what we expect!
9238+ /// TODO(dual_funding): Allow contributions, pass intended amount and inputs
92539239 #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
92549240 pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
92559241 fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
92569242 holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
92579243 their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
9258- funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, total_witness_weight: Weight,
92599244 user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
92609245 ) -> Result<Self, ChannelError>
92619246 where ES::Target: EntropySource,
92629247 F::Target: FeeEstimator,
92639248 L::Target: Logger,
92649249 {
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);
92749255 let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
92759256 channel_value_satoshis, msg.common_fields.dust_limit_satoshis);
92769257 let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
@@ -9304,7 +9285,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
93049285 logger,
93059286 false,
93069287
9307- funding_satoshis ,
9288+ our_funding_satoshis ,
93089289
93099290 counterparty_pubkeys,
93109291 channel_type,
@@ -9319,10 +9300,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
93199300 context.channel_id = channel_id;
93209301
93219302 let dual_funding_context = DualFundingChannelContext {
9322- our_funding_satoshis: funding_satoshis ,
9303+ our_funding_satoshis: our_funding_satoshis ,
93239304 funding_tx_locktime: LockTime::from_consensus(msg.locktime),
93249305 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(),
93269307 };
93279308
93289309 let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
@@ -9334,7 +9315,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
93349315 feerate_sat_per_kw: dual_funding_context.funding_feerate_sat_per_1000_weight,
93359316 funding_tx_locktime: dual_funding_context.funding_tx_locktime,
93369317 is_initiator: false,
9337- inputs_to_contribute: funding_inputs ,
9318+ inputs_to_contribute: our_funding_inputs ,
93389319 outputs_to_contribute: Vec::new(),
93399320 expected_remote_shared_funding_output: Some((context.get_funding_redeemscript().to_p2wsh(), context.channel_value_satoshis)),
93409321 }
@@ -10467,7 +10448,7 @@ mod tests {
1046710448 use bitcoin::amount::Amount;
1046810449 use bitcoin::constants::ChainHash;
1046910450 use bitcoin::script::{ScriptBuf, Builder};
10470- use bitcoin::transaction::{Transaction, TxIn, TxOut, Version};
10451+ use bitcoin::transaction::{Transaction, TxOut, Version};
1047110452 use bitcoin::opcodes;
1047210453 use bitcoin::network::Network;
1047310454 use crate::ln::onion_utils::INVALID_ONION_BLINDING;
@@ -10489,7 +10470,7 @@ mod tests {
1048910470 use crate::routing::router::{Path, RouteHop};
1049010471 use crate::util::config::UserConfig;
1049110472 use crate::util::errors::APIError;
10492- use crate::util::ser::{ReadableArgs, TransactionU16LenLimited, Writeable};
10473+ use crate::util::ser::{ReadableArgs, Writeable};
1049310474 use crate::util::test_utils;
1049410475 use crate::util::test_utils::{OnGetShutdownScriptpubkey, TestKeysInterface};
1049510476 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
@@ -12240,82 +12221,39 @@ mod tests {
1224012221 assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
1224112222 }
1224212223
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-
1225612224 #[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 ;
1225912227 use bitcoin::Weight;
1226012228
12261- // normal use case, output is less than the available inputs
12229+ // 2 inputs with weight 300, initiator, 2000 sat/kw feerate
1226212230 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
1227412233 );
1227512234
12235+ // higher feerate
1227612236 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
1228512239 );
1228612240
12241+ // only 1 input
1228712242 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
1229612245 );
1229712246
12247+ // 0 input weight
1229812248 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
1230712251 );
1230812252
12309- // below dust limit
12253+ // not initiator
1231012254 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
1231912257 );
1232012258 }
1232112259}
0 commit comments