Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PrecompileEnvironment.ChainConfig() #32

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/vm/contracts.libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 14 additions & 4 deletions core/vm/contracts.libevm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func TestPrecompileOverride(t *testing.T) {
}

type statefulPrecompileOutput struct {
ChainID *big.Int
Caller, Self common.Address
StateValue common.Hash
ReadOnly bool
Expand Down Expand Up @@ -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),
Expand All @@ -153,10 +155,17 @@ func TestNewStatefulPrecompile(t *testing.T) {
caller := rng.Address()
input := rng.Bytes(8)
value := rng.Hash()

state, evm := ethtest.NewZeroEVM(t, ethtest.WithBlockContext(
core.NewEVMBlockContext(header, nil, rng.AddressPtr()),
))
chainID := rng.BigUint64()

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 {
Expand Down Expand Up @@ -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,
Expand Down
39 changes: 30 additions & 9 deletions libevm/ethtest/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
})
}