@@ -33,11 +33,15 @@ use bitcoin::{EcdsaSigHashType, Script};
33
33
use bitcoin:: util:: taproot:: { self , ControlBlock , LeafVersion , TapLeafHash } ;
34
34
use descriptor;
35
35
use interpreter;
36
+ use miniscript:: iter:: PkPkh ;
36
37
use miniscript:: limits:: SEQUENCE_LOCKTIME_DISABLE_FLAG ;
37
38
use miniscript:: satisfy:: { After , Older } ;
38
39
use Preimage32 ;
39
40
use Satisfier ;
40
- use { Descriptor , DescriptorPublicKey , DescriptorTrait , MiniscriptKey , ToPublicKey , TranslatePk2 } ;
41
+ use {
42
+ Descriptor , DescriptorPublicKey , DescriptorTrait , MiniscriptKey , ToPublicKey , TranslatePk ,
43
+ TranslatePk2 ,
44
+ } ;
41
45
42
46
mod finalizer;
43
47
@@ -872,6 +876,12 @@ pub trait PsbtInputExt {
872
876
/// Note that his method doesn't check that the `witness_utxo` or `non_witness_utxo` is
873
877
/// consistent with the descriptor. To do that see [`update_input_with_descriptor`].
874
878
///
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
+ ///
875
885
/// [`update_input_with_descriptor`]: PsbtExt::update_input_with_descriptor
876
886
fn update_with_descriptor_unchecked (
877
887
& mut self ,
@@ -889,48 +899,75 @@ impl PsbtInputExt for psbt::Input {
889
899
890
900
let derived = if let Descriptor :: Tr ( _) = & descriptor {
891
901
// 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,
897
922
(
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 ( ) ) ,
900
925
) ,
901
926
) ;
902
- Ok ( derived)
903
- } ) ?;
904
927
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 ) ;
912
933
let tapleaf_hash = TapLeafHash :: from_script ( & leaf_script. 0 , leaf_script. 1 ) ;
913
934
let control_block = spend_info
914
935
. control_block ( & leaf_script)
915
936
. expect ( "Control block must exist in script map for every known leaf" ) ;
916
937
self . tap_scripts . insert ( control_block, leaf_script) ;
917
938
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)
926
945
}
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
+ } ) ;
928
969
}
929
970
}
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;
934
971
}
935
972
936
973
derived
@@ -944,6 +981,7 @@ impl PsbtInputExt for psbt::Input {
944
981
) ;
945
982
Ok ( derived)
946
983
} ) ?;
984
+
947
985
self . bip32_derivation = bip32_derivation. into_inner ( ) ;
948
986
949
987
match & derived {
0 commit comments