@@ -40,8 +40,9 @@ use bitcoin::{secp256k1, Sequence, Txid, Witness};
40
40
use crate :: chain:: transaction:: OutPoint ;
41
41
use crate :: crypto:: utils:: { hkdf_extract_expand_twice, sign, sign_with_aux_rand} ;
42
42
use crate :: ln:: chan_utils:: {
43
- make_funding_redeemscript, ChannelPublicKeys , ChannelTransactionParameters , ClosingTransaction ,
44
- CommitmentTransaction , HTLCOutputInCommitment , HolderCommitmentTransaction ,
43
+ get_revokeable_redeemscript, make_funding_redeemscript, ChannelPublicKeys ,
44
+ ChannelTransactionParameters , ClosingTransaction , CommitmentTransaction ,
45
+ HTLCOutputInCommitment , HolderCommitmentTransaction ,
45
46
} ;
46
47
use crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI ;
47
48
use crate :: ln:: channel_keys:: {
@@ -68,6 +69,7 @@ use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner};
68
69
use crate :: sign:: taproot:: TaprootChannelSigner ;
69
70
use crate :: util:: atomic_counter:: AtomicCounter ;
70
71
use crate :: util:: invoice:: construct_invoice_preimage;
72
+ use core:: convert:: TryInto ;
71
73
use core:: ops:: Deref ;
72
74
use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
73
75
#[ cfg( taproot) ]
@@ -108,7 +110,13 @@ pub struct DelayedPaymentOutputDescriptor {
108
110
pub channel_keys_id : [ u8 ; 32 ] ,
109
111
/// The value of the channel which this output originated from, possibly indirectly.
110
112
pub channel_value_satoshis : u64 ,
113
+ /// The channel public keys and other parameters needed to generate a spending transaction or to provide to a re-derived signer through
114
+ /// [`ChannelSigner::provide_channel_parameters`].
115
+ ///
116
+ /// Added as optional, but always `Some` if the descriptor was produced in v0.0.122 or later.
117
+ pub channel_transaction_parameters : Option < ChannelTransactionParameters > ,
111
118
}
119
+
112
120
impl DelayedPaymentOutputDescriptor {
113
121
/// The maximum length a well-formed witness spending one of these should have.
114
122
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
@@ -127,6 +135,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, {
127
135
( 8 , revocation_pubkey, required) ,
128
136
( 10 , channel_keys_id, required) ,
129
137
( 12 , channel_value_satoshis, required) ,
138
+ ( 13 , channel_transaction_parameters, option) ,
130
139
} ) ;
131
140
132
141
pub ( crate ) const P2WPKH_WITNESS_WEIGHT : u64 = 1 /* num stack items */ +
@@ -155,6 +164,7 @@ pub struct StaticPaymentOutputDescriptor {
155
164
/// Added as optional, but always `Some` if the descriptor was produced in v0.0.117 or later.
156
165
pub channel_transaction_parameters : Option < ChannelTransactionParameters > ,
157
166
}
167
+
158
168
impl StaticPaymentOutputDescriptor {
159
169
/// Returns the `witness_script` of the spendable output.
160
170
///
@@ -306,23 +316,124 @@ impl SpendableOutputDescriptor {
306
316
///
307
317
/// This is not exported to bindings users as there is no standard serialization for an input.
308
318
/// See [`Self::create_spendable_outputs_psbt`] instead.
309
- pub fn to_psbt_input ( & self ) -> bitcoin:: psbt:: Input {
319
+ ///
320
+ /// The proprietary field is used to store add tweak for the signing key of this transaction.
321
+ /// See the [DelayedPaymentBasepoint::derive_add_tweak] docs for more info on add tweak and how to use it.
322
+ ///
323
+ /// To get the proprietary field use:
324
+ /// ```
325
+ /// use bitcoin::psbt::{PartiallySignedTransaction};
326
+ /// use bitcoin::hashes::hex::FromHex;
327
+ ///
328
+ /// # let s = "70736274ff0100520200000001dee978529ab3e61a2987bea5183713d0e6d5ceb5ac81100fdb54a1a2\
329
+ /// # 69cef505000000000090000000011f26000000000000160014abb3ab63280d4ccc5c11d6b50fd427a8\
330
+ /// # e19d6470000000000001012b10270000000000002200200afe4736760d814a2651bae63b572d935d9a\
331
+ /// # b74a1a16c01774e341a32afa763601054d63210394a27a700617f5b7aee72bd4f8076b5770a582b7fb\
332
+ /// # d1d4ee2ea3802cd3cfbe2067029000b27521034629b1c8fdebfaeb58a74cd181f485e2c462e594cb30\
333
+ /// # 34dee655875f69f6c7c968ac20fc144c444b5f7370656e6461626c655f6f7574707574006164645f74\
334
+ /// # 7765616b20a86534f38ad61dc580ef41c3886204adf0911b81619c1ad7a2f5b5de39a2ba600000";
335
+ /// # let psbt = PartiallySignedTransaction::deserialize(<Vec<u8> as FromHex>::from_hex(s).unwrap().as_slice()).unwrap();
336
+ /// let key = bitcoin::psbt::raw::ProprietaryKey {
337
+ /// prefix: "LDK_spendable_output".as_bytes().to_vec(),
338
+ /// subtype: 0,
339
+ /// key: "add_tweak".as_bytes().to_vec(),
340
+ /// };
341
+ /// let value = psbt
342
+ /// .inputs
343
+ /// .first()
344
+ /// .expect("Unable to get add tweak as there are no inputs")
345
+ /// .proprietary
346
+ /// .get(&key)
347
+ /// .map(|x| x.to_owned());
348
+ /// ```
349
+ pub fn to_psbt_input < T : secp256k1:: Signing > (
350
+ & self , secp_ctx : & Secp256k1 < T > ,
351
+ ) -> bitcoin:: psbt:: Input {
310
352
match self {
311
353
SpendableOutputDescriptor :: StaticOutput { output, .. } => {
312
354
// Is a standard P2WPKH, no need for witness script
313
355
bitcoin:: psbt:: Input { witness_utxo : Some ( output. clone ( ) ) , ..Default :: default ( ) }
314
356
} ,
315
- SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
316
- // TODO we could add the witness script as well
357
+ SpendableOutputDescriptor :: DelayedPaymentOutput ( DelayedPaymentOutputDescriptor {
358
+ channel_transaction_parameters,
359
+ per_commitment_point,
360
+ revocation_pubkey,
361
+ to_self_delay,
362
+ output,
363
+ ..
364
+ } ) => {
365
+ let delayed_payment_basepoint = channel_transaction_parameters
366
+ . as_ref ( )
367
+ . map ( |params| params. holder_pubkeys . delayed_payment_basepoint ) ;
368
+
369
+ let ( witness_script, add_tweak) =
370
+ if let Some ( basepoint) = delayed_payment_basepoint. as_ref ( ) {
371
+ let payment_key = DelayedPaymentKey :: from_basepoint (
372
+ secp_ctx,
373
+ basepoint,
374
+ & per_commitment_point,
375
+ ) ;
376
+ // Required to derive signing key: privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
377
+ let add_tweak = basepoint. derive_add_tweak ( & per_commitment_point) ;
378
+ (
379
+ Some ( get_revokeable_redeemscript (
380
+ & revocation_pubkey,
381
+ * to_self_delay,
382
+ & payment_key,
383
+ ) ) ,
384
+ Some ( add_tweak) ,
385
+ )
386
+ } else {
387
+ ( None , None )
388
+ } ;
389
+
317
390
bitcoin:: psbt:: Input {
318
- witness_utxo : Some ( descriptor. output . clone ( ) ) ,
391
+ witness_utxo : Some ( output. clone ( ) ) ,
392
+ witness_script,
393
+ proprietary : add_tweak
394
+ . map ( |add_tweak| {
395
+ vec ! [ (
396
+ bitcoin:: psbt:: raw:: ProprietaryKey {
397
+ // A non standard namespace for spendable outputs, used to store the tweak needed
398
+ // to derive the private key
399
+ prefix: "LDK_spendable_output" . as_bytes( ) . to_vec( ) ,
400
+ subtype: 0 ,
401
+ key: "add_tweak" . as_bytes( ) . to_vec( ) ,
402
+ } ,
403
+ add_tweak. to_vec( ) ,
404
+ ) ]
405
+ . into_iter ( )
406
+ . collect ( )
407
+ } )
408
+ . unwrap_or_default ( ) ,
319
409
..Default :: default ( )
320
410
}
321
411
} ,
322
412
SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
323
- // TODO we could add the witness script as well
413
+ let witness_script = if let Some ( true ) =
414
+ descriptor. channel_transaction_parameters . as_ref ( ) . and_then ( |channel_params| {
415
+ Some (
416
+ channel_params
417
+ . channel_type_features
418
+ . supports_anchors_zero_fee_htlc_tx ( ) ,
419
+ )
420
+ } ) {
421
+ descriptor. witness_script ( )
422
+ } else {
423
+ descriptor. channel_transaction_parameters . as_ref ( ) . and_then ( |channel_params| {
424
+ // Use simplified derivation, assuming `option_static_remotekey` is negotiated.
425
+ // `remote_payment_basepoint` is used as Payment Key.
426
+ let payment_point = channel_params. holder_pubkeys . payment_point ;
427
+ Some ( ScriptBuf :: new_p2pkh (
428
+ & bitcoin:: PublicKey :: new ( payment_point) . pubkey_hash ( ) ,
429
+ ) )
430
+ } )
431
+ } ;
432
+ // With simplified derivation, the private payment key is equal to private payment basepoint,
433
+ // so add tweak is not needed.
324
434
bitcoin:: psbt:: Input {
325
435
witness_utxo : Some ( descriptor. output . clone ( ) ) ,
436
+ witness_script,
326
437
..Default :: default ( )
327
438
}
328
439
} ,
@@ -345,8 +456,8 @@ impl SpendableOutputDescriptor {
345
456
/// does not match the one we can spend.
346
457
///
347
458
/// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
348
- pub fn create_spendable_outputs_psbt (
349
- descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
459
+ pub fn create_spendable_outputs_psbt < T : secp256k1 :: Signing > (
460
+ secp_ctx : & Secp256k1 < T > , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
350
461
change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
351
462
locktime : Option < LockTime > ,
352
463
) -> Result < ( PartiallySignedTransaction , u64 ) , ( ) > {
@@ -438,7 +549,8 @@ impl SpendableOutputDescriptor {
438
549
change_destination_script,
439
550
) ?;
440
551
441
- let psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( ) ) . collect :: < Vec < _ > > ( ) ;
552
+ let psbt_inputs =
553
+ descriptors. iter ( ) . map ( |d| d. to_psbt_input ( & secp_ctx) ) . collect :: < Vec < _ > > ( ) ;
442
554
let psbt = PartiallySignedTransaction {
443
555
inputs : psbt_inputs,
444
556
outputs : vec ! [ Default :: default ( ) ; tx. output. len( ) ] ,
@@ -2024,6 +2136,51 @@ impl KeysManager {
2024
2136
2025
2137
Ok ( psbt)
2026
2138
}
2139
+
2140
+ /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
2141
+ /// output to the given change destination (if sufficient change value remains). The
2142
+ /// transaction will have a feerate, at least, of the given value.
2143
+ ///
2144
+ /// The `locktime` argument is used to set the transaction's locktime. If `None`, the
2145
+ /// transaction will have a locktime of 0. It it recommended to set this to the current block
2146
+ /// height to avoid fee sniping, unless you have some specific reason to use a different
2147
+ /// locktime.
2148
+ ///
2149
+ /// Returns `Err(())` if the output value is greater than the input value minus required fee,
2150
+ /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
2151
+ /// does not match the one we can spend.
2152
+ ///
2153
+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
2154
+ ///
2155
+ /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
2156
+ /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
2157
+ pub fn spend_spendable_outputs < C : Signing > (
2158
+ & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
2159
+ change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
2160
+ locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ,
2161
+ ) -> Result < Transaction , ( ) > {
2162
+ let ( mut psbt, expected_max_weight) =
2163
+ SpendableOutputDescriptor :: create_spendable_outputs_psbt (
2164
+ & self . secp_ctx ,
2165
+ descriptors,
2166
+ outputs,
2167
+ change_destination_script,
2168
+ feerate_sat_per_1000_weight,
2169
+ locktime,
2170
+ ) ?;
2171
+ psbt = self . sign_spendable_outputs_psbt ( descriptors, psbt, secp_ctx) ?;
2172
+
2173
+ let spend_tx = psbt. extract_tx ( ) ;
2174
+
2175
+ debug_assert ! ( expected_max_weight >= spend_tx. weight( ) . to_wu( ) ) ;
2176
+ // Note that witnesses with a signature vary somewhat in size, so allow
2177
+ // `expected_max_weight` to overshoot by up to 3 bytes per input.
2178
+ debug_assert ! (
2179
+ expected_max_weight <= spend_tx. weight( ) . to_wu( ) + descriptors. len( ) as u64 * 3
2180
+ ) ;
2181
+
2182
+ Ok ( spend_tx)
2183
+ }
2027
2184
}
2028
2185
2029
2186
impl EntropySource for KeysManager {
@@ -2112,6 +2269,7 @@ impl OutputSpender for KeysManager {
2112
2269
) -> Result < Transaction , ( ) > {
2113
2270
let ( mut psbt, expected_max_weight) =
2114
2271
SpendableOutputDescriptor :: create_spendable_outputs_psbt (
2272
+ secp_ctx,
2115
2273
descriptors,
2116
2274
outputs,
2117
2275
change_destination_script,
0 commit comments