From 430f69e01eb33a1b2f4f3c9372da14d01aaba62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 2 Mar 2021 23:51:03 +0200 Subject: [PATCH] core/vm/runtime: more unshipping --- core/vm/runtime/runtime_test.go | 225 +------------------------------- 1 file changed, 2 insertions(+), 223 deletions(-) diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index af69e3333..6e0434c2c 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -330,14 +330,14 @@ func (s *stepCounter) CaptureStart(from common.Address, to common.Address, creat return nil } -func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, rStack *vm.ReturnStack, rData []byte, contract *vm.Contract, depth int, err error) error { +func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { s.steps++ // Enable this for more output //s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err) return nil } -func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, rStack *vm.ReturnStack, contract *vm.Contract, depth int, err error) error { +func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { return nil } @@ -345,227 +345,6 @@ func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, return nil } -func TestJumpSub1024Limit(t *testing.T) { - state, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - address := common.HexToAddress("0x0a") - // Code is - // 0 beginsub - // 1 push 0 - // 3 jumpsub - // - // The code recursively calls itself. It should error when the returns-stack - // grows above 1023 - state.SetCode(address, []byte{ - byte(vm.PUSH1), 3, - byte(vm.JUMPSUB), - byte(vm.BEGINSUB), - byte(vm.PUSH1), 3, - byte(vm.JUMPSUB), - }) - tracer := stepCounter{inner: vm.NewJSONLogger(nil, os.Stdout)} - // Enable 2315 - _, _, err := Call(address, nil, &Config{State: state, - GasLimit: 20000, - ChainConfig: params.AllEthashProtocolChanges, - EVMConfig: vm.Config{ - ExtraEips: []int{2315}, - Debug: true, - //Tracer: vm.NewJSONLogger(nil, os.Stdout), - Tracer: &tracer, - }}) - exp := "return stack limit reached" - if err.Error() != exp { - t.Fatalf("expected %v, got %v", exp, err) - } - if exp, got := 2048, tracer.steps; exp != got { - t.Fatalf("expected %d steps, got %d", exp, got) - } -} - -func TestReturnSubShallow(t *testing.T) { - state, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - address := common.HexToAddress("0x0a") - // The code does returnsub without having anything on the returnstack. - // It should not panic, but just fail after one step - state.SetCode(address, []byte{ - byte(vm.PUSH1), 5, - byte(vm.JUMPSUB), - byte(vm.RETURNSUB), - byte(vm.PC), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - byte(vm.PC), - }) - tracer := stepCounter{} - - // Enable 2315 - _, _, err := Call(address, nil, &Config{State: state, - GasLimit: 10000, - ChainConfig: params.AllEthashProtocolChanges, - EVMConfig: vm.Config{ - ExtraEips: []int{2315}, - Debug: true, - Tracer: &tracer, - }}) - - exp := "invalid retsub" - if err.Error() != exp { - t.Fatalf("expected %v, got %v", exp, err) - } - if exp, got := 4, tracer.steps; exp != got { - t.Fatalf("expected %d steps, got %d", exp, got) - } -} - -// disabled -- only used for generating markdown -func DisabledTestReturnCases(t *testing.T) { - cfg := &Config{ - EVMConfig: vm.Config{ - Debug: true, - Tracer: vm.NewMarkdownLogger(nil, os.Stdout), - ExtraEips: []int{2315}, - }, - } - // This should fail at first opcode - Execute([]byte{ - byte(vm.RETURNSUB), - byte(vm.PC), - byte(vm.PC), - }, nil, cfg) - - // Should also fail - Execute([]byte{ - byte(vm.PUSH1), 5, - byte(vm.JUMPSUB), - byte(vm.RETURNSUB), - byte(vm.PC), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - byte(vm.PC), - }, nil, cfg) - - // This should complete - Execute([]byte{ - byte(vm.PUSH1), 0x4, - byte(vm.JUMPSUB), - byte(vm.STOP), - byte(vm.BEGINSUB), - byte(vm.PUSH1), 0x9, - byte(vm.JUMPSUB), - byte(vm.RETURNSUB), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - }, nil, cfg) -} - -// DisabledTestEipExampleCases contains various testcases that are used for the -// EIP examples -// This test is disabled, as it's only used for generating markdown -func DisabledTestEipExampleCases(t *testing.T) { - cfg := &Config{ - EVMConfig: vm.Config{ - Debug: true, - Tracer: vm.NewMarkdownLogger(nil, os.Stdout), - ExtraEips: []int{2315}, - }, - } - prettyPrint := func(comment string, code []byte) { - instrs := make([]string, 0) - it := asm.NewInstructionIterator(code) - for it.Next() { - if it.Arg() != nil && 0 < len(it.Arg()) { - instrs = append(instrs, fmt.Sprintf("%v 0x%x", it.Op(), it.Arg())) - } else { - instrs = append(instrs, fmt.Sprintf("%v", it.Op())) - } - } - ops := strings.Join(instrs, ", ") - - fmt.Printf("%v\nBytecode: `0x%x` (`%v`)\n", - comment, - code, ops) - Execute(code, nil, cfg) - } - - { // First eip testcase - code := []byte{ - byte(vm.PUSH1), 4, - byte(vm.JUMPSUB), - byte(vm.STOP), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - } - prettyPrint("This should jump into a subroutine, back out and stop.", code) - } - - { - code := []byte{ - byte(vm.PUSH9), 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 4 + 8, - byte(vm.JUMPSUB), - byte(vm.STOP), - byte(vm.BEGINSUB), - byte(vm.PUSH1), 8 + 9, - byte(vm.JUMPSUB), - byte(vm.RETURNSUB), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - } - prettyPrint("This should execute fine, going into one two depths of subroutines", code) - } - // TODO(@holiman) move this test into an actual test, which not only prints - // out the trace. - { - code := []byte{ - byte(vm.PUSH9), 0x01, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 4 + 8, - byte(vm.JUMPSUB), - byte(vm.STOP), - byte(vm.BEGINSUB), - byte(vm.PUSH1), 8 + 9, - byte(vm.JUMPSUB), - byte(vm.RETURNSUB), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - } - prettyPrint("This should fail, since the given location is outside of the "+ - "code-range. The code is the same as previous example, except that the "+ - "pushed location is `0x01000000000000000c` instead of `0x0c`.", code) - } - { - // This should fail at first opcode - code := []byte{ - byte(vm.RETURNSUB), - byte(vm.PC), - byte(vm.PC), - } - prettyPrint("This should fail at first opcode, due to shallow `return_stack`", code) - - } - { - code := []byte{ - byte(vm.PUSH1), 5, // Jump past the subroutine - byte(vm.JUMP), - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - byte(vm.JUMPDEST), - byte(vm.PUSH1), 3, // Now invoke the subroutine - byte(vm.JUMPSUB), - } - prettyPrint("In this example. the JUMPSUB is on the last byte of code. When the "+ - "subroutine returns, it should hit the 'virtual stop' _after_ the bytecode, "+ - "and not exit with error", code) - } - - { - code := []byte{ - byte(vm.BEGINSUB), - byte(vm.RETURNSUB), - byte(vm.STOP), - } - prettyPrint("In this example, the code 'walks' into a subroutine, which is not "+ - "allowed, and causes an error", code) - } -} - // benchmarkNonModifyingCode benchmarks code, but if the code modifies the // state, this should not be used, since it does not reset the state between runs. func benchmarkNonModifyingCode(gas uint64, code []byte, name string, b *testing.B) {