github.com/calmw/ethereum@v0.1.1/core/vm/instructions_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "fmt" 23 "math/big" 24 "os" 25 "testing" 26 27 "github.com/calmw/ethereum/common" 28 "github.com/calmw/ethereum/core/rawdb" 29 "github.com/calmw/ethereum/core/state" 30 "github.com/calmw/ethereum/core/types" 31 "github.com/calmw/ethereum/crypto" 32 "github.com/calmw/ethereum/params" 33 "github.com/holiman/uint256" 34 ) 35 36 type TwoOperandTestcase struct { 37 X string 38 Y string 39 Expected string 40 } 41 42 type twoOperandParams struct { 43 x string 44 y string 45 } 46 47 var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" 48 var commonParams []*twoOperandParams 49 var twoOpMethods map[string]executionFunc 50 51 type contractRef struct { 52 addr common.Address 53 } 54 55 func (c contractRef) Address() common.Address { 56 return c.addr 57 } 58 59 func init() { 60 // Params is a list of common edgecases that should be used for some common tests 61 params := []string{ 62 "0000000000000000000000000000000000000000000000000000000000000000", // 0 63 "0000000000000000000000000000000000000000000000000000000000000001", // +1 64 "0000000000000000000000000000000000000000000000000000000000000005", // +5 65 "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1 66 "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max 67 "8000000000000000000000000000000000000000000000000000000000000000", // - max 68 "8000000000000000000000000000000000000000000000000000000000000001", // - max+1 69 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5 70 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1 71 } 72 // Params are combined so each param is used on each 'side' 73 commonParams = make([]*twoOperandParams, len(params)*len(params)) 74 for i, x := range params { 75 for j, y := range params { 76 commonParams[i*len(params)+j] = &twoOperandParams{x, y} 77 } 78 } 79 twoOpMethods = map[string]executionFunc{ 80 "add": opAdd, 81 "sub": opSub, 82 "mul": opMul, 83 "div": opDiv, 84 "sdiv": opSdiv, 85 "mod": opMod, 86 "smod": opSmod, 87 "exp": opExp, 88 "signext": opSignExtend, 89 "lt": opLt, 90 "gt": opGt, 91 "slt": opSlt, 92 "sgt": opSgt, 93 "eq": opEq, 94 "and": opAnd, 95 "or": opOr, 96 "xor": opXor, 97 "byte": opByte, 98 "shl": opSHL, 99 "shr": opSHR, 100 "sar": opSAR, 101 } 102 } 103 104 func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { 105 var ( 106 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 107 stack = newstack() 108 pc = uint64(0) 109 evmInterpreter = env.interpreter 110 ) 111 112 for i, test := range tests { 113 x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.X)) 114 y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Y)) 115 expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected)) 116 stack.push(x) 117 stack.push(y) 118 opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) 119 if len(stack.data) != 1 { 120 t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data)) 121 } 122 actual := stack.pop() 123 124 if actual.Cmp(expected) != 0 { 125 t.Errorf("Testcase %v %d, %v(%x, %x): expected %x, got %x", name, i, name, x, y, expected, actual) 126 } 127 } 128 } 129 130 func TestByteOp(t *testing.T) { 131 tests := []TwoOperandTestcase{ 132 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"}, 133 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"}, 134 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"}, 135 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"}, 136 {"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"}, 137 {"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"}, 138 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"}, 139 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"}, 140 } 141 testTwoOperandOp(t, tests, opByte, "byte") 142 } 143 144 func TestSHL(t *testing.T) { 145 // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left 146 tests := []TwoOperandTestcase{ 147 {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"}, 148 {"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, 149 {"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, 150 {"0000000000000000000000000000000000000000000000000000000000000001", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, 151 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 152 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, 153 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, 154 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, 155 {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, 156 {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, 157 } 158 testTwoOperandOp(t, tests, opSHL, "shl") 159 } 160 161 func TestSHR(t *testing.T) { 162 // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right 163 tests := []TwoOperandTestcase{ 164 {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, 165 {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, 166 {"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"}, 167 {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, 168 {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, 169 {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, 170 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 171 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 172 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, 173 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, 174 {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, 175 } 176 testTwoOperandOp(t, tests, opSHR, "shr") 177 } 178 179 func TestSAR(t *testing.T) { 180 // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right 181 tests := []TwoOperandTestcase{ 182 {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, 183 {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, 184 {"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"}, 185 {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 186 {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 187 {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 188 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 189 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 190 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 191 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, 192 {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, 193 {"4000000000000000000000000000000000000000000000000000000000000000", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, 194 {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "f8", "000000000000000000000000000000000000000000000000000000000000007f"}, 195 {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, 196 {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000000"}, 197 {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, 198 } 199 200 testTwoOperandOp(t, tests, opSAR, "sar") 201 } 202 203 func TestAddMod(t *testing.T) { 204 var ( 205 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 206 stack = newstack() 207 evmInterpreter = NewEVMInterpreter(env) 208 pc = uint64(0) 209 ) 210 tests := []struct { 211 x string 212 y string 213 z string 214 expected string 215 }{ 216 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 217 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", 218 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 219 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", 220 }, 221 } 222 // x + y = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd 223 // in 256 bit repr, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd 224 225 for i, test := range tests { 226 x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.x)) 227 y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.y)) 228 z := new(uint256.Int).SetBytes(common.Hex2Bytes(test.z)) 229 expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.expected)) 230 stack.push(z) 231 stack.push(y) 232 stack.push(x) 233 opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) 234 actual := stack.pop() 235 if actual.Cmp(expected) != 0 { 236 t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual) 237 } 238 } 239 } 240 241 // utility function to fill the json-file with testcases 242 // Enable this test to generate the 'testcases_xx.json' files 243 func TestWriteExpectedValues(t *testing.T) { 244 t.Skip("Enable this test to create json test cases.") 245 246 // getResult is a convenience function to generate the expected values 247 getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { 248 var ( 249 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 250 stack = newstack() 251 pc = uint64(0) 252 interpreter = env.interpreter 253 ) 254 result := make([]TwoOperandTestcase, len(args)) 255 for i, param := range args { 256 x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x)) 257 y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y)) 258 stack.push(x) 259 stack.push(y) 260 opFn(&pc, interpreter, &ScopeContext{nil, stack, nil}) 261 actual := stack.pop() 262 result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)} 263 } 264 return result 265 } 266 267 for name, method := range twoOpMethods { 268 data, err := json.Marshal(getResult(commonParams, method)) 269 if err != nil { 270 t.Fatal(err) 271 } 272 _ = os.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) 273 if err != nil { 274 t.Fatal(err) 275 } 276 } 277 } 278 279 // TestJsonTestcases runs through all the testcases defined as json-files 280 func TestJsonTestcases(t *testing.T) { 281 for name := range twoOpMethods { 282 data, err := os.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) 283 if err != nil { 284 t.Fatal("Failed to read file", err) 285 } 286 var testcases []TwoOperandTestcase 287 json.Unmarshal(data, &testcases) 288 testTwoOperandOp(t, testcases, twoOpMethods[name], name) 289 } 290 } 291 292 func opBenchmark(bench *testing.B, op executionFunc, args ...string) { 293 var ( 294 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 295 stack = newstack() 296 scope = &ScopeContext{nil, stack, nil} 297 evmInterpreter = NewEVMInterpreter(env) 298 ) 299 300 env.interpreter = evmInterpreter 301 // convert args 302 intArgs := make([]*uint256.Int, len(args)) 303 for i, arg := range args { 304 intArgs[i] = new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) 305 } 306 pc := uint64(0) 307 bench.ResetTimer() 308 for i := 0; i < bench.N; i++ { 309 for _, arg := range intArgs { 310 stack.push(arg) 311 } 312 op(&pc, evmInterpreter, scope) 313 stack.pop() 314 } 315 bench.StopTimer() 316 317 for i, arg := range args { 318 want := new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) 319 if have := intArgs[i]; !want.Eq(have) { 320 bench.Fatalf("input #%d mutated, have %x want %x", i, have, want) 321 } 322 } 323 } 324 325 func BenchmarkOpAdd64(b *testing.B) { 326 x := "ffffffff" 327 y := "fd37f3e2bba2c4f" 328 329 opBenchmark(b, opAdd, x, y) 330 } 331 332 func BenchmarkOpAdd128(b *testing.B) { 333 x := "ffffffffffffffff" 334 y := "f5470b43c6549b016288e9a65629687" 335 336 opBenchmark(b, opAdd, x, y) 337 } 338 339 func BenchmarkOpAdd256(b *testing.B) { 340 x := "0802431afcbce1fc194c9eaa417b2fb67dc75a95db0bc7ec6b1c8af11df6a1da9" 341 y := "a1f5aac137876480252e5dcac62c354ec0d42b76b0642b6181ed099849ea1d57" 342 343 opBenchmark(b, opAdd, x, y) 344 } 345 346 func BenchmarkOpSub64(b *testing.B) { 347 x := "51022b6317003a9d" 348 y := "a20456c62e00753a" 349 350 opBenchmark(b, opSub, x, y) 351 } 352 353 func BenchmarkOpSub128(b *testing.B) { 354 x := "4dde30faaacdc14d00327aac314e915d" 355 y := "9bbc61f5559b829a0064f558629d22ba" 356 357 opBenchmark(b, opSub, x, y) 358 } 359 360 func BenchmarkOpSub256(b *testing.B) { 361 x := "4bfcd8bb2ac462735b48a17580690283980aa2d679f091c64364594df113ea37" 362 y := "97f9b1765588c4e6b69142eb00d20507301545acf3e1238c86c8b29be227d46e" 363 364 opBenchmark(b, opSub, x, y) 365 } 366 367 func BenchmarkOpMul(b *testing.B) { 368 x := alphabetSoup 369 y := alphabetSoup 370 371 opBenchmark(b, opMul, x, y) 372 } 373 374 func BenchmarkOpDiv256(b *testing.B) { 375 x := "ff3f9014f20db29ae04af2c2d265de17" 376 y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611" 377 opBenchmark(b, opDiv, x, y) 378 } 379 380 func BenchmarkOpDiv128(b *testing.B) { 381 x := "fdedc7f10142ff97" 382 y := "fbdfda0e2ce356173d1993d5f70a2b11" 383 opBenchmark(b, opDiv, x, y) 384 } 385 386 func BenchmarkOpDiv64(b *testing.B) { 387 x := "fcb34eb3" 388 y := "f97180878e839129" 389 opBenchmark(b, opDiv, x, y) 390 } 391 392 func BenchmarkOpSdiv(b *testing.B) { 393 x := "ff3f9014f20db29ae04af2c2d265de17" 394 y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611" 395 396 opBenchmark(b, opSdiv, x, y) 397 } 398 399 func BenchmarkOpMod(b *testing.B) { 400 x := alphabetSoup 401 y := alphabetSoup 402 403 opBenchmark(b, opMod, x, y) 404 } 405 406 func BenchmarkOpSmod(b *testing.B) { 407 x := alphabetSoup 408 y := alphabetSoup 409 410 opBenchmark(b, opSmod, x, y) 411 } 412 413 func BenchmarkOpExp(b *testing.B) { 414 x := alphabetSoup 415 y := alphabetSoup 416 417 opBenchmark(b, opExp, x, y) 418 } 419 420 func BenchmarkOpSignExtend(b *testing.B) { 421 x := alphabetSoup 422 y := alphabetSoup 423 424 opBenchmark(b, opSignExtend, x, y) 425 } 426 427 func BenchmarkOpLt(b *testing.B) { 428 x := alphabetSoup 429 y := alphabetSoup 430 431 opBenchmark(b, opLt, x, y) 432 } 433 434 func BenchmarkOpGt(b *testing.B) { 435 x := alphabetSoup 436 y := alphabetSoup 437 438 opBenchmark(b, opGt, x, y) 439 } 440 441 func BenchmarkOpSlt(b *testing.B) { 442 x := alphabetSoup 443 y := alphabetSoup 444 445 opBenchmark(b, opSlt, x, y) 446 } 447 448 func BenchmarkOpSgt(b *testing.B) { 449 x := alphabetSoup 450 y := alphabetSoup 451 452 opBenchmark(b, opSgt, x, y) 453 } 454 455 func BenchmarkOpEq(b *testing.B) { 456 x := alphabetSoup 457 y := alphabetSoup 458 459 opBenchmark(b, opEq, x, y) 460 } 461 func BenchmarkOpEq2(b *testing.B) { 462 x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" 463 y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe" 464 opBenchmark(b, opEq, x, y) 465 } 466 func BenchmarkOpAnd(b *testing.B) { 467 x := alphabetSoup 468 y := alphabetSoup 469 470 opBenchmark(b, opAnd, x, y) 471 } 472 473 func BenchmarkOpOr(b *testing.B) { 474 x := alphabetSoup 475 y := alphabetSoup 476 477 opBenchmark(b, opOr, x, y) 478 } 479 480 func BenchmarkOpXor(b *testing.B) { 481 x := alphabetSoup 482 y := alphabetSoup 483 484 opBenchmark(b, opXor, x, y) 485 } 486 487 func BenchmarkOpByte(b *testing.B) { 488 x := alphabetSoup 489 y := alphabetSoup 490 491 opBenchmark(b, opByte, x, y) 492 } 493 494 func BenchmarkOpAddmod(b *testing.B) { 495 x := alphabetSoup 496 y := alphabetSoup 497 z := alphabetSoup 498 499 opBenchmark(b, opAddmod, x, y, z) 500 } 501 502 func BenchmarkOpMulmod(b *testing.B) { 503 x := alphabetSoup 504 y := alphabetSoup 505 z := alphabetSoup 506 507 opBenchmark(b, opMulmod, x, y, z) 508 } 509 510 func BenchmarkOpSHL(b *testing.B) { 511 x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" 512 y := "ff" 513 514 opBenchmark(b, opSHL, x, y) 515 } 516 func BenchmarkOpSHR(b *testing.B) { 517 x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" 518 y := "ff" 519 520 opBenchmark(b, opSHR, x, y) 521 } 522 func BenchmarkOpSAR(b *testing.B) { 523 x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" 524 y := "ff" 525 526 opBenchmark(b, opSAR, x, y) 527 } 528 func BenchmarkOpIsZero(b *testing.B) { 529 x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" 530 opBenchmark(b, opIszero, x) 531 } 532 533 func TestOpMstore(t *testing.T) { 534 var ( 535 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 536 stack = newstack() 537 mem = NewMemory() 538 evmInterpreter = NewEVMInterpreter(env) 539 ) 540 541 env.interpreter = evmInterpreter 542 mem.Resize(64) 543 pc := uint64(0) 544 v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700" 545 stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v))) 546 stack.push(new(uint256.Int)) 547 opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) 548 if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v { 549 t.Fatalf("Mstore fail, got %v, expected %v", got, v) 550 } 551 stack.push(new(uint256.Int).SetUint64(0x1)) 552 stack.push(new(uint256.Int)) 553 opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) 554 if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" { 555 t.Fatalf("Mstore failed to overwrite previous value") 556 } 557 } 558 559 func BenchmarkOpMstore(bench *testing.B) { 560 var ( 561 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 562 stack = newstack() 563 mem = NewMemory() 564 evmInterpreter = NewEVMInterpreter(env) 565 ) 566 567 env.interpreter = evmInterpreter 568 mem.Resize(64) 569 pc := uint64(0) 570 memStart := new(uint256.Int) 571 value := new(uint256.Int).SetUint64(0x1337) 572 573 bench.ResetTimer() 574 for i := 0; i < bench.N; i++ { 575 stack.push(value) 576 stack.push(memStart) 577 opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) 578 } 579 } 580 581 func TestOpTstore(t *testing.T) { 582 var ( 583 statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) 584 env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{}) 585 stack = newstack() 586 mem = NewMemory() 587 evmInterpreter = NewEVMInterpreter(env) 588 caller = common.Address{} 589 to = common.Address{1} 590 contractRef = contractRef{caller} 591 contract = NewContract(contractRef, AccountRef(to), new(big.Int), 0) 592 scopeContext = ScopeContext{mem, stack, contract} 593 value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700") 594 ) 595 596 // Add a stateObject for the caller and the contract being called 597 statedb.CreateAccount(caller) 598 statedb.CreateAccount(to) 599 600 env.interpreter = evmInterpreter 601 pc := uint64(0) 602 // push the value to the stack 603 stack.push(new(uint256.Int).SetBytes(value)) 604 // push the location to the stack 605 stack.push(new(uint256.Int)) 606 opTstore(&pc, evmInterpreter, &scopeContext) 607 // there should be no elements on the stack after TSTORE 608 if stack.len() != 0 { 609 t.Fatal("stack wrong size") 610 } 611 // push the location to the stack 612 stack.push(new(uint256.Int)) 613 opTload(&pc, evmInterpreter, &scopeContext) 614 // there should be one element on the stack after TLOAD 615 if stack.len() != 1 { 616 t.Fatal("stack wrong size") 617 } 618 val := stack.peek() 619 if !bytes.Equal(val.Bytes(), value) { 620 t.Fatal("incorrect element read from transient storage") 621 } 622 } 623 624 func BenchmarkOpKeccak256(bench *testing.B) { 625 var ( 626 env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) 627 stack = newstack() 628 mem = NewMemory() 629 evmInterpreter = NewEVMInterpreter(env) 630 ) 631 env.interpreter = evmInterpreter 632 mem.Resize(32) 633 pc := uint64(0) 634 start := new(uint256.Int) 635 636 bench.ResetTimer() 637 for i := 0; i < bench.N; i++ { 638 stack.push(uint256.NewInt(32)) 639 stack.push(start) 640 opKeccak256(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) 641 } 642 } 643 644 func TestCreate2Addreses(t *testing.T) { 645 type testcase struct { 646 origin string 647 salt string 648 code string 649 expected string 650 } 651 652 for i, tt := range []testcase{ 653 { 654 origin: "0x0000000000000000000000000000000000000000", 655 salt: "0x0000000000000000000000000000000000000000", 656 code: "0x00", 657 expected: "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38", 658 }, 659 { 660 origin: "0xdeadbeef00000000000000000000000000000000", 661 salt: "0x0000000000000000000000000000000000000000", 662 code: "0x00", 663 expected: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3", 664 }, 665 { 666 origin: "0xdeadbeef00000000000000000000000000000000", 667 salt: "0xfeed000000000000000000000000000000000000", 668 code: "0x00", 669 expected: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833", 670 }, 671 { 672 origin: "0x0000000000000000000000000000000000000000", 673 salt: "0x0000000000000000000000000000000000000000", 674 code: "0xdeadbeef", 675 expected: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e", 676 }, 677 { 678 origin: "0x00000000000000000000000000000000deadbeef", 679 salt: "0xcafebabe", 680 code: "0xdeadbeef", 681 expected: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7", 682 }, 683 { 684 origin: "0x00000000000000000000000000000000deadbeef", 685 salt: "0xcafebabe", 686 code: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", 687 expected: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C", 688 }, 689 { 690 origin: "0x0000000000000000000000000000000000000000", 691 salt: "0x0000000000000000000000000000000000000000", 692 code: "0x", 693 expected: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0", 694 }, 695 } { 696 origin := common.BytesToAddress(common.FromHex(tt.origin)) 697 salt := common.BytesToHash(common.FromHex(tt.salt)) 698 code := common.FromHex(tt.code) 699 codeHash := crypto.Keccak256(code) 700 address := crypto.CreateAddress2(origin, salt, codeHash) 701 /* 702 stack := newstack() 703 // salt, but we don't need that for this test 704 stack.push(big.NewInt(int64(len(code)))) //size 705 stack.push(big.NewInt(0)) // memstart 706 stack.push(big.NewInt(0)) // value 707 gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0) 708 fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String()) 709 */ 710 expected := common.BytesToAddress(common.FromHex(tt.expected)) 711 if !bytes.Equal(expected.Bytes(), address.Bytes()) { 712 t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String()) 713 } 714 } 715 } 716 717 func TestRandom(t *testing.T) { 718 type testcase struct { 719 name string 720 random common.Hash 721 } 722 723 for _, tt := range []testcase{ 724 {name: "empty hash", random: common.Hash{}}, 725 {name: "1", random: common.Hash{0}}, 726 {name: "emptyCodeHash", random: emptyCodeHash}, 727 {name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})}, 728 } { 729 var ( 730 env = NewEVM(BlockContext{Random: &tt.random}, TxContext{}, nil, params.TestChainConfig, Config{}) 731 stack = newstack() 732 pc = uint64(0) 733 evmInterpreter = env.interpreter 734 ) 735 opRandom(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) 736 if len(stack.data) != 1 { 737 t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data)) 738 } 739 actual := stack.pop() 740 expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.random.Bytes())) 741 if overflow { 742 t.Errorf("Testcase %v: invalid overflow", tt.name) 743 } 744 if actual.Cmp(expected) != 0 { 745 t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual) 746 } 747 } 748 }