19
19
//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
20
20
//!
21
21
22
+ use util:: { script_is_v1_tr, witness_size} ;
23
+
22
24
use super :: { sanity_check, Psbt } ;
23
25
use super :: { Error , InputError , PsbtInputSatisfier } ;
24
26
use bitcoin:: secp256k1:: { self , Secp256k1 } ;
27
+ use bitcoin:: util:: taproot:: LeafVersion ;
25
28
use bitcoin:: { self , PublicKey , Script } ;
26
29
use descriptor:: DescriptorTrait ;
27
30
use interpreter;
28
31
use Descriptor ;
29
32
use Miniscript ;
30
- use { BareCtx , Legacy , Segwitv0 } ;
33
+ use Satisfier ;
34
+ use XOnlyPubKey ;
35
+ use { BareCtx , Legacy , Segwitv0 , Tap } ;
36
+
37
+ // Satisfy the taproot descriptor. It is not possible to infer the complete
38
+ // descriptor from psbt because the information about all the scripts might not
39
+ // be present. Also, currently the spec does not support hidden branches, so
40
+ // inferring a descriptor is not possible
41
+ fn construct_tap_witness (
42
+ spk : & Script ,
43
+ sat : & PsbtInputSatisfier ,
44
+ ) -> Result < Vec < Vec < u8 > > , InputError > {
45
+ assert ! ( script_is_v1_tr( & spk) ) ;
46
+
47
+ // try the script spend path first
48
+ if let Some ( sig) = <PsbtInputSatisfier as Satisfier < XOnlyPubKey > >:: lookup_tap_key_spend_sig ( sat)
49
+ {
50
+ return Ok ( vec ! [ sig. serialize( ) ] ) ;
51
+ }
52
+ // Next script spends
53
+ let ( mut min_wit, mut min_wit_len) = ( None , None ) ;
54
+ if let Some ( block_map) =
55
+ <PsbtInputSatisfier as Satisfier < XOnlyPubKey > >:: lookup_tap_control_block_map ( sat)
56
+ {
57
+ for ( control_block, ( script, ver) ) in block_map {
58
+ if * ver != LeafVersion :: default ( ) {
59
+ // We don't know how to satisfy non default version scripts yet
60
+ continue ;
61
+ }
62
+ let ms = match Miniscript :: < XOnlyPubKey , Tap > :: parse_insane ( script) {
63
+ Ok ( ms) => ms,
64
+ Err ( ..) => continue , // try another script
65
+ } ;
66
+ let mut wit = match ms. satisfy ( sat) {
67
+ Ok ( ms) => ms,
68
+ Err ( ..) => continue ,
69
+ } ;
70
+ wit. push ( ms. encode ( ) . into_bytes ( ) ) ;
71
+ wit. push ( control_block. serialize ( ) ) ;
72
+ let wit_len = Some ( witness_size ( & wit) ) ;
73
+ if min_wit_len. is_some ( ) && wit_len > min_wit_len {
74
+ continue ;
75
+ } else {
76
+ // store the minimum
77
+ min_wit = Some ( wit) ;
78
+ min_wit_len = wit_len;
79
+ }
80
+ }
81
+ min_wit. ok_or ( InputError :: CouldNotSatisfyTr )
82
+ } else {
83
+ // No control blocks found
84
+ Err ( InputError :: CouldNotSatisfyTr )
85
+ }
86
+ }
87
+
31
88
// Get the scriptpubkey for the psbt input
32
89
fn get_scriptpubkey ( psbt : & Psbt , index : usize ) -> Result < & Script , InputError > {
33
90
let script_pubkey;
@@ -301,13 +358,21 @@ pub fn finalize<C: secp256k1::Verification>(
301
358
302
359
// Actually construct the witnesses
303
360
for index in 0 ..psbt. inputs . len ( ) {
304
- // Get a descriptor for this input
305
- let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e , index ) ) ? ;
361
+ let spk = get_scriptpubkey ( psbt , index ) . map_err ( |e| Error :: InputError ( e , index ) ) ? ;
362
+ let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
306
363
307
- //generate the satisfaction witness and scriptsig
308
- let ( witness, script_sig) = desc
309
- . get_satisfaction ( PsbtInputSatisfier :: new ( & psbt, index) )
310
- . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?;
364
+ let ( witness, script_sig) = if script_is_v1_tr ( spk) {
365
+ // Deal with tr case separately, unfortunately we cannot infer the full descriptor for Tr
366
+ let wit = construct_tap_witness ( spk, & sat) . map_err ( |e| Error :: InputError ( e, index) ) ?;
367
+ ( wit, Script :: new ( ) )
368
+ } else {
369
+ // Get a descriptor for this input.
370
+ let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
371
+
372
+ //generate the satisfaction witness and scriptsig
373
+ desc. get_satisfaction ( & sat)
374
+ . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?
375
+ } ;
311
376
312
377
let input = & mut psbt. inputs [ index] ;
313
378
//Fill in the satisfactions
@@ -322,12 +387,24 @@ pub fn finalize<C: secp256k1::Verification>(
322
387
Some ( witness)
323
388
} ;
324
389
//reset everything
325
- input. redeem_script = None ;
326
- input. partial_sigs . clear ( ) ;
327
- input. sighash_type = None ;
328
- input. redeem_script = None ;
329
- input. bip32_derivation . clear ( ) ;
330
- input. witness_script = None ;
390
+ input. partial_sigs . clear ( ) ; // 0x02
391
+ input. sighash_type = None ; // 0x03
392
+ input. redeem_script = None ; // 0x04
393
+ input. witness_script = None ; // 0x05
394
+ input. bip32_derivation . clear ( ) ; // 0x05
395
+ // finalized witness 0x06 and 0x07 are not clear
396
+ // 0x09 Proof of reserves not yet supported
397
+ input. ripemd160_preimages . clear ( ) ; // 0x0a
398
+ input. sha256_preimages . clear ( ) ; // 0x0b
399
+ input. hash160_preimages . clear ( ) ; // 0x0c
400
+ input. hash256_preimages . clear ( ) ; // 0x0d
401
+ // psbt v2 fields till 0x012 not supported
402
+ input. tap_key_sig = None ; // 0x013
403
+ input. tap_script_sigs . clear ( ) ; // 0x014
404
+ input. tap_scripts . clear ( ) ; // 0x015
405
+ input. tap_key_origins . clear ( ) ; // 0x16
406
+ input. tap_internal_key = None ; // x017
407
+ input. tap_merkle_root = None ; // 0x018
331
408
}
332
409
// Double check everything with the interpreter
333
410
// This only checks whether the script will be executed
0 commit comments