8 "github.com/bytom/vapor/testutil"
11 func TestNumericOps(t *testing.T) {
12 type testStruct struct {
14 startVM *virtualMachine
16 wantVM *virtualMachine
18 cases := []testStruct{{
20 startVM: &virtualMachine{
22 dataStack: [][]byte{{2}},
24 wantVM: &virtualMachine{
26 dataStack: [][]byte{{3}},
30 startVM: &virtualMachine{
32 dataStack: [][]byte{{2}},
34 wantVM: &virtualMachine{
36 dataStack: [][]byte{{1}},
40 startVM: &virtualMachine{
42 dataStack: [][]byte{{2}},
44 wantVM: &virtualMachine{
46 dataStack: [][]byte{{4}},
50 startVM: &virtualMachine{
52 dataStack: [][]byte{{2}},
54 wantVM: &virtualMachine{
56 dataStack: [][]byte{{1}},
60 startVM: &virtualMachine{
62 dataStack: [][]byte{Int64Bytes(-2)},
64 wantVM: &virtualMachine{
66 dataStack: [][]byte{Int64Bytes(-1)},
70 startVM: &virtualMachine{
72 dataStack: [][]byte{Int64Bytes(-1)},
74 wantVM: &virtualMachine{
76 dataStack: [][]byte{Int64Bytes(-1)},
80 startVM: &virtualMachine{
82 dataStack: [][]byte{{2}},
84 wantVM: &virtualMachine{
87 dataStack: [][]byte{Int64Bytes(-2)},
91 startVM: &virtualMachine{
93 dataStack: [][]byte{{2}},
95 wantVM: &virtualMachine{
97 dataStack: [][]byte{{2}},
101 startVM: &virtualMachine{
103 dataStack: [][]byte{Int64Bytes(-2)},
105 wantVM: &virtualMachine{
108 dataStack: [][]byte{{2}},
112 startVM: &virtualMachine{
114 dataStack: [][]byte{{2}},
116 wantVM: &virtualMachine{
119 dataStack: [][]byte{{}},
123 startVM: &virtualMachine{
125 dataStack: [][]byte{{2}},
127 wantVM: &virtualMachine{
129 dataStack: [][]byte{{1}},
133 startVM: &virtualMachine{
135 dataStack: [][]byte{{2}, {1}},
137 wantVM: &virtualMachine{
140 dataStack: [][]byte{{3}},
144 startVM: &virtualMachine{
146 dataStack: [][]byte{{2}, {1}},
148 wantVM: &virtualMachine{
151 dataStack: [][]byte{{1}},
155 startVM: &virtualMachine{
157 dataStack: [][]byte{{2}, {1}},
159 wantVM: &virtualMachine{
162 dataStack: [][]byte{{2}},
166 startVM: &virtualMachine{
168 dataStack: [][]byte{{2}, {1}},
170 wantVM: &virtualMachine{
173 dataStack: [][]byte{{2}},
177 startVM: &virtualMachine{
179 dataStack: [][]byte{Int64Bytes(-2), {1}},
181 wantVM: &virtualMachine{
184 dataStack: [][]byte{Int64Bytes(-2)},
188 startVM: &virtualMachine{
190 dataStack: [][]byte{Int64Bytes(-2), Int64Bytes(-1)},
192 wantVM: &virtualMachine{
195 dataStack: [][]byte{{2}},
199 startVM: &virtualMachine{
201 dataStack: [][]byte{Int64Bytes(-3), Int64Bytes(2)},
203 wantVM: &virtualMachine{
206 dataStack: [][]byte{Int64Bytes(-1)},
210 startVM: &virtualMachine{
212 dataStack: [][]byte{{2}, {}},
217 startVM: &virtualMachine{
219 dataStack: [][]byte{{2}, {1}},
221 wantVM: &virtualMachine{
224 dataStack: [][]byte{{}},
228 startVM: &virtualMachine{
230 dataStack: [][]byte{Int64Bytes(-12), {10}},
232 wantVM: &virtualMachine{
235 dataStack: [][]byte{{8}},
239 startVM: &virtualMachine{
241 dataStack: [][]byte{{2}, {0}},
246 startVM: &virtualMachine{
248 dataStack: [][]byte{{2}, {1}},
250 wantVM: &virtualMachine{
253 dataStack: [][]byte{{4}},
257 startVM: &virtualMachine{
259 dataStack: [][]byte{Int64Bytes(-2), {1}},
261 wantVM: &virtualMachine{
264 dataStack: [][]byte{Int64Bytes(-4)},
268 startVM: &virtualMachine{
270 dataStack: [][]byte{{2}, {1}},
272 wantVM: &virtualMachine{
275 dataStack: [][]byte{{1}},
279 startVM: &virtualMachine{
281 dataStack: [][]byte{Int64Bytes(-2), {1}},
283 wantVM: &virtualMachine{
286 dataStack: [][]byte{Int64Bytes(-1)},
290 startVM: &virtualMachine{
292 dataStack: [][]byte{{2}, {1}},
294 wantVM: &virtualMachine{
297 dataStack: [][]byte{{1}},
301 startVM: &virtualMachine{
303 dataStack: [][]byte{{2}, {1}},
305 wantVM: &virtualMachine{
308 dataStack: [][]byte{{1}},
312 startVM: &virtualMachine{
314 dataStack: [][]byte{{2}, {1}},
316 wantVM: &virtualMachine{
319 dataStack: [][]byte{{}},
322 op: OP_NUMEQUALVERIFY,
323 startVM: &virtualMachine{
325 dataStack: [][]byte{{2}, {2}},
327 wantVM: &virtualMachine{
330 dataStack: [][]byte{},
333 op: OP_NUMEQUALVERIFY,
334 startVM: &virtualMachine{
336 dataStack: [][]byte{{1}, {2}},
338 wantErr: ErrVerifyFailed,
341 startVM: &virtualMachine{
343 dataStack: [][]byte{{2}, {1}},
345 wantVM: &virtualMachine{
348 dataStack: [][]byte{{1}},
352 startVM: &virtualMachine{
354 dataStack: [][]byte{{2}, {1}},
356 wantVM: &virtualMachine{
359 dataStack: [][]byte{{}},
362 op: OP_LESSTHANOREQUAL,
363 startVM: &virtualMachine{
365 dataStack: [][]byte{{2}, {1}},
367 wantVM: &virtualMachine{
370 dataStack: [][]byte{{}},
374 startVM: &virtualMachine{
376 dataStack: [][]byte{{2}, {1}},
378 wantVM: &virtualMachine{
381 dataStack: [][]byte{{1}},
384 op: OP_GREATERTHANOREQUAL,
385 startVM: &virtualMachine{
387 dataStack: [][]byte{{2}, {1}},
389 wantVM: &virtualMachine{
392 dataStack: [][]byte{{1}},
396 startVM: &virtualMachine{
398 dataStack: [][]byte{{2}, {1}},
400 wantVM: &virtualMachine{
403 dataStack: [][]byte{{1}},
407 startVM: &virtualMachine{
409 dataStack: [][]byte{{1}, {2}},
411 wantVM: &virtualMachine{
414 dataStack: [][]byte{{1}},
418 startVM: &virtualMachine{
420 dataStack: [][]byte{{2}, {1}},
422 wantVM: &virtualMachine{
425 dataStack: [][]byte{{2}},
429 startVM: &virtualMachine{
431 dataStack: [][]byte{{1}, {2}},
433 wantVM: &virtualMachine{
436 dataStack: [][]byte{{2}},
440 startVM: &virtualMachine{
442 dataStack: [][]byte{{1}, {1}, {2}},
444 wantVM: &virtualMachine{
447 dataStack: [][]byte{{1}},
451 startVM: &virtualMachine{
453 dataStack: [][]byte{{15}, {2}, {3}},
455 wantVM: &virtualMachine{
458 dataStack: [][]byte{{10}},
462 startVM: &virtualMachine{
464 dataStack: [][]byte{Int64Bytes(-654), {3}, {2}},
466 wantVM: &virtualMachine{
469 dataStack: [][]byte{Int64Bytes(-981)},
473 startVM: &virtualMachine{
475 dataStack: [][]byte{Int64Bytes(-654), {3}, {}},
477 wantVM: &virtualMachine{
480 dataStack: [][]byte{},
486 OP_1ADD, OP_1SUB, OP_2MUL, OP_2DIV, OP_NEGATE, OP_ABS, OP_NOT, OP_0NOTEQUAL,
487 OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_LSHIFT, OP_RSHIFT, OP_BOOLAND,
488 OP_BOOLOR, OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL, OP_LESSTHAN,
489 OP_LESSTHANOREQUAL, OP_GREATERTHAN, OP_GREATERTHANOREQUAL, OP_MIN, OP_MAX, OP_WITHIN,
493 for _, op := range numops {
494 cases = append(cases, testStruct{
496 startVM: &virtualMachine{
498 dataStack: [][]byte{{2}, {2}, {2}},
500 wantErr: ErrRunLimitExceeded,
504 for i, c := range cases {
505 err := ops[c.op].fn(c.startVM)
507 if err != c.wantErr {
508 t.Errorf("case %d, op %s: got err = %v want %v", i, ops[c.op].name, err, c.wantErr)
511 if c.wantErr != nil {
515 if !testutil.DeepEqual(c.startVM, c.wantVM) {
516 t.Errorf("case %d, op %s: unexpected vm result\n\tgot: %+v\n\twant: %+v\n", i, ops[c.op].name, c.startVM, c.wantVM)
521 func TestRangeErrs(t *testing.T) {
527 {fmt.Sprintf("%d 1ADD", int64(math.MinInt64)), false},
528 {fmt.Sprintf("%d 1ADD", int64(math.MaxInt64)-1), false},
529 {fmt.Sprintf("%d 1ADD", int64(math.MaxInt64)), true},
531 {fmt.Sprintf("%d 1SUB", int64(math.MaxInt64)), false},
532 {fmt.Sprintf("%d 1SUB", int64(math.MinInt64)+1), false},
533 {fmt.Sprintf("%d 1SUB", int64(math.MinInt64)), true},
535 {fmt.Sprintf("%d 2MUL", int64(math.MaxInt64)/2-1), false},
536 {fmt.Sprintf("%d 2MUL", int64(math.MaxInt64)/2+1), true},
537 {fmt.Sprintf("%d 2MUL", int64(math.MinInt64)/2+1), false},
538 {fmt.Sprintf("%d 2MUL", int64(math.MinInt64)/2-1), true},
540 {"-1 NEGATE", false},
541 {fmt.Sprintf("%d NEGATE", int64(math.MaxInt64)), false},
542 {fmt.Sprintf("%d NEGATE", int64(math.MinInt64)), true},
545 {fmt.Sprintf("%d ABS", int64(math.MaxInt64)), false},
546 {fmt.Sprintf("%d ABS", int64(math.MinInt64)), true},
548 {fmt.Sprintf("%d %d ADD", int64(math.MinInt64), int64(math.MaxInt64)), false},
549 {fmt.Sprintf("%d %d ADD", int64(math.MaxInt64)/2-1, int64(math.MaxInt64)/2-2), false},
550 {fmt.Sprintf("%d %d ADD", int64(math.MaxInt64)/2+1, int64(math.MaxInt64)/2+2), true},
551 {fmt.Sprintf("%d %d ADD", int64(math.MinInt64)/2+1, int64(math.MinInt64)/2+2), false},
552 {fmt.Sprintf("%d %d ADD", int64(math.MinInt64)/2-1, int64(math.MinInt64)/2-2), true},
554 {fmt.Sprintf("1 %d SUB", int64(math.MaxInt64)), false},
555 {fmt.Sprintf("-1 %d SUB", int64(math.MinInt64)), false},
556 {fmt.Sprintf("1 %d SUB", int64(math.MinInt64)), true},
557 {fmt.Sprintf("-1 %d SUB", int64(math.MaxInt64)), false},
558 {fmt.Sprintf("-2 %d SUB", int64(math.MaxInt64)), true},
559 {"1 2 LSHIFT", false},
560 {"-1 2 LSHIFT", false},
561 {"-1 63 LSHIFT", false},
562 {"-1 64 LSHIFT", true},
563 {"0 64 LSHIFT", false},
564 {"1 62 LSHIFT", false},
565 {"1 63 LSHIFT", true},
566 {fmt.Sprintf("%d 0 LSHIFT", int64(math.MaxInt64)), false},
567 {fmt.Sprintf("%d 1 LSHIFT", int64(math.MaxInt64)), true},
568 {fmt.Sprintf("%d 1 LSHIFT", int64(math.MaxInt64)/2), false},
569 {fmt.Sprintf("%d 2 LSHIFT", int64(math.MaxInt64)/2), true},
570 {fmt.Sprintf("%d 0 LSHIFT", int64(math.MinInt64)), false},
571 {fmt.Sprintf("%d 1 LSHIFT", int64(math.MinInt64)), true},
572 {fmt.Sprintf("%d 1 LSHIFT", int64(math.MinInt64)/2), false},
573 {fmt.Sprintf("%d 2 LSHIFT", int64(math.MinInt64)/2), true},
574 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64)/2-1, 2, 1), false},
575 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64)/2+1, 2, 1), true},
576 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64)/2+1, 2, 1), false},
577 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64)/2-1, 2, 1), true},
578 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64), 3, 2), true},
579 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64), 2, 3), false},
580 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64), 3, 2), true},
581 {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64), 2, 3), false},
584 for i, c := range cases {
585 prog, _ := Assemble(c.prog)
586 vm := &virtualMachine{
593 if c.expectRangeErr {
594 t.Errorf("case %d (%s): expected range error, got none", i, c.prog)
597 if !c.expectRangeErr {
598 t.Errorf("case %d (%s): got unexpected range error", i, c.prog)
601 if c.expectRangeErr {
602 t.Errorf("case %d (%s): expected range error, got %s", i, c.prog, err)
604 t.Errorf("case %d (%s): got unexpected error %s", i, c.prog, err)