2
2
3
3
#![ cfg_attr( fuzzing, no_main) ]
4
4
5
- #[ cfg( any( fuzzing, test) ) ]
6
- use std:: sync:: Arc ;
7
-
8
- #[ cfg( any( fuzzing, test) ) ]
9
- use old_simplicity:: { types:: Final as OldFinal , Value as OldValue } ;
10
- #[ cfg( any( fuzzing, test) ) ]
11
- use simplicity:: types:: Final ;
12
-
13
- #[ cfg( any( fuzzing, test) ) ]
14
- fn convert_ty ( new : & Final ) -> Option < Arc < OldFinal > > {
15
- /// Our stack of tasks describing “what we need to do next.”
16
- enum Task < ' a > {
17
- /// Convert this `Final` into an `OldFinal`.
18
- NeedType ( & ' a Final ) ,
19
- Binary {
20
- is_sum : bool ,
21
- dupe : bool ,
22
- } ,
23
- }
24
-
25
- // We'll push tasks onto this stack until everything is converted.
26
- let mut task_stack = vec ! [ Task :: NeedType ( new) ] ;
27
- // As we finish conversion of subtrees, we store them here along with
28
- // a count of units. Because the released version of 0.3.0 does not
29
- // have any typeskip optimization we need to bail out if there are
30
- // too many units, since otherwise we will OOM in from_compact_bits.
31
- let mut result_stack: Vec < ( usize , Arc < OldFinal > ) > = vec ! [ ] ;
32
- const MAX_UNITS : usize = 1024 * 1024 ;
33
-
34
- // Process tasks in LIFO order
35
- while let Some ( task) = task_stack. pop ( ) {
36
- match task {
37
- Task :: NeedType ( final_ty) => {
38
- if final_ty. is_unit ( ) {
39
- result_stack. push ( ( 1 , OldFinal :: unit ( ) ) ) ;
40
- } else if let Some ( ( left, right) ) = final_ty. as_sum ( ) {
41
- let dupe = Arc :: ptr_eq ( left, right) ;
42
- task_stack. push ( Task :: Binary { is_sum : true , dupe } ) ;
43
- if !dupe {
44
- task_stack. push ( Task :: NeedType ( right) ) ;
45
- }
46
- task_stack. push ( Task :: NeedType ( left) ) ;
47
- } else if let Some ( ( left, right) ) = final_ty. as_product ( ) {
48
- let dupe = Arc :: ptr_eq ( left, right) ;
49
- task_stack. push ( Task :: Binary {
50
- is_sum : false ,
51
- dupe,
52
- } ) ;
53
- if !dupe {
54
- task_stack. push ( Task :: NeedType ( right) ) ;
55
- }
56
- task_stack. push ( Task :: NeedType ( left) ) ;
57
- } else {
58
- unreachable ! ( ) ;
59
- }
60
- }
61
- Task :: Binary { is_sum, dupe } => {
62
- let right = result_stack. pop ( ) . expect ( "right type missing" ) ;
63
- let left = if dupe {
64
- ( right. 0 , Arc :: clone ( & right. 1 ) )
65
- } else {
66
- result_stack. pop ( ) . expect ( "left type missing" )
67
- } ;
68
- let new_total = left. 0 + right. 0 ;
69
- if new_total > MAX_UNITS {
70
- return None ;
71
- }
72
- if is_sum {
73
- result_stack. push ( ( new_total, OldFinal :: sum ( left. 1 , right. 1 ) ) ) ;
74
- } else {
75
- result_stack. push ( ( new_total, OldFinal :: product ( left. 1 , right. 1 ) ) ) ;
76
- }
77
- }
78
- }
79
- }
80
-
81
- // At the end, we should have exactly one final type.
82
- assert_eq ! ( result_stack. len( ) , 1 , "Internal conversion error" ) ;
83
- let ( _, res) = result_stack. pop ( ) . unwrap ( ) ;
84
- Some ( res)
85
- }
86
-
87
5
#[ cfg( any( fuzzing, test) ) ]
88
6
fn do_test ( data : & [ u8 ] ) {
89
7
let mut extractor_1 = simplicity_fuzz:: Extractor :: new ( data) ;
@@ -95,8 +13,8 @@ fn do_test(data: &[u8]) {
95
13
) {
96
14
( Some ( val) , Some ( old_val) ) => ( val, old_val) ,
97
15
( None , None ) => return ,
98
- ( Some ( val ) , None ) => panic ! ( "Could extract new value but not old." ) ,
99
- ( None , Some ( val ) ) => panic ! ( "Could extract old value but not new." ) ,
16
+ ( Some ( _ ) , None ) => panic ! ( "Could extract new value but not old." ) ,
17
+ ( None , Some ( _ ) ) => panic ! ( "Could extract old value but not new." ) ,
100
18
} ;
101
19
102
20
assert ! ( val. iter_compact( ) . eq( old_val. iter_compact( ) ) ) ;
0 commit comments