Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

evm: remove CommitStateDB and stateObject #84

Merged
merged 6 commits into from
Jun 8, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func NewEthermintApp(
params.NewAppModule(app.ParamsKeeper),
transferModule,
// Ethermint app modules
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.BankKeeper),
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
)

// During begin block slashing happens after distr.BeginBlocker so that
Expand Down
57 changes: 18 additions & 39 deletions tests/importer/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func createAndTestGenesis(t *testing.T, cms sdk.CommitMultiStore, ak authkeeper.
genBlock := ethcore.DefaultGenesisBlock()
ms := cms.CacheMultiStore()
ctx := sdk.NewContext(ms, tmproto.Header{}, false, logger)
evmKeeper.CommitStateDB.WithContext(ctx)
evmKeeper.WithContext(ctx)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

// Set the default Ethermint parameters to the parameter keeper store
evmKeeper.SetParams(ctx, evmtypes.DefaultParams())
Expand All @@ -126,25 +126,19 @@ func createAndTestGenesis(t *testing.T, cms sdk.CommitMultiStore, ak authkeeper.
addr := ethcmn.HexToAddress(addrStr)
acc := genBlock.Alloc[addr]

evmKeeper.CommitStateDB.AddBalance(addr, acc.Balance)
evmKeeper.CommitStateDB.SetCode(addr, acc.Code)
evmKeeper.CommitStateDB.SetNonce(addr, acc.Nonce)
evmKeeper.AddBalance(addr, acc.Balance)
evmKeeper.SetCode(addr, acc.Code)
evmKeeper.SetNonce(addr, acc.Nonce)

for key, value := range acc.Storage {
evmKeeper.CommitStateDB.SetState(addr, key, value)
evmKeeper.SetState(addr, key, value)
}
}

// get balance of one of the genesis account having 400 ETH
b := evmKeeper.CommitStateDB.GetBalance(genInvestor)
b := evmKeeper.GetBalance(genInvestor)
require.Equal(t, "200000000000000000000", b.String())

// commit the stateDB with 'false' to delete empty objects
//
// NOTE: Commit does not yet return the intra merkle root (version)
_, err := evmKeeper.CommitStateDB.Commit(false)
require.NoError(t, err)

// persist multi-store cache state
ms.Write()

Expand Down Expand Up @@ -267,15 +261,13 @@ func TestImportBlocks(t *testing.T) {
ms := cms.CacheMultiStore()
ctx := sdk.NewContext(ms, tmproto.Header{}, false, logger)
ctx = ctx.WithBlockHeight(int64(block.NumberU64()))
evmKeeper.CommitStateDB.WithContext(ctx)
evmKeeper.WithContext(ctx)

if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
applyDAOHardFork(evmKeeper)
}

for i, tx := range block.Transactions() {
evmKeeper.CommitStateDB.Prepare(tx.Hash(), block.Hash(), i)
// evmKeeper.CommitStateDB.Set(block.Hash())
for _, tx := range block.Transactions() {

receipt, gas, err := applyTransaction(
chainConfig, chainContext, nil, gp, evmKeeper, header, tx, usedGas, vmConfig,
Expand All @@ -287,10 +279,6 @@ func TestImportBlocks(t *testing.T) {
// apply mining rewards
accumulateRewards(chainConfig, evmKeeper, header, block.Uncles())

// commit stateDB
_, err := evmKeeper.CommitStateDB.Commit(chainConfig.IsEIP158(block.Number()))
require.NoError(t, err, "failed to commit StateDB")

// simulate BaseApp EndBlocker commitment
ms.Write()
cms.Commit()
Expand Down Expand Up @@ -325,12 +313,12 @@ func accumulateRewards(
r.Sub(r, header.Number)
r.Mul(r, blockReward)
r.Div(r, rewardBig8)
evmKeeper.CommitStateDB.AddBalance(uncle.Coinbase, r)
evmKeeper.AddBalance(uncle.Coinbase, r)
r.Div(blockReward, rewardBig32)
reward.Add(reward, r)
}

evmKeeper.CommitStateDB.AddBalance(header.Coinbase, reward)
evmKeeper.AddBalance(header.Coinbase, reward)
}

// ApplyDAOHardFork modifies the state database according to the DAO hard-fork
Expand All @@ -341,14 +329,13 @@ func accumulateRewards(
// Ref: https://github.com/ethereum/go-ethereum/blob/52f2461774bcb8cdd310f86b4bc501df5b783852/consensus/misc/dao.go#L74
func applyDAOHardFork(evmKeeper *evmkeeper.Keeper) {
// Retrieve the contract to refund balances into
if !evmKeeper.CommitStateDB.Exist(ethparams.DAORefundContract) {
evmKeeper.CommitStateDB.CreateAccount(ethparams.DAORefundContract)
if !evmKeeper.Exist(ethparams.DAORefundContract) {
evmKeeper.CreateAccount(ethparams.DAORefundContract)
}

// Move every DAO account and extra-balance account funds into the refund contract
for _, addr := range ethparams.DAODrainList() {
evmKeeper.CommitStateDB.AddBalance(ethparams.DAORefundContract, evmKeeper.CommitStateDB.GetBalance(addr))
evmKeeper.CommitStateDB.SetBalance(addr, new(big.Int))
evmKeeper.AddBalance(ethparams.DAORefundContract, evmKeeper.GetBalance(addr))
}
}

Expand All @@ -374,7 +361,7 @@ func applyTransaction(

// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmenv := ethvm.NewEVM(blockCtx, txCtx, evmKeeper.CommitStateDB, config, cfg)
vmenv := ethvm.NewEVM(blockCtx, txCtx, evmKeeper, config, cfg)

// Apply the transaction to the current state (included in the env)
execResult, err := ethcore.ApplyMessage(vmenv, msg, gp)
Expand All @@ -383,19 +370,11 @@ func applyTransaction(
return &ethtypes.Receipt{}, 0, nil
}

// Update the state with pending changes
var intRoot ethcmn.Hash
if config.IsByzantium(header.Number) {
err = evmKeeper.CommitStateDB.Finalise(true)
} else {
intRoot, err = evmKeeper.CommitStateDB.IntermediateRoot(config.IsEIP158(header.Number))
}

if err != nil {
return nil, execResult.UsedGas, err
}

root := intRoot.Bytes()
root := ethcmn.Hash{}.Bytes()
*usedGas += execResult.UsedGas

// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
Expand All @@ -410,11 +389,11 @@ func applyTransaction(
}

// Set the receipt logs and create a bloom for filtering
receipt.Logs, err = evmKeeper.CommitStateDB.GetLogs(tx.Hash())
receipt.Logs = evmKeeper.GetTxLogs(tx.Hash())
receipt.Bloom = ethtypes.CreateBloom(ethtypes.Receipts{receipt})
receipt.BlockHash = evmKeeper.CommitStateDB.BlockHash()
receipt.BlockHash = header.Hash()
receipt.BlockNumber = header.Number
receipt.TransactionIndex = uint(evmKeeper.CommitStateDB.TxIndex())
receipt.TransactionIndex = uint(evmKeeper.GetTxIndexTransient())

return receipt, execResult.UsedGas, err
}
31 changes: 3 additions & 28 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@ func InitGenesis(
ctx sdk.Context,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder to self: read genesis.json specification since it represents the state of all the modules when imported/exported

k *keeper.Keeper,
accountKeeper types.AccountKeeper, // nolint: interfacer
bankKeeper types.BankKeeper,
data types.GenesisState,
) []abci.ValidatorUpdate {
k.WithContext(ctx)
k.WithChainID(ctx)

k.CommitStateDB.WithContext(ctx)

k.SetParams(ctx, data.Params)
evmDenom := data.Params.EvmDenom

for _, account := range data.Accounts {
address := ethcmn.HexToAddress(account.Address)
Expand All @@ -47,46 +43,25 @@ func InitGenesis(
)
}

evmBalance := bankKeeper.GetBalance(ctx, accAddress, evmDenom)
k.CommitStateDB.SetBalance(address, evmBalance.Amount.BigInt())
k.CommitStateDB.SetNonce(address, acc.GetSequence())
k.CommitStateDB.SetCode(address, ethcmn.Hex2Bytes(account.Code))
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
k.SetCode(address, ethcmn.Hex2Bytes(account.Code))

for _, storage := range account.Storage {
k.SetState(address, ethcmn.HexToHash(storage.Key), ethcmn.HexToHash(storage.Value))
}
}

var err error
for _, txLog := range data.TxsLogs {
err = k.CommitStateDB.SetLogs(ethcmn.HexToHash(txLog.Hash), txLog.EthLogs())
if err != nil {
panic(err)
}
k.SetLogs(ethcmn.HexToHash(txLog.Hash), txLog.EthLogs())
}

k.SetChainConfig(ctx, data.ChainConfig)

// set state objects and code to store
_, err = k.CommitStateDB.Commit(false)
if err != nil {
panic(err)
}

// set storage to store
// NOTE: don't delete empty object to prevent import-export simulation failure
err = k.CommitStateDB.Finalise(false)
if err != nil {
panic(err)
}

return []abci.ValidatorUpdate{}
}

// ExportGenesis exports genesis state of the EVM module
func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak types.AccountKeeper) *types.GenesisState {
k.WithContext(ctx)
k.CommitStateDB.WithContext(ctx)

// nolint: prealloc
var ethGenAccounts []types.GenesisAccount
Expand All @@ -106,7 +81,7 @@ func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak types.AccountKeeper) *t

genAccount := types.GenesisAccount{
Address: addr.String(),
Code: ethcmn.Bytes2Hex(k.CommitStateDB.GetCode(addr)),
Code: ethcmn.Bytes2Hex(k.GetCode(addr)),
Storage: storage,
}

Expand Down
4 changes: 2 additions & 2 deletions x/evm/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ func (suite *EvmTestSuite) TestInitGenesis() {
if tc.expPanic {
suite.Require().Panics(
func() {
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState)
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.genState)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
},
)
} else {
suite.Require().NotPanics(
func() {
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, suite.app.BankKeeper, *tc.genState)
_ = evm.InitGenesis(suite.ctx, suite.app.EvmKeeper, suite.app.AccountKeeper, *tc.genState)
},
)
}
Expand Down
5 changes: 2 additions & 3 deletions x/evm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/x/evm/types"
)

// NewHandler returns a handler for Ethermint type messages.
func NewHandler(k *keeper.Keeper) sdk.Handler {
func NewHandler(server types.MsgServer) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (result *sdk.Result, err error) {
defer Recover(&err)

Expand All @@ -22,7 +21,7 @@ func NewHandler(k *keeper.Keeper) sdk.Handler {
switch msg := msg.(type) {
case *types.MsgEthereumTx:
// execute state transition
res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg)
res, err := server.EthereumTx(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)

default:
Expand Down
18 changes: 7 additions & 11 deletions x/evm/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (suite *EvmTestSuite) SetupTest() {

suite.app = app.Setup(checkTx)
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-1", Time: time.Now().UTC()})
suite.app.EvmKeeper.CommitStateDB.WithContext(suite.ctx)
suite.app.EvmKeeper.WithContext(suite.ctx)
suite.handler = evm.NewHandler(suite.app.EvmKeeper)
suite.codec = suite.app.AppCodec()
suite.chainID = suite.app.EvmKeeper.ChainID()
Expand Down Expand Up @@ -84,7 +84,6 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
{
"passed",
func() {
suite.app.EvmKeeper.CommitStateDB.SetBalance(suite.from, big.NewInt(100))
to := ethcmn.BytesToAddress(suite.to)
tx = types.NewMsgEthereumTx(suite.chainID, 0, &to, big.NewInt(100), 0, big.NewInt(10000), nil, nil)
tx.From = suite.from.String()
Expand Down Expand Up @@ -189,11 +188,10 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
suite.Require().Equal(len(txResponse.Logs[0].Topics), 2)

hash := []byte{1}
err = suite.app.EvmKeeper.CommitStateDB.SetLogs(ethcmn.BytesToHash(hash), types.LogsToEthereum(txResponse.Logs))
suite.app.EvmKeeper.SetLogs(ethcmn.BytesToHash(hash), types.LogsToEthereum(txResponse.Logs))
suite.Require().NoError(err)

logs, err := suite.app.EvmKeeper.CommitStateDB.GetLogs(ethcmn.BytesToHash(hash))
suite.Require().NoError(err, "failed to get logs")
logs := suite.app.EvmKeeper.GetTxLogs(ethcmn.BytesToHash(hash))

suite.Require().Equal(logs, txResponse.Logs)
}
Expand Down Expand Up @@ -310,8 +308,6 @@ func (suite *EvmTestSuite) TestSendTransaction() {
gasLimit := uint64(21000)
gasPrice := big.NewInt(0x55ae82600)

suite.app.EvmKeeper.CommitStateDB.SetBalance(suite.from, big.NewInt(100))

// send simple value transfer with gasLimit=21000
tx := types.NewMsgEthereumTx(suite.chainID, 1, &ethcmn.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil, nil)
tx.From = suite.from.String()
Expand Down Expand Up @@ -390,12 +386,12 @@ func (suite *EvmTestSuite) TestOutOfGasWhenDeployContract() {
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)

snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)
snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper)
suite.Require().Nil(err)

defer func() {
if r := recover(); r != nil {
currentCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)
currentCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper)
suite.Require().Nil(err)
suite.Require().Equal(snapshotCommitStateDBJson, currentCommitStateDBJson)
} else {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -419,13 +415,13 @@ func (suite *EvmTestSuite) TestErrorWhenDeployContract() {
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)

snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)
snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper)
suite.Require().Nil(err)

_, sdkErr := suite.handler(suite.ctx, tx)
suite.Require().NotNil(sdkErr)

currentCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)
currentCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper)
suite.Require().Nil(err)
suite.Require().Equal(snapshotCommitStateDBJson, currentCommitStateDBJson)
}
23 changes: 4 additions & 19 deletions x/evm/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,22 @@ func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
// deleting the empty ones. It also sets the bloom filers for the request block to
// the store. The EVM end block logic doesn't update the validator set, thus it returns
// an empty slice.
func (k Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)

// Gas costs are handled within msg handler so costs should be ignored
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
k.CommitStateDB.WithContext(ctx)
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
k.WithContext(ctx)

// Update account balances before committing other parts of state
k.CommitStateDB.UpdateAccounts()

root, err := k.CommitStateDB.Commit(true)
// Commit state objects to KV store
if err != nil {
k.Logger(ctx).Error("failed to commit state objects", "error", err, "height", ctx.BlockHeight())
panic(err)
}

// reset all cache after account data has been committed, that make sure node state consistent
if err = k.CommitStateDB.Reset(root); err != nil {
panic(err)
}

// get the block bloom bytes from the transient store and set it to the persistent storage
bloomBig, found := k.GetBlockBloomTransient()
if !found {
bloomBig = big.NewInt(0)
}

bloom := ethtypes.BytesToBloom(bloomBig.Bytes())
k.SetBlockBloom(ctx, req.Height, bloom)
k.SetBlockBloom(infCtx, req.Height, bloom)
k.WithContext(ctx)

return []abci.ValidatorUpdate{}
}
Loading