Skip to content

Commit 5c1f285

Browse files
committed
Merge branch 'libevm' into arr4n/precompile-env-evm-call
2 parents 2abf1f2 + f1dba53 commit 5c1f285

File tree

7 files changed

+70
-16
lines changed

7 files changed

+70
-16
lines changed

core/vm/contracts.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ func init() {
148148
}
149149

150150
// ActivePrecompiles returns the precompiles enabled with the current configuration.
151-
func ActivePrecompiles(rules params.Rules) []common.Address {
151+
func ActivePrecompiles(rules params.Rules) (active []common.Address) {
152+
defer func() {
153+
active = rules.Hooks().ActivePrecompiles(append([]common.Address{}, active...))
154+
}()
152155
switch {
153156
case rules.IsCancun:
154157
return PrecompiledAddressesCancun

core/vm/contracts.libevm_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,25 @@ func TestCanCreateContract(t *testing.T) {
423423
})
424424
}
425425
}
426+
427+
func TestActivePrecompilesOverride(t *testing.T) {
428+
newRules := func() params.Rules {
429+
return new(params.ChainConfig).Rules(big.NewInt(0), false, 0)
430+
}
431+
defaultActive := vm.ActivePrecompiles(newRules())
432+
433+
rng := ethtest.NewPseudoRand(0xDecafC0ffeeBad)
434+
precompiles := make([]common.Address, rng.Intn(10)+5)
435+
for i := range precompiles {
436+
precompiles[i] = rng.Address()
437+
}
438+
hooks := &hookstest.Stub{
439+
ActivePrecompilesFn: func(active []common.Address) []common.Address {
440+
assert.Equal(t, defaultActive, active, "ActivePrecompiles() hook receives default addresses")
441+
return precompiles
442+
},
443+
}
444+
hooks.Register(t)
445+
446+
require.Equal(t, precompiles, vm.ActivePrecompiles(newRules()), "vm.ActivePrecompiles() returns overridden addresses")
447+
}

core/vm/evm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
159159
// Reset resets the EVM with a new transaction context.Reset
160160
// This is not threadsafe and should only be done very cautiously.
161161
func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) {
162-
evm.TxContext, evm.StateDB = overrideEVMResetArgs(txCtx, statedb)
162+
evm.TxContext, evm.StateDB = evm.overrideEVMResetArgs(txCtx, statedb)
163163
}
164164

165165
// Cancel cancels any running EVM operation. This may be called concurrently and

core/vm/evm.libevm_test.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"math/big"
2020
"testing"
2121

22+
"github.com/stretchr/testify/assert"
2223
"github.com/stretchr/testify/require"
2324

2425
"github.com/ethereum/go-ethereum/params"
@@ -27,23 +28,25 @@ import (
2728
type evmArgOverrider struct {
2829
newEVMchainID int64
2930

30-
resetTxCtx TxContext
31-
resetStateDB StateDB
31+
gotResetChainID *big.Int
32+
resetTxContextTo TxContext
33+
resetStateDBTo StateDB
3234
}
3335

34-
func (o evmArgOverrider) OverrideNewEVMArgs(args *NewEVMArgs) *NewEVMArgs {
36+
func (o *evmArgOverrider) OverrideNewEVMArgs(args *NewEVMArgs) *NewEVMArgs {
3537
args.ChainConfig = &params.ChainConfig{ChainID: big.NewInt(o.newEVMchainID)}
3638
return args
3739
}
3840

39-
func (o evmArgOverrider) OverrideEVMResetArgs(*EVMResetArgs) *EVMResetArgs {
41+
func (o *evmArgOverrider) OverrideEVMResetArgs(r params.Rules, _ *EVMResetArgs) *EVMResetArgs {
42+
o.gotResetChainID = r.ChainID
4043
return &EVMResetArgs{
41-
TxContext: o.resetTxCtx,
42-
StateDB: o.resetStateDB,
44+
TxContext: o.resetTxContextTo,
45+
StateDB: o.resetStateDBTo,
4346
}
4447
}
4548

46-
func (o evmArgOverrider) register(t *testing.T) {
49+
func (o *evmArgOverrider) register(t *testing.T) {
4750
t.Helper()
4851
libevmHooks = nil
4952
RegisterHooks(o)
@@ -71,15 +74,20 @@ func TestOverrideEVMResetArgs(t *testing.T) {
7174
// Equivalent to rationale for TestOverrideNewEVMArgs above.
7275
var _ func(TxContext, StateDB) = (*EVM)(nil).Reset
7376

74-
const gasPrice = 1357924680
75-
hooks := evmArgOverrider{
76-
resetTxCtx: TxContext{
77+
const (
78+
chainID = 0xc0ffee
79+
gasPrice = 1357924680
80+
)
81+
hooks := &evmArgOverrider{
82+
newEVMchainID: chainID,
83+
resetTxContextTo: TxContext{
7784
GasPrice: big.NewInt(gasPrice),
7885
},
7986
}
8087
hooks.register(t)
8188

8289
evm := NewEVM(BlockContext{}, TxContext{}, nil, nil, Config{})
8390
evm.Reset(TxContext{}, nil)
84-
require.Equalf(t, big.NewInt(gasPrice), evm.GasPrice, "%T.GasPrice set by Reset() hook", evm)
91+
assert.Equalf(t, big.NewInt(chainID), hooks.gotResetChainID, "%T.ChainID passed to Reset() hook", params.Rules{})
92+
assert.Equalf(t, big.NewInt(gasPrice), evm.GasPrice, "%T.GasPrice set by Reset() hook", evm)
8593
}

core/vm/hooks.libevm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var libevmHooks Hooks
3333
// See [RegisterHooks].
3434
type Hooks interface {
3535
OverrideNewEVMArgs(*NewEVMArgs) *NewEVMArgs
36-
OverrideEVMResetArgs(*EVMResetArgs) *EVMResetArgs
36+
OverrideEVMResetArgs(params.Rules, *EVMResetArgs) *EVMResetArgs
3737
}
3838

3939
// NewEVMArgs are the arguments received by [NewEVM], available for override
@@ -67,10 +67,10 @@ func overrideNewEVMArgs(
6767
return args.BlockContext, args.TxContext, args.StateDB, args.ChainConfig, args.Config
6868
}
6969

70-
func overrideEVMResetArgs(txCtx TxContext, statedb StateDB) (TxContext, StateDB) {
70+
func (evm *EVM) overrideEVMResetArgs(txCtx TxContext, statedb StateDB) (TxContext, StateDB) {
7171
if libevmHooks == nil {
7272
return txCtx, statedb
7373
}
74-
args := libevmHooks.OverrideEVMResetArgs(&EVMResetArgs{txCtx, statedb})
74+
args := libevmHooks.OverrideEVMResetArgs(evm.chainRules, &EVMResetArgs{txCtx, statedb})
7575
return args.TxContext, args.StateDB
7676
}

libevm/hookstest/stub.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type Stub struct {
4545
CheckConfigCompatibleFn func(*params.ChainConfig, *big.Int, uint64) *params.ConfigCompatError
4646
DescriptionSuffix string
4747
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
48+
ActivePrecompilesFn func([]common.Address) []common.Address
4849
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
4950
CanCreateContractFn func(*libevm.AddressContext, uint64, libevm.StateReader) (uint64, error)
5051
}
@@ -71,6 +72,15 @@ func (s Stub) PrecompileOverride(a common.Address) (libevm.PrecompiledContract,
7172
return p, ok
7273
}
7374

75+
// ActivePrecompiles proxies arguments to the s.ActivePrecompilesFn function if
76+
// non-nil, otherwise it acts as a noop.
77+
func (s Stub) ActivePrecompiles(active []common.Address) []common.Address {
78+
if f := s.ActivePrecompilesFn; f != nil {
79+
return f(active)
80+
}
81+
return active
82+
}
83+
7484
// CheckConfigForkOrder proxies arguments to the s.CheckConfigForkOrderFn
7585
// function if non-nil, otherwise it acts as a noop.
7686
func (s Stub) CheckConfigForkOrder() error {

params/hooks.libevm.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ type RulesHooks interface {
4848
// [PrecompiledContract] is non-nil. If it returns `false` then the default
4949
// precompile behaviour is honoured.
5050
PrecompileOverride(common.Address) (_ libevm.PrecompiledContract, override bool)
51+
// ActivePrecompiles receives the addresses that would usually be returned
52+
// by a call to [vm.ActivePrecompiles] and MUST return the value to be
53+
// returned by said function, which will be propagated. It MAY alter the
54+
// received slice. The value it returns MUST be consistent with the
55+
// behaviour of the PrecompileOverride hook.
56+
ActivePrecompiles([]common.Address) []common.Address
5157
}
5258

5359
// RulesAllowlistHooks are a subset of [RulesHooks] that gate actions, signalled
@@ -120,3 +126,8 @@ func (NOOPHooks) CanCreateContract(_ *libevm.AddressContext, gas uint64, _ libev
120126
func (NOOPHooks) PrecompileOverride(common.Address) (libevm.PrecompiledContract, bool) {
121127
return nil, false
122128
}
129+
130+
// ActivePrecompiles echoes the active addresses unchanged.
131+
func (NOOPHooks) ActivePrecompiles(active []common.Address) []common.Address {
132+
return active
133+
}

0 commit comments

Comments
 (0)