Skip to content

Commit 2f78471

Browse files
committed
Account for grind_signatures in splice funding tx
When estimating the splice funding transaction fees, adjust for grind_signatures. Since LDK supplies one of the signatures, only adjust by 1 WU even though spending the shared input requires two signatures.
1 parent 36ef03c commit 2f78471

File tree

4 files changed

+75
-43
lines changed

4 files changed

+75
-43
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ const MULTISIG_SCRIPT_SIZE: u64 = 1 + // OP_2
127127
/// Unlike in the [spec], 72 WU is used for the max signature size since 73 WU signatures are
128128
/// non-standard.
129129
///
130+
/// Note: If you have the `grind_signatures` feature enabled, this will be at least 1 byte
131+
/// shorter.
132+
///
130133
/// [spec]: https://github.com/lightning/bolts/blob/master/03-transactions.md#expected-weight-of-the-commitment-transaction
131134
pub const FUNDING_TRANSACTION_WITNESS_WEIGHT: u64 = 1 + // number_of_witness_elements
132135
1 + // nil_len

lightning/src/ln/channel.rs

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6547,6 +6547,11 @@ fn estimate_v2_funding_transaction_fee(
65476547
.saturating_add(BASE_INPUT_WEIGHT)
65486548
.saturating_add(EMPTY_SCRIPT_SIG_WEIGHT)
65496549
.saturating_add(FUNDING_TRANSACTION_WITNESS_WEIGHT);
6550+
#[cfg(feature = "grind_signatures")]
6551+
{
6552+
// Guarantees a low R signature
6553+
weight -= 1;
6554+
}
65506555
}
65516556
}
65526557

@@ -17427,7 +17432,7 @@ mod tests {
1742717432
// splice initiator
1742817433
assert_eq!(
1742917434
estimate_v2_funding_transaction_fee(&one_input, &[], true, true, 2000),
17430-
1740,
17435+
if cfg!(feature = "grind_signatures") { 1738 } else { 1740 },
1743117436
);
1743217437

1743317438
// splice acceptor
@@ -17457,40 +17462,46 @@ mod tests {
1745717462
use crate::ln::channel::check_v2_funding_inputs_sufficient;
1745817463

1745917464
// positive case, inputs well over intended contribution
17460-
assert_eq!(
17461-
check_v2_funding_inputs_sufficient(
17462-
220_000,
17463-
&[
17464-
funding_input_sats(200_000),
17465-
funding_input_sats(100_000),
17466-
],
17467-
true,
17468-
true,
17469-
2000,
17470-
).unwrap(),
17471-
2284,
17472-
);
17465+
{
17466+
let expected_fee = if cfg!(feature = "grind_signatures") { 2282 } else { 2284 };
17467+
assert_eq!(
17468+
check_v2_funding_inputs_sufficient(
17469+
220_000,
17470+
&[
17471+
funding_input_sats(200_000),
17472+
funding_input_sats(100_000),
17473+
],
17474+
true,
17475+
true,
17476+
2000,
17477+
).unwrap(),
17478+
expected_fee,
17479+
);
17480+
}
1747317481

1747417482
// negative case, inputs clearly insufficient
1747517483
{
17476-
let res = check_v2_funding_inputs_sufficient(
17477-
220_000,
17478-
&[
17479-
funding_input_sats(100_000),
17480-
],
17481-
true,
17482-
true,
17483-
2000,
17484-
);
17484+
let expected_fee = if cfg!(feature = "grind_signatures") { 1738 } else { 1740 };
1748517485
assert_eq!(
17486-
res.err().unwrap(),
17487-
"Total input amount 100000 is lower than needed for contribution 220000, considering fees of 1740. Need more inputs.",
17486+
check_v2_funding_inputs_sufficient(
17487+
220_000,
17488+
&[
17489+
funding_input_sats(100_000),
17490+
],
17491+
true,
17492+
true,
17493+
2000,
17494+
),
17495+
Err(format!(
17496+
"Total input amount 100000 is lower than needed for contribution 220000, considering fees of {}. Need more inputs.",
17497+
expected_fee,
17498+
)),
1748817499
);
1748917500
}
1749017501

1749117502
// barely covers
1749217503
{
17493-
let expected_fee: u64 = 2284;
17504+
let expected_fee = if cfg!(feature = "grind_signatures") { 2282 } else { 2284 };
1749417505
assert_eq!(
1749517506
check_v2_funding_inputs_sufficient(
1749617507
(300_000 - expected_fee - 20) as i64,
@@ -17508,25 +17519,28 @@ mod tests {
1750817519

1750917520
// higher fee rate, does not cover
1751017521
{
17511-
let res = check_v2_funding_inputs_sufficient(
17512-
298032,
17513-
&[
17514-
funding_input_sats(200_000),
17515-
funding_input_sats(100_000),
17516-
],
17517-
true,
17518-
true,
17519-
2200,
17520-
);
17522+
let expected_fee = if cfg!(feature = "grind_signatures") { 2511 } else { 2513 };
1752117523
assert_eq!(
17522-
res.err().unwrap(),
17523-
"Total input amount 300000 is lower than needed for contribution 298032, considering fees of 2513. Need more inputs.",
17524+
check_v2_funding_inputs_sufficient(
17525+
298032,
17526+
&[
17527+
funding_input_sats(200_000),
17528+
funding_input_sats(100_000),
17529+
],
17530+
true,
17531+
true,
17532+
2200,
17533+
),
17534+
Err(format!(
17535+
"Total input amount 300000 is lower than needed for contribution 298032, considering fees of {}. Need more inputs.",
17536+
expected_fee
17537+
)),
1752417538
);
1752517539
}
1752617540

17527-
// barely covers, less fees (no extra weight, no init)
17541+
// barely covers, less fees (no extra weight, not initiator)
1752817542
{
17529-
let expected_fee: u64 = 1088;
17543+
let expected_fee = 1088;
1753017544
assert_eq!(
1753117545
check_v2_funding_inputs_sufficient(
1753217546
(300_000 - expected_fee - 20) as i64,

lightning/src/ln/interactivetxs.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,15 @@ impl InputOwned {
17061706
InputOwned::Single(single) => single.satisfaction_weight,
17071707
// TODO(taproot): Needs to consider different weights based on channel type
17081708
InputOwned::Shared(_) => {
1709-
Weight::from_wu(EMPTY_SCRIPT_SIG_WEIGHT + FUNDING_TRANSACTION_WITNESS_WEIGHT)
1709+
let mut weight = 0;
1710+
weight += EMPTY_SCRIPT_SIG_WEIGHT + FUNDING_TRANSACTION_WITNESS_WEIGHT;
1711+
#[cfg(feature = "grind_signatures")]
1712+
{
1713+
// Guarantees a low R signature
1714+
weight -= 1;
1715+
}
1716+
1717+
Weight::from_wu(weight)
17101718
},
17111719
}
17121720
}
@@ -2314,6 +2322,11 @@ pub(super) fn calculate_change_output_value(
23142322
weight = weight.saturating_add(BASE_INPUT_WEIGHT);
23152323
weight = weight.saturating_add(EMPTY_SCRIPT_SIG_WEIGHT);
23162324
weight = weight.saturating_add(FUNDING_TRANSACTION_WITNESS_WEIGHT);
2325+
#[cfg(feature = "grind_signatures")]
2326+
{
2327+
// Guarantees a low R signature
2328+
weight -= 1;
2329+
}
23172330
}
23182331
}
23192332

lightning/src/sign/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ pub struct DelayedPaymentOutputDescriptor {
112112

113113
impl DelayedPaymentOutputDescriptor {
114114
/// The maximum length a well-formed witness spending one of these should have.
115-
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
115+
///
116+
/// Note: If you have the `grind_signatures` feature enabled, this will be at least 1 byte
116117
/// shorter.
117118
pub const MAX_WITNESS_LENGTH: u64 = (1 /* witness items */
118119
+ 1 /* sig push */
@@ -194,7 +195,8 @@ impl StaticPaymentOutputDescriptor {
194195
}
195196

196197
/// The maximum length a well-formed witness spending one of these should have.
197-
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
198+
///
199+
/// Note: If you have the `grind_signatures` feature enabled, this will be at least 1 byte
198200
/// shorter.
199201
pub fn max_witness_length(&self) -> u64 {
200202
if self.needs_csv_1_for_spend() {

0 commit comments

Comments
 (0)