Skip to content

Commit 95f1e9c

Browse files
committed
Break up calculate_our_funding_satoshis() into fee estimation and output computation
1 parent 1b8ccbe commit 95f1e9c

File tree

1 file changed

+68
-53
lines changed

1 file changed

+68
-53
lines changed

lightning/src/ln/channel.rs

+68-53
Original file line numberDiff line numberDiff line change
@@ -4469,14 +4469,44 @@ 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+
/// 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): Remove once V2 channels is enabled.
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());
4485+
4486+
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4487+
if is_initiator {
4488+
weight = weight
4489+
.saturating_add(TX_COMMON_FIELDS_WEIGHT)
4490+
// The weight of the funding output, a P2WSH output
4491+
// NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4492+
// to calculate the contributed weight, so we use an all-zero hash.
4493+
.saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4494+
&WScriptHash::from_raw_hash(Hash::all_zeros())
4495+
)).to_wu())
4496+
}
4497+
4498+
fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
4499+
}
4500+
44724501
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
44734502
pub(super) fn calculate_our_funding_satoshis(
44744503
is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
44754504
total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
44764505
holder_dust_limit_satoshis: u64,
44774506
) -> Result<u64, APIError> {
4478-
let mut total_input_satoshis = 0u64;
4507+
let estimated_fee = estimate_v2_funding_transaction_fee(is_initiator, funding_inputs.len(), total_witness_weight, funding_feerate_sat_per_1000_weight);
44794508

4509+
let mut total_input_satoshis = 0u64;
44804510
for (idx, input) in funding_inputs.iter().enumerate() {
44814511
if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
44824512
total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
@@ -4486,26 +4516,8 @@ pub(super) fn calculate_our_funding_satoshis(
44864516
input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
44874517
}
44884518
}
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());
44934519

4494-
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
4495-
if is_initiator {
4496-
our_contributed_weight = our_contributed_weight
4497-
.saturating_add(TX_COMMON_FIELDS_WEIGHT)
4498-
// The weight of a P2WSH output to be added later.
4499-
//
4500-
// NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
4501-
// to calculate the contributed weight, so we use an all-zero hash.
4502-
.saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
4503-
&WScriptHash::from_raw_hash(Hash::all_zeros())
4504-
)).to_wu())
4505-
}
4506-
4507-
let funding_satoshis = total_input_satoshis
4508-
.saturating_sub(fee_for_weight(funding_feerate_sat_per_1000_weight, our_contributed_weight));
4520+
let funding_satoshis = total_input_satoshis.saturating_sub(estimated_fee);
45094521
if funding_satoshis < holder_dust_limit_satoshis {
45104522
Ok(0)
45114523
} else {
@@ -12240,6 +12252,42 @@ mod tests {
1224012252
assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
1224112253
}
1224212254

12255+
#[test]
12256+
fn test_estimate_v2_unding_transaction_fee() {
12257+
use crate::ln::channel::estimate_v2_funding_transaction_fee;
12258+
use bitcoin::Weight;
12259+
12260+
// 2 inputs with weight 300, initiator, 2000 sat/kw feerate
12261+
assert_eq!(
12262+
estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 2000),
12263+
1668
12264+
);
12265+
12266+
// higher feerate
12267+
assert_eq!(
12268+
estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 3000),
12269+
2502
12270+
);
12271+
12272+
// only 1 input
12273+
assert_eq!(
12274+
estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(300), 2000),
12275+
1348
12276+
);
12277+
12278+
// 0 input weight
12279+
assert_eq!(
12280+
estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
12281+
748
12282+
);
12283+
12284+
// not initiator
12285+
assert_eq!(
12286+
estimate_v2_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
12287+
320
12288+
);
12289+
}
12290+
1224312291
fn funding_input_sats(input_value_sats: u64) -> (TxIn, TransactionU16LenLimited) {
1224412292
let input_1_prev_out = TxOut { value: Amount::from_sat(input_value_sats), script_pubkey: ScriptBuf::default() };
1224512293
let input_1_prev_tx = Transaction {
@@ -12273,39 +12321,6 @@ mod tests {
1227312321
298332
1227412322
);
1227512323

12276-
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
12285-
);
12286-
12287-
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
12296-
);
12297-
12298-
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
12307-
);
12308-
1230912324
// below dust limit
1231012325
assert_eq!(
1231112326
calculate_our_funding_satoshis(

0 commit comments

Comments
 (0)