From 1d3bd1ab00e2e5f7e0e64db7bee40b4f65a429c6 Mon Sep 17 00:00:00 2001 From: cokicm Date: Tue, 21 May 2024 00:46:47 +0200 Subject: [PATCH] Adding check inside EVM loop for errors to avoid executing contract when it should be stopped. --- state/runtime/evm/state.go | 7 +++++++ state/runtime/evm/state_test.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/state/runtime/evm/state.go b/state/runtime/evm/state.go index 52c1b528a9..58e704b044 100644 --- a/state/runtime/evm/state.go +++ b/state/runtime/evm/state.go @@ -243,6 +243,13 @@ func (c *state) Run() ([]byte, error) { if tracer != nil { c.captureExecution(op.String(), ipCopy, gasCopy, gasCopy-c.gas) } + + // In case there was an error set in current instruction, let the execution trace + // to allow easier debugging and stop the execution. + if err := c.err; err != nil { + break + } + // check if stack size exceeds the max size if c.stack.sp > stackSize { c.exit(&runtime.StackOverflowError{StackLen: c.stack.sp, Limit: stackSize}) diff --git a/state/runtime/evm/state_test.go b/state/runtime/evm/state_test.go index 320b34d5fc..ae225594d4 100644 --- a/state/runtime/evm/state_test.go +++ b/state/runtime/evm/state_test.go @@ -27,6 +27,10 @@ func (c *codeHelper) push1() { c.buf = append(c.buf, 0x1) } +func (c *codeHelper) opDup() { + c.buf = append(c.buf, DUP16) +} + func (c *codeHelper) pop() { c.buf = append(c.buf, POP) } @@ -126,3 +130,20 @@ func TestOpcodeNotFound(t *testing.T) { _, err := s.Run() assert.Equal(t, errOpCodeNotFound, err) } + +func TestErrorHandlingStopsContractExecution(t *testing.T) { + code := codeHelper{} + code.opDup() + code.opDup() + + s, closeFn := getState(&chain.ForksInTime{}) + defer closeFn() + + s.code = code.buf + s.gas = 10000 + s.host = &mockHost{} + + _, err := s.Run() + assert.Error(t, err, "The EVM did not handle an error") + assert.Equal(t, s.ip, 0, "The EVM did not executingon first error.") +}