@@ -775,17 +775,13 @@ impl Property for ExtData {
775
775
let mut ops_count = 0 ;
776
776
let mut ops_count_sat_vec = Vec :: with_capacity ( n) ;
777
777
let mut ops_count_nsat_sum = 0 ;
778
- let mut op_count_sat = Some ( 0 ) ;
779
778
let mut timelocks = Vec :: with_capacity ( n) ;
780
779
let mut stack_elem_count_sat_vec = Vec :: with_capacity ( n) ;
781
- let mut stack_elem_count_sat = Some ( 0 ) ;
782
780
let mut stack_elem_count_dissat = Some ( 0 ) ;
783
781
let mut max_sat_size_vec = Vec :: with_capacity ( n) ;
784
- let mut max_sat_size = Some ( ( 0 , 0 ) ) ;
785
782
let mut max_dissat_size = Some ( ( 0 , 0 ) ) ;
786
783
// the max element count is same as max sat element count when satisfying one element + 1
787
784
let mut exec_stack_elem_count_sat_vec = Vec :: with_capacity ( n) ;
788
- let mut exec_stack_elem_count_sat = Some ( 0 ) ;
789
785
let mut exec_stack_elem_count_dissat = Some ( 0 ) ;
790
786
791
787
for i in 0 ..n {
@@ -822,61 +818,60 @@ impl Property for ExtData {
822
818
) ;
823
819
}
824
820
825
- // We sort by [satisfaction cost - dissatisfaction cost] to make a worst-case (the most
826
- // costy satisfaction are satisfied, the most costy dissatisfactions are dissatisfied)
827
- // sum of the cost by iterating through the sorted vector *backward*.
828
- stack_elem_count_sat_vec. sort_by ( |a, b| {
829
- a. 0 . map ( |x| a. 1 . map ( |y| x as isize - y as isize ) )
830
- . cmp ( & b. 0 . map ( |x| b. 1 . map ( |y| x as isize - y as isize ) ) )
831
- } ) ;
832
- for ( i, & ( x, y) ) in stack_elem_count_sat_vec. iter ( ) . rev ( ) . enumerate ( ) {
833
- stack_elem_count_sat = if i <= k {
834
- x. and_then ( |x| stack_elem_count_sat. map ( |count| count + x) )
835
- } else {
836
- y. and_then ( |y| stack_elem_count_sat. map ( |count| count + y) )
837
- } ;
838
- }
821
+ stack_elem_count_sat_vec. sort_by ( sat_minus_option_dissat) ;
822
+ let stack_elem_count_sat =
823
+ stack_elem_count_sat_vec
824
+ . iter ( )
825
+ . rev ( )
826
+ . enumerate ( )
827
+ . fold ( Some ( 0 ) , |acc, ( i, & ( x, y) ) | {
828
+ if i <= k {
829
+ opt_add ( acc, x)
830
+ } else {
831
+ opt_add ( acc, y)
832
+ }
833
+ } ) ;
839
834
840
- // Same logic as above
841
- exec_stack_elem_count_sat_vec . sort_by ( |a , b| {
842
- a . 0 . map ( |x| a . 1 . map ( |y| x as isize - y as isize ) )
843
- . cmp ( & b . 0 . map ( |x| b . 1 . map ( |y| x as isize - y as isize ) ) )
844
- } ) ;
845
- for ( i, & ( x, y) ) in exec_stack_elem_count_sat_vec . iter ( ) . rev ( ) . enumerate ( ) {
846
- exec_stack_elem_count_sat = if i <= k {
847
- opt_max ( exec_stack_elem_count_sat , x)
848
- } else {
849
- opt_max ( exec_stack_elem_count_sat , y)
850
- } ;
851
- }
835
+ exec_stack_elem_count_sat_vec . sort_by ( sat_minus_option_dissat ) ;
836
+ let exec_stack_elem_count_sat = exec_stack_elem_count_sat_vec
837
+ . iter ( )
838
+ . rev ( )
839
+ . enumerate ( )
840
+ . fold ( Some ( 0 ) , |acc , ( i, & ( x, y) ) | {
841
+ if i <= k {
842
+ opt_max ( acc , x)
843
+ } else {
844
+ opt_max ( acc , y)
845
+ }
846
+ } ) ;
852
847
853
- // Same for the size cost. A bit more intricated as we need to account for both the witness
854
- // and scriptSig cost, so we end up with a tuple of Options of tuples. We use the witness
855
- // cost (first element of the mentioned tuple) here.
856
848
// FIXME: Maybe make the ExtData struct aware of Ctx and add a one_cost() method here ?
857
- max_sat_size_vec. sort_by ( |a, b| {
858
- a. 0 . map ( |x| a. 1 . map ( |y| x. 0 as isize - y. 0 as isize ) )
859
- . cmp ( & b. 0 . map ( |x| b. 1 . map ( |y| x. 0 as isize - y. 0 as isize ) ) )
860
- } ) ;
861
- for ( i, & ( x, y) ) in max_sat_size_vec. iter ( ) . enumerate ( ) {
862
- max_sat_size = if i <= k {
863
- x. and_then ( |x| max_sat_size. map ( |( w, s) | ( w + x. 0 , s + x. 1 ) ) )
864
- } else {
865
- y. and_then ( |y| max_sat_size. map ( |( w, s) | ( w + y. 0 , s + y. 1 ) ) )
866
- } ;
867
- }
849
+ max_sat_size_vec. sort_by ( sat_minus_dissat_witness) ;
850
+ let max_sat_size =
851
+ max_sat_size_vec
852
+ . iter ( )
853
+ . enumerate ( )
854
+ . fold ( Some ( ( 0 , 0 ) ) , |acc, ( i, & ( x, y) ) | {
855
+ if i <= k {
856
+ opt_tuple_add ( acc, x)
857
+ } else {
858
+ opt_tuple_add ( acc, y)
859
+ }
860
+ } ) ;
861
+
862
+ ops_count_sat_vec. sort_by ( sat_minus_dissat) ;
863
+ let op_count_sat =
864
+ ops_count_sat_vec
865
+ . iter ( )
866
+ . enumerate ( )
867
+ . fold ( Some ( 0 ) , |acc, ( i, & ( x, y) ) | {
868
+ if i <= k {
869
+ opt_add ( acc, x)
870
+ } else {
871
+ opt_add ( acc, Some ( y) )
872
+ }
873
+ } ) ;
868
874
869
- ops_count_sat_vec. sort_by ( |a, b| {
870
- a. 0 . map ( |x| x as isize - a. 1 as isize )
871
- . cmp ( & b. 0 . map ( |x| x as isize - b. 1 as isize ) )
872
- } ) ;
873
- for ( i, & ( x, y) ) in ops_count_sat_vec. iter ( ) . enumerate ( ) {
874
- op_count_sat = if i <= k {
875
- opt_add ( op_count_sat, x)
876
- } else {
877
- opt_add ( op_count_sat, Some ( y) )
878
- } ;
879
- }
880
875
Ok ( ExtData {
881
876
pk_cost : pk_cost + n - 1 , //all pk cost + (n-1)*ADD
882
877
has_free_verify : true ,
@@ -1034,7 +1029,47 @@ impl Property for ExtData {
1034
1029
}
1035
1030
}
1036
1031
1037
- // Returns Some(max(x,y)) is both x and y are Some. Otherwise, return none
1032
+ // Function to pass to sort_by. Sort by (satisfaction cost - dissatisfaction cost).
1033
+ //
1034
+ // We sort by (satisfaction cost - dissatisfaction cost) to make a worst-case (the most
1035
+ // costy satisfactions are satisfied, the most costy dissatisfactions are dissatisfied).
1036
+ //
1037
+ // Args are of form: (<count_sat>, <count_dissat>)
1038
+ fn sat_minus_dissat < ' r , ' s > (
1039
+ a : & ' r ( Option < usize > , usize ) ,
1040
+ b : & ' s ( Option < usize > , usize ) ,
1041
+ ) -> std:: cmp:: Ordering {
1042
+ a. 0 . map ( |x| x as isize - a. 1 as isize )
1043
+ . cmp ( & b. 0 . map ( |x| x as isize - b. 1 as isize ) )
1044
+ }
1045
+
1046
+ // Function to pass to sort_by. Sort by (satisfaction cost - dissatisfaction cost).
1047
+ //
1048
+ // We sort by (satisfaction cost - dissatisfaction cost) to make a worst-case (the most
1049
+ // costy satisfactions are satisfied, the most costy dissatisfactions are dissatisfied).
1050
+ //
1051
+ // Args are of form: (<count_sat>, <count_dissat>)
1052
+ fn sat_minus_option_dissat < ' r , ' s > (
1053
+ a : & ' r ( Option < usize > , Option < usize > ) ,
1054
+ b : & ' s ( Option < usize > , Option < usize > ) ,
1055
+ ) -> std:: cmp:: Ordering {
1056
+ a. 0 . map ( |x| a. 1 . map ( |y| x as isize - y as isize ) )
1057
+ . cmp ( & b. 0 . map ( |x| b. 1 . map ( |y| x as isize - y as isize ) ) )
1058
+ }
1059
+
1060
+ // Function to pass to sort_by. Sort by (satisfaction cost - dissatisfaction cost) of cost of witness.
1061
+ //
1062
+ // Args are of form: (<max_sat_size>, <count_dissat_size>)
1063
+ // max_[dis]sat_size of form: (<cost_of_witness>, <cost_of_sciptsig>)
1064
+ fn sat_minus_dissat_witness < ' r , ' s > (
1065
+ a : & ' r ( Option < ( usize , usize ) > , Option < ( usize , usize ) > ) ,
1066
+ b : & ' s ( Option < ( usize , usize ) > , Option < ( usize , usize ) > ) ,
1067
+ ) -> std:: cmp:: Ordering {
1068
+ a. 0 . map ( |x| a. 1 . map ( |y| x. 0 as isize - y. 0 as isize ) )
1069
+ . cmp ( & b. 0 . map ( |x| b. 1 . map ( |y| x. 0 as isize - y. 0 as isize ) ) )
1070
+ }
1071
+
1072
+ /// Returns Some(max(x,y)) is both x and y are Some. Otherwise, returns `None`.
1038
1073
fn opt_max < T : Ord > ( a : Option < T > , b : Option < T > ) -> Option < T > {
1039
1074
if let ( Some ( x) , Some ( y) ) = ( a, b) {
1040
1075
Some ( cmp:: max ( x, y) )
@@ -1043,7 +1078,12 @@ fn opt_max<T: Ord>(a: Option<T>, b: Option<T>) -> Option<T> {
1043
1078
}
1044
1079
}
1045
1080
1046
- // Returns Some(x+y) is both x and y are Some. Otherwise, return none
1081
+ /// Returns Some(x+y) is both x and y are Some. Otherwise, returns `None`.
1047
1082
fn opt_add ( a : Option < usize > , b : Option < usize > ) -> Option < usize > {
1048
1083
a. and_then ( |x| b. map ( |y| x + y) )
1049
1084
}
1085
+
1086
+ /// Returns Some((x0+y0, x1+y1)) is both x and y are Some. Otherwise, returns `None`.
1087
+ fn opt_tuple_add ( a : Option < ( usize , usize ) > , b : Option < ( usize , usize ) > ) -> Option < ( usize , usize ) > {
1088
+ a. and_then ( |x| b. map ( |( w, s) | ( w + x. 0 , s + x. 1 ) ) )
1089
+ }
0 commit comments