@@ -844,10 +844,14 @@ where
844844 }
845845 Concrete :: And ( ref subs) => {
846846 assert_eq ! ( subs. len( ) , 2 , "and takes 2 args" ) ;
847- let mut left = best_compilations ( policy_cache, & subs[ 0 ] , sat_prob, dissat_prob) ?;
848- let mut right = best_compilations ( policy_cache, & subs[ 1 ] , sat_prob, dissat_prob) ?;
849- let mut q_zero_right = best_compilations ( policy_cache, & subs[ 1 ] , sat_prob, None ) ?;
850- let mut q_zero_left = best_compilations ( policy_cache, & subs[ 0 ] , sat_prob, None ) ?;
847+ let mut left =
848+ best_compilations ( policy_cache, subs[ 0 ] . as_ref ( ) , sat_prob, dissat_prob) ?;
849+ let mut right =
850+ best_compilations ( policy_cache, subs[ 1 ] . as_ref ( ) , sat_prob, dissat_prob) ?;
851+ let mut q_zero_right =
852+ best_compilations ( policy_cache, subs[ 1 ] . as_ref ( ) , sat_prob, None ) ?;
853+ let mut q_zero_left =
854+ best_compilations ( policy_cache, subs[ 0 ] . as_ref ( ) , sat_prob, None ) ?;
851855
852856 compile_binary ! ( & mut left, & mut right, [ 1.0 , 1.0 ] , Terminal :: AndB ) ;
853857 compile_binary ! ( & mut right, & mut left, [ 1.0 , 1.0 ] , Terminal :: AndB ) ;
@@ -871,48 +875,56 @@ where
871875 let rw = subs[ 1 ] . 0 as f64 / total;
872876
873877 //and-or
874- if let ( Concrete :: And ( x) , _) = ( & subs[ 0 ] . 1 , & subs[ 1 ] . 1 ) {
878+ if let ( Concrete :: And ( x) , _) = ( subs[ 0 ] . 1 . as_ref ( ) , subs[ 1 ] . 1 . as_ref ( ) ) {
875879 let mut a1 = best_compilations (
876880 policy_cache,
877- & x[ 0 ] ,
881+ x[ 0 ] . as_ref ( ) ,
878882 lw * sat_prob,
879883 Some ( dissat_prob. unwrap_or ( 0 as f64 ) + rw * sat_prob) ,
880884 ) ?;
881- let mut a2 = best_compilations ( policy_cache, & x[ 0 ] , lw * sat_prob, None ) ?;
885+ let mut a2 = best_compilations ( policy_cache, x[ 0 ] . as_ref ( ) , lw * sat_prob, None ) ?;
882886
883887 let mut b1 = best_compilations (
884888 policy_cache,
885- & x[ 1 ] ,
889+ x[ 1 ] . as_ref ( ) ,
886890 lw * sat_prob,
887891 Some ( dissat_prob. unwrap_or ( 0 as f64 ) + rw * sat_prob) ,
888892 ) ?;
889- let mut b2 = best_compilations ( policy_cache, & x[ 1 ] , lw * sat_prob, None ) ?;
893+ let mut b2 = best_compilations ( policy_cache, x[ 1 ] . as_ref ( ) , lw * sat_prob, None ) ?;
890894
891- let mut c =
892- best_compilations ( policy_cache, & subs[ 1 ] . 1 , rw * sat_prob, dissat_prob) ?;
895+ let mut c = best_compilations (
896+ policy_cache,
897+ subs[ 1 ] . 1 . as_ref ( ) ,
898+ rw * sat_prob,
899+ dissat_prob,
900+ ) ?;
893901
894902 compile_tern ! ( & mut a1, & mut b2, & mut c, [ lw, rw] ) ;
895903 compile_tern ! ( & mut b1, & mut a2, & mut c, [ lw, rw] ) ;
896904 } ;
897- if let ( _, Concrete :: And ( x) ) = ( & subs[ 0 ] . 1 , & subs[ 1 ] . 1 ) {
905+ if let ( _, Concrete :: And ( x) ) = ( & subs[ 0 ] . 1 . as_ref ( ) , subs[ 1 ] . 1 . as_ref ( ) ) {
898906 let mut a1 = best_compilations (
899907 policy_cache,
900- & x[ 0 ] ,
908+ x[ 0 ] . as_ref ( ) ,
901909 rw * sat_prob,
902910 Some ( dissat_prob. unwrap_or ( 0 as f64 ) + lw * sat_prob) ,
903911 ) ?;
904- let mut a2 = best_compilations ( policy_cache, & x[ 0 ] , rw * sat_prob, None ) ?;
912+ let mut a2 = best_compilations ( policy_cache, x[ 0 ] . as_ref ( ) , rw * sat_prob, None ) ?;
905913
906914 let mut b1 = best_compilations (
907915 policy_cache,
908- & x[ 1 ] ,
916+ x[ 1 ] . as_ref ( ) ,
909917 rw * sat_prob,
910918 Some ( dissat_prob. unwrap_or ( 0 as f64 ) + lw * sat_prob) ,
911919 ) ?;
912- let mut b2 = best_compilations ( policy_cache, & x[ 1 ] , rw * sat_prob, None ) ?;
920+ let mut b2 = best_compilations ( policy_cache, x[ 1 ] . as_ref ( ) , rw * sat_prob, None ) ?;
913921
914- let mut c =
915- best_compilations ( policy_cache, & subs[ 0 ] . 1 , lw * sat_prob, dissat_prob) ?;
922+ let mut c = best_compilations (
923+ policy_cache,
924+ subs[ 0 ] . 1 . as_ref ( ) ,
925+ lw * sat_prob,
926+ dissat_prob,
927+ ) ?;
916928
917929 compile_tern ! ( & mut a1, & mut b2, & mut c, [ rw, lw] ) ;
918930 compile_tern ! ( & mut b1, & mut a2, & mut c, [ rw, lw] ) ;
@@ -931,12 +943,22 @@ where
931943 let mut r_comp = vec ! [ ] ;
932944
933945 for dissat_prob in dissat_probs ( rw) . iter ( ) {
934- let l = best_compilations ( policy_cache, & subs[ 0 ] . 1 , lw * sat_prob, * dissat_prob) ?;
946+ let l = best_compilations (
947+ policy_cache,
948+ subs[ 0 ] . 1 . as_ref ( ) ,
949+ lw * sat_prob,
950+ * dissat_prob,
951+ ) ?;
935952 l_comp. push ( l) ;
936953 }
937954
938955 for dissat_prob in dissat_probs ( lw) . iter ( ) {
939- let r = best_compilations ( policy_cache, & subs[ 1 ] . 1 , rw * sat_prob, * dissat_prob) ?;
956+ let r = best_compilations (
957+ policy_cache,
958+ subs[ 1 ] . 1 . as_ref ( ) ,
959+ rw * sat_prob,
960+ * dissat_prob,
961+ ) ?;
940962 r_comp. push ( r) ;
941963 }
942964
@@ -971,8 +993,8 @@ where
971993 let sp = sat_prob * k_over_n;
972994 //Expressions must be dissatisfiable
973995 let dp = Some ( dissat_prob. unwrap_or ( 0 as f64 ) + ( 1.0 - k_over_n) * sat_prob) ;
974- let be = best ( types:: Base :: B , policy_cache, ast, sp, dp) ?;
975- let bw = best ( types:: Base :: W , policy_cache, ast, sp, dp) ?;
996+ let be = best ( types:: Base :: B , policy_cache, ast. as_ref ( ) , sp, dp) ?;
997+ let bw = best ( types:: Base :: W , policy_cache, ast. as_ref ( ) , sp, dp) ?;
976998
977999 let diff = be. cost_1d ( sp, dp) - bw. cost_1d ( sp, dp) ;
9781000 best_es. push ( ( be. comp_ext_data , be) ) ;
@@ -1005,7 +1027,7 @@ where
10051027 let key_vec: Vec < Pk > = subs
10061028 . iter ( )
10071029 . filter_map ( |s| {
1008- if let Concrete :: Key ( ref pk) = * s {
1030+ if let Concrete :: Key ( ref pk) = s . as_ref ( ) {
10091031 Some ( pk. clone ( ) )
10101032 } else {
10111033 None
@@ -1025,9 +1047,11 @@ where
10251047 _ if k == subs. len ( ) => {
10261048 let mut it = subs. iter ( ) ;
10271049 let mut policy = it. next ( ) . expect ( "No sub policy in thresh() ?" ) . clone ( ) ;
1028- policy = it. fold ( policy, |acc, pol| Concrete :: And ( vec ! [ acc, pol. clone( ) ] ) ) ;
1050+ policy = it. fold ( policy, |acc, pol| {
1051+ Concrete :: And ( vec ! [ acc, pol. clone( ) ] ) . into ( )
1052+ } ) ;
10291053
1030- ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1054+ ret = best_compilations ( policy_cache, policy. as_ref ( ) , sat_prob, dissat_prob) ?;
10311055 }
10321056 _ => { }
10331057 }
@@ -1239,8 +1263,11 @@ mod tests {
12391263 fn compile_timelocks ( ) {
12401264 // artificially create a policy that is problematic and try to compile
12411265 let pol: SPolicy = Concrete :: And ( vec ! [
1242- Concrete :: Key ( "A" . to_string( ) ) ,
1243- Concrete :: And ( vec![ Concrete :: after( 9 ) , Concrete :: after( 1000_000_000 ) ] ) ,
1266+ Arc :: new( Concrete :: Key ( "A" . to_string( ) ) ) ,
1267+ Arc :: new( Concrete :: And ( vec![
1268+ Arc :: new( Concrete :: after( 9 ) ) ,
1269+ Arc :: new( Concrete :: after( 1000_000_000 ) ) ,
1270+ ] ) ) ,
12441271 ] ) ;
12451272 assert ! ( pol. compile:: <Segwitv0 >( ) . is_err( ) ) ;
12461273
@@ -1346,13 +1373,22 @@ mod tests {
13461373
13471374 // Liquid policy
13481375 let policy: BPolicy = Concrete :: Or ( vec ! [
1349- ( 127 , Concrete :: Threshold ( 3 , key_pol[ 0 ..5 ] . to_owned( ) ) ) ,
1376+ (
1377+ 127 ,
1378+ Arc :: new( Concrete :: Threshold (
1379+ 3 ,
1380+ key_pol[ 0 ..5 ] . iter( ) . map( |p| ( p. clone( ) ) . into( ) ) . collect( ) ,
1381+ ) ) ,
1382+ ) ,
13501383 (
13511384 1 ,
1352- Concrete :: And ( vec![
1353- Concrete :: Older ( Sequence :: from_height( 10000 ) ) ,
1354- Concrete :: Threshold ( 2 , key_pol[ 5 ..8 ] . to_owned( ) ) ,
1355- ] ) ,
1385+ Arc :: new( Concrete :: And ( vec![
1386+ Arc :: new( Concrete :: Older ( Sequence :: from_height( 10000 ) ) ) ,
1387+ Arc :: new( Concrete :: Threshold (
1388+ 2 ,
1389+ key_pol[ 5 ..8 ] . iter( ) . map( |p| ( p. clone( ) ) . into( ) ) . collect( ) ,
1390+ ) ) ,
1391+ ] ) ) ,
13561392 ) ,
13571393 ] ) ;
13581394
@@ -1471,8 +1507,10 @@ mod tests {
14711507 // and to a ms thresh otherwise.
14721508 // k = 1 (or 2) does not compile, see https://github.com/rust-bitcoin/rust-miniscript/issues/114
14731509 for k in & [ 10 , 15 , 21 ] {
1474- let pubkeys: Vec < Concrete < bitcoin:: PublicKey > > =
1475- keys. iter ( ) . map ( |pubkey| Concrete :: Key ( * pubkey) ) . collect ( ) ;
1510+ let pubkeys: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys
1511+ . iter ( )
1512+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1513+ . collect ( ) ;
14761514 let big_thresh = Concrete :: Threshold ( * k, pubkeys) ;
14771515 let big_thresh_ms: SegwitMiniScript = big_thresh. compile ( ) . unwrap ( ) ;
14781516 if * k == 21 {
@@ -1499,18 +1537,18 @@ mod tests {
14991537 // or(thresh(52, [pubkey; 52]), thresh(52, [pubkey; 52])) results in a 3642-bytes long
15001538 // witness script with only 54 stack elements
15011539 let ( keys, _) = pubkeys_and_a_sig ( 104 ) ;
1502- let keys_a: Vec < Concrete < bitcoin:: PublicKey > > = keys[ ..keys. len ( ) / 2 ]
1540+ let keys_a: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys[ ..keys. len ( ) / 2 ]
15031541 . iter ( )
1504- . map ( |pubkey| Concrete :: Key ( * pubkey) )
1542+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
15051543 . collect ( ) ;
1506- let keys_b: Vec < Concrete < bitcoin:: PublicKey > > = keys[ keys. len ( ) / 2 ..]
1544+ let keys_b: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys[ keys. len ( ) / 2 ..]
15071545 . iter ( )
1508- . map ( |pubkey| Concrete :: Key ( * pubkey) )
1546+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
15091547 . collect ( ) ;
15101548
15111549 let thresh_res: Result < SegwitMiniScript , _ > = Concrete :: Or ( vec ! [
1512- ( 1 , Concrete :: Threshold ( keys_a. len( ) , keys_a) ) ,
1513- ( 1 , Concrete :: Threshold ( keys_b. len( ) , keys_b) ) ,
1550+ ( 1 , Arc :: new ( Concrete :: Threshold ( keys_a. len( ) , keys_a) ) ) ,
1551+ ( 1 , Arc :: new ( Concrete :: Threshold ( keys_b. len( ) , keys_b) ) ) ,
15141552 ] )
15151553 . compile ( ) ;
15161554 let script_size = thresh_res. clone ( ) . and_then ( |m| Ok ( m. script_size ( ) ) ) ;
@@ -1523,8 +1561,10 @@ mod tests {
15231561
15241562 // Hit the maximum witness stack elements limit
15251563 let ( keys, _) = pubkeys_and_a_sig ( 100 ) ;
1526- let keys: Vec < Concrete < bitcoin:: PublicKey > > =
1527- keys. iter ( ) . map ( |pubkey| Concrete :: Key ( * pubkey) ) . collect ( ) ;
1564+ let keys: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys
1565+ . iter ( )
1566+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1567+ . collect ( ) ;
15281568 let thresh_res: Result < SegwitMiniScript , _ > =
15291569 Concrete :: Threshold ( keys. len ( ) , keys) . compile ( ) ;
15301570 let n_elements = thresh_res
@@ -1542,8 +1582,10 @@ mod tests {
15421582 fn shared_limits ( ) {
15431583 // Test the maximum number of OPs with a 67-of-68 multisig
15441584 let ( keys, _) = pubkeys_and_a_sig ( 68 ) ;
1545- let keys: Vec < Concrete < bitcoin:: PublicKey > > =
1546- keys. iter ( ) . map ( |pubkey| Concrete :: Key ( * pubkey) ) . collect ( ) ;
1585+ let keys: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys
1586+ . iter ( )
1587+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1588+ . collect ( ) ;
15471589 let thresh_res: Result < SegwitMiniScript , _ > =
15481590 Concrete :: Threshold ( keys. len ( ) - 1 , keys) . compile ( ) ;
15491591 let ops_count = thresh_res. clone ( ) . and_then ( |m| Ok ( m. ext . ops . op_count ( ) ) ) ;
@@ -1555,8 +1597,10 @@ mod tests {
15551597 ) ;
15561598 // For legacy too..
15571599 let ( keys, _) = pubkeys_and_a_sig ( 68 ) ;
1558- let keys: Vec < Concrete < bitcoin:: PublicKey > > =
1559- keys. iter ( ) . map ( |pubkey| Concrete :: Key ( * pubkey) ) . collect ( ) ;
1600+ let keys: Vec < Arc < Concrete < bitcoin:: PublicKey > > > = keys
1601+ . iter ( )
1602+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1603+ . collect ( ) ;
15601604 let thresh_res = Concrete :: Threshold ( keys. len ( ) - 1 , keys) . compile :: < Legacy > ( ) ;
15611605 let ops_count = thresh_res. clone ( ) . and_then ( |m| Ok ( m. ext . ops . op_count ( ) ) ) ;
15621606 assert_eq ! (
@@ -1568,8 +1612,9 @@ mod tests {
15681612
15691613 // Test that we refuse to compile policies with duplicated keys
15701614 let ( keys, _) = pubkeys_and_a_sig ( 1 ) ;
1571- let key = Concrete :: Key ( keys[ 0 ] ) ;
1572- let res = Concrete :: Or ( vec ! [ ( 1 , key. clone( ) ) , ( 1 , key. clone( ) ) ] ) . compile :: < Segwitv0 > ( ) ;
1615+ let key = Arc :: new ( Concrete :: Key ( keys[ 0 ] ) ) ;
1616+ let res =
1617+ Concrete :: Or ( vec ! [ ( 1 , Arc :: clone( & key) ) , ( 1 , Arc :: clone( & key) ) ] ) . compile :: < Segwitv0 > ( ) ;
15731618 assert_eq ! (
15741619 res,
15751620 Err ( CompilerError :: PolicyError (
0 commit comments