@@ -22,6 +22,7 @@ use std::convert::From;
22
22
use std:: marker:: PhantomData ;
23
23
use std:: { cmp, error, f64, fmt, mem} ;
24
24
25
+ use miniscript:: context:: SigType ;
25
26
use miniscript:: limits:: MAX_PUBKEYS_PER_MULTISIG ;
26
27
use miniscript:: types:: { self , ErrorKind , ExtData , Property , Type } ;
27
28
use miniscript:: ScriptContext ;
@@ -994,18 +995,34 @@ where
994
995
} )
995
996
. collect ( ) ;
996
997
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
+ }
1006
1025
}
1007
-
1008
- ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1009
1026
}
1010
1027
1011
1028
// FIXME: Should we also optimize thresh(1, subs) ?
@@ -1168,7 +1185,7 @@ mod tests {
1168
1185
1169
1186
use miniscript:: { satisfy, Legacy , Segwitv0 } ;
1170
1187
use policy:: Liftable ;
1171
- use script_num_size;
1188
+ use { script_num_size, Tap } ;
1172
1189
1173
1190
type SPolicy = Concrete < String > ;
1174
1191
type BPolicy = Concrete < bitcoin:: PublicKey > ;
@@ -1554,6 +1571,17 @@ mod tests {
1554
1571
) )
1555
1572
) ;
1556
1573
}
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
+ }
1557
1585
}
1558
1586
1559
1587
#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments