Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Commit

Permalink
evm: fix begin and endblock (#583)
Browse files Browse the repository at this point in the history
* evm: fix begin and endblock

* fix tests and changelog

* fix gas

* update GetBlockBloom
  • Loading branch information
fedekunze committed Oct 20, 2020
1 parent b6e1839 commit d274c76
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

* (evm) [\#583](https://github.com/cosmos/ethermint/pull/583) Fixes incorrect resetting of tx count and block bloom during `BeginBlock`, as well as gas consumption.
* (crypto) [\#577](https://github.com/cosmos/ethermint/pull/577) Fix `BIP44HDPath` that did not prepend `m/` to the path. This now uses the `DefaultBaseDerivationPath` variable from go-ethereum to ensure addresses are consistent.

## [v0.2.1] - 2020-09-30
Expand Down
49 changes: 0 additions & 49 deletions x/evm/abci.go

This file was deleted.

55 changes: 55 additions & 0 deletions x/evm/keeper/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package keeper

import (
"math/big"

abci "github.com/tendermint/tendermint/abci/types"

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

ethtypes "github.com/ethereum/go-ethereum/core/types"
)

// BeginBlock sets the block hash -> block height map for the previous block height
// and resets the Bloom filter and the transaction count to 0.
func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
if req.Header.LastBlockId.GetHash() == nil || req.Header.GetHeight() < 1 {
return
}

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

k.SetBlockHash(ctx, req.Header.LastBlockId.GetHash(), req.Header.GetHeight()-1)

// reset counters that are used on CommitStateDB.Prepare
k.Bloom = big.NewInt(0)
k.TxCount = 0
}

// EndBlock updates the accounts and commits state objects to the KV Store, while
// deleting the empty ones. It also sets the bloom filers for the request block to
// the store. The EVM end block loginc doesn't update the validator set, thus it returns
// an empty slice.
func (k Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
// Gas costs are handled within msg handler so costs should be ignored
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())

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

// Commit state objects to KV store
_, err := k.Commit(ctx, true)
if err != nil {
panic(err)
}

// Clear accounts cache after account data has been committed
k.ClearStateObjects(ctx)

// set the block bloom filter bytes to store
bloom := ethtypes.BytesToBloom(k.Bloom.Bytes())
k.SetBlockBloom(ctx, req.Height, bloom)

return []abci.ValidatorUpdate{}
}
56 changes: 56 additions & 0 deletions x/evm/keeper/abci_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package keeper_test

import (
abci "github.com/tendermint/tendermint/abci/types"
)

func (suite *KeeperTestSuite) TestBeginBlock() {
req := abci.RequestBeginBlock{
Header: abci.Header{
LastBlockId: abci.BlockID{
Hash: []byte("hash"),
},
Height: 10,
},
}

// get the initial consumption
initialConsumed := suite.ctx.GasMeter().GasConsumed()

// update the counters
suite.app.EvmKeeper.Bloom.SetInt64(10)
suite.app.EvmKeeper.TxCount = 10

suite.app.EvmKeeper.BeginBlock(suite.ctx, abci.RequestBeginBlock{})
suite.Require().NotZero(suite.app.EvmKeeper.Bloom.Int64())
suite.Require().NotZero(suite.app.EvmKeeper.TxCount)

suite.Require().Equal(int64(initialConsumed), int64(suite.ctx.GasMeter().GasConsumed()))

suite.app.EvmKeeper.BeginBlock(suite.ctx, req)
suite.Require().Zero(suite.app.EvmKeeper.Bloom.Int64())
suite.Require().Zero(suite.app.EvmKeeper.TxCount)

suite.Require().Equal(int64(initialConsumed), int64(suite.ctx.GasMeter().GasConsumed()))

lastHeight, found := suite.app.EvmKeeper.GetBlockHash(suite.ctx, req.Header.LastBlockId.Hash)
suite.Require().True(found)
suite.Require().Equal(int64(9), lastHeight)
}

func (suite *KeeperTestSuite) TestEndBlock() {
// update the counters
suite.app.EvmKeeper.Bloom.SetInt64(10)

// set gas limit to 1 to ensure no gas is consumed during the operation
initialConsumed := suite.ctx.GasMeter().GasConsumed()

_ = suite.app.EvmKeeper.EndBlock(suite.ctx, abci.RequestEndBlock{Height: 100})

suite.Require().Equal(int64(initialConsumed), int64(suite.ctx.GasMeter().GasConsumed()))

bloom, found := suite.app.EvmKeeper.GetBlockBloom(suite.ctx, 100)
suite.Require().True(found)
suite.Require().Equal(int64(10), bloom.Big().Int64())

}
2 changes: 1 addition & 1 deletion x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (k Keeper) GetBlockBloom(ctx sdk.Context, height int64) (ethtypes.Bloom, bo
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixBloom)
has := store.Has(types.BloomKey(height))
if !has {
return ethtypes.Bloom{}, true // TODO: sometimes bloom cannot be found, fix this
return ethtypes.Bloom{}, false
}

bz := store.Get(types.BloomKey(height))
Expand Down
4 changes: 2 additions & 2 deletions x/evm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ func (am AppModule) NewQuerierHandler() sdk.Querier {

// BeginBlock function for module at start of each block
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
BeginBlock(am.keeper, ctx, req)
am.keeper.BeginBlock(ctx, req)
}

// EndBlock function for module at end of block
func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
return EndBlock(am.keeper, ctx, req)
return am.keeper.EndBlock(ctx, req)
}

// InitGenesis instantiates the genesis state
Expand Down

0 comments on commit d274c76

Please sign in to comment.