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

imp(evm): use generic base account instead of EthAccount #129

Merged
merged 6 commits into from
Sep 2, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (deps) [#117](https://github.com/EscanBE/evermint/pull/117) Bumps ibc-go to v7.4.0 which include patch for ASA-2024-007
- (deps) [#120](https://github.com/EscanBE/evermint/pull/120) Bump cosmos-sdk v0.47.13, ibc-go v7.8.0, cometbft v0.37.5
- (vesting) [#128](https://github.com/EscanBE/evermint/pull/128) Remove `x/vesting` module and disable vesting
- (evm) [#129](https://github.com/EscanBE/evermint/pull/129) Use generic base account instead of EthAccount

# Evermint changelog

Expand Down
40 changes: 31 additions & 9 deletions app/ante/evm/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ import (
ethtypes "github.com/ethereum/go-ethereum/core/types"
)

// EthAccountVerificationDecorator validates an account balance checks
type EthAccountVerificationDecorator struct {
// ExternalOwnedAccountVerificationDecorator validates an account balance checks
type ExternalOwnedAccountVerificationDecorator struct {
ak evmtypes.AccountKeeper
bk evmtypes.BankKeeper
evmKeeper EVMKeeper
}

// NewEthAccountVerificationDecorator creates a new EthAccountVerificationDecorator
func NewEthAccountVerificationDecorator(ak evmtypes.AccountKeeper, ek EVMKeeper) EthAccountVerificationDecorator {
return EthAccountVerificationDecorator{
// NewExternalOwnedAccountVerificationDecorator creates a new ExternalOwnedAccountVerificationDecorator
func NewExternalOwnedAccountVerificationDecorator(ak evmtypes.AccountKeeper, bk evmtypes.BankKeeper, ek EVMKeeper) ExternalOwnedAccountVerificationDecorator {
return ExternalOwnedAccountVerificationDecorator{
ak: ak,
bk: bk,
evmKeeper: ek,
}
}
Expand All @@ -40,7 +42,7 @@ func NewEthAccountVerificationDecorator(ak evmtypes.AccountKeeper, ek EVMKeeper)
// - any of the msgs is not a MsgEthereumTx
// - from address is empty
// - account balance is lower than the transaction cost
func (avd EthAccountVerificationDecorator) AnteHandle(
func (avd ExternalOwnedAccountVerificationDecorator) AnteHandle(
ctx sdk.Context,
tx sdk.Tx,
simulate bool,
Expand All @@ -50,6 +52,8 @@ func (avd EthAccountVerificationDecorator) AnteHandle(
return next(ctx, tx, simulate)
}

var params *evmtypes.Params

for i, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
Expand All @@ -76,11 +80,29 @@ func (avd EthAccountVerificationDecorator) AnteHandle(
avd.ak.SetAccount(ctx, acc)
acct = statedb.NewEmptyAccount()
} else if acct.IsContract() {
return ctx, errorsmod.Wrapf(errortypes.ErrInvalidType,
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash)
return ctx, errorsmod.Wrapf(
errortypes.ErrInvalidType,
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash,
)
}

var spendableBalance *big.Int
if acct.Balance != nil && acct.Balance.Sign() > 0 {
if params == nil {
p := avd.evmKeeper.GetParams(ctx)
params = &p
}
spendableCoin := avd.bk.SpendableCoin(ctx, from, params.EvmDenom)
if spendableCoin.IsNil() || spendableCoin.IsZero() {
spendableBalance = common.Big0
} else {
spendableBalance = spendableCoin.Amount.BigInt()
}
} else {
spendableBalance = acct.Balance
}

if err := keeper.CheckSenderBalance(sdkmath.NewIntFromBigInt(acct.Balance), txData); err != nil {
if err := keeper.CheckSenderBalance(sdkmath.NewIntFromBigInt(spendableBalance), txData); err != nil {
return ctx, errorsmod.Wrap(err, "failed to check sender balance")
}
}
Expand Down
114 changes: 76 additions & 38 deletions app/ante/evm/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package evm_test

import (
"github.com/EscanBE/evermint/v12/constants"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"math"
"math/big"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -18,9 +21,9 @@ import (
ethtypes "github.com/ethereum/go-ethereum/core/types"
)

func (suite *AnteTestSuite) TestNewEthAccountVerificationDecorator() {
dec := ethante.NewEthAccountVerificationDecorator(
suite.app.AccountKeeper, suite.app.EvmKeeper,
func (suite *AnteTestSuite) TestNewExternalOwnedAccountVerificationDecorator() {
dec := ethante.NewExternalOwnedAccountVerificationDecorator(
suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.EvmKeeper,
)

addr := testutiltx.GenerateAddress()
Expand All @@ -36,74 +39,109 @@ func (suite *AnteTestSuite) TestNewEthAccountVerificationDecorator() {
tx := evmtypes.NewTx(ethContractCreationTxParams)
tx.From = addr.Hex()

var vmdb *statedb.StateDB

testCases := []struct {
name string
tx sdk.Tx
malleate func()
malleate func(sdk.Context, *statedb.StateDB)
checkTx bool
expPass bool
}{
{"not CheckTx", nil, func() {}, false, true},
{"invalid transaction type", &testutiltx.InvalidTx{}, func() {}, true, false},
{
"sender not set to msg",
tx,
func() {},
true,
false,
name: "not CheckTx",
tx: nil,
malleate: func(_ sdk.Context, _ *statedb.StateDB) {},
checkTx: false,
expPass: true,
},
{
"sender not EOA",
tx,
func() {
name: "invalid transaction type",
tx: &testutiltx.InvalidTx{},
malleate: func(_ sdk.Context, _ *statedb.StateDB) {},
checkTx: true,
expPass: false,
},
{
name: "sender not set to msg",
tx: tx,
malleate: func(_ sdk.Context, _ *statedb.StateDB) {},
checkTx: true,
expPass: false,
},
{
name: "sender not EOA",
tx: tx,
malleate: func(_ sdk.Context, vmdb *statedb.StateDB) {
// set not as an EOA
vmdb.SetCode(addr, []byte("1"))
},
true,
false,
checkTx: true,
expPass: false,
},
{
"not enough balance to cover tx cost",
tx,
func() {
name: "not enough balance to cover tx cost",
tx: tx,
malleate: func(_ sdk.Context, vmdb *statedb.StateDB) {
// reset back to EOA
vmdb.SetCode(addr, nil)
},
true,
false,
checkTx: true,
expPass: false,
},
{
"success new account",
tx,
func() {
name: "success new account",
tx: tx,
malleate: func(_ sdk.Context, vmdb *statedb.StateDB) {
vmdb.AddBalance(addr, big.NewInt(1000000))
},
true,
true,
checkTx: true,
expPass: true,
},
{
"success existing account",
tx,
func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
name: "success existing account",
tx: tx,
malleate: func(ctx sdk.Context, vmdb *statedb.StateDB) {
acc := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr.Bytes())
suite.app.AccountKeeper.SetAccount(ctx, acc)

vmdb.AddBalance(addr, big.NewInt(1000000))
},
true,
true,
checkTx: true,
expPass: true,
},
{
name: "not enough spendable balance",
tx: tx,
malleate: func(ctx sdk.Context, vmdb *statedb.StateDB) {
acc := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr.Bytes())

const amount = 1_000_000

baseVestingAcc := &vestingtypes.BaseVestingAccount{
BaseAccount: acc.(*authtypes.BaseAccount),
OriginalVesting: sdk.NewCoins(sdk.NewCoin(constants.BaseDenom, sdk.NewInt(amount))),
DelegatedFree: sdk.NewCoins(sdk.NewCoin(constants.BaseDenom, sdk.NewInt(0))),
DelegatedVesting: sdk.NewCoins(sdk.NewCoin(constants.BaseDenom, sdk.NewInt(0))),
EndTime: ctx.BlockTime().Add(99 * 365 * 24 * time.Hour).Unix(),
}
suite.app.AccountKeeper.SetAccount(ctx, &vestingtypes.DelayedVestingAccount{
BaseVestingAccount: baseVestingAcc,
})

vmdb.AddBalance(addr, big.NewInt(amount))
},
checkTx: true,
expPass: false,
},
}

for _, tc := range testCases {
suite.Run(tc.name, func() {
vmdb = testutil.NewStateDB(suite.ctx, suite.app.EvmKeeper)
tc.malleate()
ctx, _ := suite.ctx.CacheContext()
vmdb := testutil.NewStateDB(ctx, suite.app.EvmKeeper)
tc.malleate(ctx, vmdb)
suite.Require().NoError(vmdb.Commit())

_, err := dec.AnteHandle(suite.ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, testutil.NextFn)
_, err := dec.AnteHandle(ctx.WithIsCheckTx(tc.checkTx), tc.tx, false, testutil.NextFn)

if tc.expPass {
suite.Require().NoError(err)
Expand Down
2 changes: 1 addition & 1 deletion app/ante/handler_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func newEVMAnteHandler(options HandlerOptions) sdk.AnteHandler {
evmante.NewEthMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper),
evmante.NewEthValidateBasicDecorator(options.EvmKeeper),
evmante.NewEthSigVerificationDecorator(options.EvmKeeper),
evmante.NewEthAccountVerificationDecorator(options.AccountKeeper, options.EvmKeeper),
evmante.NewExternalOwnedAccountVerificationDecorator(options.AccountKeeper, options.BankKeeper, options.EvmKeeper),
evmante.NewEthBasicValidationDecorator(),
evmante.NewCanTransferDecorator(options.EvmKeeper),
evmante.NewEthGasConsumeDecorator(options.BankKeeper, options.DistributionKeeper, options.EvmKeeper, options.StakingKeeper, options.MaxTxGasWanted),
Expand Down
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ func NewEvermint(

// use custom Ethermint account for contracts
chainApp.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], evertypes.ProtoAccount, maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(), authAddr,
appCodec, keys[authtypes.StoreKey], authtypes.ProtoBaseAccount, maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(), authAddr,
)
chainApp.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], chainApp.AccountKeeper, chainApp.BlockedAddrs(), authAddr,
Expand Down
4 changes: 2 additions & 2 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,9 @@ paths:
- Query
/evmos/evm/v1/balances/{address}:
get:
summary: |-
summary: >-
Balance queries the balance of a the EVM denomination for a single
EthAccount.
account.
operationId: Balance
responses:
'200':
Expand Down
12 changes: 2 additions & 10 deletions client/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
"path/filepath"
"strings"

"github.com/ethereum/go-ethereum/common"

tmconfig "github.com/cometbft/cometbft/config"
tmrand "github.com/cometbft/cometbft/libs/rand"
"github.com/cometbft/cometbft/types"
Expand Down Expand Up @@ -341,10 +339,7 @@ func initTestnetFiles(
}

genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, &evertypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0),
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))

valTokens := sdk.TokensFromConsensusPower(100, evertypes.PowerReduction)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
Expand Down Expand Up @@ -417,10 +412,7 @@ func initTestnetFiles(
sdk.NewCoin(constants.BaseDenom, sdk.TokensFromConsensusPower(1000, evertypes.PowerReduction)),
}
genBalances = append(genBalances, banktypes.Balance{Address: normalAccountAddr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, &evertypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(normalAccountAddr, nil, 0, 0),
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(normalAccountAddr, nil, 0, 0))
}

if err := initGenFiles(clientCtx, mbm, args.chainID, constants.BaseDenom, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
Expand Down
11 changes: 2 additions & 9 deletions cmd/evmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/cometbft/cometbft/types"
tmtime "github.com/cometbft/cometbft/types/time"
clientconfig "github.com/cosmos/cosmos-sdk/client/config"
"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"net"
Expand Down Expand Up @@ -334,10 +333,7 @@ func initTestnetFiles(
}

genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, &evertypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0),
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))

valTokens := sdk.TokensFromConsensusPower(100, evertypes.PowerReduction)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
Expand Down Expand Up @@ -412,10 +408,7 @@ func initTestnetFiles(
sdk.NewCoin(constants.BaseDenom, sdk.TokensFromConsensusPower(1000, evertypes.PowerReduction)),
}
genBalances = append(genBalances, banktypes.Balance{Address: normalAccountAddr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, &evertypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(normalAccountAddr, nil, 0, 0),
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(normalAccountAddr, nil, 0, 0))
}

if err := initGenFiles(clientCtx, mbm, args.chainID, constants.BaseDenom, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
Expand Down
14 changes: 3 additions & 11 deletions ibc/testing/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (

"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/common"

sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
Expand All @@ -21,7 +19,6 @@ import (

"github.com/EscanBE/evermint/v12/crypto/ethsecp256k1"
evertypes "github.com/EscanBE/evermint/v12/types"
evmtypes "github.com/EscanBE/evermint/v12/x/evm/types"
)

// ChainIDPrefix defines the default chain ID prefix for our test chains
Expand Down Expand Up @@ -59,19 +56,14 @@ func NewTestChain(t *testing.T, coord *ibcgotesting.Coordinator, chainID string)

baseAcc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)

acc := &evertypes.EthAccount{
BaseAccount: baseAcc,
CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(),
}

amount := sdk.TokensFromConsensusPower(1, evertypes.PowerReduction)

balance := banktypes.Balance{
Address: acc.GetAddress().String(),
Address: baseAcc.GetAddress().String(),
Coins: sdk.NewCoins(sdk.NewCoin(constants.BaseDenom, amount)),
}

app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, chainID, balance)
app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{baseAcc}, chainID, balance)

// create current header and call begin block
header := tmproto.Header{
Expand All @@ -95,7 +87,7 @@ func NewTestChain(t *testing.T, coord *ibcgotesting.Coordinator, chainID string)
Vals: valSet,
Signers: signers,
SenderPrivKey: senderPrivKey,
SenderAccount: acc,
SenderAccount: baseAcc,
NextVals: valSet,
}

Expand Down
Loading