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

Misc cleanup #188

Merged
merged 14 commits into from
Mar 12, 2020
17 changes: 16 additions & 1 deletion app/ethermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
"github.com/cosmos/ethermint/x/evm"

abci "github.com/tendermint/tendermint/abci/types"
log "github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"
)
Expand Down Expand Up @@ -366,6 +366,21 @@ func (app *EthermintApp) SimulationManager() *module.SimulationManager {
return app.sm
}

// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *EthermintApp) GetKey(storeKey string) *sdk.KVStoreKey {
return app.keys[storeKey]
}

// Codec returns Ethermint's codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *EthermintApp) Codec() *codec.Codec {
return app.cdc
}

// GetMaccPerms returns a copy of the module account permissions
func GetMaccPerms() map[string][]string {
dupMaccPerms := make(map[string][]string)
Expand Down
34 changes: 34 additions & 0 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package app

import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
)

// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp.
func Setup(isCheckTx bool) *EthermintApp {
db := dbm.NewMemDB()
app := NewEthermintApp(log.NewNopLogger(), db, nil, true, 0)
if !isCheckTx {
// init chain must be called to stop deliverState from being nil
genesisState := simapp.NewDefaultGenesisState()
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
if err != nil {
panic(err)
}

// Initialize the chain
app.InitChain(
abci.RequestInitChain{
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
)
}

return app
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/ethereum/go-ethereum v1.9.0
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/go-kit/kit v0.9.0
github.com/golang/mock v1.3.1 // indirect
github.com/gorilla/mux v1.7.3
github.com/huin/goupnp v1.0.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func init() {

const (
// Amino encoding name
EthermintAccountName = "emint/Account"
EthermintAccountName = "ethermint/Account"
)

// RegisterCodec registers all the necessary types with amino for the given
Expand Down
42 changes: 42 additions & 0 deletions x/evm/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package evm

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 Bloom and Hash mappings and resets the Bloom filter and
// the transaction count to 0.
func BeginBlock(k Keeper, ctx sdk.Context, req abci.RequestBeginBlock) {
// Consider removing this when using evm as module without web3 API
bloom := ethtypes.BytesToBloom(k.Bloom.Bytes())
k.SetBlockBloomMapping(ctx, bloom, req.Header.GetHeight()-1)
k.SetBlockHashMapping(ctx, req.Header.LastBlockId.GetHash(), req.Header.GetHeight()-1)
k.Bloom = big.NewInt(0)
k.TxCount = 0
}

// EndBlock updates the accounts and commits states objects to the KV Store
func EndBlock(k Keeper, ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
// Gas costs are handled within msg handler so costs should be ignored
ctx = ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter())

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

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

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

return []abci.ValidatorUpdate{}
}
8 changes: 4 additions & 4 deletions x/evm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ func handleEthTxMsg(ctx sdk.Context, k Keeper, msg types.EthereumTxMsg) (*sdk.Re
Simulate: ctx.IsCheckTx(),
}
// Prepare db for logs
k.CommitStateDB.Prepare(ethHash, common.Hash{}, k.TxCount.Get())
k.TxCount.Increment()
k.CommitStateDB.Prepare(ethHash, common.Hash{}, k.TxCount)
k.TxCount++

// TODO: move to keeper
bloom, res, err := st.TransitionCSDB(ctx)
Expand Down Expand Up @@ -114,8 +114,8 @@ func handleEmintMsg(ctx sdk.Context, k Keeper, msg types.EmintMsg) (*sdk.Result,
}

// Prepare db for logs
k.CommitStateDB.Prepare(common.Hash{}, common.Hash{}, k.TxCount.Get()) // Cannot provide tx hash
k.TxCount.Increment()
k.CommitStateDB.Prepare(common.Hash{}, common.Hash{}, k.TxCount) // Cannot provide tx hash
k.TxCount++

_, res, err := st.TransitionCSDB(ctx)
if err != nil {
Expand Down
22 changes: 3 additions & 19 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
ethvm "github.com/ethereum/go-ethereum/core/vm"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/ethermint/x/evm/types"
ethstate "github.com/ethereum/go-ethereum/core/state"
ethtypes "github.com/ethereum/go-ethereum/core/types"
Expand All @@ -26,34 +25,19 @@ type Keeper struct {
// Web3 API
blockKey sdk.StoreKey
CommitStateDB *types.CommitStateDB
TxCount *count
TxCount int
Bloom *big.Int
}

// TODO: move to types
type count int

func (c *count) Get() int {
return (int)(*c)
}

func (c *count) Increment() {
*c++
}

func (c *count) Reset() {
*c = 0
}

// NewKeeper generates new evm module keeper
func NewKeeper(
cdc *codec.Codec, blockKey, codeKey, storeKey sdk.StoreKey, ak auth.AccountKeeper,
cdc *codec.Codec, blockKey, codeKey, storeKey sdk.StoreKey, ak types.AccountKeeper,
) Keeper {
return Keeper{
cdc: cdc,
blockKey: blockKey,
CommitStateDB: types.NewCommitStateDB(sdk.Context{}, codeKey, storeKey, ak),
TxCount: new(count),
TxCount: 0,
Bloom: big.NewInt(0),
}
}
Expand Down
111 changes: 44 additions & 67 deletions x/evm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
@@ -1,110 +1,87 @@
package keeper
package keeper_test

import (
"math/big"
"testing"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
"github.com/stretchr/testify/suite"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/params"

"github.com/cosmos/ethermint/types"
evmtypes "github.com/cosmos/ethermint/x/evm/types"
"github.com/cosmos/ethermint/app"
"github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/x/evm/types"

ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"

abci "github.com/tendermint/tendermint/abci/types"
tmlog "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
)

var (
address = ethcmn.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b4c1")

accKey = sdk.NewKVStoreKey("acc")
storeKey = sdk.NewKVStoreKey(evmtypes.StoreKey)
codeKey = sdk.NewKVStoreKey(evmtypes.CodeKey)
blockKey = sdk.NewKVStoreKey(evmtypes.BlockKey)
storeKey = sdk.NewKVStoreKey(types.StoreKey)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
codeKey = sdk.NewKVStoreKey(types.CodeKey)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
blockKey = sdk.NewKVStoreKey(types.BlockKey)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

logger = tmlog.NewNopLogger()
)

func newTestCodec() *codec.Codec {
cdc := codec.New()
type KeeperTestSuite struct {
suite.Suite

ctx sdk.Context
querier sdk.Querier
app *app.EthermintApp
}

evmtypes.RegisterCodec(cdc)
types.RegisterCodec(cdc)
auth.RegisterCodec(cdc)
sdk.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
func (suite *KeeperTestSuite) SetupTest() {
checkTx := false

suite.app = app.Setup(checkTx)
suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1})
suite.querier = keeper.NewQuerier(suite.app.EvmKeeper)
}

return cdc
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

func TestDBStorage(t *testing.T) {
// create logger, codec and root multi-store
cdc := newTestCodec()

// The ParamsKeeper handles parameter storage for the application
keyParams := sdk.NewKVStoreKey(params.StoreKey)
tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams)
// Set specific supspaces
authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace)
ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount)
ek := NewKeeper(cdc, blockKey, codeKey, storeKey, ak)

db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
// mount stores
keys := []*sdk.KVStoreKey{accKey, storeKey, codeKey, blockKey}
for _, key := range keys {
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil)
}

// load latest version (root)
err := cms.LoadLatestVersion()
require.NoError(t, err)

// First execution
ms := cms.CacheMultiStore()
ctx := sdk.NewContext(ms, abci.Header{}, false, logger)
ctx = ctx.WithBlockHeight(1)
func (suite *KeeperTestSuite) TestDBStorage() {
suite.app.Commit()

// Perform state transitions
ek.SetBalance(ctx, address, big.NewInt(5))
ek.SetNonce(ctx, address, 4)
ek.SetState(ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3"))
ek.SetCode(ctx, address, []byte{0x1})
suite.app.EvmKeeper.SetBalance(suite.ctx, address, big.NewInt(5))
suite.app.EvmKeeper.SetNonce(suite.ctx, address, 4)
suite.app.EvmKeeper.SetState(suite.ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3"))
suite.app.EvmKeeper.SetCode(suite.ctx, address, []byte{0x1})

// Test block hash mapping functionality
ek.SetBlockHashMapping(ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"), 7)
ek.SetBlockHashMapping(ctx, []byte{0x43, 0x32}, 8)
suite.app.EvmKeeper.SetBlockHashMapping(suite.ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"), 7)
suite.app.EvmKeeper.SetBlockHashMapping(suite.ctx, []byte{0x43, 0x32}, 8)

// Test block height mapping functionality
testBloom := ethtypes.BytesToBloom([]byte{0x1, 0x3})
ek.SetBlockBloomMapping(ctx, testBloom, 4)
suite.app.EvmKeeper.SetBlockBloomMapping(suite.ctx, testBloom, 4)

// Get those state transitions
require.Equal(t, ek.GetBalance(ctx, address).Cmp(big.NewInt(5)), 0)
require.Equal(t, ek.GetNonce(ctx, address), uint64(4))
require.Equal(t, ek.GetState(ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3"))
require.Equal(t, ek.GetCode(ctx, address), []byte{0x1})
suite.Require().Equal(suite.app.EvmKeeper.GetBalance(suite.ctx, address).Cmp(big.NewInt(5)), 0)
suite.Require().Equal(suite.app.EvmKeeper.GetNonce(suite.ctx, address), uint64(4))
suite.Require().Equal(suite.app.EvmKeeper.GetState(suite.ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3"))
suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, address), []byte{0x1})

require.Equal(t, ek.GetBlockHashMapping(ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68")), int64(7))
require.Equal(t, ek.GetBlockHashMapping(ctx, []byte{0x43, 0x32}), int64(8))
suite.Require().Equal(suite.app.EvmKeeper.GetBlockHashMapping(suite.ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68")), int64(7))
suite.Require().Equal(suite.app.EvmKeeper.GetBlockHashMapping(suite.ctx, []byte{0x43, 0x32}), int64(8))

require.Equal(t, ek.GetBlockBloomMapping(ctx, 4), testBloom)
suite.Require().Equal(suite.app.EvmKeeper.GetBlockBloomMapping(suite.ctx, 4), testBloom)

// commit stateDB
_, err = ek.Commit(ctx, false)
require.NoError(t, err, "failed to commit StateDB")
_, err := suite.app.EvmKeeper.Commit(suite.ctx, false)
suite.Require().NoError(err, "failed to commit StateDB")

// simulate BaseApp EndBlocker commitment
ms.Write()
cms.Commit()
suite.app.Commit()
}
Loading