Skip to content

Commit 1a6dd02

Browse files
authored
feat: override vm.NewEVM() args (#35)
* feat: override `vm.NewEVM()` args * test: `vm.Hooks.OverrideNewEVMArgs` * refactor: use `NewEVMArgs struct` in hook * chore: `gci` * fix: clear `vm.Hooks` at end of test
1 parent 81e109a commit 1a6dd02

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

core/vm/evm.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
143143
blockCtx.BlobBaseFee = new(big.Int)
144144
}
145145
}
146+
blockCtx, txCtx, statedb, chainConfig, config = overrideNewEVMArgs(blockCtx, txCtx, statedb, chainConfig, config)
146147
evm := &EVM{
147148
Context: blockCtx,
148149
TxContext: txCtx,

core/vm/evm.libevm_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package vm
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/ethereum/go-ethereum/params"
10+
)
11+
12+
type chainIDOverrider struct {
13+
chainID int64
14+
}
15+
16+
func (o chainIDOverrider) OverrideNewEVMArgs(args *NewEVMArgs) *NewEVMArgs {
17+
args.ChainConfig = &params.ChainConfig{ChainID: big.NewInt(o.chainID)}
18+
return args
19+
}
20+
21+
func TestOverrideNewEVMArgs(t *testing.T) {
22+
// The overrideNewEVMArgs function accepts and returns all arguments to
23+
// NewEVM(), in order. Here we lock in our assumption of that order. If this
24+
// breaks then all functionality overriding the args MUST be updated.
25+
var _ func(BlockContext, TxContext, StateDB, *params.ChainConfig, Config) *EVM = NewEVM
26+
27+
const chainID = 13579
28+
libevmHooks = nil
29+
RegisterHooks(chainIDOverrider{chainID: chainID})
30+
defer func() { libevmHooks = nil }()
31+
32+
got := NewEVM(BlockContext{}, TxContext{}, nil, nil, Config{}).ChainConfig().ChainID
33+
require.Equal(t, big.NewInt(chainID), got)
34+
}

core/vm/hooks.libevm.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package vm
2+
3+
import "github.com/ethereum/go-ethereum/params"
4+
5+
// RegisterHooks registers the Hooks. It is expected to be called in an `init()`
6+
// function and MUST NOT be called more than once.
7+
func RegisterHooks(h Hooks) {
8+
if libevmHooks != nil {
9+
panic("already registered")
10+
}
11+
libevmHooks = h
12+
}
13+
14+
var libevmHooks Hooks
15+
16+
// Hooks are arbitrary configuration functions to modify default VM behaviour.
17+
type Hooks interface {
18+
OverrideNewEVMArgs(*NewEVMArgs) *NewEVMArgs
19+
}
20+
21+
// NewEVMArgs are the arguments received by [NewEVM], available for override.
22+
type NewEVMArgs struct {
23+
BlockContext BlockContext
24+
TxContext TxContext
25+
StateDB StateDB
26+
ChainConfig *params.ChainConfig
27+
Config Config
28+
}
29+
30+
func overrideNewEVMArgs(
31+
blockCtx BlockContext,
32+
txCtx TxContext,
33+
statedb StateDB,
34+
chainConfig *params.ChainConfig,
35+
config Config,
36+
) (BlockContext, TxContext, StateDB, *params.ChainConfig, Config) {
37+
if libevmHooks == nil {
38+
return blockCtx, txCtx, statedb, chainConfig, config
39+
}
40+
args := libevmHooks.OverrideNewEVMArgs(&NewEVMArgs{blockCtx, txCtx, statedb, chainConfig, config})
41+
return args.BlockContext, args.TxContext, args.StateDB, args.ChainConfig, args.Config
42+
}

0 commit comments

Comments
 (0)