From 45d0287943418356d93af08d9037b7986fe6e7a0 Mon Sep 17 00:00:00 2001 From: Daniel Ziabko Date: Thu, 26 Sep 2019 18:36:46 -0400 Subject: [PATCH] Agharta/eip145 bitwise shift (#54) * Agharta/eip1014 create2 (#5) * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Added error handling for precompiles and removed skipped tests (#54) * Created branch & added new opcode into opcode.go file * Implemented create function for Create2 contracts * Added create2 function * Implemented create function for Create2 contracts * Rebased with development 2nd * Cleaned up code/comments & removed print statements. * Cleaned up comments & reverted go.mod & go.sum to original * Removed Constantinople tests & some tests involving non-implemented opcodes (EIP 145/1052) to pass CI. * Fixed removal of stBugs, stShift & stExtCodeHash tests * Fixed instructions_test salt parameter passed to CreateAddress2. * Changed local vars to camel case * Fixed error refactor. * Cleaned up comments. Skipped tests involving EIP684 (Collision). * Fixed error checking for evm.Run(). * Adding STC bugfix for Agharta dev (#7) * docs: badges badges badges badges (#80) * docs: add gitter badge * docs: add circle-ci badge * Update README.md * Update README.md * Update README.md * State trie clearing fix (#82) * Fixed commit state trie clearing detail * Added stc to miner work state committing * Finished SAR, SHR, SHL opcodes. EIP 145 * Fixed shift instructions' return values. Added check for ConstantinopleFix fork in tests for skipping Constantinople tests. * Removed stShift as unsupportedDir. * Agharta/eip1014 create2 (#5) * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Added error handling for precompiles and removed skipped tests (#54) * Created branch & added new opcode into opcode.go file * Implemented create function for Create2 contracts * Added create2 function * Implemented create function for Create2 contracts * Rebased with development 2nd * Cleaned up code/comments & removed print statements. * Cleaned up comments & reverted go.mod & go.sum to original * Removed Constantinople tests & some tests involving non-implemented opcodes (EIP 145/1052) to pass CI. * Fixed removal of stBugs, stShift & stExtCodeHash tests * Fixed instructions_test salt parameter passed to CreateAddress2. * Changed local vars to camel case * Fixed error refactor. * Cleaned up comments. Skipped tests involving EIP684 (Collision). * Fixed error checking for evm.Run(). * Fixed shift instructions' return values. Added check for ConstantinopleFix fork in tests for skipping Constantinople tests. * Finished SAR, SHR, SHL opcodes. EIP 145 * Removed stShift as unsupportedDir. * Rebased with development. * Removed duplicated exec(). * Revert "Agharta/eip1014 create2 (#5)" This reverts commit 641082aa960d0115fe9079255b7f34866cd66733. * Added back isAgharta check in ruleSet. * Fixed IsAgharta check. * Agharta/eip1014 create2 (#5) * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Added error handling for precompiles and removed skipped tests (#54) * Created branch & added new opcode into opcode.go file * Implemented create function for Create2 contracts * Added create2 function * Implemented create function for Create2 contracts * Rebased with development 2nd * Cleaned up code/comments & removed print statements. * Cleaned up comments & reverted go.mod & go.sum to original * Removed Constantinople tests & some tests involving non-implemented opcodes (EIP 145/1052) to pass CI. * Fixed removal of stBugs, stShift & stExtCodeHash tests * Fixed instructions_test salt parameter passed to CreateAddress2. * Changed local vars to camel case * Fixed error refactor. * Cleaned up comments. Skipped tests involving EIP684 (Collision). * Fixed error checking for evm.Run(). * Fixed shift instructions' return values. Added check for ConstantinopleFix fork in tests for skipping Constantinople tests. * Finished SAR, SHR, SHL opcodes. EIP 145 * Removed stShift as unsupportedDir. * Agharta/eip1014 create2 (#5) * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Atlantis config (#50) * Added Atlantis fork in builtin mainnet and morden config * Fixed difficulty test at 10_000_000 block (Atlantis) * Added tests for Atlantis difficulty transition * cmd/geth rename client (#52) * Added error handling for precompiles and removed skipped tests (#54) * Makefile and README updates (#49) * wip makefile updates * Fixed makefile and updated README * Fixed readme changes * Added go module documentation and fixed wiki links to EP * Added go modules on for makefile commands and documentation * makefile: fix version string (#57) * Dockerfile configuration (#56) * Added Dockerfile setup * Added Dockerfile setup * Fixed build command * Removed private repo authentication in Dockerfile * Enforced go modules on for every part of the test command (#60) * docs: update readme (#59) * docs: update readme * Update README.md * Update README.md * ci: prepare assets for release (#64) * ci: prepare assets for release * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: fix indentation * ci: release in build step * ci: calculate sha256sums * ci: store artifacts * ci: do a reverse copy * ci: fix bash syntax * ci: indicate os in release * ci: pushd and pop'd ;) * Receipt fixes and state trie clearing detail (#62) * receipt and state trie clearing changes * Fixed receipt storage and added backward compatible decoding * Implemented create function for Create2 contracts * Created branch & added new opcode into opcode.go file * Added create2 function * Implemented create function for Create2 contracts * Finished Create2 opcode & cleaned up comments * Created branch & added new opcode into opcode.go file * Added create2 function * Added error handling for precompiles and removed skipped tests (#54) * Created branch & added new opcode into opcode.go file * Implemented create function for Create2 contracts * Added create2 function * Implemented create function for Create2 contracts * Rebased with development 2nd * Cleaned up code/comments & removed print statements. * Cleaned up comments & reverted go.mod & go.sum to original * Removed Constantinople tests & some tests involving non-implemented opcodes (EIP 145/1052) to pass CI. * Fixed removal of stBugs, stShift & stExtCodeHash tests * Fixed instructions_test salt parameter passed to CreateAddress2. * Changed local vars to camel case * Fixed error refactor. * Cleaned up comments. Skipped tests involving EIP684 (Collision). * Fixed error checking for evm.Run(). * Fixed shift instructions' return values. Added check for ConstantinopleFix fork in tests for skipping Constantinople tests. * Finished SAR, SHR, SHL opcodes. EIP 145 * Rebased with development. * Revert "Agharta/eip1014 create2 (#5)" This reverts commit 641082aa960d0115fe9079255b7f34866cd66733. * Added back isAgharta check in ruleSet. * Fixed IsAgharta check. * Removed ConstantinopleFix flag to skip Constantinople. * Removed ConstantinopleFix flag to skip Constantinople. * Reverted go.mod file to original. * Removed unused ShiftTest struct. * Fixed formatting in opcodes.go & gas.go --- core/vm/gas.go | 3 + core/vm/instructions.go | 47 +++++++++++ core/vm/instructions_test.go | 159 +++++++++++++++++++++++++++++++++++ core/vm/jump_table.go | 15 ++++ core/vm/opcodes.go | 9 ++ go.mod | 2 +- tests/state_test.go | 1 - 7 files changed, 234 insertions(+), 2 deletions(-) diff --git a/core/vm/gas.go b/core/vm/gas.go index 448711ad..99af6004 100644 --- a/core/vm/gas.go +++ b/core/vm/gas.go @@ -136,6 +136,9 @@ var _baseCheck = map[OpCode]req{ XOR: {2, GasFastestStep, 1}, NOT: {1, GasFastestStep, 1}, BYTE: {2, GasFastestStep, 1}, + SHL: {2, GasFastestStep, 1}, + SHR: {2, GasFastestStep, 1}, + SAR: {2, GasFastestStep, 1}, CALLDATALOAD: {1, GasFastestStep, 1}, CALLDATACOPY: {3, GasFastestStep, 1}, MLOAD: {1, GasFastestStep, 1}, diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 62bd2d14..ea4f9229 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -22,6 +22,7 @@ import ( "github.com/eth-classic/go-ethereum/common" "github.com/eth-classic/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/common/math" ) var callStipend = big.NewInt(2300) // Free gas given at beginning of call. @@ -273,6 +274,52 @@ func opMulmod(pc *uint64, env Environment, contract *Contract, memory *Memory, s return nil, nil } +func opSHL(pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) { + shift, value := math.U256(stack.pop()), math.U256(stack.pop()) + + if shift.Cmp(big.NewInt(256)) >= 0 { + value.SetUint64(0) + } else { + n := uint(shift.Uint64()) + math.U256(value.Lsh(value, n)) + } + stack.push(value) + return nil, nil +} + +func opSHR(pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) { + shift, value := math.U256(stack.pop()), math.U256(stack.pop()) + + if shift.Cmp(big.NewInt(256)) >= 0 { + value.SetUint64(0) + } else { + n := uint(shift.Uint64()) + math.U256(value.Rsh(value, n)) + } + stack.push(value) + return nil, nil +} + +func opSAR(pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) { + shift, value := math.U256(stack.pop()), math.S256(stack.pop()) + + if shift.Cmp(big.NewInt(256)) >= 0 { + if value.Sign() >= 0 { + value.SetUint64(0) + } else { + value.SetInt64(-1) + } + + stack.push(math.U256(value)) + } else { + n := uint(shift.Uint64()) + // value + value.Rsh(value, n) + stack.push(math.U256(value)) + } + return nil, nil +} + func opSha3(pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64())) diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 7f68395c..99aedb3e 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -19,6 +19,7 @@ package vm import ( "bytes" "testing" + "math/big" "github.com/eth-classic/go-ethereum/common" "github.com/eth-classic/go-ethereum/crypto" @@ -92,3 +93,161 @@ func TestCreate2Addresses(t *testing.T) { } } + +type TwoOperandTestcase struct { + X string + Y string + Expected string +} + +type twoOperandParams struct { + x string + y string +} + +var commonParams []*twoOperandParams +var twoOpMethods map[string]instrFn + +func init() { + + // Params is a list of common edgecases that should be used for some common tests + params := []string{ + "0000000000000000000000000000000000000000000000000000000000000000", // 0 + "0000000000000000000000000000000000000000000000000000000000000001", // +1 + "0000000000000000000000000000000000000000000000000000000000000005", // +5 + "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1 + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max + "8000000000000000000000000000000000000000000000000000000000000000", // - max + "8000000000000000000000000000000000000000000000000000000000000001", // - max+1 + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1 + } + // Params are combined so each param is used on each 'side' + commonParams = make([]*twoOperandParams, len(params)*len(params)) + for i, x := range params { + for j, y := range params { + commonParams[i*len(params)+j] = &twoOperandParams{x, y} + } + } + twoOpMethods = map[string]instrFn{ + "add": opAdd, + "sub": opSub, + "mul": opMul, + "div": opDiv, + "sdiv": opSdiv, + "mod": opMod, + "smod": opSmod, + "exp": opExp, + "signext": opSignExtend, + "lt": opLt, + "gt": opGt, + "slt": opSlt, + "sgt": opSgt, + "eq": opEq, + "and": opAnd, + "or": opOr, + "xor": opXor, + "byte": opByte, + "shl": opSHL, + "shr": opSHR, + "sar": opSAR, + } +} + +func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn instrFn, name string) { + + var ( + stack = newstack() + pc = uint64(0) + ) + + for i, test := range tests { + x := new(big.Int).SetBytes(common.Hex2Bytes(test.X)) + y := new(big.Int).SetBytes(common.Hex2Bytes(test.Y)) + expected := new(big.Int).SetBytes(common.Hex2Bytes(test.Expected)) + stack.push(x) + stack.push(y) + opFn(&pc, nil, nil, nil, stack) + actual := stack.pop() + + if actual.Cmp(expected) != 0 { + t.Errorf("Testcase %v %d, %v(%x, %x): expected %x, got %x", name, i, name, x, y, expected, actual) + } else { + t.Log("Worked") + } + + } +} + +func TestByteOp(t *testing.T) { + tests := []TwoOperandTestcase{ + {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"}, + {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"}, + {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"}, + {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"}, + {"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"}, + {"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"}, + } + testTwoOperandOp(t, tests, opByte, "byte") +} + +func TestSHL(t *testing.T) { + // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left + tests := []TwoOperandTestcase{ + {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"}, + {"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, + {"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"0000000000000000000000000000000000000000000000000000000000000001", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, + } + testTwoOperandOp(t, tests, opSHL, "shl") +} + +func TestSHR(t *testing.T) { + // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right + tests := []TwoOperandTestcase{ + {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, + } + testTwoOperandOp(t, tests, opSHR, "shr") +} + +func TestSAR(t *testing.T) { + // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right + tests := []TwoOperandTestcase{ + {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"4000000000000000000000000000000000000000000000000000000000000000", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "f8", "000000000000000000000000000000000000000000000000000000000000007f"}, + {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, + {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000000"}, + {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, + } + + testTwoOperandOp(t, tests, opSAR, "sar") +} diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 7042d962..56eebff5 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -67,6 +67,21 @@ func newJumpTable(ruleset RuleSet, blockNumber *big.Int) vmJumpTable { } if ruleset.IsAgharta(blockNumber) { + + jumpTable[SHL] = jumpPtr{ + fn: opSHL, + valid: true, + } + + jumpTable[SHR] = jumpPtr{ + fn: opSHR, + valid: true, + } + + jumpTable[SAR] = jumpPtr{ + fn: opSAR, + valid: true, + } jumpTable[CREATE2] = jumpPtr{ fn: opCreate2, valid: true, diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index a4ad9517..684678bb 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -63,6 +63,9 @@ const ( XOR NOT BYTE + SHL + SHR + SAR SHA3 = 0x20 ) @@ -236,6 +239,9 @@ var opCodeToString = map[OpCode]string{ OR: "OR", XOR: "XOR", BYTE: "BYTE", + SHL: "SHL", + SHR: "SHR", + SAR: "SAR", ADDMOD: "ADDMOD", MULMOD: "MULMOD", @@ -517,6 +523,9 @@ var stringToOp = map[string]OpCode{ "STATICCALL": STATICCALL, "REVERT": REVERT, "SUICIDE": SUICIDE, + "SHL": SHL, + "SHR": SHR, + "SAR": SAR, } func StringToOp(str string) OpCode { diff --git a/go.mod b/go.mod index 5804944f..c4cac726 100644 --- a/go.mod +++ b/go.mod @@ -36,4 +36,4 @@ require ( gopkg.in/urfave/cli.v1 v1.17.0 ) -replace github.com/eth-classic/go-ethereum/accounts/abi/bind v0.0.0-20190521151733-fe17e9e1e2ce => ./accounts/abi/bind +replace github.com/eth-classic/go-ethereum/accounts/abi/bind v0.0.0-20190521151733-fe17e9e1e2ce => ./accounts/abi/bind \ No newline at end of file diff --git a/tests/state_test.go b/tests/state_test.go index adfa4f14..e4f4cd62 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -695,7 +695,6 @@ func TestAllETH(t *testing.T) { unsupportedDirs := map[string]bool{ "stZeroKnowledge": true, "stZeroKnowledge2": true, - "stShift": true, "stExtCodeHash": true, }