From 3bb76e8533918a8df065c1278d1585fcd2621ed3 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 8 Dec 2020 16:01:28 -0300 Subject: [PATCH] evm: extra eips param (#643) * evm: extra eips param * changelog --- CHANGELOG.md | 4 ++++ x/evm/types/params.go | 31 +++++++++++++++++++++++++++++-- x/evm/types/params_test.go | 14 ++++++++++++-- x/evm/types/state_transition.go | 9 +++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5877c7e..d815baf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased +### Improvements + +* (evm) [\#627](https://github.com/cosmos/ethermint/issues/627) Add extra EIPs parameter to apply custom EVM jump tables. + ### Bug Fixes * (evm) [\#621](https://github.com/cosmos/ethermint/issues/621) EVM `GenesisAccount` fields now share the same format as the auth module `Account`. diff --git a/x/evm/types/params.go b/x/evm/types/params.go index af7be03d..7024a4a1 100644 --- a/x/evm/types/params.go +++ b/x/evm/types/params.go @@ -8,6 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/params" + "github.com/ethereum/go-ethereum/core/vm" + ethermint "github.com/cosmos/ethermint/types" ) @@ -21,6 +23,7 @@ var ( ParamStoreKeyEVMDenom = []byte("EVMDenom") ParamStoreKeyEnableCreate = []byte("EnableCreate") ParamStoreKeyEnableCall = []byte("EnableCall") + ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs") ) // ParamKeyTable returns the parameter key table. @@ -37,14 +40,17 @@ type Params struct { EnableCreate bool `json:"enable_create" yaml:"enable_create"` // EnableCall toggles state transitions that use the vm.Call function EnableCall bool `json:"enable_call" yaml:"enable_call"` + // ExtraEIPs defines the additional EIPs for the vm.Config + ExtraEIPs []int `json:"extra_eips" yaml:"extra_eips"` } // NewParams creates a new Params instance -func NewParams(evmDenom string, enableCreate, enableCall bool) Params { +func NewParams(evmDenom string, enableCreate, enableCall bool, extraEIPs ...int) Params { return Params{ EvmDenom: evmDenom, EnableCreate: enableCreate, EnableCall: enableCall, + ExtraEIPs: extraEIPs, } } @@ -54,6 +60,7 @@ func DefaultParams() Params { EvmDenom: ethermint.AttoPhoton, EnableCreate: true, EnableCall: true, + ExtraEIPs: []int(nil), // TODO: define default values } } @@ -69,12 +76,17 @@ func (p *Params) ParamSetPairs() params.ParamSetPairs { params.NewParamSetPair(ParamStoreKeyEVMDenom, &p.EvmDenom, validateEVMDenom), params.NewParamSetPair(ParamStoreKeyEnableCreate, &p.EnableCreate, validateBool), params.NewParamSetPair(ParamStoreKeyEnableCall, &p.EnableCall, validateBool), + params.NewParamSetPair(ParamStoreKeyExtraEIPs, &p.ExtraEIPs, validateEIPs), } } // Validate performs basic validation on evm parameters. func (p Params) Validate() error { - return sdk.ValidateDenom(p.EvmDenom) + if err := sdk.ValidateDenom(p.EvmDenom); err != nil { + return err + } + + return validateEIPs(p.ExtraEIPs) } func validateEVMDenom(i interface{}) error { @@ -93,3 +105,18 @@ func validateBool(i interface{}) error { } return nil } + +func validateEIPs(i interface{}) error { + eips, ok := i.([]int) + if !ok { + return fmt.Errorf("invalid EIP slice type: %T", i) + } + + for _, eip := range eips { + if !vm.ValidEip(eip) { + return fmt.Errorf("EIP %d is not activateable", eip) + } + } + + return nil +} diff --git a/x/evm/types/params_test.go b/x/evm/types/params_test.go index 044876eb..83332fd0 100644 --- a/x/evm/types/params_test.go +++ b/x/evm/types/params_test.go @@ -15,7 +15,7 @@ func TestParamsValidate(t *testing.T) { {"default", DefaultParams(), false}, { "valid", - NewParams("ara", true, true), + NewParams("ara", true, true, 2929, 1884, 1344), false, }, { @@ -30,6 +30,14 @@ func TestParamsValidate(t *testing.T) { }, true, }, + { + "invalid eip", + Params{ + EvmDenom: "stake", + ExtraEIPs: []int{1}, + }, + true, + }, } for _, tc := range testCases { @@ -48,8 +56,10 @@ func TestParamsValidatePriv(t *testing.T) { require.NoError(t, validateEVMDenom("aphoton")) require.Error(t, validateBool("")) require.NoError(t, validateBool(true)) + require.Error(t, validateEIPs("")) + require.NoError(t, validateEIPs([]int{1884})) } func TestParams_String(t *testing.T) { - require.Equal(t, "evm_denom: aphoton\nenable_create: true\nenable_call: true\n", DefaultParams().String()) + require.Equal(t, "evm_denom: aphoton\nenable_create: true\nenable_call: true\nextra_eips: []\n", DefaultParams().String()) } diff --git a/x/evm/types/state_transition.go b/x/evm/types/state_transition.go index 3e8ece42..b2853832 100644 --- a/x/evm/types/state_transition.go +++ b/x/evm/types/state_transition.go @@ -77,6 +77,7 @@ func (st StateTransition) newEVM( gasLimit uint64, gasPrice *big.Int, config ChainConfig, + extraEIPs []int, ) *vm.EVM { // Create context for evm context := vm.Context{ @@ -92,7 +93,11 @@ func (st StateTransition) newEVM( GasPrice: gasPrice, } - return vm.NewEVM(context, csdb, config.EthereumConfig(st.ChainID), vm.Config{}) + vmConfig := vm.Config{ + ExtraEips: extraEIPs, + } + + return vm.NewEVM(context, csdb, config.EthereumConfig(st.ChainID), vmConfig) } // TransitionDb will transition the state by applying the current transaction and @@ -139,7 +144,7 @@ func (st StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (*Ex return nil, errors.New("gas price cannot be nil") } - evm := st.newEVM(ctx, csdb, gasLimit, gasPrice.Int, config) + evm := st.newEVM(ctx, csdb, gasLimit, gasPrice.Int, config, params.ExtraEIPs) var ( ret []byte