Sets up basic storage test for keeper and moves commit function to end of block in module from handler (#112)
This commit is contained in:
parent
46e5278355
commit
f7ad8f53f0
@ -98,12 +98,6 @@ func handleETHTxMsg(ctx sdk.Context, keeper Keeper, msg types.EthereumTxMsg) sdk
|
|||||||
|
|
||||||
keeper.csdb.Finalise(true) // Change to depend on config
|
keeper.csdb.Finalise(true) // Change to depend on config
|
||||||
|
|
||||||
// TODO: Remove commit from tx handler (should be done at end of block)
|
|
||||||
_, err = keeper.csdb.Commit(true)
|
|
||||||
if err != nil {
|
|
||||||
return sdk.ErrUnknownRequest("Failed to write data to kv store").Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Consume gas from sender
|
// TODO: Consume gas from sender
|
||||||
|
|
||||||
return sdk.Result{Data: addr.Bytes(), GasUsed: msg.Data.GasLimit - leftOverGas}
|
return sdk.Result{Data: addr.Bytes(), GasUsed: msg.Data.GasLimit - leftOverGas}
|
||||||
|
95
x/evm/keeper_test.go
Normal file
95
x/evm/keeper_test.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package evm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
|
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"
|
||||||
|
|
||||||
|
ethcmn "github.com/ethereum/go-ethereum/common"
|
||||||
|
"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")
|
||||||
|
storageKey = sdk.NewKVStoreKey(evmtypes.EvmStoreKey)
|
||||||
|
codeKey = sdk.NewKVStoreKey(evmtypes.EvmCodeKey)
|
||||||
|
|
||||||
|
logger = tmlog.NewNopLogger()
|
||||||
|
)
|
||||||
|
|
||||||
|
func newTestCodec() *codec.Codec {
|
||||||
|
cdc := codec.New()
|
||||||
|
|
||||||
|
evmtypes.RegisterCodec(cdc)
|
||||||
|
types.RegisterCodec(cdc)
|
||||||
|
auth.RegisterCodec(cdc)
|
||||||
|
sdk.RegisterCodec(cdc)
|
||||||
|
codec.RegisterCrypto(cdc)
|
||||||
|
|
||||||
|
return cdc
|
||||||
|
}
|
||||||
|
|
||||||
|
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, params.DefaultCodespace)
|
||||||
|
// Set specific supspaces
|
||||||
|
authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace)
|
||||||
|
ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount)
|
||||||
|
ek := NewKeeper(ak, storageKey, codeKey, cdc)
|
||||||
|
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
cms := store.NewCommitMultiStore(db)
|
||||||
|
// mount stores
|
||||||
|
keys := []*sdk.KVStoreKey{accKey, storageKey, codeKey}
|
||||||
|
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)
|
||||||
|
|
||||||
|
// 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})
|
||||||
|
|
||||||
|
// 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})
|
||||||
|
|
||||||
|
// commit stateDB
|
||||||
|
_, err = ek.Commit(ctx, false)
|
||||||
|
require.NoError(t, err, "failed to commit StateDB")
|
||||||
|
|
||||||
|
// simulate BaseApp EndBlocker commitment
|
||||||
|
ms.Write()
|
||||||
|
cms.Commit()
|
||||||
|
}
|
@ -17,22 +17,25 @@ import (
|
|||||||
var _ module.AppModuleBasic = AppModuleBasic{}
|
var _ module.AppModuleBasic = AppModuleBasic{}
|
||||||
var _ module.AppModule = AppModule{}
|
var _ module.AppModule = AppModule{}
|
||||||
|
|
||||||
// app module Basics object
|
// AppModuleBasic struct
|
||||||
type AppModuleBasic struct{}
|
type AppModuleBasic struct{}
|
||||||
|
|
||||||
|
// Name for app module basic
|
||||||
func (AppModuleBasic) Name() string {
|
func (AppModuleBasic) Name() string {
|
||||||
return types.ModuleName
|
return types.ModuleName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterCodec registers types for module
|
||||||
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
||||||
types.RegisterCodec(cdc)
|
types.RegisterCodec(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultGenesis is json default structure
|
||||||
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
||||||
return types.ModuleCdc.MustMarshalJSON(DefaultGenesisState())
|
return types.ModuleCdc.MustMarshalJSON(DefaultGenesisState())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation check of the Genesis
|
// ValidateGenesis is the validation check of the Genesis
|
||||||
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
||||||
var data GenesisState
|
var data GenesisState
|
||||||
err := types.ModuleCdc.UnmarshalJSON(bz, &data)
|
err := types.ModuleCdc.UnmarshalJSON(bz, &data)
|
||||||
@ -43,21 +46,22 @@ func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
|||||||
return ValidateGenesis(data)
|
return ValidateGenesis(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register rest routes
|
// RegisterRESTRoutes Registers rest routes
|
||||||
func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
|
func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
|
||||||
//rpc.RegisterRoutes(ctx, rtr, StoreKey)
|
//rpc.RegisterRoutes(ctx, rtr, StoreKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the root query command of this module
|
// GetQueryCmd Gets the root query command of this module
|
||||||
func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
||||||
return cli.GetQueryCmd(types.ModuleName, cdc)
|
return cli.GetQueryCmd(types.ModuleName, cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the root tx command of this module
|
// GetTxCmd Gets the root tx command of this module
|
||||||
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
||||||
return cli.GetTxCmd(types.ModuleName, cdc)
|
return cli.GetTxCmd(types.ModuleName, cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppModule is struct that defines variables used within module
|
||||||
type AppModule struct {
|
type AppModule struct {
|
||||||
AppModuleBasic
|
AppModuleBasic
|
||||||
keeper Keeper
|
keeper Keeper
|
||||||
@ -71,40 +75,55 @@ func NewAppModule(keeper Keeper) AppModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name is module name
|
||||||
func (AppModule) Name() string {
|
func (AppModule) Name() string {
|
||||||
return types.ModuleName
|
return types.ModuleName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterInvariants interface for registering invariants
|
||||||
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
||||||
|
|
||||||
|
// Route specifies path for transactions
|
||||||
func (am AppModule) Route() string {
|
func (am AppModule) Route() string {
|
||||||
return types.RouterKey
|
return types.RouterKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHandler sets up a new handler for module
|
||||||
func (am AppModule) NewHandler() sdk.Handler {
|
func (am AppModule) NewHandler() sdk.Handler {
|
||||||
return NewHandler(am.keeper)
|
return NewHandler(am.keeper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuerierRoute sets up path for queries
|
||||||
func (am AppModule) QuerierRoute() string {
|
func (am AppModule) QuerierRoute() string {
|
||||||
return types.ModuleName
|
return types.ModuleName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewQuerierHandler sets up new querier handler for module
|
||||||
func (am AppModule) NewQuerierHandler() sdk.Querier {
|
func (am AppModule) NewQuerierHandler() sdk.Querier {
|
||||||
return NewQuerier(am.keeper)
|
return NewQuerier(am.keeper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BeginBlock function for module at start of each block
|
||||||
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||||
|
|
||||||
|
// EndBlock function for module at end of block
|
||||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||||
// TODO: Commit database here ?
|
_, err := am.keeper.csdb.Commit(true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return []abci.ValidatorUpdate{}
|
return []abci.ValidatorUpdate{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitGenesis instantiates the genesis state
|
||||||
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
||||||
var genesisState GenesisState
|
var genesisState GenesisState
|
||||||
types.ModuleCdc.MustUnmarshalJSON(data, &genesisState)
|
types.ModuleCdc.MustUnmarshalJSON(data, &genesisState)
|
||||||
return InitGenesis(ctx, am.keeper, genesisState)
|
return InitGenesis(ctx, am.keeper, genesisState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExportGenesis exports the genesis state to be used by daemon
|
||||||
func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||||
gs := ExportGenesis(ctx, am.keeper)
|
gs := ExportGenesis(ctx, am.keeper)
|
||||||
return types.ModuleCdc.MustMarshalJSON(gs)
|
return types.ModuleCdc.MustMarshalJSON(gs)
|
||||||
|
Loading…
Reference in New Issue
Block a user