1919//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
2020//!
2121
22+ use util:: { script_is_v1_tr, witness_size} ;
23+
2224use super :: { sanity_check, Psbt } ;
2325use super :: { Error , InputError , PsbtInputSatisfier } ;
2426use bitcoin:: blockdata:: witness:: Witness ;
2527use bitcoin:: secp256k1:: { self , Secp256k1 } ;
28+ use bitcoin:: util:: taproot:: LeafVersion ;
2629use bitcoin:: { self , PublicKey , Script } ;
2730use descriptor:: DescriptorTrait ;
2831use interpreter;
2932use Descriptor ;
3033use Miniscript ;
31- use { BareCtx , Legacy , Segwitv0 } ;
34+ use Satisfier ;
35+ use XOnlyKey ;
36+ use { BareCtx , Legacy , Segwitv0 , Tap } ;
37+
38+ // Satisfy the taproot descriptor. It is not possible to infer the complete
39+ // descriptor from psbt because the information about all the scripts might not
40+ // be present. Also, currently the spec does not support hidden branches, so
41+ // inferring a descriptor is not possible
42+ fn construct_tap_witness (
43+ spk : & Script ,
44+ sat : & PsbtInputSatisfier ,
45+ allow_mall : bool ,
46+ ) -> Result < Vec < Vec < u8 > > , InputError > {
47+ assert ! ( script_is_v1_tr( & spk) ) ;
48+
49+ // try the script spend path first
50+ if let Some ( sig) = <PsbtInputSatisfier as Satisfier < XOnlyKey > >:: lookup_tap_key_spend_sig ( sat) {
51+ return Ok ( vec ! [ sig. to_vec( ) ] ) ;
52+ }
53+ // Next script spends
54+ let ( mut min_wit, mut min_wit_len) = ( None , None ) ;
55+ if let Some ( block_map) =
56+ <PsbtInputSatisfier as Satisfier < XOnlyKey > >:: lookup_tap_control_block_map ( sat)
57+ {
58+ for ( control_block, ( script, ver) ) in block_map {
59+ if * ver != LeafVersion :: default ( ) {
60+ // We don't know how to satisfy non default version scripts yet
61+ continue ;
62+ }
63+ let ms = match Miniscript :: < XOnlyKey , Tap > :: parse_insane ( script) {
64+ Ok ( ms) => ms,
65+ Err ( ..) => continue , // try another script
66+ } ;
67+ let mut wit = if allow_mall {
68+ match ms. satisfy_malleable ( sat) {
69+ Ok ( ms) => ms,
70+ Err ( ..) => continue ,
71+ }
72+ } else {
73+ match ms. satisfy ( sat) {
74+ Ok ( ms) => ms,
75+ Err ( ..) => continue ,
76+ }
77+ } ;
78+ wit. push ( ms. encode ( ) . into_bytes ( ) ) ;
79+ wit. push ( control_block. serialize ( ) ) ;
80+ let wit_len = Some ( witness_size ( & wit) ) ;
81+ if min_wit_len. is_some ( ) && wit_len > min_wit_len {
82+ continue ;
83+ } else {
84+ // store the minimum
85+ min_wit = Some ( wit) ;
86+ min_wit_len = wit_len;
87+ }
88+ }
89+ min_wit. ok_or ( InputError :: CouldNotSatisfyTr )
90+ } else {
91+ // No control blocks found
92+ Err ( InputError :: CouldNotSatisfyTr )
93+ }
94+ }
95+
3296// Get the scriptpubkey for the psbt input
3397fn get_scriptpubkey ( psbt : & Psbt , index : usize ) -> Result < & Script , InputError > {
3498 let script_pubkey;
@@ -299,16 +363,28 @@ pub fn finalize_helper<C: secp256k1::Verification>(
299363
300364 // Actually construct the witnesses
301365 for index in 0 ..psbt. inputs . len ( ) {
302- // Get a descriptor for this input
303- let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
366+ let ( witness, script_sig) = {
367+ let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
368+ let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
304369
305- //generate the satisfaction witness and scriptsig
306- let ( witness, script_sig) = if !allow_mall {
307- desc. get_satisfaction ( PsbtInputSatisfier :: new ( & psbt, index) )
308- } else {
309- desc. get_satisfaction_mall ( PsbtInputSatisfier :: new ( & psbt, index) )
310- }
311- . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?;
370+ if script_is_v1_tr ( spk) {
371+ // Deal with tr case separately, unfortunately we cannot infer the full descriptor for Tr
372+ let wit = construct_tap_witness ( spk, & sat, allow_mall)
373+ . map_err ( |e| Error :: InputError ( e, index) ) ?;
374+ ( wit, Script :: new ( ) )
375+ } else {
376+ // Get a descriptor for this input.
377+ let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
378+
379+ //generate the satisfaction witness and scriptsig
380+ if !allow_mall {
381+ desc. get_satisfaction ( PsbtInputSatisfier :: new ( & psbt, index) )
382+ } else {
383+ desc. get_satisfaction_mall ( PsbtInputSatisfier :: new ( & psbt, index) )
384+ }
385+ . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?
386+ }
387+ } ;
312388
313389 let input = & mut psbt. inputs [ index] ;
314390 //Fill in the satisfactions
@@ -323,12 +399,24 @@ pub fn finalize_helper<C: secp256k1::Verification>(
323399 Some ( witness)
324400 } ;
325401 //reset everything
326- input. redeem_script = None ;
327- input. partial_sigs . clear ( ) ;
328- input. sighash_type = None ;
329- input. redeem_script = None ;
330- input. bip32_derivation . clear ( ) ;
331- input. witness_script = None ;
402+ input. partial_sigs . clear ( ) ; // 0x02
403+ input. sighash_type = None ; // 0x03
404+ input. redeem_script = None ; // 0x04
405+ input. witness_script = None ; // 0x05
406+ input. bip32_derivation . clear ( ) ; // 0x05
407+ // finalized witness 0x06 and 0x07 are not clear
408+ // 0x09 Proof of reserves not yet supported
409+ input. ripemd160_preimages . clear ( ) ; // 0x0a
410+ input. sha256_preimages . clear ( ) ; // 0x0b
411+ input. hash160_preimages . clear ( ) ; // 0x0c
412+ input. hash256_preimages . clear ( ) ; // 0x0d
413+ // psbt v2 fields till 0x012 not supported
414+ input. tap_key_sig = None ; // 0x013
415+ input. tap_script_sigs . clear ( ) ; // 0x014
416+ input. tap_scripts . clear ( ) ; // 0x015
417+ input. tap_key_origins . clear ( ) ; // 0x16
418+ input. tap_internal_key = None ; // x017
419+ input. tap_merkle_root = None ; // 0x018
332420 }
333421 // Double check everything with the interpreter
334422 // This only checks whether the script will be executed
0 commit comments