@@ -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.123 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,121 @@ 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
+ [ (
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 ) = descriptor
414
+ . channel_transaction_parameters
415
+ . as_ref ( )
416
+ . and_then ( |channel_params| Some ( channel_params. supports_anchors ( ) ) )
417
+ {
418
+ descriptor. witness_script ( )
419
+ } else {
420
+ descriptor. channel_transaction_parameters . as_ref ( ) . and_then ( |channel_params| {
421
+ // Use simplified derivation, assuming `option_static_remotekey` is negotiated.
422
+ // `remote_payment_basepoint` is used as Payment Key.
423
+ let payment_point = channel_params. holder_pubkeys . payment_point ;
424
+ Some ( ScriptBuf :: new_p2pkh (
425
+ & bitcoin:: PublicKey :: new ( payment_point) . pubkey_hash ( ) ,
426
+ ) )
427
+ } )
428
+ } ;
429
+ // With simplified derivation, the private payment key is equal to private payment basepoint,
430
+ // so add tweak is not needed.
324
431
bitcoin:: psbt:: Input {
325
432
witness_utxo : Some ( descriptor. output . clone ( ) ) ,
433
+ witness_script,
326
434
..Default :: default ( )
327
435
}
328
436
} ,
@@ -345,8 +453,8 @@ impl SpendableOutputDescriptor {
345
453
/// does not match the one we can spend.
346
454
///
347
455
/// 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 > ,
456
+ pub fn create_spendable_outputs_psbt < T : secp256k1 :: Signing > (
457
+ secp_ctx : & Secp256k1 < T > , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > ,
350
458
change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 ,
351
459
locktime : Option < LockTime > ,
352
460
) -> Result < ( PartiallySignedTransaction , u64 ) , ( ) > {
@@ -438,7 +546,8 @@ impl SpendableOutputDescriptor {
438
546
change_destination_script,
439
547
) ?;
440
548
441
- let psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( ) ) . collect :: < Vec < _ > > ( ) ;
549
+ let psbt_inputs =
550
+ descriptors. iter ( ) . map ( |d| d. to_psbt_input ( & secp_ctx) ) . collect :: < Vec < _ > > ( ) ;
442
551
let psbt = PartiallySignedTransaction {
443
552
inputs : psbt_inputs,
444
553
outputs : vec ! [ Default :: default ( ) ; tx. output. len( ) ] ,
@@ -2112,6 +2221,7 @@ impl OutputSpender for KeysManager {
2112
2221
) -> Result < Transaction , ( ) > {
2113
2222
let ( mut psbt, expected_max_weight) =
2114
2223
SpendableOutputDescriptor :: create_spendable_outputs_psbt (
2224
+ secp_ctx,
2115
2225
descriptors,
2116
2226
outputs,
2117
2227
change_destination_script,
0 commit comments