github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/pushdata_test.go (about) 1 package vm 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/bytom/bytom/testutil" 8 ) 9 10 func TestPushdataOps(t *testing.T) { 11 type testStruct struct { 12 op Op 13 startVM *virtualMachine 14 wantErr error 15 wantVM *virtualMachine 16 } 17 cases := []testStruct{{ 18 op: OP_FALSE, 19 startVM: &virtualMachine{ 20 runLimit: 50000, 21 dataStack: [][]byte{}, 22 }, 23 wantVM: &virtualMachine{ 24 runLimit: 49991, 25 dataStack: [][]byte{{}}, 26 }, 27 }, { 28 op: OP_FALSE, 29 startVM: &virtualMachine{ 30 runLimit: 1, 31 dataStack: [][]byte{}, 32 }, 33 wantErr: ErrRunLimitExceeded, 34 }, { 35 op: OP_1NEGATE, 36 startVM: &virtualMachine{ 37 runLimit: 50000, 38 dataStack: [][]byte{}, 39 }, 40 wantVM: &virtualMachine{ 41 runLimit: 49983, 42 dataStack: [][]byte{Int64Bytes(-1)}, 43 }, 44 }, { 45 op: OP_1NEGATE, 46 startVM: &virtualMachine{ 47 runLimit: 1, 48 dataStack: [][]byte{}, 49 }, 50 wantErr: ErrRunLimitExceeded, 51 }} 52 53 pushdataops := []Op{OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4} 54 for i := 1; i <= 75; i++ { 55 pushdataops = append(pushdataops, Op(i)) 56 } 57 for _, op := range pushdataops { 58 cases = append(cases, testStruct{ 59 op: op, 60 startVM: &virtualMachine{ 61 runLimit: 50000, 62 dataStack: [][]byte{}, 63 data: []byte("data"), 64 }, 65 wantVM: &virtualMachine{ 66 runLimit: 49987, 67 dataStack: [][]byte{[]byte("data")}, 68 data: []byte("data"), 69 }, 70 }, testStruct{ 71 op: op, 72 startVM: &virtualMachine{ 73 runLimit: 1, 74 dataStack: [][]byte{}, 75 data: []byte("data"), 76 }, 77 wantErr: ErrRunLimitExceeded, 78 }) 79 } 80 81 pushops := append(pushdataops, OP_FALSE, OP_1NEGATE, OP_NOP) 82 for _, op := range pushops { 83 cases = append(cases, testStruct{ 84 op: op, 85 startVM: &virtualMachine{ 86 runLimit: 0, 87 dataStack: [][]byte{}, 88 }, 89 wantErr: ErrRunLimitExceeded, 90 }) 91 } 92 93 for i, c := range cases { 94 err := ops[c.op].fn(c.startVM) 95 96 if err != c.wantErr { 97 t.Errorf("case %d, op %s: got err = %v want %v", i, ops[c.op].name, err, c.wantErr) 98 continue 99 } 100 if c.wantErr != nil { 101 continue 102 } 103 104 if !testutil.DeepEqual(c.startVM, c.wantVM) { 105 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) 106 } 107 } 108 } 109 110 func TestPushDataBytes(t *testing.T) { 111 type test struct { 112 data []byte 113 want []byte 114 } 115 cases := []test{{ 116 data: nil, 117 want: []byte{byte(OP_0)}, 118 }, { 119 data: make([]byte, 255), 120 want: append([]byte{byte(OP_PUSHDATA1), 0xff}, make([]byte, 255)...), 121 }, { 122 data: make([]byte, 1<<8), 123 want: append([]byte{byte(OP_PUSHDATA2), 0, 1}, make([]byte, 1<<8)...), 124 }, { 125 data: make([]byte, 1<<16), 126 want: append([]byte{byte(OP_PUSHDATA4), 0, 0, 1, 0}, make([]byte, 1<<16)...), 127 }} 128 129 for i := 1; i <= 75; i++ { 130 cases = append(cases, test{ 131 data: make([]byte, i), 132 want: append([]byte{byte(OP_DATA_1) - 1 + byte(i)}, make([]byte, i)...), 133 }) 134 } 135 136 for _, c := range cases { 137 got := PushdataBytes(c.data) 138 139 dl := len(c.data) 140 if dl > 10 { 141 dl = 10 142 } 143 if !bytes.Equal(got, c.want) { 144 t.Errorf("PushdataBytes(%x...) = %x...[%d] want %x...[%d]", c.data[:dl], got[:dl], len(got), c.want[:dl], len(c.want)) 145 } 146 } 147 } 148 149 func TestPushdataInt64(t *testing.T) { 150 type test struct { 151 num int64 152 want []byte 153 } 154 cases := []test{{ 155 num: 0, 156 want: []byte{byte(OP_0)}, 157 }, { 158 num: 17, 159 want: []byte{byte(OP_DATA_1), 0x11}, 160 }, { 161 num: 255, 162 want: []byte{byte(OP_DATA_1), 0xff}, 163 }, { 164 num: 256, 165 want: []byte{byte(OP_DATA_2), 0x00, 0x01}, 166 }, { 167 num: -1, 168 want: []byte{byte(OP_DATA_8), 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 169 }, { 170 num: -2, 171 want: []byte{byte(OP_DATA_8), 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 172 }} 173 174 for i := 1; i <= 16; i++ { 175 cases = append(cases, test{ 176 num: int64(i), 177 want: []byte{byte(OP_1) - 1 + byte(i)}, 178 }) 179 } 180 181 for _, c := range cases { 182 got := PushdataInt64(c.num) 183 184 if !bytes.Equal(got, c.want) { 185 t.Errorf("PushdataInt64(%d) = %x want %x", c.num, got, c.want) 186 } 187 } 188 }