feat: PrecompileEnvironment.ChainConfig() (#32)

This commit is contained in:
Arran Schlosberg 2024-09-18 12:29:56 -04:00 committed by GitHub
parent df1338920b
commit 81e109afcc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 13 deletions

View file

@ -94,6 +94,7 @@ func (p statefulPrecompile) Run([]byte) ([]byte, error) {
// A PrecompileEnvironment provides information about the context in which a
// precompiled contract is being run.
type PrecompileEnvironment interface {
ChainConfig() *params.ChainConfig
Rules() params.Rules
ReadOnly() bool
// StateDB will be non-nil i.f.f !ReadOnly().
@ -121,7 +122,8 @@ type PrecompileEnvironment interface {
var _ PrecompileEnvironment = (*evmCallArgs)(nil)
func (args *evmCallArgs) Rules() params.Rules { return args.evm.chainRules }
func (args *evmCallArgs) ChainConfig() *params.ChainConfig { return args.evm.chainConfig }
func (args *evmCallArgs) Rules() params.Rules { return args.evm.chainRules }
func (args *evmCallArgs) ReadOnly() bool {
if args.readWrite == inheritReadOnly {

View file

@ -84,6 +84,7 @@ func TestPrecompileOverride(t *testing.T) {
}
type statefulPrecompileOutput struct {
ChainID *big.Int
Caller, Self common.Address
StateValue common.Hash
ReadOnly bool
@ -127,6 +128,7 @@ func TestNewStatefulPrecompile(t *testing.T) {
addrs := env.Addresses()
out := &statefulPrecompileOutput{
ChainID: env.ChainConfig().ChainID,
Caller: addrs.Caller,
Self: addrs.Self,
StateValue: env.ReadOnlyState().GetState(precompile, slot),
@ -153,10 +155,17 @@ func TestNewStatefulPrecompile(t *testing.T) {
caller := rng.Address()
input := rng.Bytes(8)
value := rng.Hash()
chainID := rng.BigUint64()
state, evm := ethtest.NewZeroEVM(t, ethtest.WithBlockContext(
core.NewEVMBlockContext(header, nil, rng.AddressPtr()),
))
state, evm := ethtest.NewZeroEVM(
t,
ethtest.WithBlockContext(
core.NewEVMBlockContext(header, nil, rng.AddressPtr()),
),
ethtest.WithChainConfig(
&params.ChainConfig{ChainID: chainID},
),
)
state.SetState(precompile, slot, value)
tests := []struct {
@ -199,6 +208,7 @@ func TestNewStatefulPrecompile(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
wantReturnData := statefulPrecompileOutput{
ChainID: chainID,
Caller: caller,
Self: precompile,
StateValue: value,

View file

@ -25,7 +25,7 @@ func NewZeroEVM(tb testing.TB, opts ...EVMOption) (*state.StateDB, *vm.EVM) {
sdb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
require.NoError(tb, err, "state.New()")
vm := vm.NewEVM(
args := &evmConstructorArgs{
vm.BlockContext{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
@ -34,28 +34,49 @@ func NewZeroEVM(tb testing.TB, opts ...EVMOption) (*state.StateDB, *vm.EVM) {
sdb,
&params.ChainConfig{},
vm.Config{},
)
}
for _, o := range opts {
o.apply(vm)
o.apply(args)
}
return sdb, vm
return sdb, vm.NewEVM(
args.blockContext,
args.txContext,
args.stateDB,
args.chainConfig,
args.config,
)
}
type evmConstructorArgs struct {
blockContext vm.BlockContext
txContext vm.TxContext
stateDB vm.StateDB
chainConfig *params.ChainConfig
config vm.Config
}
// An EVMOption configures the EVM returned by [NewZeroEVM].
type EVMOption interface {
apply(*vm.EVM)
apply(*evmConstructorArgs)
}
type funcOption func(*vm.EVM)
type funcOption func(*evmConstructorArgs)
var _ EVMOption = funcOption(nil)
func (f funcOption) apply(vm *vm.EVM) { f(vm) }
func (f funcOption) apply(args *evmConstructorArgs) { f(args) }
// WithBlockContext overrides the default context.
func WithBlockContext(c vm.BlockContext) EVMOption {
return funcOption(func(vm *vm.EVM) {
vm.Context = c
return funcOption(func(args *evmConstructorArgs) {
args.blockContext = c
})
}
// WithBlockContext overrides the default context.
func WithChainConfig(c *params.ChainConfig) EVMOption {
return funcOption(func(args *evmConstructorArgs) {
args.chainConfig = c
})
}