handle interrupt

This commit is contained in:
Sina Mahmoodi 2024-04-23 13:50:15 +02:00
parent 08f3166868
commit 9fb41e9905
2 changed files with 21 additions and 7 deletions

View file

@ -23,6 +23,7 @@ import (
"math/big" "math/big"
"slices" "slices"
"strings" "strings"
"sync/atomic"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -115,6 +116,7 @@ type flatCallTracer struct {
config flatCallTracerConfig config flatCallTracerConfig
ctx *tracers.Context // Holds tracer context data ctx *tracers.Context // Holds tracer context data
reason error // Textual reason for the interruption reason error // Textual reason for the interruption
interrupt atomic.Bool // Atomic flag to signal execution interruption
activePrecompiles []common.Address // Updated on tx start based on given rules activePrecompiles []common.Address // Updated on tx start based on given rules
} }
@ -169,6 +171,9 @@ func (t *flatCallTracer) OnEnter(depth int, typ byte, from common.Address, to co
// OnExit is called when EVM exits a scope, even if the scope didn't // OnExit is called when EVM exits a scope, even if the scope didn't
// execute any code. // execute any code.
func (t *flatCallTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { func (t *flatCallTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
if t.interrupt.Load() {
return
}
t.tracer.OnExit(depth, output, gasUsed, err, reverted) t.tracer.OnExit(depth, output, gasUsed, err, reverted)
if depth == 0 { if depth == 0 {
@ -194,6 +199,9 @@ func (t *flatCallTracer) OnExit(depth int, output []byte, gasUsed uint64, err er
} }
func (t *flatCallTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { func (t *flatCallTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
if t.interrupt.Load() {
return
}
t.tracer.OnTxStart(env, tx, from) t.tracer.OnTxStart(env, tx, from)
// Update list of precompiles based on current block // Update list of precompiles based on current block
rules := env.ChainConfig.Rules(env.BlockNumber, env.Random != nil, env.Time) rules := env.ChainConfig.Rules(env.BlockNumber, env.Random != nil, env.Time)
@ -201,6 +209,9 @@ func (t *flatCallTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction
} }
func (t *flatCallTracer) OnTxEnd(receipt *types.Receipt, err error) { func (t *flatCallTracer) OnTxEnd(receipt *types.Receipt, err error) {
if t.interrupt.Load() {
return
}
t.tracer.OnTxEnd(receipt, err) t.tracer.OnTxEnd(receipt, err)
} }
@ -225,7 +236,7 @@ func (t *flatCallTracer) GetResult() (json.RawMessage, error) {
// Stop terminates execution of the tracer at the first opportune moment. // Stop terminates execution of the tracer at the first opportune moment.
func (t *flatCallTracer) Stop(err error) { func (t *flatCallTracer) Stop(err error) {
t.reason = err t.reason = err
t.tracer.Stop(err) t.interrupt.Store(true)
} }
// isPrecompiled returns whether the addr is a precompile. // isPrecompiled returns whether the addr is a precompile.

View file

@ -1,7 +1,6 @@
package native_test package native_test
import ( import (
"encoding/json"
"errors" "errors"
"math/big" "math/big"
"testing" "testing"
@ -16,17 +15,21 @@ import (
) )
func TestCallFlatStop(t *testing.T) { func TestCallFlatStop(t *testing.T) {
tracer, err := tracers.DefaultDirectory.New("flatCallTracer", &tracers.Context{}, nil)
ctx := &tracers.Context{}
tracer, err := tracers.DefaultDirectory.New("flatCallTracer", ctx, json.RawMessage(`{}`))
require.NoError(t, err) require.NoError(t, err)
// this error should be returned by GetResult // this error should be returned by GetResult
stopError := errors.New("stop error") stopError := errors.New("stop error")
// simulate a transaction // simulate a transaction
tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil) tx := types.NewTx(&types.LegacyTx{
Nonce: 0,
To: &common.Address{},
Value: big.NewInt(0),
Gas: 0,
GasPrice: big.NewInt(0),
Data: nil,
})
tracer.OnTxStart(&tracing.VMContext{ tracer.OnTxStart(&tracing.VMContext{
ChainConfig: params.MainnetChainConfig, ChainConfig: params.MainnetChainConfig,