8 "github.com/vapor/errors"
9 "github.com/vapor/math/checked"
10 "github.com/vapor/testutil"
13 func TestParseOp(t *testing.T) {
20 prog: []byte{byte(OP_ADD)},
21 want: Instruction{Op: OP_ADD, Len: 1},
23 prog: []byte{byte(OP_16)},
24 want: Instruction{Op: OP_16, Data: []byte{16}, Len: 1},
26 prog: []byte{byte(OP_DATA_5), 1, 1, 1, 1, 1},
27 want: Instruction{Op: OP_DATA_5, Data: []byte{1, 1, 1, 1, 1}, Len: 6},
29 prog: []byte{byte(OP_DATA_5), 1, 1, 1, 1, 1, 255},
30 want: Instruction{Op: OP_DATA_5, Data: []byte{1, 1, 1, 1, 1}, Len: 6},
32 prog: []byte{byte(OP_PUSHDATA1), 1, 1},
33 want: Instruction{Op: OP_PUSHDATA1, Data: []byte{1}, Len: 3},
35 prog: []byte{byte(OP_PUSHDATA1), 1, 1, 255},
36 want: Instruction{Op: OP_PUSHDATA1, Data: []byte{1}, Len: 3},
38 prog: []byte{byte(OP_PUSHDATA2), 1, 0, 1},
39 want: Instruction{Op: OP_PUSHDATA2, Data: []byte{1}, Len: 4},
41 prog: []byte{byte(OP_PUSHDATA2), 1, 0, 1, 255},
42 want: Instruction{Op: OP_PUSHDATA2, Data: []byte{1}, Len: 4},
44 prog: []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0, 1},
45 want: Instruction{Op: OP_PUSHDATA4, Data: []byte{1}, Len: 6},
47 prog: []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0, 1, 255},
48 want: Instruction{Op: OP_PUSHDATA4, Data: []byte{1}, Len: 6},
51 wantErr: ErrShortProgram,
53 prog: []byte{byte(OP_0)},
55 wantErr: ErrShortProgram,
57 prog: []byte{byte(OP_DATA_1)},
58 wantErr: ErrShortProgram,
60 prog: []byte{byte(OP_PUSHDATA1)},
61 wantErr: ErrShortProgram,
63 prog: []byte{byte(OP_PUSHDATA1), 1},
64 wantErr: ErrShortProgram,
66 prog: []byte{byte(OP_PUSHDATA2)},
67 wantErr: ErrShortProgram,
69 prog: []byte{byte(OP_PUSHDATA2), 1, 0},
70 wantErr: ErrShortProgram,
72 prog: []byte{byte(OP_PUSHDATA4)},
73 wantErr: ErrShortProgram,
75 prog: []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0},
76 wantErr: ErrShortProgram,
79 prog: []byte{0x6d, 0x6b, 0xaa, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x4e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
80 wantErr: checked.ErrOverflow,
83 for _, c := range cases {
84 t.Run(fmt.Sprintf("%d: %x", c.pc, c.prog), func(t *testing.T) {
85 got, gotErr := ParseOp(c.prog, c.pc)
87 if errors.Root(gotErr) != c.wantErr {
88 t.Errorf("ParseOp(%x, %d) error = %v want %v", c.prog, c.pc, gotErr, c.wantErr)
95 if !testutil.DeepEqual(got, c.want) {
96 t.Errorf("ParseOp(%x, %d) = %+v want %+v", c.prog, c.pc, got, c.want)
102 func TestParseProgram(t *testing.T) {
109 prog: []byte{byte(OP_2), byte(OP_3), byte(OP_ADD), byte(OP_5), byte(OP_NUMEQUAL)},
111 {Op: OP_2, Data: []byte{0x02}, Len: 1},
112 {Op: OP_3, Data: []byte{0x03}, Len: 1},
113 {Op: OP_ADD, Len: 1},
114 {Op: OP_5, Data: []byte{0x05}, Len: 1},
115 {Op: OP_NUMEQUAL, Len: 1},
126 for _, c := range cases {
127 got, gotErr := ParseProgram(c.prog)
129 if errors.Root(gotErr) != c.wantErr {
130 t.Errorf("ParseProgram(%x) error = %v want %v", c.prog, gotErr, c.wantErr)
133 if c.wantErr != nil {
137 if !testutil.DeepEqual(got, c.want) {
138 t.Errorf("ParseProgram(%x) = %+v want %+v", c.prog, got, c.want)
143 func TestIsPushData(t *testing.T) {
149 want: Instruction{Op: OP_16, Data: []byte{16}, Len: 1},
152 want: Instruction{Op: OP_DATA_32, Data: []byte{16}, Len: 1},
155 want: Instruction{Op: OP_FALSE, Data: []byte{}, Len: 1},
158 want: Instruction{Op: OP_TRUE, Data: []byte{1}, Len: 1},
161 want: Instruction{Op: OP_JUMP, Data: []byte{0x00000000}, Len: 1},
162 wantErr: ErrShortProgram,
165 want: Instruction{Op: OP_ADD, Data: []byte{0x12, 0x56}, Len: 2},
166 wantErr: ErrShortProgram,
170 for _, c := range cases {
171 if c.want.IsPushdata() {
172 t.Logf("check success")
173 } else if c.wantErr != nil {
174 t.Logf("check err success")
176 t.Errorf("check false: %v -- %v", reflect.ValueOf(ops[OP_1].fn), reflect.ValueOf(ops[c.want.Op].fn))