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

Extend x/evm module params with enabled_precompiles #55

Merged
merged 12 commits into from
May 3, 2024
17 changes: 11 additions & 6 deletions proto/ethermint/evm/v1/evm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ message Params {
repeated int64 extra_eips = 4 [(gogoproto.customname) = "ExtraEIPs", (gogoproto.moretags) = "yaml:\"extra_eips\""];
// chain_config defines the EVM chain configuration parameters
ChainConfig chain_config = 5 [(gogoproto.moretags) = "yaml:\"chain_config\"", (gogoproto.nullable) = false];
// list of allowed eip712 msgs and their types
// eip712_allowed_msgs contains list of allowed eip712 msgs and their types
repeated EIP712AllowedMsg eip712_allowed_msgs = 6
[(gogoproto.customname) = "EIP712AllowedMsgs", (gogoproto.nullable) = false];
// allow_unprotected_txs defines if replay-protected (i.e non EIP155
// signed) transactions can be executed on the state machine.
bool allow_unprotected_txs = 7;
// enabled_precompiles contains list of hex-encoded evm addresses of enabled precompiled contracts.
// Precompile must be registered before it can be enabled.
repeated string enabled_precompiles = 8;
}

// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
Expand Down Expand Up @@ -246,20 +249,20 @@ message TraceConfig {

// EIP712AllowedMsg stores an allowed legacy msg and its eip712 type.
message EIP712AllowedMsg {
// msg's proto type name. ie "/cosmos.bank.v1beta1.MsgSend"
// msg_type_url is a msg's proto type name. ie "/cosmos.bank.v1beta1.MsgSend"
evgeniy-scherbina marked this conversation as resolved.
Show resolved Hide resolved
string msg_type_url = 1;

// name of the eip712 value type. ie "MsgValueSend"
// msg_value_type_name is a name of the eip712 value type. ie "MsgValueSend"
string msg_value_type_name = 2;

// types of the msg value
// value_types is a list of msg value types
repeated EIP712MsgAttrType value_types = 3 [(gogoproto.nullable) = false];

// nested types of the msg value
// nested_types is a list of msg value nested types
repeated EIP712NestedMsgType nested_types = 4 [(gogoproto.nullable) = false];
}

// EIP712MsgType is the eip712 type of a single message.
// EIP712NestedMsgType is the eip712 type of a single message.
message EIP712NestedMsgType {
// name of the nested type. ie "Fee", "Coin"
string name = 1;
Expand All @@ -270,6 +273,8 @@ message EIP712NestedMsgType {

// EIP712MsgAttrType is the eip712 type of a single message attribute.
message EIP712MsgAttrType {
// name
string name = 1;
// type
string type = 2;
}
13 changes: 11 additions & 2 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"

precompile_modules "github.com/ethereum/go-ethereum/precompile/modules"
ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/evm/keeper"
"github.com/evmos/ethermint/x/evm/types"
Expand All @@ -36,10 +36,19 @@ func InitGenesis(
k *keeper.Keeper,
accountKeeper types.AccountKeeper,
data types.GenesisState,
registeredModules []precompile_modules.Module,
) []abci.ValidatorUpdate {
k.WithChainID(ctx)

err := k.SetParams(ctx, data.Params)
err := types.CheckIfEnabledPrecompilesAreRegistered(
registeredModules,
data.Params.GetEnabledPrecompiles(),
)
if err != nil {
panic(err)
}

err = k.SetParams(ctx, data.Params)
if err != nil {
panic(fmt.Errorf("error setting params %s", err))
}
Expand Down
209 changes: 139 additions & 70 deletions x/evm/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package evm_test
import (
"math/big"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/ethereum/go-ethereum/common"
precompile_modules "github.com/ethereum/go-ethereum/precompile/modules"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/evmos/ethermint/crypto/ethsecp256k1"
etherminttypes "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/evm"
Expand All @@ -18,123 +19,191 @@ func (suite *EvmTestSuite) TestInitGenesis() {
suite.Require().NoError(err)

address := common.HexToAddress(privkey.PubKey().Address().String())
hexAddr1 := "0x1000000000000000000000000000000000000000"
hexAddr2 := "0x2000000000000000000000000000000000000000"

var vmdb *statedb.StateDB

testCases := []struct {
name string
malleate func()
genState *types.GenesisState
expPanic bool
name string
malleate func()
getGenState func() *types.GenesisState
registeredModules []precompile_modules.Module
expPanic bool
}{
{
"default",
func() {},
types.DefaultGenesisState(),
false,
name: "default",
malleate: func() {},
getGenState: func() *types.GenesisState {
return types.DefaultGenesisState()
},
expPanic: false,
},
{
"valid account",
func() {
name: "valid account",
malleate: func() {
vmdb.AddBalance(address, big.NewInt(1))
},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Storage: types.Storage{
{Key: common.BytesToHash([]byte("key")).String(), Value: common.BytesToHash([]byte("value")).String()},
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Storage: types.Storage{
{Key: common.BytesToHash([]byte("key")).String(), Value: common.BytesToHash([]byte("value")).String()},
},
},
},
},
}
},
false,
expPanic: false,
},
{
"account not found",
func() {},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
name: "account not found",
malleate: func() {},
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
},
},
},
}
},
true,
expPanic: true,
},
{
"invalid account type",
func() {
name: "invalid account type",
malleate: func() {
acc := authtypes.NewBaseAccountWithAddress(address.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
},
},
},
}
},
true,
expPanic: true,
},
{
"invalid code hash",
func() {
name: "invalid code hash",
malleate: func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "ffffffff",
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "ffffffff",
},
},
},
}
},
true,
expPanic: true,
},
{
"ignore empty account code checking",
func() {
name: "ignore empty account code checking",
malleate: func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())

suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "",
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "",
},
},
},
}
},
false,
expPanic: false,
},
{
"ignore empty account code checking with non-empty codehash",
func() {
name: "ignore empty account code checking with non-empty codehash",
malleate: func() {
ethAcc := &etherminttypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(address.Bytes(), nil, 0, 0),
CodeHash: common.BytesToHash([]byte{1, 2, 3}).Hex(),
}

suite.app.AccountKeeper.SetAccount(suite.ctx, ethAcc)
},
&types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "",
getGenState: func() *types.GenesisState {
return &types.GenesisState{
Params: types.DefaultParams(),
Accounts: []types.GenesisAccount{
{
Address: address.String(),
Code: "",
},
},
},
}
},
expPanic: false,
},
{
name: "precompile is enabled and registered",
malleate: func() {},
getGenState: func() *types.GenesisState {
defaultGen := types.DefaultGenesisState()
defaultGen.Params.EnabledPrecompiles = []string{hexAddr1}
return defaultGen
},
registeredModules: []precompile_modules.Module{
{Address: common.HexToAddress(hexAddr1)},
},
expPanic: false,
},
{
name: "precompile is enabled, but not registered",
malleate: func() {},
getGenState: func() *types.GenesisState {
defaultGen := types.DefaultGenesisState()
defaultGen.Params.EnabledPrecompiles = []string{hexAddr1}
return defaultGen
},
registeredModules: nil,
expPanic: true,
},
{
name: "enabled precompiles are not sorted",
malleate: func() {},
getGenState: func() *types.GenesisState {
defaultGen := types.DefaultGenesisState()
defaultGen.Params.EnabledPrecompiles = []string{hexAddr2, hexAddr1}
return defaultGen
},
registeredModules: []precompile_modules.Module{
{Address: common.HexToAddress(hexAddr1)},
{Address: common.HexToAddress(hexAddr2)},
},
expPanic: true,
},
{
name: "enabled precompiles are not unique",
malleate: func() {},
getGenState: func() *types.GenesisState {
defaultGen := types.DefaultGenesisState()
defaultGen.Params.EnabledPrecompiles = []string{hexAddr1, hexAddr1}
return defaultGen
},
registeredModules: []precompile_modules.Module{
{Address: common.HexToAddress(hexAddr1)},
},
false,
expPanic: true,
},
}

Expand All @@ -149,13 +218,13 @@ func (suite *EvmTestSuite) TestInitGenesis() {
if tc.expPanic {
suite.Require().Panics(
func() {
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.genState)
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.getGenState(), tc.registeredModules)
},
)
} else {
suite.Require().NotPanics(
func() {
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.genState)
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.getGenState(), tc.registeredModules)
},
)
}
Expand Down