@@ -28,6 +28,7 @@ use core::ops::Range;
2828use core:: str:: { self , FromStr } ;
2929
3030use bitcoin:: blockdata:: witness:: Witness ;
31+ use bitcoin:: hashes:: sha256;
3132use bitcoin:: util:: address:: WitnessVersion ;
3233use bitcoin:: { self , secp256k1, Address , Network , Script , TxIn } ;
3334use sync:: Arc ;
@@ -36,8 +37,8 @@ use self::checksum::verify_checksum;
3637use crate :: miniscript:: { Legacy , Miniscript , Segwitv0 } ;
3738use crate :: prelude:: * ;
3839use crate :: {
39- expression, miniscript, BareCtx , Error , ForEach , ForEachKey , MiniscriptKey , Satisfier ,
40- ToPublicKey , TranslatePk , TranslatePk2 ,
40+ expression, miniscript, BareCtx , Error , ForEach , ForEachKey , MiniscriptKey , PkTranslator ,
41+ Satisfier , ToPublicKey , TranslatePk , Translator ,
4142} ;
4243
4344mod bare;
@@ -475,25 +476,19 @@ where
475476 Q : MiniscriptKey ,
476477{
477478 type Output = Descriptor < Q > ;
479+
478480 /// Converts a descriptor using abstract keys to one using specific keys.
479- ///
480- /// # Panics
481- ///
482- /// If `fpk` returns an uncompressed key when converting to a Segwit descriptor.
483- /// To prevent this panic, ensure `fpk` returns an error in this case instead.
484- fn translate_pk < Fpk , Fpkh , E > ( & self , mut fpk : Fpk , mut fpkh : Fpkh ) -> Result < Descriptor < Q > , E >
481+ fn translate_pk < T , E > ( & self , t : & mut T ) -> Result < Self :: Output , E >
485482 where
486- Fpk : FnMut ( & P ) -> Result < Q , E > ,
487- Fpkh : FnMut ( & P :: Hash ) -> Result < Q :: Hash , E > ,
488- Q : MiniscriptKey ,
483+ T : Translator < P , Q , E > ,
489484 {
490485 let desc = match * self {
491- Descriptor :: Bare ( ref bare) => Descriptor :: Bare ( bare. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
492- Descriptor :: Pkh ( ref pk) => Descriptor :: Pkh ( pk. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
493- Descriptor :: Wpkh ( ref pk) => Descriptor :: Wpkh ( pk. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
494- Descriptor :: Sh ( ref sh) => Descriptor :: Sh ( sh. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
495- Descriptor :: Wsh ( ref wsh) => Descriptor :: Wsh ( wsh. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
496- Descriptor :: Tr ( ref tr) => Descriptor :: Tr ( tr. translate_pk ( & mut fpk , & mut fpkh ) ?) ,
486+ Descriptor :: Bare ( ref bare) => Descriptor :: Bare ( bare. translate_pk ( t ) ?) ,
487+ Descriptor :: Pkh ( ref pk) => Descriptor :: Pkh ( pk. translate_pk ( t ) ?) ,
488+ Descriptor :: Wpkh ( ref pk) => Descriptor :: Wpkh ( pk. translate_pk ( t ) ?) ,
489+ Descriptor :: Sh ( ref sh) => Descriptor :: Sh ( sh. translate_pk ( t ) ?) ,
490+ Descriptor :: Wsh ( ref wsh) => Descriptor :: Wsh ( wsh. translate_pk ( t ) ?) ,
491+ Descriptor :: Tr ( ref tr) => Descriptor :: Tr ( tr. translate_pk ( t ) ?) ,
497492 } ;
498493 Ok ( desc)
499494 }
@@ -529,7 +524,19 @@ impl Descriptor<DescriptorPublicKey> {
529524 /// In most cases, you would want to use [`Self::derived_descriptor`] directly to obtain
530525 /// a [`Descriptor<bitcoin::PublicKey>`]
531526 pub fn derive ( & self , index : u32 ) -> Descriptor < DerivedDescriptorKey > {
532- self . translate_pk2_infallible ( |pk| pk. clone ( ) . derive ( index) )
527+ struct Derivator ( u32 ) ;
528+
529+ impl PkTranslator < DescriptorPublicKey , DerivedDescriptorKey , ( ) > for Derivator {
530+ fn pk ( & mut self , pk : & DescriptorPublicKey ) -> Result < DerivedDescriptorKey , ( ) > {
531+ Ok ( pk. clone ( ) . derive ( self . 0 ) )
532+ }
533+
534+ fn pkh ( & mut self , pkh : & DescriptorPublicKey ) -> Result < DerivedDescriptorKey , ( ) > {
535+ Ok ( pkh. clone ( ) . derive ( self . 0 ) )
536+ }
537+ }
538+ self . translate_pk ( & mut Derivator ( index) )
539+ . expect ( "BIP 32 key index substitution cannot fail" )
533540 }
534541
535542 /// Derive a [`Descriptor`] with a concrete [`bitcoin::PublicKey`] at a given index
@@ -561,9 +568,28 @@ impl Descriptor<DescriptorPublicKey> {
561568 secp : & secp256k1:: Secp256k1 < C > ,
562569 index : u32 ,
563570 ) -> Result < Descriptor < bitcoin:: PublicKey > , ConversionError > {
564- let derived = self
565- . derive ( index)
566- . translate_pk2 ( |xpk| xpk. derive_public_key ( secp) ) ?;
571+ struct Derivator < ' a , C : secp256k1:: Verification > ( & ' a secp256k1:: Secp256k1 < C > ) ;
572+
573+ impl < ' a , C : secp256k1:: Verification >
574+ PkTranslator < DerivedDescriptorKey , bitcoin:: PublicKey , ConversionError >
575+ for Derivator < ' a , C >
576+ {
577+ fn pk (
578+ & mut self ,
579+ pk : & DerivedDescriptorKey ,
580+ ) -> Result < bitcoin:: PublicKey , ConversionError > {
581+ pk. derive_public_key ( & self . 0 )
582+ }
583+
584+ fn pkh (
585+ & mut self ,
586+ pkh : & DerivedDescriptorKey ,
587+ ) -> Result < bitcoin:: hashes:: hash160:: Hash , ConversionError > {
588+ Ok ( pkh. derive_public_key ( & self . 0 ) ?. to_pubkeyhash ( ) )
589+ }
590+ }
591+
592+ let derived = self . derive ( index) . translate_pk ( & mut Derivator ( secp) ) ?;
567593 Ok ( derived)
568594 }
569595
@@ -575,39 +601,79 @@ impl Descriptor<DescriptorPublicKey> {
575601 secp : & secp256k1:: Secp256k1 < C > ,
576602 s : & str ,
577603 ) -> Result < ( Descriptor < DescriptorPublicKey > , KeyMap ) , Error > {
578- let parse_key = |s : & String ,
579- key_map : & mut KeyMap |
580- -> Result < DescriptorPublicKey , DescriptorKeyParseError > {
604+ fn parse_key < C : secp256k1:: Signing > (
605+ s : & String ,
606+ key_map : & mut KeyMap ,
607+ secp : & secp256k1:: Secp256k1 < C > ,
608+ ) -> Result < DescriptorPublicKey , Error > {
581609 let ( public_key, secret_key) = match DescriptorSecretKey :: from_str ( s) {
582- Ok ( sk) => ( sk. to_public ( secp) ?, Some ( sk) ) ,
583- Err ( _) => ( DescriptorPublicKey :: from_str ( s) ?, None ) ,
610+ Ok ( sk) => (
611+ sk. to_public ( secp)
612+ . map_err ( |e| Error :: Unexpected ( e. to_string ( ) ) ) ?,
613+ Some ( sk) ,
614+ ) ,
615+ Err ( _) => (
616+ DescriptorPublicKey :: from_str ( s)
617+ . map_err ( |e| Error :: Unexpected ( e. to_string ( ) ) ) ?,
618+ None ,
619+ ) ,
584620 } ;
585621
586622 if let Some ( secret_key) = secret_key {
587623 key_map. insert ( public_key. clone ( ) , secret_key) ;
588624 }
589625
590626 Ok ( public_key)
591- } ;
627+ }
628+
629+ let mut keymap_pk = KeyMapWrapper ( HashMap :: new ( ) , secp) ;
592630
593- let mut keymap_pk = KeyMap :: new ( ) ;
594- let mut keymap_pkh = KeyMap :: new ( ) ;
631+ struct KeyMapWrapper < ' a , C : secp256k1:: Signing > ( KeyMap , & ' a secp256k1:: Secp256k1 < C > ) ;
632+
633+ impl < ' a , C : secp256k1:: Signing > Translator < String , DescriptorPublicKey , Error >
634+ for KeyMapWrapper < ' a , C >
635+ {
636+ fn pk ( & mut self , pk : & String ) -> Result < DescriptorPublicKey , Error > {
637+ parse_key ( pk, & mut self . 0 , self . 1 )
638+ }
639+
640+ fn pkh ( & mut self , pkh : & String ) -> Result < DescriptorPublicKey , Error > {
641+ parse_key ( pkh, & mut self . 0 , self . 1 )
642+ }
643+
644+ fn sha256 ( & mut self , sha256 : & String ) -> Result < sha256:: Hash , Error > {
645+ let hash =
646+ sha256:: Hash :: from_str ( sha256) . map_err ( |e| Error :: Unexpected ( e. to_string ( ) ) ) ?;
647+ Ok ( hash)
648+ }
649+ }
595650
596651 let descriptor = Descriptor :: < String > :: from_str ( s) ?;
597652 let descriptor = descriptor
598- . translate_pk (
599- |pk| parse_key ( pk, & mut keymap_pk) ,
600- |pkh| parse_key ( pkh, & mut keymap_pkh) ,
601- )
653+ . translate_pk ( & mut keymap_pk)
602654 . map_err ( |e| Error :: Unexpected ( e. to_string ( ) ) ) ?;
603655
604- keymap_pk. extend ( keymap_pkh. into_iter ( ) ) ;
605-
606- Ok ( ( descriptor, keymap_pk) )
656+ Ok ( ( descriptor, keymap_pk. 0 ) )
607657 }
608658
609659 /// Serialize a descriptor to string with its secret keys
610660 pub fn to_string_with_secret ( & self , key_map : & KeyMap ) -> String {
661+ struct KeyMapLookUp < ' a > ( & ' a KeyMap ) ;
662+
663+ impl < ' a > Translator < DescriptorPublicKey , String , ( ) > for KeyMapLookUp < ' a > {
664+ fn pk ( & mut self , pk : & DescriptorPublicKey ) -> Result < String , ( ) > {
665+ key_to_string ( pk, self . 0 )
666+ }
667+
668+ fn pkh ( & mut self , pkh : & DescriptorPublicKey ) -> Result < String , ( ) > {
669+ key_to_string ( pkh, self . 0 )
670+ }
671+
672+ fn sha256 ( & mut self , sha256 : & sha256:: Hash ) -> Result < String , ( ) > {
673+ Ok ( sha256. to_string ( ) )
674+ }
675+ }
676+
611677 fn key_to_string ( pk : & DescriptorPublicKey , key_map : & KeyMap ) -> Result < String , ( ) > {
612678 Ok ( match key_map. get ( pk) {
613679 Some ( secret) => secret. to_string ( ) ,
@@ -616,10 +682,7 @@ impl Descriptor<DescriptorPublicKey> {
616682 }
617683
618684 let descriptor = self
619- . translate_pk :: < _ , _ , ( ) > (
620- |pk| key_to_string ( pk, key_map) ,
621- |pkh| key_to_string ( pkh, key_map) ,
622- )
685+ . translate_pk ( & mut KeyMapLookUp ( key_map) )
623686 . expect ( "Translation to string cannot fail" ) ;
624687
625688 descriptor. to_string ( )
@@ -731,7 +794,7 @@ mod tests {
731794 use crate :: descriptor:: { DescriptorPublicKey , DescriptorSecretKey , DescriptorXKey , SinglePub } ;
732795 #[ cfg( feature = "compiler" ) ]
733796 use crate :: policy;
734- use crate :: { hex_script, Descriptor , DummyKey , Error , Miniscript , Satisfier , TranslatePk2 } ;
797+ use crate :: { hex_script, Descriptor , DummyKey , Error , Miniscript , Satisfier } ;
735798
736799 type StdDescriptor = Descriptor < PublicKey > ;
737800 const TEST_PK : & ' static str =
@@ -1468,19 +1531,14 @@ mod tests {
14681531 assert_eq ! ( desc_one. to_string( ) , raw_desc_one) ;
14691532 assert_eq ! ( desc_two. to_string( ) , raw_desc_two) ;
14701533
1471- // Derive a child in case the descriptor is ranged. If it's not this won't have any
1472- // effect
1473- let desc_one = desc_one. derive ( index) ;
1474- let desc_two = desc_two. derive ( index) ;
1475-
14761534 // Same address
14771535 let addr_one = desc_one
1478- . translate_pk2 ( |xpk| xpk . derive_public_key ( & secp_ctx) )
1536+ . derived_descriptor ( & secp_ctx, index )
14791537 . unwrap ( )
14801538 . address ( bitcoin:: Network :: Bitcoin )
14811539 . unwrap ( ) ;
14821540 let addr_two = desc_two
1483- . translate_pk2 ( |xpk| xpk . derive_public_key ( & secp_ctx) )
1541+ . derived_descriptor ( & secp_ctx, index )
14841542 . unwrap ( )
14851543 . address ( bitcoin:: Network :: Bitcoin )
14861544 . unwrap ( ) ;
0 commit comments