@@ -26,7 +26,7 @@ use crate::miniscript::{Legacy, Miniscript, Segwitv0};
2626use crate :: prelude:: * ;
2727use crate :: {
2828 expression, hash256, miniscript, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier ,
29- ToPublicKey , TranslatePk , Translator ,
29+ ToPublicKey , TranslateErr , TranslatePk , Translator ,
3030} ;
3131
3232mod bare;
@@ -177,8 +177,8 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
177177 }
178178
179179 /// Create a new PkH descriptor
180- pub fn new_pkh ( pk : Pk ) -> Self {
181- Descriptor :: Pkh ( Pkh :: new ( pk) )
180+ pub fn new_pkh ( pk : Pk ) -> Result < Self , Error > {
181+ Ok ( Descriptor :: Pkh ( Pkh :: new ( pk) ? ) )
182182 }
183183
184184 /// Create a new Wpkh descriptor
@@ -519,7 +519,7 @@ where
519519 type Output = Descriptor < Q > ;
520520
521521 /// Converts a descriptor using abstract keys to one using specific keys.
522- fn translate_pk < T , E > ( & self , t : & mut T ) -> Result < Self :: Output , E >
522+ fn translate_pk < T , E > ( & self , t : & mut T ) -> Result < Self :: Output , TranslateErr < E > >
523523 where
524524 T : Translator < P , Q , E > ,
525525 {
@@ -582,6 +582,7 @@ impl Descriptor<DescriptorPublicKey> {
582582 translate_hash_clone ! ( DescriptorPublicKey , DescriptorPublicKey , ConversionError ) ;
583583 }
584584 self . translate_pk ( & mut Derivator ( index) )
585+ . map_err ( |e| e. expect_translator_err ( "No Context errors while translating" ) )
585586 }
586587
587588 #[ deprecated( note = "use at_derivation_index instead" ) ]
@@ -694,9 +695,12 @@ impl Descriptor<DescriptorPublicKey> {
694695 }
695696
696697 let descriptor = Descriptor :: < String > :: from_str ( s) ?;
697- let descriptor = descriptor
698- . translate_pk ( & mut keymap_pk)
699- . map_err ( |e| Error :: Unexpected ( e. to_string ( ) ) ) ?;
698+ let descriptor = descriptor. translate_pk ( & mut keymap_pk) . map_err ( |e| {
699+ Error :: Unexpected (
700+ e. expect_translator_err ( "No Outer context errors" )
701+ . to_string ( ) ,
702+ )
703+ } ) ?;
700704
701705 Ok ( ( descriptor, keymap_pk. 0 ) )
702706 }
@@ -823,49 +827,15 @@ impl Descriptor<DescriptorPublicKey> {
823827
824828 for ( i, desc) in descriptors. iter_mut ( ) . enumerate ( ) {
825829 let mut index_choser = IndexChoser ( i) ;
826- * desc = desc. translate_pk ( & mut index_choser) ?;
830+ * desc = desc
831+ . translate_pk ( & mut index_choser)
832+ . map_err ( |e| e. expect_translator_err ( "No Context errors possible" ) ) ?;
827833 }
828834
829835 Ok ( descriptors)
830836 }
831837}
832838
833- impl < Pk : MiniscriptKey > Descriptor < Pk > {
834- /// Whether this descriptor is a multipath descriptor that contains any 2 multipath keys
835- /// with a different number of derivation paths.
836- /// Such a descriptor is invalid according to BIP389.
837- pub fn multipath_length_mismatch ( & self ) -> bool {
838- // (Ab)use `for_each_key` to record the number of derivation paths a multipath key has.
839- #[ derive( PartialEq ) ]
840- enum MultipathLenChecker {
841- SinglePath ,
842- MultipathLen ( usize ) ,
843- LenMismatch ,
844- }
845-
846- let mut checker = MultipathLenChecker :: SinglePath ;
847- self . for_each_key ( |key| {
848- match key. num_der_paths ( ) {
849- 0 | 1 => { }
850- n => match checker {
851- MultipathLenChecker :: SinglePath => {
852- checker = MultipathLenChecker :: MultipathLen ( n) ;
853- }
854- MultipathLenChecker :: MultipathLen ( len) => {
855- if len != n {
856- checker = MultipathLenChecker :: LenMismatch ;
857- }
858- }
859- MultipathLenChecker :: LenMismatch => { }
860- } ,
861- }
862- true
863- } ) ;
864-
865- checker == MultipathLenChecker :: LenMismatch
866- }
867- }
868-
869839impl Descriptor < DefiniteDescriptorKey > {
870840 /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
871841 /// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a
@@ -909,8 +879,11 @@ impl Descriptor<DefiniteDescriptorKey> {
909879 translate_hash_clone ! ( DefiniteDescriptorKey , bitcoin:: PublicKey , ConversionError ) ;
910880 }
911881
912- let derived = self . translate_pk ( & mut Derivator ( secp) ) ?;
913- Ok ( derived)
882+ let derived = self . translate_pk ( & mut Derivator ( secp) ) ;
883+ match derived {
884+ Ok ( derived) => Ok ( derived) ,
885+ Err ( e) => Err ( e. expect_translator_err ( "No Context errors when deriving keys" ) ) ,
886+ }
914887 }
915888}
916889
@@ -944,10 +917,6 @@ impl_from_str!(
944917 expression:: FromTree :: from_tree( & top)
945918 } ?;
946919
947- if desc. multipath_length_mismatch( ) {
948- return Err ( Error :: MultipathDescLenMismatch ) ;
949- }
950-
951920 Ok ( desc)
952921 }
953922) ;
@@ -1297,7 +1266,7 @@ mod tests {
12971266 ) ;
12981267 assert_eq ! ( bare. unsigned_script_sig( ) , bitcoin:: ScriptBuf :: new( ) ) ;
12991268
1300- let pkh = Descriptor :: new_pkh ( pk) ;
1269+ let pkh = Descriptor :: new_pkh ( pk) . unwrap ( ) ;
13011270 pkh. satisfy ( & mut txin, & satisfier) . expect ( "satisfaction" ) ;
13021271 assert_eq ! (
13031272 txin,
@@ -1992,7 +1961,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
19921961 // We can parse a multipath descriptors, and make it into separate single-path descriptors.
19931962 let desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))" ) . unwrap ( ) ;
19941963 assert ! ( desc. is_multipath( ) ) ;
1995- assert ! ( !desc. multipath_length_mismatch( ) ) ;
19961964 assert_eq ! ( desc. into_single_descriptors( ) . unwrap( ) , vec![
19971965 Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))" ) . unwrap( ) ,
19981966 Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))" ) . unwrap( ) ,
@@ -2002,7 +1970,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
20021970 // Even if only one of the keys is multipath.
20031971 let desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap ( ) ;
20041972 assert ! ( desc. is_multipath( ) ) ;
2005- assert ! ( !desc. multipath_length_mismatch( ) ) ;
20061973 assert_eq ! ( desc. into_single_descriptors( ) . unwrap( ) , vec![
20071974 Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap( ) ,
20081975 Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap( ) ,
@@ -2011,7 +1978,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
20111978 // We can detect regular single-path descriptors.
20121979 let notmulti_desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap ( ) ;
20131980 assert ! ( !notmulti_desc. is_multipath( ) ) ;
2014- assert ! ( !notmulti_desc. multipath_length_mismatch( ) ) ;
20151981 assert_eq ! (
20161982 notmulti_desc. clone( ) . into_single_descriptors( ) . unwrap( ) ,
20171983 vec![ notmulti_desc]
@@ -2021,4 +1987,54 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
20211987 Descriptor :: < DescriptorPublicKey > :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))" ) . unwrap_err ( ) ;
20221988 Descriptor :: < DescriptorPublicKey > :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))" ) . unwrap_err ( ) ;
20231989 }
1990+
1991+ #[ test]
1992+ fn test_context_pks ( ) {
1993+ let comp_key = bitcoin:: PublicKey :: from_str (
1994+ "02015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
1995+ )
1996+ . unwrap ( ) ;
1997+ let x_only_key = bitcoin:: key:: XOnlyPublicKey :: from_str (
1998+ "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
1999+ )
2000+ . unwrap ( ) ;
2001+ let uncomp_key = bitcoin:: PublicKey :: from_str ( "04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4" ) . unwrap ( ) ;
2002+
2003+ type Desc = Descriptor < DescriptorPublicKey > ;
2004+
2005+ // Legacy tests, x-only keys are not supported
2006+ Desc :: from_str ( & format ! ( "sh(pk({}))" , comp_key) ) . unwrap ( ) ;
2007+ Desc :: from_str ( & format ! ( "sh(pk({}))" , uncomp_key) ) . unwrap ( ) ;
2008+ Desc :: from_str ( & format ! ( "sh(pk({}))" , x_only_key) ) . unwrap_err ( ) ;
2009+
2010+ // bare tests, x-only keys not supported
2011+ Desc :: from_str ( & format ! ( "pk({})" , comp_key) ) . unwrap ( ) ;
2012+ Desc :: from_str ( & format ! ( "pk({})" , uncomp_key) ) . unwrap ( ) ;
2013+ Desc :: from_str ( & format ! ( "pk({})" , x_only_key) ) . unwrap_err ( ) ;
2014+
2015+ // pkh tests, x-only keys not supported
2016+ Desc :: from_str ( & format ! ( "pkh({})" , comp_key) ) . unwrap ( ) ;
2017+ Desc :: from_str ( & format ! ( "pkh({})" , uncomp_key) ) . unwrap ( ) ;
2018+ Desc :: from_str ( & format ! ( "pkh({})" , x_only_key) ) . unwrap_err ( ) ;
2019+
2020+ // wpkh tests, uncompressed and x-only keys not supported
2021+ Desc :: from_str ( & format ! ( "wpkh({})" , comp_key) ) . unwrap ( ) ;
2022+ Desc :: from_str ( & format ! ( "wpkh({})" , uncomp_key) ) . unwrap_err ( ) ;
2023+ Desc :: from_str ( & format ! ( "wpkh({})" , x_only_key) ) . unwrap_err ( ) ;
2024+
2025+ // Segwitv0 tests, uncompressed and x-only keys not supported
2026+ Desc :: from_str ( & format ! ( "wsh(pk({}))" , comp_key) ) . unwrap ( ) ;
2027+ Desc :: from_str ( & format ! ( "wsh(pk({}))" , uncomp_key) ) . unwrap_err ( ) ;
2028+ Desc :: from_str ( & format ! ( "wsh(pk({}))" , x_only_key) ) . unwrap_err ( ) ;
2029+
2030+ // Tap tests, key path
2031+ Desc :: from_str ( & format ! ( "tr({})" , comp_key) ) . unwrap ( ) ;
2032+ Desc :: from_str ( & format ! ( "tr({})" , uncomp_key) ) . unwrap_err ( ) ;
2033+ Desc :: from_str ( & format ! ( "tr({})" , x_only_key) ) . unwrap ( ) ;
2034+
2035+ // Tap tests, script path
2036+ Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, comp_key) ) . unwrap ( ) ;
2037+ Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, uncomp_key) ) . unwrap_err ( ) ;
2038+ Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
2039+ }
20242040}
0 commit comments