github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/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{{}, {}, Uint64Bytes(50000)}, 161 }, 162 wantErr: ErrRunLimitExceeded, 163 }, { 164 op: OP_CHECKPREDICATE, 165 startVM: &virtualMachine{ 166 runLimit: 50000, 167 dataStack: [][]byte{{0x05}, {0x07}, {0x02}, {byte(OP_ADD), byte(OP_12), byte(OP_NUMEQUAL)}, {}}, 168 }, 169 wantVM: &virtualMachine{ 170 deferredCost: -49968, 171 dataStack: [][]byte{{0x01}}, 172 }, 173 }, { 174 // stack underflow in child vm should produce false result in parent vm 175 op: OP_CHECKPREDICATE, 176 startVM: &virtualMachine{ 177 runLimit: 50000, 178 dataStack: [][]byte{{0x05}, {0x07}, {0x01}, {byte(OP_ADD), byte(OP_DATA_12), byte(OP_NUMEQUAL)}, {}}, 179 }, 180 wantVM: &virtualMachine{ 181 deferredCost: -49954, 182 dataStack: [][]byte{{0x05}, {}}, 183 }, 184 }} 185 186 limitChecks := []Op{ 187 OP_CHECKPREDICATE, OP_VERIFY, OP_FAIL, 188 } 189 190 for _, op := range limitChecks { 191 cases = append(cases, testStruct{ 192 op: op, 193 startVM: &virtualMachine{runLimit: 0}, 194 wantErr: ErrRunLimitExceeded, 195 }) 196 } 197 198 for i, c := range cases { 199 err := ops[c.op].fn(c.startVM) 200 201 if err != c.wantErr { 202 t.Errorf("case %d, op %s: got err = %v want %v", i, c.op.String(), err, c.wantErr) 203 continue 204 } 205 if c.wantErr != nil { 206 continue 207 } 208 209 if !testutil.DeepEqual(c.startVM, c.wantVM) { 210 t.Errorf("case %d, op %s: unexpected vm result\n\tgot: %+v\n\twant: %+v\n", i, c.op.String(), c.startVM, c.wantVM) 211 } 212 } 213 }