@@ -26,7 +26,7 @@ use crate::miniscript::{Legacy, Miniscript, Segwitv0};
26
26
use crate :: prelude:: * ;
27
27
use crate :: {
28
28
expression, hash256, miniscript, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier ,
29
- ToPublicKey , TranslatePk , Translator ,
29
+ ToPublicKey , TranslateErr , TranslatePk , Translator ,
30
30
} ;
31
31
32
32
mod bare;
@@ -177,8 +177,8 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
177
177
}
178
178
179
179
/// 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) ? ) )
182
182
}
183
183
184
184
/// Create a new Wpkh descriptor
@@ -519,7 +519,7 @@ where
519
519
type Output = Descriptor < Q > ;
520
520
521
521
/// 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 > >
523
523
where
524
524
T : Translator < P , Q , E > ,
525
525
{
@@ -582,6 +582,7 @@ impl Descriptor<DescriptorPublicKey> {
582
582
translate_hash_clone ! ( DescriptorPublicKey , DescriptorPublicKey , ConversionError ) ;
583
583
}
584
584
self . translate_pk ( & mut Derivator ( index) )
585
+ . map_err ( |e| e. expect_translator_err ( "No Context errors while translating" ) )
585
586
}
586
587
587
588
#[ deprecated( note = "use at_derivation_index instead" ) ]
@@ -694,9 +695,12 @@ impl Descriptor<DescriptorPublicKey> {
694
695
}
695
696
696
697
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
+ } ) ?;
700
704
701
705
Ok ( ( descriptor, keymap_pk. 0 ) )
702
706
}
@@ -823,49 +827,15 @@ impl Descriptor<DescriptorPublicKey> {
823
827
824
828
for ( i, desc) in descriptors. iter_mut ( ) . enumerate ( ) {
825
829
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" ) ) ?;
827
833
}
828
834
829
835
Ok ( descriptors)
830
836
}
831
837
}
832
838
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
-
869
839
impl Descriptor < DefiniteDescriptorKey > {
870
840
/// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
871
841
/// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a
@@ -909,8 +879,11 @@ impl Descriptor<DefiniteDescriptorKey> {
909
879
translate_hash_clone ! ( DefiniteDescriptorKey , bitcoin:: PublicKey , ConversionError ) ;
910
880
}
911
881
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
+ }
914
887
}
915
888
}
916
889
@@ -944,10 +917,6 @@ impl_from_str!(
944
917
expression:: FromTree :: from_tree( & top)
945
918
} ?;
946
919
947
- if desc. multipath_length_mismatch( ) {
948
- return Err ( Error :: MultipathDescLenMismatch ) ;
949
- }
950
-
951
920
Ok ( desc)
952
921
}
953
922
) ;
@@ -1297,7 +1266,7 @@ mod tests {
1297
1266
) ;
1298
1267
assert_eq ! ( bare. unsigned_script_sig( ) , bitcoin:: ScriptBuf :: new( ) ) ;
1299
1268
1300
- let pkh = Descriptor :: new_pkh ( pk) ;
1269
+ let pkh = Descriptor :: new_pkh ( pk) . unwrap ( ) ;
1301
1270
pkh. satisfy ( & mut txin, & satisfier) . expect ( "satisfaction" ) ;
1302
1271
assert_eq ! (
1303
1272
txin,
@@ -1992,7 +1961,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1992
1961
// We can parse a multipath descriptors, and make it into separate single-path descriptors.
1993
1962
let desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))" ) . unwrap ( ) ;
1994
1963
assert ! ( desc. is_multipath( ) ) ;
1995
- assert ! ( !desc. multipath_length_mismatch( ) ) ;
1996
1964
assert_eq ! ( desc. into_single_descriptors( ) . unwrap( ) , vec![
1997
1965
Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))" ) . unwrap( ) ,
1998
1966
Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))" ) . unwrap( ) ,
@@ -2002,7 +1970,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2002
1970
// Even if only one of the keys is multipath.
2003
1971
let desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap ( ) ;
2004
1972
assert ! ( desc. is_multipath( ) ) ;
2005
- assert ! ( !desc. multipath_length_mismatch( ) ) ;
2006
1973
assert_eq ! ( desc. into_single_descriptors( ) . unwrap( ) , vec![
2007
1974
Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap( ) ,
2008
1975
Descriptor :: from_str( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap( ) ,
@@ -2011,7 +1978,6 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2011
1978
// We can detect regular single-path descriptors.
2012
1979
let notmulti_desc = Descriptor :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))" ) . unwrap ( ) ;
2013
1980
assert ! ( !notmulti_desc. is_multipath( ) ) ;
2014
- assert ! ( !notmulti_desc. multipath_length_mismatch( ) ) ;
2015
1981
assert_eq ! (
2016
1982
notmulti_desc. clone( ) . into_single_descriptors( ) . unwrap( ) ,
2017
1983
vec![ notmulti_desc]
@@ -2021,4 +1987,54 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2021
1987
Descriptor :: < DescriptorPublicKey > :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))" ) . unwrap_err ( ) ;
2022
1988
Descriptor :: < DescriptorPublicKey > :: from_str ( "wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))" ) . unwrap_err ( ) ;
2023
1989
}
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
+ }
2024
2040
}
0 commit comments