@@ -33,11 +33,15 @@ use bitcoin::{EcdsaSigHashType, Script};
3333use bitcoin:: util:: taproot:: { self , ControlBlock , LeafVersion , TapLeafHash } ;
3434use descriptor;
3535use interpreter;
36+ use miniscript:: iter:: PkPkh ;
3637use miniscript:: limits:: SEQUENCE_LOCKTIME_DISABLE_FLAG ;
3738use miniscript:: satisfy:: { After , Older } ;
3839use Preimage32 ;
3940use Satisfier ;
40- use { Descriptor , DescriptorPublicKey , DescriptorTrait , MiniscriptKey , ToPublicKey , TranslatePk2 } ;
41+ use {
42+ Descriptor , DescriptorPublicKey , DescriptorTrait , MiniscriptKey , ToPublicKey , TranslatePk ,
43+ TranslatePk2 ,
44+ } ;
4145
4246mod finalizer;
4347
@@ -872,6 +876,12 @@ pub trait PsbtInputExt {
872876 /// Note that his method doesn't check that the `witness_utxo` or `non_witness_utxo` is
873877 /// consistent with the descriptor. To do that see [`update_input_with_descriptor`].
874878 ///
879+ /// ## Return value
880+ ///
881+ /// For convenience, this returns the concrete descriptor that is computed internally to fill
882+ /// out the PSBT input fields. If you are checking the validity of `witness_utxo` or
883+ /// `non_witness_utxo` yourself you should check the `script_pubkey` against it.
884+ ///
875885 /// [`update_input_with_descriptor`]: PsbtExt::update_input_with_descriptor
876886 fn update_with_descriptor_unchecked (
877887 & mut self ,
@@ -889,48 +899,75 @@ impl PsbtInputExt for psbt::Input {
889899
890900 let derived = if let Descriptor :: Tr ( _) = & descriptor {
891901 // have to use a RefCell because we can't pass FnMut to translate_pk2
892- let tap_key_origins = RefCell :: new ( BTreeMap :: new ( ) ) ;
893- let derived = descriptor. translate_pk2 ( |xpk| {
894- let derived = xpk. derive_public_key ( & secp) ?;
895- tap_key_origins. borrow_mut ( ) . insert (
896- derived. to_x_only_pubkey ( ) ,
902+ let mut hash_lookup = BTreeMap :: new ( ) ;
903+ let derived = descriptor. translate_pk (
904+ |xpk| xpk. derive_public_key ( & secp) ,
905+ |xpk| {
906+ let xonly = xpk. derive_public_key ( & secp) ?. to_x_only_pubkey ( ) ;
907+ let hash = xonly. to_pubkeyhash ( ) ;
908+ hash_lookup. insert ( hash, xonly) ;
909+ Ok ( hash)
910+ } ,
911+ ) ?;
912+
913+ // NOTE: they will both always be Tr
914+ if let ( Descriptor :: Tr ( tr_derived) , Descriptor :: Tr ( tr_xpk) ) = ( & derived, descriptor) {
915+ let spend_info = tr_derived. spend_info ( ) ;
916+ let ik_derived = spend_info. internal_key ( ) ;
917+ let ik_xpk = tr_xpk. internal_key ( ) ;
918+ self . tap_internal_key = Some ( ik_derived) ;
919+ self . tap_merkle_root = spend_info. merkle_root ( ) ;
920+ self . tap_key_origins . insert (
921+ ik_derived,
897922 (
898- vec ! [ /* we'll populate this in the next loop */ ] ,
899- ( xpk . master_fingerprint ( ) , xpk . full_derivation_path ( ) ) ,
923+ vec ! [ ] ,
924+ ( ik_xpk . master_fingerprint ( ) , ik_xpk . full_derivation_path ( ) ) ,
900925 ) ,
901926 ) ;
902- Ok ( derived)
903- } ) ?;
904927
905- let mut tap_key_origins = tap_key_origins. into_inner ( ) ;
906-
907- // NOTE: the derived descriptor will always be Tr
908- if let Descriptor :: Tr ( tr) = & derived {
909- let spend_info = tr. spend_info ( ) ;
910- for ( _depth, ms) in tr. iter_scripts ( ) {
911- let leaf_script = ( ms. encode ( ) , LeafVersion :: TapScript ) ;
928+ for ( ( _depth_der, ms_derived) , ( _depth, ms) ) in
929+ tr_derived. iter_scripts ( ) . zip ( tr_xpk. iter_scripts ( ) )
930+ {
931+ debug_assert_eq ! ( _depth_der, _depth) ;
932+ let leaf_script = ( ms_derived. encode ( ) , LeafVersion :: TapScript ) ;
912933 let tapleaf_hash = TapLeafHash :: from_script ( & leaf_script. 0 , leaf_script. 1 ) ;
913934 let control_block = spend_info
914935 . control_block ( & leaf_script)
915936 . expect ( "Control block must exist in script map for every known leaf" ) ;
916937 self . tap_scripts . insert ( control_block, leaf_script) ;
917938
918- for pk in ms. iter_pk ( ) {
919- if let Some ( ( tapleaf_hashes, _) ) =
920- tap_key_origins. get_mut ( & pk. to_x_only_pubkey ( ) )
921- {
922- // To avoid duplication when the same key is in the same leaf more than
923- // once. (even though I think this is usually not allowed)
924- if tapleaf_hashes. last ( ) != Some ( & tapleaf_hash) {
925- tapleaf_hashes. push ( tapleaf_hash)
939+ for ( pk_pkh_derived, pk_pkh_xpk) in
940+ ms_derived. iter_pk_pkh ( ) . zip ( ms. iter_pk_pkh ( ) )
941+ {
942+ let ( xonly, xpk) = match ( pk_pkh_derived, pk_pkh_xpk) {
943+ ( PkPkh :: PlainPubkey ( pk) , PkPkh :: PlainPubkey ( xpk) ) => {
944+ ( pk. to_x_only_pubkey ( ) , xpk)
926945 }
927- }
946+ ( PkPkh :: HashedPubkey ( hash) , PkPkh :: HashedPubkey ( xpk) ) => (
947+ hash_lookup
948+ . get ( & hash)
949+ . expect ( "translate_pk inserted an entry for every hash" )
950+ . clone ( ) ,
951+ xpk,
952+ ) ,
953+ _ => unreachable ! ( "the iterators work in the same order" ) ,
954+ } ;
955+
956+ self . tap_key_origins
957+ . entry ( xonly)
958+ . and_modify ( |( tapleaf_hashes, _) | {
959+ if tapleaf_hashes. last ( ) != Some ( & tapleaf_hash) {
960+ tapleaf_hashes. push ( tapleaf_hash) ;
961+ }
962+ } )
963+ . or_insert_with ( || {
964+ (
965+ vec ! [ tapleaf_hash] ,
966+ ( xpk. master_fingerprint ( ) , xpk. full_derivation_path ( ) ) ,
967+ )
968+ } ) ;
928969 }
929970 }
930-
931- self . tap_internal_key = Some ( spend_info. internal_key ( ) ) ;
932- self . tap_merkle_root = spend_info. merkle_root ( ) ;
933- self . tap_key_origins = tap_key_origins;
934971 }
935972
936973 derived
@@ -944,6 +981,7 @@ impl PsbtInputExt for psbt::Input {
944981 ) ;
945982 Ok ( derived)
946983 } ) ?;
984+
947985 self . bip32_derivation = bip32_derivation. into_inner ( ) ;
948986
949987 match & derived {
0 commit comments