@@ -36,15 +36,13 @@ mod bare;
3636mod iter;
3737mod segwitv0;
3838mod sh;
39- mod sortedmulti;
4039mod tr;
4140
4241// Descriptor Exports
4342pub use self :: bare:: { Bare , Pkh } ;
4443pub use self :: iter:: PkIter ;
45- pub use self :: segwitv0:: { Wpkh , Wsh , WshInner } ;
44+ pub use self :: segwitv0:: { Wpkh , Wsh } ;
4645pub use self :: sh:: { Sh , ShInner } ;
47- pub use self :: sortedmulti:: SortedMultiVec ;
4846pub use self :: tr:: {
4947 TapTree , TapTreeDepthError , TapTreeIter , TapTreeIterItem , Tr , TrSpendInfo , TrSpendInfoIter ,
5048 TrSpendInfoIterItem ,
@@ -256,18 +254,11 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
256254 Descriptor :: Pkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
257255 Descriptor :: Wpkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
258256 Descriptor :: Sh ( ref sh) => match * sh. as_inner ( ) {
259- ShInner :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
260- WshInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
261- WshInner :: Ms ( ref ms) => PkIter :: from_miniscript_segwit ( ms) ,
262- } ,
257+ ShInner :: Wsh ( ref wsh) => PkIter :: from_miniscript_segwit ( wsh. as_inner ( ) ) ,
263258 ShInner :: Wpkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
264- ShInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
265259 ShInner :: Ms ( ref ms) => PkIter :: from_miniscript_legacy ( ms) ,
266260 } ,
267- Descriptor :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
268- WshInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
269- WshInner :: Ms ( ref ms) => PkIter :: from_miniscript_segwit ( ms) ,
270- } ,
261+ Descriptor :: Wsh ( ref wsh) => PkIter :: from_miniscript_segwit ( wsh. as_inner ( ) ) ,
271262 Descriptor :: Tr ( ref tr) => PkIter :: from_tr ( tr) ,
272263 }
273264 }
@@ -313,18 +304,29 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
313304 Descriptor :: Pkh ( ref _pkh) => DescriptorType :: Pkh ,
314305 Descriptor :: Wpkh ( ref _wpkh) => DescriptorType :: Wpkh ,
315306 Descriptor :: Sh ( ref sh) => match sh. as_inner ( ) {
316- ShInner :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
317- WshInner :: SortedMulti ( ref _smv) => DescriptorType :: ShWshSortedMulti ,
318- WshInner :: Ms ( ref _ms) => DescriptorType :: ShWsh ,
319- } ,
307+ ShInner :: Wsh ( ref wsh) => {
308+ if let Terminal :: SortedMulti ( ..) = wsh. as_inner ( ) . node {
309+ DescriptorType :: ShWshSortedMulti
310+ } else {
311+ DescriptorType :: ShWsh
312+ }
313+ }
320314 ShInner :: Wpkh ( ref _wpkh) => DescriptorType :: ShWpkh ,
321- ShInner :: SortedMulti ( ref _smv) => DescriptorType :: ShSortedMulti ,
322- ShInner :: Ms ( ref _ms) => DescriptorType :: Sh ,
323- } ,
324- Descriptor :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
325- WshInner :: SortedMulti ( ref _smv) => DescriptorType :: WshSortedMulti ,
326- WshInner :: Ms ( ref _ms) => DescriptorType :: Wsh ,
315+ ShInner :: Ms ( ref ms) => {
316+ if let Terminal :: SortedMulti ( ..) = ms. node {
317+ DescriptorType :: ShSortedMulti
318+ } else {
319+ DescriptorType :: Sh
320+ }
321+ }
327322 } ,
323+ Descriptor :: Wsh ( ref wsh) => {
324+ if let Terminal :: SortedMulti ( ..) = wsh. as_inner ( ) . node {
325+ DescriptorType :: WshSortedMulti
326+ } else {
327+ DescriptorType :: Wsh
328+ }
329+ }
328330 Descriptor :: Tr ( ref _tr) => DescriptorType :: Tr ,
329331 }
330332 }
@@ -1208,6 +1210,7 @@ mod tests {
12081210
12091211 use super :: { checksum, * } ;
12101212 use crate :: hex_script;
1213+ use crate :: miniscript:: context:: ScriptContextError ;
12111214 #[ cfg( feature = "compiler" ) ]
12121215 use crate :: policy;
12131216
@@ -1257,7 +1260,7 @@ mod tests {
12571260 StdDescriptor :: from_str( "sh(sortedmulti)" )
12581261 . unwrap_err( )
12591262 . to_string( ) ,
1260- "sortedmulti must have at least 1 children, but found 0 "
1263+ "expected threshold, found terminal "
12611264 ) ; //issue 202
12621265 assert_eq ! (
12631266 StdDescriptor :: from_str( & format!( "sh(sortedmulti(2,{}))" , & TEST_PK [ 3 ..69 ] ) )
@@ -2884,4 +2887,26 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
28842887 let definite: Result < Descriptor < DefiniteDescriptorKey > , _ > = desc. try_into ( ) ;
28852888 assert ! ( matches!( definite, Err ( NonDefiniteKeyError :: Wildcard ) ) ) ;
28862889 }
2890+
2891+ #[ test]
2892+ fn too_many_pubkeys_for_p2sh ( ) {
2893+ // Arbitrary 65-byte public key (66 with length prefix).
2894+ let pk = PublicKey :: from_str (
2895+ "0400232a2acfc9b43fa89f1b4f608fde335d330d7114f70ea42bfb4a41db368a3e3be6934a4097dd25728438ef73debb1f2ffdb07fec0f18049df13bdc5285dc5b" ,
2896+ )
2897+ . unwrap ( ) ;
2898+
2899+ // This is legal for CHECKMULTISIG, but the 8 keys consume the whole 520 bytes
2900+ // allowed by P2SH, meaning that the full script goes over the limit.
2901+ let thresh = Threshold :: new ( 2 , vec ! [ pk; 8 ] ) . expect ( "the thresh is ok.." ) ;
2902+ let script = Miniscript :: < _ , Legacy > :: sortedmulti ( thresh) . encode ( ) ;
2903+ let res = Miniscript :: < _ , Legacy > :: decode ( & script) ;
2904+
2905+ let error = res. expect_err ( "decoding should err" ) ;
2906+
2907+ match error {
2908+ Error :: ContextError ( ScriptContextError :: MaxRedeemScriptSizeExceeded { .. } ) => { } // ok
2909+ other => panic ! ( "unexpected error: {:?}" , other) ,
2910+ }
2911+ }
28872912}
0 commit comments