Skip to content

Commit 7147775

Browse files
jkczyzTheBlueMatt
authored andcommitted
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. Backport of 4698026
1 parent 4e7f464 commit 7147775

File tree

6 files changed

+97
-49
lines changed

6 files changed

+97
-49
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: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6561,6 +6561,11 @@ fn estimate_v2_funding_transaction_fee(
65616561
.saturating_add(BASE_INPUT_WEIGHT)
65626562
.saturating_add(EMPTY_SCRIPT_SIG_WEIGHT)
65636563
.saturating_add(FUNDING_TRANSACTION_WITNESS_WEIGHT);
6564+
#[cfg(feature = "grind_signatures")]
6565+
{
6566+
// Guarantees a low R signature
6567+
weight -= 1;
6568+
}
65646569
}
65656570
}
65666571

@@ -17413,19 +17418,19 @@ mod tests {
1741317418
// 2 inputs, initiator, 2000 sat/kw feerate
1741417419
assert_eq!(
1741517420
estimate_v2_funding_transaction_fee(&two_inputs, &[], true, false, 2000),
17416-
1516,
17421+
if cfg!(feature = "grind_signatures") { 1512 } else { 1516 },
1741717422
);
1741817423

1741917424
// higher feerate
1742017425
assert_eq!(
1742117426
estimate_v2_funding_transaction_fee(&two_inputs, &[], true, false, 3000),
17422-
2274,
17427+
if cfg!(feature = "grind_signatures") { 2268 } else { 2274 },
1742317428
);
1742417429

1742517430
// only 1 input
1742617431
assert_eq!(
1742717432
estimate_v2_funding_transaction_fee(&one_input, &[], true, false, 2000),
17428-
972,
17433+
if cfg!(feature = "grind_signatures") { 970 } else { 972 },
1742917434
);
1743017435

1743117436
// 0 inputs
@@ -17443,13 +17448,13 @@ mod tests {
1744317448
// splice initiator
1744417449
assert_eq!(
1744517450
estimate_v2_funding_transaction_fee(&one_input, &[], true, true, 2000),
17446-
1740,
17451+
if cfg!(feature = "grind_signatures") { 1736 } else { 1740 },
1744717452
);
1744817453

1744917454
// splice acceptor
1745017455
assert_eq!(
1745117456
estimate_v2_funding_transaction_fee(&one_input, &[], false, true, 2000),
17452-
544,
17457+
if cfg!(feature = "grind_signatures") { 542 } else { 544 },
1745317458
);
1745417459
}
1745517460

@@ -17473,40 +17478,46 @@ mod tests {
1747317478
use crate::ln::channel::check_v2_funding_inputs_sufficient;
1747417479

1747517480
// positive case, inputs well over intended contribution
17476-
assert_eq!(
17477-
check_v2_funding_inputs_sufficient(
17478-
220_000,
17479-
&[
17480-
funding_input_sats(200_000),
17481-
funding_input_sats(100_000),
17482-
],
17483-
true,
17484-
true,
17485-
2000,
17486-
).unwrap(),
17487-
2284,
17488-
);
17481+
{
17482+
let expected_fee = if cfg!(feature = "grind_signatures") { 2278 } else { 2284 };
17483+
assert_eq!(
17484+
check_v2_funding_inputs_sufficient(
17485+
220_000,
17486+
&[
17487+
funding_input_sats(200_000),
17488+
funding_input_sats(100_000),
17489+
],
17490+
true,
17491+
true,
17492+
2000,
17493+
).unwrap(),
17494+
expected_fee,
17495+
);
17496+
}
1748917497

1749017498
// negative case, inputs clearly insufficient
1749117499
{
17492-
let res = check_v2_funding_inputs_sufficient(
17493-
220_000,
17494-
&[
17495-
funding_input_sats(100_000),
17496-
],
17497-
true,
17498-
true,
17499-
2000,
17500-
);
17500+
let expected_fee = if cfg!(feature = "grind_signatures") { 1736 } else { 1740 };
1750117501
assert_eq!(
17502-
res.err().unwrap(),
17503-
"Total input amount 100000 is lower than needed for contribution 220000, considering fees of 1740. Need more inputs.",
17502+
check_v2_funding_inputs_sufficient(
17503+
220_000,
17504+
&[
17505+
funding_input_sats(100_000),
17506+
],
17507+
true,
17508+
true,
17509+
2000,
17510+
),
17511+
Err(format!(
17512+
"Total input amount 100000 is lower than needed for contribution 220000, considering fees of {}. Need more inputs.",
17513+
expected_fee,
17514+
)),
1750417515
);
1750517516
}
1750617517

1750717518
// barely covers
1750817519
{
17509-
let expected_fee: u64 = 2284;
17520+
let expected_fee = if cfg!(feature = "grind_signatures") { 2278 } else { 2284 };
1751017521
assert_eq!(
1751117522
check_v2_funding_inputs_sufficient(
1751217523
(300_000 - expected_fee - 20) as i64,
@@ -17524,25 +17535,28 @@ mod tests {
1752417535

1752517536
// higher fee rate, does not cover
1752617537
{
17527-
let res = check_v2_funding_inputs_sufficient(
17528-
298032,
17529-
&[
17530-
funding_input_sats(200_000),
17531-
funding_input_sats(100_000),
17532-
],
17533-
true,
17534-
true,
17535-
2200,
17536-
);
17538+
let expected_fee = if cfg!(feature = "grind_signatures") { 2506 } else { 2513 };
1753717539
assert_eq!(
17538-
res.err().unwrap(),
17539-
"Total input amount 300000 is lower than needed for contribution 298032, considering fees of 2513. Need more inputs.",
17540+
check_v2_funding_inputs_sufficient(
17541+
298032,
17542+
&[
17543+
funding_input_sats(200_000),
17544+
funding_input_sats(100_000),
17545+
],
17546+
true,
17547+
true,
17548+
2200,
17549+
),
17550+
Err(format!(
17551+
"Total input amount 300000 is lower than needed for contribution 298032, considering fees of {}. Need more inputs.",
17552+
expected_fee
17553+
)),
1754017554
);
1754117555
}
1754217556

17543-
// barely covers, less fees (no extra weight, no init)
17557+
// barely covers, less fees (no extra weight, not initiator)
1754417558
{
17545-
let expected_fee: u64 = 1088;
17559+
let expected_fee = if cfg!(feature = "grind_signatures") { 1084 } else { 1088 };
1754617560
assert_eq!(
1754717561
check_v2_funding_inputs_sufficient(
1754817562
(300_000 - expected_fee - 20) as i64,

lightning/src/ln/funding.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,13 @@ impl FundingTxInput {
143143
/// [`TxIn::sequence`]: bitcoin::TxIn::sequence
144144
/// [`set_sequence`]: Self::set_sequence
145145
pub fn new_p2wpkh(prevtx: Transaction, vout: u32) -> Result<Self, ()> {
146-
let witness_weight = Weight::from_wu(P2WPKH_WITNESS_WEIGHT);
146+
let witness_weight = Weight::from_wu(P2WPKH_WITNESS_WEIGHT)
147+
- if cfg!(feature = "grind_signatures") {
148+
// Guarantees a low R signature
149+
Weight::from_wu(1)
150+
} else {
151+
Weight::ZERO
152+
};
147153
FundingTxInput::new(prevtx, vout, witness_weight, Script::is_p2wpkh)
148154
}
149155

lightning/src/ln/interactivetxs.rs

Lines changed: 19 additions & 2 deletions
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
}
@@ -2312,6 +2320,11 @@ pub(super) fn calculate_change_output_value(
23122320
weight = weight.saturating_add(BASE_INPUT_WEIGHT);
23132321
weight = weight.saturating_add(EMPTY_SCRIPT_SIG_WEIGHT);
23142322
weight = weight.saturating_add(FUNDING_TRANSACTION_WITNESS_WEIGHT);
2323+
#[cfg(feature = "grind_signatures")]
2324+
{
2325+
// Guarantees a low R signature
2326+
weight -= 1;
2327+
}
23152328
}
23162329
}
23172330

@@ -3357,7 +3370,11 @@ mod tests {
33573370

33583371
let total_inputs: Amount = input_prevouts.iter().map(|o| o.value).sum();
33593372
let total_outputs: Amount = outputs.iter().map(|o| o.value).sum();
3360-
let fees = Amount::from_sat(1740);
3373+
let fees = if cfg!(feature = "grind_signatures") {
3374+
Amount::from_sat(1734)
3375+
} else {
3376+
Amount::from_sat(1740)
3377+
};
33613378
let common_fees = Amount::from_sat(234);
33623379

33633380
// There is leftover for change

lightning/src/sign/mod.rs

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

118118
impl DelayedPaymentOutputDescriptor {
119119
/// The maximum length a well-formed witness spending one of these should have.
120-
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
120+
///
121+
/// Note: If you have the `grind_signatures` feature enabled, this will be at least 1 byte
121122
/// shorter.
122123
pub const MAX_WITNESS_LENGTH: u64 = (1 /* witness items */
123124
+ 1 /* sig push */
@@ -198,7 +199,8 @@ impl StaticPaymentOutputDescriptor {
198199
}
199200

200201
/// The maximum length a well-formed witness spending one of these should have.
201-
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
202+
///
203+
/// Note: If you have the `grind_signatures` feature enabled, this will be at least 1 byte
202204
/// shorter.
203205
pub fn max_witness_length(&self) -> u64 {
204206
if self.needs_csv_1_for_spend() {

lightning/src/util/test_utils.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,10 +2220,16 @@ impl TestWalletSource {
22202220
utxo.output.value,
22212221
EcdsaSighashType::All,
22222222
)?;
2223+
#[cfg(not(feature = "grind_signatures"))]
22232224
let signature = self.secp.sign_ecdsa(
22242225
&secp256k1::Message::from_digest(sighash.to_byte_array()),
22252226
&self.secret_key,
22262227
);
2228+
#[cfg(feature = "grind_signatures")]
2229+
let signature = self.secp.sign_ecdsa_low_r(
2230+
&secp256k1::Message::from_digest(sighash.to_byte_array()),
2231+
&self.secret_key,
2232+
);
22272233
let bitcoin_sig =
22282234
bitcoin::ecdsa::Signature { signature, sighash_type: EcdsaSighashType::All };
22292235
tx.input[i].witness =

0 commit comments

Comments
 (0)