github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/control_test.go (about) 1 package vm 2 3 import ( 4 "testing" 5 6 "github.com/bytom/bytom/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 }