@@ -18,7 +18,7 @@ use bitcoin::blockdata::script::{Script, ScriptBuf, Builder};
18
18
use bitcoin:: blockdata:: opcodes;
19
19
use bitcoin:: ecdsa:: Signature as EcdsaSignature ;
20
20
use bitcoin:: network:: constants:: Network ;
21
- use bitcoin:: psbt:: PartiallySignedTransaction ;
21
+ use bitcoin:: psbt:: { PartiallySignedTransaction , raw } ;
22
22
use bitcoin:: bip32:: { ExtendedPrivKey , ExtendedPubKey , ChildNumber } ;
23
23
use bitcoin:: sighash;
24
24
use bitcoin:: sighash:: EcdsaSighashType ;
@@ -37,13 +37,13 @@ use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
37
37
use bitcoin:: secp256k1:: schnorr;
38
38
use bitcoin:: { secp256k1, Sequence , Witness , Txid } ;
39
39
40
+ use crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI ;
40
41
use crate :: util:: transaction_utils;
41
42
use crate :: crypto:: utils:: { hkdf_extract_expand_twice, sign, sign_with_aux_rand} ;
42
43
use crate :: util:: ser:: { Writeable , Writer , Readable , ReadableArgs } ;
43
44
use crate :: chain:: transaction:: OutPoint ;
44
- use crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI ;
45
45
use crate :: ln:: { chan_utils, PaymentPreimage } ;
46
- use crate :: ln:: chan_utils:: { HTLCOutputInCommitment , make_funding_redeemscript, ChannelPublicKeys , HolderCommitmentTransaction , ChannelTransactionParameters , CommitmentTransaction , ClosingTransaction } ;
46
+ use crate :: ln:: chan_utils:: { HTLCOutputInCommitment , make_funding_redeemscript, ChannelPublicKeys , HolderCommitmentTransaction , ChannelTransactionParameters , CommitmentTransaction , ClosingTransaction , get_revokeable_redeemscript } ;
47
47
use crate :: ln:: channel_keys:: { DelayedPaymentBasepoint , DelayedPaymentKey , HtlcKey , HtlcBasepoint , RevocationKey , RevocationBasepoint } ;
48
48
use crate :: ln:: msgs:: { UnsignedChannelAnnouncement , UnsignedGossipMessage } ;
49
49
#[ cfg( taproot) ]
@@ -103,7 +103,13 @@ pub struct DelayedPaymentOutputDescriptor {
103
103
pub channel_keys_id : [ u8 ; 32 ] ,
104
104
/// The value of the channel which this output originated from, possibly indirectly.
105
105
pub channel_value_satoshis : u64 ,
106
+ /// The channel public keys and other parameters needed to generate a spending transaction or to provide to a re-derived signer through
107
+ /// [`ChannelSigner::provide_channel_parameters`].
108
+ ///
109
+ /// Added as optional, but always `Some` if the descriptor was produced in v0.0.120 or later.
110
+ pub channel_transaction_parameters : Option < ChannelTransactionParameters > ,
106
111
}
112
+
107
113
impl DelayedPaymentOutputDescriptor {
108
114
/// The maximum length a well-formed witness spending one of these should have.
109
115
/// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte
@@ -121,6 +127,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, {
121
127
( 8 , revocation_pubkey, required) ,
122
128
( 10 , channel_keys_id, required) ,
123
129
( 12 , channel_value_satoshis, required) ,
130
+ ( 14 , channel_transaction_parameters, option) ,
124
131
} ) ;
125
132
126
133
pub ( crate ) const P2WPKH_WITNESS_WEIGHT : u64 = 1 /* num stack items */ +
@@ -149,21 +156,24 @@ pub struct StaticPaymentOutputDescriptor {
149
156
/// Added as optional, but always `Some` if the descriptor was produced in v0.0.117 or later.
150
157
pub channel_transaction_parameters : Option < ChannelTransactionParameters > ,
151
158
}
159
+
152
160
impl StaticPaymentOutputDescriptor {
153
161
/// Returns the `witness_script` of the spendable output.
154
162
///
155
163
/// Note that this will only return `Some` for [`StaticPaymentOutputDescriptor`]s that
156
164
/// originated from an anchor outputs channel, as they take the form of a P2WSH script.
157
165
pub fn witness_script ( & self ) -> Option < ScriptBuf > {
158
166
self . channel_transaction_parameters . as_ref ( )
159
- . and_then ( |channel_params|
160
- if channel_params. channel_type_features . supports_anchors_zero_fee_htlc_tx ( ) {
161
- let payment_point = channel_params. holder_pubkeys . payment_point ;
167
+ . and_then ( |channel_params| {
168
+ // Use simplified derivation, assuming `option_static_remotekey` is negotiated.
169
+ // `remote_payment_basepoint` is used as Payment Key.
170
+ let payment_point = channel_params. holder_pubkeys . payment_point ;
171
+ if channel_params. channel_type_features . supports_anchors_zero_fee_htlc_tx ( ) {
162
172
Some ( chan_utils:: get_to_countersignatory_with_anchors_redeemscript ( & payment_point) )
163
- } else {
164
- None
165
- }
166
- )
173
+ } else {
174
+ Some ( ScriptBuf :: new_p2pkh ( & bitcoin :: PublicKey :: new ( payment_point ) . pubkey_hash ( ) ) )
175
+ }
176
+ } )
167
177
}
168
178
169
179
/// The maximum length a well-formed witness spending one of these should have.
@@ -304,7 +314,7 @@ impl SpendableOutputDescriptor {
304
314
///
305
315
/// This is not exported to bindings users as there is no standard serialization for an input.
306
316
/// See [`Self::create_spendable_outputs_psbt`] instead.
307
- pub fn to_psbt_input ( & self ) -> bitcoin:: psbt:: Input {
317
+ pub fn to_psbt_input < T : secp256k1 :: Signing > ( & self , secp_ctx : & Secp256k1 < T > ) -> bitcoin:: psbt:: Input {
308
318
match self {
309
319
SpendableOutputDescriptor :: StaticOutput { output, .. } => {
310
320
// Is a standard P2WPKH, no need for witness script
@@ -314,16 +324,49 @@ impl SpendableOutputDescriptor {
314
324
}
315
325
} ,
316
326
SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
317
- // TODO we could add the witness script as well
327
+ let delayed_payment_basepoint = descriptor. channel_transaction_parameters . as_ref ( ) . map ( |params| DelayedPaymentBasepoint :: from (
328
+ params. holder_pubkeys . delayed_payment_basepoint ,
329
+ ) ) ;
330
+
331
+ let ( witness_script, add_tweak) = if let Some ( basepoint) = delayed_payment_basepoint. as_ref ( ) {
332
+ let payment_key = DelayedPaymentKey :: from_basepoint (
333
+ secp_ctx,
334
+ basepoint,
335
+ & descriptor. per_commitment_point ,
336
+ ) ;
337
+ // Required to derive signing key: privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
338
+ let add_tweak = basepoint. derive_add_tweak ( & descriptor. per_commitment_point ) ;
339
+ ( Some ( get_revokeable_redeemscript (
340
+ & descriptor. revocation_pubkey ,
341
+ descriptor. to_self_delay ,
342
+ & payment_key,
343
+ ) ) , Some ( add_tweak) )
344
+ } else {
345
+ ( None , None )
346
+ } ;
347
+
318
348
bitcoin:: psbt:: Input {
319
349
witness_utxo : Some ( descriptor. output . clone ( ) ) ,
350
+ witness_script,
351
+ proprietary : add_tweak. map ( |add_tweak| { vec ! [ (
352
+ raw:: ProprietaryKey {
353
+ prefix: "LDK_spendable_output" . as_bytes( ) . to_vec( ) ,
354
+ subtype: 0 ,
355
+ key: "add_tweak" . as_bytes( ) . to_vec( ) ,
356
+ } ,
357
+ add_tweak. to_vec( ) ,
358
+ ) ] . into_iter ( ) . collect ( ) } ) . unwrap_or_default ( ) ,
320
359
..Default :: default ( )
321
360
}
322
361
} ,
323
362
SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
324
- // TODO we could add the witness script as well
363
+ let witness_script = descriptor. witness_script ( ) ;
364
+
365
+ // With simplified derivation, the private payment key is equal to private payment basepoint,
366
+ // so add tweak is not needed.
325
367
bitcoin:: psbt:: Input {
326
368
witness_utxo : Some ( descriptor. output . clone ( ) ) ,
369
+ witness_script,
327
370
..Default :: default ( )
328
371
}
329
372
} ,
@@ -347,6 +390,7 @@ impl SpendableOutputDescriptor {
347
390
///
348
391
/// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
349
392
pub fn create_spendable_outputs_psbt ( descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 , locktime : Option < LockTime > ) -> Result < ( PartiallySignedTransaction , u64 ) , ( ) > {
393
+ let secp_ctx = Secp256k1 :: new ( ) ;
350
394
let mut input = Vec :: with_capacity ( descriptors. len ( ) ) ;
351
395
let mut input_value = 0 ;
352
396
let mut witness_weight = 0 ;
@@ -413,7 +457,7 @@ impl SpendableOutputDescriptor {
413
457
let expected_max_weight =
414
458
transaction_utils:: maybe_add_change_output ( & mut tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script) ?;
415
459
416
- let psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( ) ) . collect :: < Vec < _ > > ( ) ;
460
+ let psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( & secp_ctx ) ) . collect :: < Vec < _ > > ( ) ;
417
461
let psbt = PartiallySignedTransaction {
418
462
inputs : psbt_inputs,
419
463
outputs : vec ! [ Default :: default ( ) ; tx. output. len( ) ] ,
@@ -1615,6 +1659,7 @@ impl KeysManager {
1615
1659
/// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
1616
1660
/// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
1617
1661
pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : ScriptBuf , feerate_sat_per_1000_weight : u32 , locktime : Option < LockTime > , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
1662
+ // TODO: provide channel keys to construct witness script
1618
1663
let ( mut psbt, expected_max_weight) = SpendableOutputDescriptor :: create_spendable_outputs_psbt ( descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime) ?;
1619
1664
psbt = self . sign_spendable_outputs_psbt ( descriptors, psbt, secp_ctx) ?;
1620
1665
0 commit comments