Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions core/vm/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,6 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
return c.isCode(udest)
}

func (c *Contract) validJumpSubdest(udest uint64) bool {
// PC cannot go beyond len(code) and certainly can't be bigger than 63 bits.
// Don't bother checking for BEGINSUB in that case.
if int64(udest) < 0 || udest >= uint64(len(c.Code)) {
return false
}
// Only BEGINSUBs allowed for destinations
if OpCode(c.Code[udest]) != BEGINSUB {
return false
}
return c.isCode(udest)
}

// isCode returns true if the provided PC location is an actual opcode, as
// opposed to a data-segment following a PUSHN operation.
func (c *Contract) isCode(udest uint64) bool {
Expand Down
29 changes: 0 additions & 29 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ var activators = map[int]func(*JumpTable){
2200: enable2200,
1884: enable1884,
1344: enable1344,
2315: enable2315,
}

// EnableEIP enables the given EIP on the config.
Expand Down Expand Up @@ -108,34 +107,6 @@ func enable2200(jt *JumpTable) {
jt[SSTORE].dynamicGas = gasSStoreEIP2200
}

// enable2315 applies EIP-2315 (Simple Subroutines)
// - Adds opcodes that jump to and return from subroutines
func enable2315(jt *JumpTable) {
// New opcode
jt[BEGINSUB] = &operation{
execute: opBeginSub,
constantGas: GasQuickStep,
minStack: minStack(0, 0),
maxStack: maxStack(0, 0),
}
// New opcode
jt[JUMPSUB] = &operation{
execute: opJumpSub,
constantGas: GasSlowStep,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
jumps: true,
}
// New opcode
jt[RETURNSUB] = &operation{
execute: opReturnSub,
constantGas: GasFastStep,
minStack: minStack(0, 0),
maxStack: maxStack(0, 0),
jumps: true,
}
}

// enable2929 enables "EIP-2929: Gas cost increases for state access opcodes"
// https://eips.ethereum.org/EIPS/eip-2929
func enable2929(jt *JumpTable) {
Expand Down
13 changes: 0 additions & 13 deletions core/vm/gen_structlog.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 0 additions & 32 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,38 +547,6 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
return nil, nil
}

func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
return nil, ErrInvalidSubroutineEntry
}

func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
if len(callContext.rstack.data) >= 1023 {
return nil, ErrReturnStackExceeded
}
pos := callContext.stack.pop()
if !pos.IsUint64() {
return nil, ErrInvalidJump
}
posU64 := pos.Uint64()
if !callContext.contract.validJumpSubdest(posU64) {
return nil, ErrInvalidJump
}
callContext.rstack.push(uint32(*pc))
*pc = posU64 + 1
return nil, nil
}

func opReturnSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
if len(callContext.rstack.data) == 0 {
return nil, ErrInvalidRetsub
}
// Other than the check that the return stack is not empty, there is no
// need to validate the pc from 'returns', since we only ever push valid
//values onto it via jumpsub.
*pc = uint64(callContext.rstack.pop()) + 1
return nil, nil
}

func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
callContext.stack.push(new(uint256.Int).SetUint64(*pc))
return nil, nil
Expand Down
33 changes: 16 additions & 17 deletions core/vm/instructions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack = newstack()
rstack = newReturnStack()
pc = uint64(0)
evmInterpreter = env.interpreter.(*EVMInterpreter)
)
Expand All @@ -105,7 +104,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected))
stack.push(x)
stack.push(y)
opFn(&pc, evmInterpreter, &callCtx{nil, stack, rstack, nil})
opFn(&pc, evmInterpreter, &callCtx{nil, stack, nil})
if len(stack.data) != 1 {
t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data))
}
Expand Down Expand Up @@ -220,7 +219,7 @@ func TestAddMod(t *testing.T) {
stack.push(z)
stack.push(y)
stack.push(x)
opAddmod(&pc, evmInterpreter, &callCtx{nil, stack, nil, nil})
opAddmod(&pc, evmInterpreter, &callCtx{nil, stack, nil})
actual := stack.pop()
if actual.Cmp(expected) != 0 {
t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual)
Expand All @@ -231,18 +230,18 @@ func TestAddMod(t *testing.T) {
// getResult is a convenience function to generate the expected values
func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack, rstack = newstack(), newReturnStack()
pc = uint64(0)
interpreter = env.interpreter.(*EVMInterpreter)
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack = newstack()
pc = uint64(0)
interpreter = env.interpreter.(*EVMInterpreter)
)
result := make([]TwoOperandTestcase, len(args))
for i, param := range args {
x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x))
y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y))
stack.push(x)
stack.push(y)
opFn(&pc, interpreter, &callCtx{nil, stack, rstack, nil})
opFn(&pc, interpreter, &callCtx{nil, stack, nil})
actual := stack.pop()
result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)}
}
Expand Down Expand Up @@ -282,7 +281,7 @@ func TestJsonTestcases(t *testing.T) {
func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack, rstack = newstack(), newReturnStack()
stack = newstack()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)

Expand All @@ -300,7 +299,7 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
a.SetBytes(arg)
stack.push(a)
}
op(&pc, evmInterpreter, &callCtx{nil, stack, rstack, nil})
op(&pc, evmInterpreter, &callCtx{nil, stack, nil})
stack.pop()
}
}
Expand Down Expand Up @@ -516,7 +515,7 @@ func BenchmarkOpIsZero(b *testing.B) {
func TestOpMstore(t *testing.T) {
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack, rstack = newstack(), newReturnStack()
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)
Expand All @@ -526,12 +525,12 @@ func TestOpMstore(t *testing.T) {
pc := uint64(0)
v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
stack.pushN(*new(uint256.Int).SetBytes(common.Hex2Bytes(v)), *new(uint256.Int))
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, rstack, nil})
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v {
t.Fatalf("Mstore fail, got %v, expected %v", got, v)
}
stack.pushN(*new(uint256.Int).SetUint64(0x1), *new(uint256.Int))
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, rstack, nil})
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
t.Fatalf("Mstore failed to overwrite previous value")
}
Expand All @@ -540,7 +539,7 @@ func TestOpMstore(t *testing.T) {
func BenchmarkOpMstore(bench *testing.B) {
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack, rstack = newstack(), newReturnStack()
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)
Expand All @@ -554,14 +553,14 @@ func BenchmarkOpMstore(bench *testing.B) {
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
stack.pushN(*value, *memStart)
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, rstack, nil})
opMstore(&pc, evmInterpreter, &callCtx{mem, stack, nil})
}
}

func BenchmarkOpSHA3(bench *testing.B) {
var (
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
stack, rstack = newstack(), newReturnStack()
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)
Expand All @@ -573,7 +572,7 @@ func BenchmarkOpSHA3(bench *testing.B) {
bench.ResetTimer()
for i := 0; i < bench.N; i++ {
stack.pushN(*uint256.NewInt().SetUint64(32), *start)
opSha3(&pc, evmInterpreter, &callCtx{mem, stack, rstack, nil})
opSha3(&pc, evmInterpreter, &callCtx{mem, stack, nil})
}
}

Expand Down
16 changes: 6 additions & 10 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ type Interpreter interface {
type callCtx struct {
memory *Memory
stack *Stack
rstack *ReturnStack
contract *Contract
}

Expand Down Expand Up @@ -161,14 +160,12 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}

var (
op OpCode // current opcode
mem = NewMemory() // bound memory
stack = newstack() // local stack
returns = newReturnStack() // local returns stack
op OpCode // current opcode
mem = NewMemory() // bound memory
stack = newstack() // local stack
callContext = &callCtx{
memory: mem,
stack: stack,
rstack: returns,
contract: contract,
}
// For optimisation reason we're using uint64 as the program counter.
Expand All @@ -187,17 +184,16 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// they are returned to the pools
defer func() {
returnStack(stack)
returnRStack(returns)
}()
contract.Input = input

if in.cfg.Debug {
defer func() {
if err != nil {
if !logged {
in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, returns, in.returnData, contract, in.evm.depth, err)
in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, in.returnData, contract, in.evm.depth, err)
} else {
in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, returns, contract, in.evm.depth, err)
in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
}
}
}()
Expand Down Expand Up @@ -279,7 +275,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}

if in.cfg.Debug {
in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, returns, in.returnData, contract, in.evm.depth, err)
in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, in.returnData, contract, in.evm.depth, err)
logged = true
}

Expand Down
1 change: 0 additions & 1 deletion core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ type JumpTable [256]*operation
// contantinople, istanbul, petersburg and berlin instructions.
func newBerlinInstructionSet() JumpTable {
instructionSet := newIstanbulInstructionSet()
enable2315(&instructionSet) // Subroutines - https://eips.ethereum.org/EIPS/eip-2315
enable2929(&instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929
return instructionSet
}
Expand Down
Loading