@@ -16,6 +16,7 @@ use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, EcdsaSighashType
16
16
use bitcoin:: blockdata:: script:: { Script , Builder } ;
17
17
use bitcoin:: blockdata:: opcodes;
18
18
use bitcoin:: network:: constants:: Network ;
19
+ use bitcoin:: psbt:: PartiallySignedTransaction ;
19
20
use bitcoin:: util:: bip32:: { ExtendedPrivKey , ExtendedPubKey , ChildNumber } ;
20
21
use bitcoin:: util:: sighash;
21
22
@@ -218,6 +219,126 @@ impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
218
219
( 2 , StaticPaymentOutput ) ,
219
220
) ;
220
221
222
+ impl SpendableOutputDescriptor {
223
+ /// Turns this into a [`bitcoin::psbt::Input`] which can be used to create a
224
+ /// [`PartiallySignedTransaction`] which spends the given descriptor.
225
+ ///
226
+ /// Note that this does not include any signatures, just the information required to
227
+ /// construct the transaction and sign it.
228
+ pub fn to_psbt_input ( & self ) -> bitcoin:: psbt:: Input {
229
+ match self {
230
+ SpendableOutputDescriptor :: StaticOutput { output, .. } => {
231
+ // Is a standard P2WPKH, no need for witness script
232
+ bitcoin:: psbt:: Input {
233
+ witness_utxo : Some ( output. clone ( ) ) ,
234
+ ..Default :: default ( )
235
+ }
236
+ } ,
237
+ SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
238
+ // TODO we could add the witness script as well
239
+ bitcoin:: psbt:: Input {
240
+ witness_utxo : Some ( descriptor. output . clone ( ) ) ,
241
+ ..Default :: default ( )
242
+ }
243
+ } ,
244
+ SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
245
+ // TODO we could add the witness script as well
246
+ bitcoin:: psbt:: Input {
247
+ witness_utxo : Some ( descriptor. output . clone ( ) ) ,
248
+ ..Default :: default ( )
249
+ }
250
+ } ,
251
+ }
252
+ }
253
+
254
+ /// Creates an unsigned [`PartiallySignedTransaction`] which spends the given descriptors to
255
+ /// the given outputs, plus an output to the given change destination (if sufficient
256
+ /// change value remains). The PSBT will have a feerate, at least, of the given value.
257
+ ///
258
+ /// The `locktime` argument is used to set the transaction's locktime. If `None`, the
259
+ /// transaction will have a locktime of 0. It it recommended to set this to the current block
260
+ /// height to avoid fee sniping, unless you have some specific reason to use a different
261
+ /// locktime.
262
+ ///
263
+ /// Returns the PSBT and expected max transaction weight.
264
+ ///
265
+ /// Returns `Err(())` if the output value is greater than the input value minus required fee,
266
+ /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
267
+ /// does not match the one we can spend.
268
+ ///
269
+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
270
+ pub fn create_spendable_outputs_psbt ( descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , locktime : Option < PackedLockTime > ) -> Result < ( PartiallySignedTransaction , usize ) , ( ) > {
271
+ let mut input = Vec :: with_capacity ( descriptors. len ( ) ) ;
272
+ let mut input_value = 0 ;
273
+ let mut witness_weight = 0 ;
274
+ let mut output_set = HashSet :: with_capacity ( descriptors. len ( ) ) ;
275
+ for outp in descriptors {
276
+ match outp {
277
+ SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
278
+ if !output_set. insert ( descriptor. outpoint ) { return Err ( ( ) ) ; }
279
+ input. push ( TxIn {
280
+ previous_output : descriptor. outpoint . into_bitcoin_outpoint ( ) ,
281
+ script_sig : Script :: new ( ) ,
282
+ sequence : Sequence :: ZERO ,
283
+ witness : Witness :: new ( ) ,
284
+ } ) ;
285
+ witness_weight += StaticPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ;
286
+ #[ cfg( feature = "grind_signatures" ) ]
287
+ { witness_weight -= 1 ; } // Guarantees a low R signature
288
+ input_value += descriptor. output . value ;
289
+ } ,
290
+ SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
291
+ if !output_set. insert ( descriptor. outpoint ) { return Err ( ( ) ) ; }
292
+ input. push ( TxIn {
293
+ previous_output : descriptor. outpoint . into_bitcoin_outpoint ( ) ,
294
+ script_sig : Script :: new ( ) ,
295
+ sequence : Sequence ( descriptor. to_self_delay as u32 ) ,
296
+ witness : Witness :: new ( ) ,
297
+ } ) ;
298
+ witness_weight += DelayedPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ;
299
+ #[ cfg( feature = "grind_signatures" ) ]
300
+ { witness_weight -= 1 ; } // Guarantees a low R signature
301
+ input_value += descriptor. output . value ;
302
+ } ,
303
+ SpendableOutputDescriptor :: StaticOutput { ref outpoint, ref output } => {
304
+ if !output_set. insert ( * outpoint) { return Err ( ( ) ) ; }
305
+ input. push ( TxIn {
306
+ previous_output : outpoint. into_bitcoin_outpoint ( ) ,
307
+ script_sig : Script :: new ( ) ,
308
+ sequence : Sequence :: ZERO ,
309
+ witness : Witness :: new ( ) ,
310
+ } ) ;
311
+ witness_weight += 1 + 73 + 34 ;
312
+ #[ cfg( feature = "grind_signatures" ) ]
313
+ { witness_weight -= 1 ; } // Guarantees a low R signature
314
+ input_value += output. value ;
315
+ }
316
+ }
317
+ if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; }
318
+ }
319
+ let mut tx = Transaction {
320
+ version : 2 ,
321
+ lock_time : locktime. unwrap_or ( PackedLockTime :: ZERO ) ,
322
+ input,
323
+ output : outputs,
324
+ } ;
325
+ let expected_max_weight =
326
+ transaction_utils:: maybe_add_change_output ( & mut tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script) ?;
327
+
328
+ let psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( ) ) . collect :: < Vec < _ > > ( ) ;
329
+ let psbt = PartiallySignedTransaction {
330
+ inputs : psbt_inputs,
331
+ outputs : vec ! [ Default :: default ( ) ; tx. output. len( ) ] ,
332
+ unsigned_tx : tx,
333
+ xpub : Default :: default ( ) ,
334
+ version : 0 ,
335
+ proprietary : Default :: default ( ) ,
336
+ unknown : Default :: default ( ) ,
337
+ } ;
338
+ Ok ( ( psbt, expected_max_weight) )
339
+ }
340
+ }
341
+
221
342
/// A trait to handle Lightning channel key material without concretizing the channel type or
222
343
/// the signature mechanism.
223
344
pub trait ChannelSigner {
@@ -1171,97 +1292,40 @@ impl KeysManager {
1171
1292
)
1172
1293
}
1173
1294
1174
- /// Creates a [`Transaction `] which spends the given descriptors to the given outputs, plus an
1175
- /// output to the given change destination (if sufficient change value remains). The
1176
- /// transaction will have a feerate, at least, of the given value .
1295
+ /// Signs the given [`PartiallySignedTransaction `] which spends the given [`SpendableOutputDescriptor`]s.
1296
+ /// The resulting inputs will be finalized and the PSBT will be ready for broadcast if there
1297
+ /// are no other inputs that need signing .
1177
1298
///
1178
- /// Returns `Err(())` if the output value is greater than the input value minus required fee,
1179
- /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
1180
- /// does not match the one we can spend.
1181
- ///
1182
- /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
1299
+ /// Returns `Err(())` if the PSBT is missing a descriptor or if we fail to sign.
1183
1300
///
1184
1301
/// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
1185
1302
/// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
1186
- pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
1187
- let mut input = Vec :: new ( ) ;
1188
- let mut input_value = 0 ;
1189
- let mut witness_weight = 0 ;
1190
- let mut output_set = HashSet :: with_capacity ( descriptors. len ( ) ) ;
1191
- for outp in descriptors {
1192
- match outp {
1193
- SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
1194
- input. push ( TxIn {
1195
- previous_output : descriptor. outpoint . into_bitcoin_outpoint ( ) ,
1196
- script_sig : Script :: new ( ) ,
1197
- sequence : Sequence :: ZERO ,
1198
- witness : Witness :: new ( ) ,
1199
- } ) ;
1200
- witness_weight += StaticPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ;
1201
- #[ cfg( feature = "grind_signatures" ) ]
1202
- { witness_weight -= 1 ; } // Guarantees a low R signature
1203
- input_value += descriptor. output . value ;
1204
- if !output_set. insert ( descriptor. outpoint ) { return Err ( ( ) ) ; }
1205
- } ,
1206
- SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
1207
- input. push ( TxIn {
1208
- previous_output : descriptor. outpoint . into_bitcoin_outpoint ( ) ,
1209
- script_sig : Script :: new ( ) ,
1210
- sequence : Sequence ( descriptor. to_self_delay as u32 ) ,
1211
- witness : Witness :: new ( ) ,
1212
- } ) ;
1213
- witness_weight += DelayedPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ;
1214
- #[ cfg( feature = "grind_signatures" ) ]
1215
- { witness_weight -= 1 ; } // Guarantees a low R signature
1216
- input_value += descriptor. output . value ;
1217
- if !output_set. insert ( descriptor. outpoint ) { return Err ( ( ) ) ; }
1218
- } ,
1219
- SpendableOutputDescriptor :: StaticOutput { ref outpoint, ref output } => {
1220
- input. push ( TxIn {
1221
- previous_output : outpoint. into_bitcoin_outpoint ( ) ,
1222
- script_sig : Script :: new ( ) ,
1223
- sequence : Sequence :: ZERO ,
1224
- witness : Witness :: new ( ) ,
1225
- } ) ;
1226
- witness_weight += 1 + 73 + 34 ;
1227
- #[ cfg( feature = "grind_signatures" ) ]
1228
- { witness_weight -= 1 ; } // Guarantees a low R signature
1229
- input_value += output. value ;
1230
- if !output_set. insert ( * outpoint) { return Err ( ( ) ) ; }
1231
- }
1232
- }
1233
- if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; }
1234
- }
1235
- let mut spend_tx = Transaction {
1236
- version : 2 ,
1237
- lock_time : PackedLockTime ( 0 ) ,
1238
- input,
1239
- output : outputs,
1240
- } ;
1241
- let expected_max_weight =
1242
- transaction_utils:: maybe_add_change_output ( & mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script) ?;
1243
-
1303
+ pub fn sign_spendable_outputs_psbt < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , psbt : & mut PartiallySignedTransaction , secp_ctx : & Secp256k1 < C > ) -> Result < ( ) , ( ) > {
1244
1304
let mut keys_cache: Option < ( InMemorySigner , [ u8 ; 32 ] ) > = None ;
1245
- let mut input_idx = 0 ;
1246
1305
for outp in descriptors {
1247
1306
match outp {
1248
1307
SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor) => {
1308
+ let input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output == descriptor. outpoint . into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?;
1249
1309
if keys_cache. is_none ( ) || keys_cache. as_ref ( ) . unwrap ( ) . 1 != descriptor. channel_keys_id {
1250
1310
keys_cache = Some ( (
1251
1311
self . derive_channel_keys ( descriptor. channel_value_satoshis , & descriptor. channel_keys_id ) ,
1252
1312
descriptor. channel_keys_id ) ) ;
1253
1313
}
1254
- spend_tx. input [ input_idx] . witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_counterparty_payment_input ( & spend_tx, input_idx, & descriptor, & secp_ctx) ?) ;
1314
+ let witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_counterparty_payment_input ( & psbt. unsigned_tx , input_idx, & descriptor, & secp_ctx) ?) ;
1315
+ psbt. inputs [ input_idx] . final_script_witness = Some ( witness) ;
1255
1316
} ,
1256
1317
SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor) => {
1318
+ let input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output == descriptor. outpoint . into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?;
1257
1319
if keys_cache. is_none ( ) || keys_cache. as_ref ( ) . unwrap ( ) . 1 != descriptor. channel_keys_id {
1258
1320
keys_cache = Some ( (
1259
1321
self . derive_channel_keys ( descriptor. channel_value_satoshis , & descriptor. channel_keys_id ) ,
1260
1322
descriptor. channel_keys_id ) ) ;
1261
1323
}
1262
- spend_tx. input [ input_idx] . witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_dynamic_p2wsh_input ( & spend_tx, input_idx, & descriptor, & secp_ctx) ?) ;
1324
+ let witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_dynamic_p2wsh_input ( & psbt. unsigned_tx , input_idx, & descriptor, & secp_ctx) ?) ;
1325
+ psbt. inputs [ input_idx] . final_script_witness = Some ( witness) ;
1263
1326
} ,
1264
- SpendableOutputDescriptor :: StaticOutput { ref output, .. } => {
1327
+ SpendableOutputDescriptor :: StaticOutput { ref outpoint, ref output } => {
1328
+ let input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output == outpoint. into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?;
1265
1329
let derivation_idx = if output. script_pubkey == self . destination_script {
1266
1330
1
1267
1331
} else {
@@ -1288,17 +1352,42 @@ impl KeysManager {
1288
1352
1289
1353
if payment_script != output. script_pubkey { return Err ( ( ) ) ; } ;
1290
1354
1291
- let sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & spend_tx ) . segwit_signature_hash( input_idx, & witness_script, output. value, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
1355
+ let sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & psbt . unsigned_tx ) . segwit_signature_hash( input_idx, & witness_script, output. value, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
1292
1356
let sig = sign_with_aux_rand ( secp_ctx, & sighash, & secret. private_key , & self ) ;
1293
1357
let mut sig_ser = sig. serialize_der ( ) . to_vec ( ) ;
1294
1358
sig_ser. push ( EcdsaSighashType :: All as u8 ) ;
1295
- spend_tx . input [ input_idx ] . witness . push ( sig_ser ) ;
1296
- spend_tx . input [ input_idx] . witness . push ( pubkey . inner . serialize ( ) . to_vec ( ) ) ;
1359
+ let witness = Witness :: from_vec ( vec ! [ sig_ser , pubkey . inner . serialize ( ) . to_vec ( ) ] ) ;
1360
+ psbt . inputs [ input_idx] . final_script_witness = Some ( witness ) ;
1297
1361
} ,
1298
1362
}
1299
- input_idx += 1 ;
1300
1363
}
1301
1364
1365
+ Ok ( ( ) )
1366
+ }
1367
+
1368
+ /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
1369
+ /// output to the given change destination (if sufficient change value remains). The
1370
+ /// transaction will have a feerate, at least, of the given value.
1371
+ ///
1372
+ /// The `locktime` argument is used to set the transaction's locktime. If `None`, the
1373
+ /// transaction will have a locktime of 0. It it recommended to set this to the current block
1374
+ /// height to avoid fee sniping, unless you have some specific reason to use a different
1375
+ /// locktime.
1376
+ ///
1377
+ /// Returns `Err(())` if the output value is greater than the input value minus required fee,
1378
+ /// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
1379
+ /// does not match the one we can spend.
1380
+ ///
1381
+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
1382
+ ///
1383
+ /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
1384
+ /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
1385
+ pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , locktime : Option < PackedLockTime > , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
1386
+ let ( mut psbt, expected_max_weight) = SpendableOutputDescriptor :: create_spendable_outputs_psbt ( descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime) ?;
1387
+ self . sign_spendable_outputs_psbt ( descriptors, & mut psbt, secp_ctx) ?;
1388
+
1389
+ let spend_tx = psbt. extract_tx ( ) ;
1390
+
1302
1391
debug_assert ! ( expected_max_weight >= spend_tx. weight( ) ) ;
1303
1392
// Note that witnesses with a signature vary somewhat in size, so allow
1304
1393
// `expected_max_weight` to overshoot by up to 3 bytes per input.
@@ -1512,8 +1601,8 @@ impl PhantomKeysManager {
1512
1601
}
1513
1602
1514
1603
/// See [`KeysManager::spend_spendable_outputs`] for documentation on this method.
1515
- pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
1516
- self . inner . spend_spendable_outputs ( descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, secp_ctx)
1604
+ pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ & SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , locktime : Option < PackedLockTime > , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
1605
+ self . inner . spend_spendable_outputs ( descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime , secp_ctx)
1517
1606
}
1518
1607
1519
1608
/// See [`KeysManager::derive_channel_keys`] for documentation on this method.
0 commit comments