OSDN Git Service

Hulk did something
[bytom/vapor.git] / protocol / vm / control_test.go
1 package vm
2
3 import (
4         "testing"
5
6         "github.com/vapor/testutil"
7 )
8
9 func TestControlOps(t *testing.T) {
10         type testStruct struct {
11                 op      Op
12                 startVM *virtualMachine
13                 wantErr error
14                 wantVM  *virtualMachine
15         }
16         cases := []testStruct{{
17                 op: OP_JUMP,
18                 startVM: &virtualMachine{
19                         runLimit: 50000,
20                         pc:       0,
21                         nextPC:   1,
22                         data:     []byte{0x05, 0x00, 0x00, 0x00},
23                 },
24                 wantErr: nil,
25                 wantVM: &virtualMachine{
26                         runLimit: 49999,
27                         pc:       0,
28                         nextPC:   5,
29                         data:     []byte{0x05, 0x00, 0x00, 0x00},
30                 },
31         }, {
32                 op: OP_JUMP,
33                 startVM: &virtualMachine{
34                         runLimit: 50000,
35                         pc:       0,
36                         nextPC:   1,
37                         data:     []byte{0xff, 0xff, 0xff, 0xff},
38                 },
39                 wantErr: nil,
40                 wantVM: &virtualMachine{
41                         runLimit: 49999,
42                         pc:       0,
43                         nextPC:   4294967295,
44                         data:     []byte{0xff, 0xff, 0xff, 0xff},
45                 },
46         }, {
47                 op: OP_JUMPIF,
48                 startVM: &virtualMachine{
49                         runLimit:     50000,
50                         pc:           0,
51                         nextPC:       1,
52                         deferredCost: 0,
53                         dataStack:    [][]byte{{1}},
54                         data:         []byte{0x05, 0x00, 0x00, 0x00},
55                 },
56                 wantErr: nil,
57                 wantVM: &virtualMachine{
58                         runLimit:     49999,
59                         pc:           0,
60                         nextPC:       5,
61                         deferredCost: -9,
62                         dataStack:    [][]byte{},
63                         data:         []byte{0x05, 0x00, 0x00, 0x00},
64                 },
65         }, {
66                 op: OP_JUMPIF,
67                 startVM: &virtualMachine{
68                         runLimit:     50000,
69                         pc:           0,
70                         nextPC:       1,
71                         deferredCost: 0,
72                         dataStack:    [][]byte{{}},
73                         data:         []byte{0x05, 0x00, 0x00, 0x00},
74                 },
75                 wantErr: nil,
76                 wantVM: &virtualMachine{
77                         runLimit:     49999,
78                         pc:           0,
79                         nextPC:       1,
80                         deferredCost: -8,
81                         dataStack:    [][]byte{},
82                         data:         []byte{0x05, 0x00, 0x00, 0x00},
83                 },
84         }, {
85                 op: OP_VERIFY,
86                 startVM: &virtualMachine{
87                         pc:           0,
88                         runLimit:     50000,
89                         deferredCost: 0,
90                         dataStack:    [][]byte{{1}},
91                 },
92                 wantErr: nil,
93                 wantVM: &virtualMachine{
94                         runLimit:     49999,
95                         deferredCost: -9,
96                         dataStack:    [][]byte{},
97                 },
98         }, {
99                 op: OP_VERIFY,
100                 startVM: &virtualMachine{
101                         runLimit:     50000,
102                         deferredCost: 0,
103                         dataStack:    [][]byte{{1, 1}},
104                 },
105                 wantErr: nil,
106                 wantVM: &virtualMachine{
107                         runLimit:     49999,
108                         deferredCost: -10,
109                         dataStack:    [][]byte{},
110                 },
111         }, {
112                 op: OP_VERIFY,
113                 startVM: &virtualMachine{
114                         runLimit:     50000,
115                         deferredCost: 0,
116                         dataStack:    [][]byte{{}},
117                 },
118                 wantErr: ErrVerifyFailed,
119         }, {
120                 startVM: &virtualMachine{runLimit: 50000},
121                 op:      OP_FAIL,
122                 wantErr: ErrReturn,
123         }, {
124                 op: OP_CHECKPREDICATE,
125                 startVM: &virtualMachine{
126                         runLimit:  50000,
127                         dataStack: [][]byte{{}, {byte(OP_TRUE)}, {}},
128                 },
129                 wantVM: &virtualMachine{
130                         runLimit:     0,
131                         deferredCost: -49951,
132                         dataStack:    [][]byte{{1}},
133                 },
134         }, {
135                 op: OP_CHECKPREDICATE,
136                 startVM: &virtualMachine{
137                         runLimit:  50000,
138                         dataStack: [][]byte{{}, {}, {}},
139                 },
140                 wantVM: &virtualMachine{
141                         runLimit:     0,
142                         deferredCost: -49952,
143                         dataStack:    [][]byte{{}},
144                 },
145         }, {
146                 op: OP_CHECKPREDICATE,
147                 startVM: &virtualMachine{
148                         runLimit:  50000,
149                         dataStack: [][]byte{{}, {byte(OP_FAIL)}, {}},
150                 },
151                 wantVM: &virtualMachine{
152                         runLimit:     0,
153                         deferredCost: -49952,
154                         dataStack:    [][]byte{{}},
155                 },
156         }, {
157                 op: OP_CHECKPREDICATE,
158                 startVM: &virtualMachine{
159                         runLimit:  50000,
160                         dataStack: [][]byte{{}, {}, Int64Bytes(-1)},
161                 },
162                 wantErr: ErrBadValue,
163         }, {
164                 op: OP_CHECKPREDICATE,
165                 startVM: &virtualMachine{
166                         runLimit:  50000,
167                         dataStack: [][]byte{{}, {}, Int64Bytes(50000)},
168                 },
169                 wantErr: ErrRunLimitExceeded,
170         }, {
171                 op: OP_CHECKPREDICATE,
172                 startVM: &virtualMachine{
173                         runLimit:  50000,
174                         dataStack: [][]byte{{0x05}, {0x07}, {0x02}, {byte(OP_ADD), byte(OP_12), byte(OP_NUMEQUAL)}, {}},
175                 },
176                 wantVM: &virtualMachine{
177                         deferredCost: -49968,
178                         dataStack:    [][]byte{{0x01}},
179                 },
180         }, {
181                 // stack underflow in child vm should produce false result in parent vm
182                 op: OP_CHECKPREDICATE,
183                 startVM: &virtualMachine{
184                         runLimit:  50000,
185                         dataStack: [][]byte{{0x05}, {0x07}, {0x01}, {byte(OP_ADD), byte(OP_DATA_12), byte(OP_NUMEQUAL)}, {}},
186                 },
187                 wantVM: &virtualMachine{
188                         deferredCost: -49954,
189                         dataStack:    [][]byte{{0x05}, {}},
190                 },
191         }}
192
193         limitChecks := []Op{
194                 OP_CHECKPREDICATE, OP_VERIFY, OP_FAIL,
195         }
196
197         for _, op := range limitChecks {
198                 cases = append(cases, testStruct{
199                         op:      op,
200                         startVM: &virtualMachine{runLimit: 0},
201                         wantErr: ErrRunLimitExceeded,
202                 })
203         }
204
205         for i, c := range cases {
206                 err := ops[c.op].fn(c.startVM)
207
208                 if err != c.wantErr {
209                         t.Errorf("case %d, op %s: got err = %v want %v", i, c.op.String(), err, c.wantErr)
210                         continue
211                 }
212                 if c.wantErr != nil {
213                         continue
214                 }
215
216                 if !testutil.DeepEqual(c.startVM, c.wantVM) {
217                         t.Errorf("case %d, op %s: unexpected vm result\n\tgot:  %+v\n\twant: %+v\n", i, c.op.String(), c.startVM, c.wantVM)
218                 }
219         }
220 }