@@ -844,10 +844,14 @@ where
844
844
}
845
845
Concrete :: And ( ref subs) => {
846
846
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 ) ?;
851
855
852
856
compile_binary ! ( & mut left, & mut right, [ 1.0 , 1.0 ] , Terminal :: AndB ) ;
853
857
compile_binary ! ( & mut right, & mut left, [ 1.0 , 1.0 ] , Terminal :: AndB ) ;
@@ -871,48 +875,56 @@ where
871
875
let rw = subs[ 1 ] . 0 as f64 / total;
872
876
873
877
//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 ( ) ) {
875
879
let mut a1 = best_compilations (
876
880
policy_cache,
877
- & x[ 0 ] ,
881
+ x[ 0 ] . as_ref ( ) ,
878
882
lw * sat_prob,
879
883
Some ( dissat_prob. unwrap_or ( 0 as f64 ) + rw * sat_prob) ,
880
884
) ?;
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 ) ?;
882
886
883
887
let mut b1 = best_compilations (
884
888
policy_cache,
885
- & x[ 1 ] ,
889
+ x[ 1 ] . as_ref ( ) ,
886
890
lw * sat_prob,
887
891
Some ( dissat_prob. unwrap_or ( 0 as f64 ) + rw * sat_prob) ,
888
892
) ?;
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 ) ?;
890
894
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
+ ) ?;
893
901
894
902
compile_tern ! ( & mut a1, & mut b2, & mut c, [ lw, rw] ) ;
895
903
compile_tern ! ( & mut b1, & mut a2, & mut c, [ lw, rw] ) ;
896
904
} ;
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 ( ) ) {
898
906
let mut a1 = best_compilations (
899
907
policy_cache,
900
- & x[ 0 ] ,
908
+ x[ 0 ] . as_ref ( ) ,
901
909
rw * sat_prob,
902
910
Some ( dissat_prob. unwrap_or ( 0 as f64 ) + lw * sat_prob) ,
903
911
) ?;
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 ) ?;
905
913
906
914
let mut b1 = best_compilations (
907
915
policy_cache,
908
- & x[ 1 ] ,
916
+ x[ 1 ] . as_ref ( ) ,
909
917
rw * sat_prob,
910
918
Some ( dissat_prob. unwrap_or ( 0 as f64 ) + lw * sat_prob) ,
911
919
) ?;
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 ) ?;
913
921
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
+ ) ?;
916
928
917
929
compile_tern ! ( & mut a1, & mut b2, & mut c, [ rw, lw] ) ;
918
930
compile_tern ! ( & mut b1, & mut a2, & mut c, [ rw, lw] ) ;
@@ -931,12 +943,22 @@ where
931
943
let mut r_comp = vec ! [ ] ;
932
944
933
945
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
+ ) ?;
935
952
l_comp. push ( l) ;
936
953
}
937
954
938
955
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
+ ) ?;
940
962
r_comp. push ( r) ;
941
963
}
942
964
@@ -971,8 +993,8 @@ where
971
993
let sp = sat_prob * k_over_n;
972
994
//Expressions must be dissatisfiable
973
995
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) ?;
976
998
977
999
let diff = be. cost_1d ( sp, dp) - bw. cost_1d ( sp, dp) ;
978
1000
best_es. push ( ( be. comp_ext_data , be) ) ;
@@ -1005,7 +1027,7 @@ where
1005
1027
let key_vec: Vec < Pk > = subs
1006
1028
. iter ( )
1007
1029
. filter_map ( |s| {
1008
- if let Concrete :: Key ( ref pk) = * s {
1030
+ if let Concrete :: Key ( ref pk) = s . as_ref ( ) {
1009
1031
Some ( pk. clone ( ) )
1010
1032
} else {
1011
1033
None
@@ -1025,9 +1047,11 @@ where
1025
1047
_ if k == subs. len ( ) => {
1026
1048
let mut it = subs. iter ( ) ;
1027
1049
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
+ } ) ;
1029
1053
1030
- ret = best_compilations ( policy_cache, & policy, sat_prob, dissat_prob) ?;
1054
+ ret = best_compilations ( policy_cache, policy. as_ref ( ) , sat_prob, dissat_prob) ?;
1031
1055
}
1032
1056
_ => { }
1033
1057
}
@@ -1239,8 +1263,11 @@ mod tests {
1239
1263
fn compile_timelocks ( ) {
1240
1264
// artificially create a policy that is problematic and try to compile
1241
1265
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
+ ] ) ) ,
1244
1271
] ) ;
1245
1272
assert ! ( pol. compile:: <Segwitv0 >( ) . is_err( ) ) ;
1246
1273
@@ -1346,13 +1373,22 @@ mod tests {
1346
1373
1347
1374
// Liquid policy
1348
1375
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
+ ) ,
1350
1383
(
1351
1384
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
+ ] ) ) ,
1356
1392
) ,
1357
1393
] ) ;
1358
1394
@@ -1471,8 +1507,10 @@ mod tests {
1471
1507
// and to a ms thresh otherwise.
1472
1508
// k = 1 (or 2) does not compile, see https://github.com/rust-bitcoin/rust-miniscript/issues/114
1473
1509
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 ( ) ;
1476
1514
let big_thresh = Concrete :: Threshold ( * k, pubkeys) ;
1477
1515
let big_thresh_ms: SegwitMiniScript = big_thresh. compile ( ) . unwrap ( ) ;
1478
1516
if * k == 21 {
@@ -1499,18 +1537,18 @@ mod tests {
1499
1537
// or(thresh(52, [pubkey; 52]), thresh(52, [pubkey; 52])) results in a 3642-bytes long
1500
1538
// witness script with only 54 stack elements
1501
1539
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 ]
1503
1541
. iter ( )
1504
- . map ( |pubkey| Concrete :: Key ( * pubkey) )
1542
+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1505
1543
. 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 ..]
1507
1545
. iter ( )
1508
- . map ( |pubkey| Concrete :: Key ( * pubkey) )
1546
+ . map ( |pubkey| Arc :: new ( Concrete :: Key ( * pubkey) ) )
1509
1547
. collect ( ) ;
1510
1548
1511
1549
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) ) ) ,
1514
1552
] )
1515
1553
. compile ( ) ;
1516
1554
let script_size = thresh_res. clone ( ) . and_then ( |m| Ok ( m. script_size ( ) ) ) ;
@@ -1523,8 +1561,10 @@ mod tests {
1523
1561
1524
1562
// Hit the maximum witness stack elements limit
1525
1563
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 ( ) ;
1528
1568
let thresh_res: Result < SegwitMiniScript , _ > =
1529
1569
Concrete :: Threshold ( keys. len ( ) , keys) . compile ( ) ;
1530
1570
let n_elements = thresh_res
@@ -1542,8 +1582,10 @@ mod tests {
1542
1582
fn shared_limits ( ) {
1543
1583
// Test the maximum number of OPs with a 67-of-68 multisig
1544
1584
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 ( ) ;
1547
1589
let thresh_res: Result < SegwitMiniScript , _ > =
1548
1590
Concrete :: Threshold ( keys. len ( ) - 1 , keys) . compile ( ) ;
1549
1591
let ops_count = thresh_res. clone ( ) . and_then ( |m| Ok ( m. ext . ops . op_count ( ) ) ) ;
@@ -1555,8 +1597,10 @@ mod tests {
1555
1597
) ;
1556
1598
// For legacy too..
1557
1599
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 ( ) ;
1560
1604
let thresh_res = Concrete :: Threshold ( keys. len ( ) - 1 , keys) . compile :: < Legacy > ( ) ;
1561
1605
let ops_count = thresh_res. clone ( ) . and_then ( |m| Ok ( m. ext . ops . op_count ( ) ) ) ;
1562
1606
assert_eq ! (
@@ -1568,8 +1612,9 @@ mod tests {
1568
1612
1569
1613
// Test that we refuse to compile policies with duplicated keys
1570
1614
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 > ( ) ;
1573
1618
assert_eq ! (
1574
1619
res,
1575
1620
Err ( CompilerError :: PolicyError (
0 commit comments