@@ -22,6 +22,7 @@ use std::convert::From;
2222use std:: marker:: PhantomData ;
2323use std:: { cmp, error, f64, fmt, mem} ;
2424
25+ use miniscript:: context:: SigType ;
2526use miniscript:: limits:: MAX_PUBKEYS_PER_MULTISIG ;
2627use miniscript:: types:: { self , ErrorKind , ExtData , Property , Type } ;
2728use miniscript:: ScriptContext ;
@@ -994,18 +995,34 @@ where
994995 } )
995996 . collect ( ) ;
996997
997- if key_vec. len ( ) == subs. len ( ) && subs. len ( ) <= MAX_PUBKEYS_PER_MULTISIG {
998- insert_wrap ! ( AstElemExt :: terminal( Terminal :: Multi ( k, key_vec) ) ) ;
999- }
1000- // Not a threshold, it's always more optimal to translate it to and()s as we save the
1001- // resulting threshold check (N EQUAL) in any case.
1002- else if k == subs. len ( ) {
1003- let mut policy = subs. first ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
1004- for sub in & subs[ 1 ..] {
1005- policy = Concrete :: And ( vec ! [ sub. clone( ) , policy] ) ;
998+ match Ctx :: sig_type ( ) {
999+ SigType :: Schnorr => {
1000+ if key_vec. len ( ) == subs. len ( ) {
1001+ insert_wrap ! ( AstElemExt :: terminal( Terminal :: MultiA ( k, key_vec) ) )
1002+ } else if k == subs. len ( ) {
1003+ let mut policy = subs. first ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
1004+ for sub in & subs[ 1 ..] {
1005+ policy = Concrete :: And ( vec ! [ sub. clone( ) , policy] ) ;
1006+ }
1007+
1008+ ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1009+ }
1010+ }
1011+ SigType :: Ecdsa => {
1012+ if key_vec. len ( ) == subs. len ( ) && subs. len ( ) <= MAX_PUBKEYS_PER_MULTISIG {
1013+ insert_wrap ! ( AstElemExt :: terminal( Terminal :: Multi ( k, key_vec) ) ) ;
1014+ }
1015+ // Not a threshold, it's always more optimal to translate it to and()s as we save the
1016+ // resulting threshold check (N EQUAL) in any case.
1017+ else if k == subs. len ( ) {
1018+ let mut policy = subs. first ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
1019+ for sub in & subs[ 1 ..] {
1020+ policy = Concrete :: And ( vec ! [ sub. clone( ) , policy] ) ;
1021+ }
1022+
1023+ ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1024+ }
10061025 }
1007-
1008- ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
10091026 }
10101027
10111028 // FIXME: Should we also optimize thresh(1, subs) ?
@@ -1168,7 +1185,7 @@ mod tests {
11681185
11691186 use miniscript:: { satisfy, Legacy , Segwitv0 } ;
11701187 use policy:: Liftable ;
1171- use script_num_size;
1188+ use { script_num_size, Tap } ;
11721189
11731190 type SPolicy = Concrete < String > ;
11741191 type BPolicy = Concrete < bitcoin:: PublicKey > ;
@@ -1554,6 +1571,17 @@ mod tests {
15541571 ) )
15551572 ) ;
15561573 }
1574+
1575+ #[ test]
1576+ fn compile_tr_thresh ( ) {
1577+ for k in 1 ..4 {
1578+ let small_thresh: Concrete < String > =
1579+ policy_str ! ( "{}" , & format!( "thresh({},pk(B),pk(C),pk(D))" , k) ) ;
1580+ let small_thresh_ms: Miniscript < String , Tap > = small_thresh. compile ( ) . unwrap ( ) ;
1581+ let small_thresh_ms_expected: Miniscript < String , Tap > = ms_str ! ( "multi_a({},B,C,D)" , k) ;
1582+ assert_eq ! ( small_thresh_ms, small_thresh_ms_expected) ;
1583+ }
1584+ }
15571585}
15581586
15591587#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments