@@ -24,6 +24,7 @@ use std::marker::PhantomData;
2424use std:: sync:: Arc ;
2525use std:: { cmp, error, f64, fmt, hash, mem} ;
2626
27+ use crate :: miniscript:: context:: SigType ;
2728use crate :: miniscript:: limits:: MAX_PUBKEYS_PER_MULTISIG ;
2829use crate :: miniscript:: types:: { self , ErrorKind , ExtData , Property , Type } ;
2930use crate :: miniscript:: ScriptContext ;
@@ -987,18 +988,23 @@ where
987988 } )
988989 . collect ( ) ;
989990
990- if key_vec. len ( ) == subs. len ( ) && subs. len ( ) <= MAX_PUBKEYS_PER_MULTISIG {
991- insert_wrap ! ( AstElemExt :: terminal( Terminal :: Multi ( k, key_vec) ) ) ;
992- }
993- // Not a threshold, it's always more optimal to translate it to and()s as we save the
994- // resulting threshold check (N EQUAL) in any case.
995- else if k == subs. len ( ) {
996- let mut policy = subs. first ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
997- for sub in & subs[ 1 ..] {
998- policy = Concrete :: And ( vec ! [ sub. clone( ) , policy] ) ;
991+ match Ctx :: sig_type ( ) {
992+ SigType :: Schnorr if key_vec. len ( ) == subs. len ( ) => {
993+ insert_wrap ! ( AstElemExt :: terminal( Terminal :: MultiA ( k, key_vec) ) )
994+ }
995+ SigType :: Ecdsa
996+ if key_vec. len ( ) == subs. len ( ) && subs. len ( ) <= MAX_PUBKEYS_PER_MULTISIG =>
997+ {
998+ insert_wrap ! ( AstElemExt :: terminal( Terminal :: Multi ( k, key_vec) ) )
999999 }
1000+ _ if k == subs. len ( ) => {
1001+ let mut it = subs. iter ( ) ;
1002+ let mut policy = it. next ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
1003+ policy = it. fold ( policy, |acc, pol| Concrete :: And ( vec ! [ acc, pol. clone( ) ] ) ) ;
10001004
1001- ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1005+ ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1006+ }
1007+ _ => { }
10021008 }
10031009
10041010 // FIXME: Should we also optimize thresh(1, subs) ?
@@ -1549,6 +1555,17 @@ mod tests {
15491555 ) )
15501556 ) ;
15511557 }
1558+
1559+ #[ test]
1560+ fn compile_tr_thresh ( ) {
1561+ for k in 1 ..4 {
1562+ let small_thresh: Concrete < String > =
1563+ policy_str ! ( "{}" , & format!( "thresh({},pk(B),pk(C),pk(D))" , k) ) ;
1564+ let small_thresh_ms: Miniscript < String , Tap > = small_thresh. compile ( ) . unwrap ( ) ;
1565+ let small_thresh_ms_expected: Miniscript < String , Tap > = ms_str ! ( "multi_a({},B,C,D)" , k) ;
1566+ assert_eq ! ( small_thresh_ms, small_thresh_ms_expected) ;
1567+ }
1568+ }
15521569}
15531570
15541571#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments