eth_getBlockByHash and block hash mapping functionality (#114)

* Set up block hash to height mapping storage and fixed linting issues

* fix typos

* Set up module query for block height

* fix bug with block mappings and implemented get block by hash

* Fix other consensus hash references
This commit is contained in:
Austin Abell 2019-09-27 10:08:45 -04:00 committed by GitHub
parent f7ad8f53f0
commit 09a71a2a3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 161 additions and 83 deletions

View File

@ -37,13 +37,13 @@ import (
const appName = "Ethermint" const appName = "Ethermint"
var ( var (
// default home directories for the application CLI // DefaultCLIHome sets the default home directories for the application CLI
DefaultCLIHome = os.ExpandEnv("$HOME/.emintcli") DefaultCLIHome = os.ExpandEnv("$HOME/.emintcli")
// DefaultNodeHome sets the folder where the applcation data and configuration will be stored // DefaultNodeHome sets the folder where the applcation data and configuration will be stored
DefaultNodeHome = os.ExpandEnv("$HOME/.emintd") DefaultNodeHome = os.ExpandEnv("$HOME/.emintd")
// The module BasicManager is in charge of setting up basic, // ModuleBasics is the module BasicManager is in charge of setting up basic,
// non-dependant module elements, such as codec registration // non-dependant module elements, such as codec registration
// and genesis verification. // and genesis verification.
ModuleBasics = module.NewBasicManager( ModuleBasics = module.NewBasicManager(
@ -131,7 +131,7 @@ func NewEthermintApp(
keys := sdk.NewKVStoreKeys(bam.MainStoreKey, auth.StoreKey, staking.StoreKey, keys := sdk.NewKVStoreKeys(bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey, supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
gov.StoreKey, params.StoreKey, evmtypes.EvmStoreKey, evmtypes.EvmCodeKey) gov.StoreKey, params.StoreKey, evmtypes.EvmStoreKey, evmtypes.EvmCodeKey, evmtypes.EvmBlockKey)
tkeys := sdk.NewTransientStoreKeys(staking.TStoreKey, params.TStoreKey) tkeys := sdk.NewTransientStoreKeys(staking.TStoreKey, params.TStoreKey)
app := &EthermintApp{ app := &EthermintApp{
@ -165,7 +165,7 @@ func NewEthermintApp(
app.slashingKeeper = slashing.NewKeeper(app.cdc, keys[slashing.StoreKey], &stakingKeeper, app.slashingKeeper = slashing.NewKeeper(app.cdc, keys[slashing.StoreKey], &stakingKeeper,
slashingSubspace, slashing.DefaultCodespace) slashingSubspace, slashing.DefaultCodespace)
app.crisisKeeper = crisis.NewKeeper(crisisSubspace, invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName) app.crisisKeeper = crisis.NewKeeper(crisisSubspace, invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName)
app.evmKeeper = evm.NewKeeper(app.accountKeeper, keys[evmtypes.EvmStoreKey], keys[evmtypes.EvmCodeKey], cdc) app.evmKeeper = evm.NewKeeper(app.accountKeeper, keys[evmtypes.EvmStoreKey], keys[evmtypes.EvmCodeKey], keys[evmtypes.EvmBlockKey], cdc)
// register the proposal types // register the proposal types
govRouter := gov.NewRouter() govRouter := gov.NewRouter()
@ -199,9 +199,9 @@ func NewEthermintApp(
// During begin block slashing happens after distr.BeginBlocker so that // During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the // there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant. // CanWithdrawInvariant invariant.
app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName) app.mm.SetOrderBeginBlockers(mint.ModuleName, distr.ModuleName, slashing.ModuleName, evmtypes.ModuleName)
app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName) app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName, evmtypes.ModuleName)
// NOTE: The genutils module must occur after staking so that pools are // NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts. // properly initialized with tokens from genesis accounts.
@ -233,28 +233,28 @@ func NewEthermintApp(
return app return app
} }
// The genesis state of the blockchain is represented here as a map of raw json // GenesisState is the state of the blockchain is represented here as a map of raw json
// messages key'd by a identifier string. // messages key'd by a identifier string.
type GenesisState map[string]json.RawMessage type GenesisState map[string]json.RawMessage
// application updates every begin block // BeginBlocker updates every begin block
func (app *EthermintApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { func (app *EthermintApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.mm.BeginBlock(ctx, req) return app.mm.BeginBlock(ctx, req)
} }
// application updates every end block // EndBlocker updates every end block
func (app *EthermintApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { func (app *EthermintApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req) return app.mm.EndBlock(ctx, req)
} }
// application update at chain initialization // InitChainer updates at chain initialization
func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState GenesisState var genesisState GenesisState
app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState) app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
return app.mm.InitGenesis(ctx, genesisState) return app.mm.InitGenesis(ctx, genesisState)
} }
// load a particular height // LoadHeight loads state at a particular height
func (app *EthermintApp) LoadHeight(height int64) error { func (app *EthermintApp) LoadHeight(height int64) error {
return app.LoadVersion(height, app.keys[bam.MainStoreKey]) return app.LoadVersion(height, app.keys[bam.MainStoreKey])
} }

View File

@ -20,8 +20,8 @@ import (
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
tmcrypto "github.com/tendermint/tendermint/crypto" tmcrypto "github.com/tendermint/tendermint/crypto"
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
) )
type testSetup struct { type testSetup struct {

View File

@ -11,8 +11,8 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
sdkrpc "github.com/cosmos/cosmos-sdk/client/rpc" sdkrpc "github.com/cosmos/cosmos-sdk/client/rpc"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
emintkeys "github.com/cosmos/ethermint/keys"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
emintkeys "github.com/cosmos/ethermint/keys"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"

View File

@ -4,9 +4,9 @@ import (
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/crypto/keys/hd"
emintCrypto "github.com/cosmos/ethermint/crypto" emintCrypto "github.com/cosmos/ethermint/crypto"
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
) )
var cdc *codec.Codec var cdc *codec.Codec

View File

@ -13,8 +13,8 @@ import (
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys" cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/crypto/keys/hd"
"github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror"
"github.com/cosmos/ethermint/crypto/keys/mintkey"
"github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/ethermint/crypto/keys/mintkey"
bip39 "github.com/cosmos/go-bip39" bip39 "github.com/cosmos/go-bip39"

View File

@ -35,8 +35,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tm-db"
tmlog "github.com/tendermint/tendermint/libs/log" tmlog "github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
) )
var ( var (
@ -326,7 +326,7 @@ func applyDAOHardFork(statedb *evmtypes.CommitStateDB) {
// and uses the input parameters for its environment. It returns the receipt // and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed, // for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid. // indicating the block was invalid.
// Function is also pulled from go-ethereum 1.9 because of the imcompatible usage // Function is also pulled from go-ethereum 1.9 because of the incompatible usage
// Ref: https://github.com/ethereum/go-ethereum/blob/52f2461774bcb8cdd310f86b4bc501df5b783852/core/state_processor.go#L88 // Ref: https://github.com/ethereum/go-ethereum/blob/52f2461774bcb8cdd310f86b4bc501df5b783852/core/state_processor.go#L88
func applyTransaction(config *ethparams.ChainConfig, bc ethcore.ChainContext, author *ethcmn.Address, gp *ethcore.GasPool, statedb *evmtypes.CommitStateDB, header *ethtypes.Header, tx *ethtypes.Transaction, usedGas *uint64, cfg ethvm.Config) (*ethtypes.Receipt, uint64, error) { func applyTransaction(config *ethparams.ChainConfig, bc ethcore.ChainContext, author *ethcmn.Address, gp *ethcore.GasPool, statedb *evmtypes.CommitStateDB, header *ethtypes.Header, tx *ethtypes.Transaction, usedGas *uint64, cfg ethvm.Config) (*ethtypes.Receipt, uint64, error) {
msg, err := tx.AsMessage(ethtypes.MakeSigner(config, header.Number)) msg, err := tx.AsMessage(ethtypes.MakeSigner(config, header.Number))

View File

@ -10,6 +10,7 @@ import (
"github.com/cosmos/ethermint/rpc/args" "github.com/cosmos/ethermint/rpc/args"
"github.com/cosmos/ethermint/utils" "github.com/cosmos/ethermint/utils"
"github.com/cosmos/ethermint/version" "github.com/cosmos/ethermint/version"
"github.com/cosmos/ethermint/x/evm"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -332,14 +333,24 @@ func (e *PublicEthAPI) EstimateGas(args CallArgs, blockNum BlockNumber) hexutil.
} }
// GetBlockByHash returns the block identified by hash. // GetBlockByHash returns the block identified by hash.
func (e *PublicEthAPI) GetBlockByHash(hash common.Hash, fullTx bool) map[string]interface{} { func (e *PublicEthAPI) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) {
return nil res, _, err := e.cliCtx.Query(fmt.Sprintf("custom/%s/%s/%s", types.ModuleName, evm.QueryHashToHeight, hash.Hex()))
if err != nil {
return nil, err
}
var out types.QueryResBlockNumber
e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
return e.getEthBlockByNumber(out.Number, fullTx)
} }
// GetBlockByNumber returns the block identified by number. // GetBlockByNumber returns the block identified by number.
func (e *PublicEthAPI) GetBlockByNumber(blockNum BlockNumber, fullTx bool) (map[string]interface{}, error) { func (e *PublicEthAPI) GetBlockByNumber(blockNum BlockNumber, fullTx bool) (map[string]interface{}, error) {
value := blockNum.Int64() value := blockNum.Int64()
return e.getEthBlockByNumber(value, fullTx)
}
func (e *PublicEthAPI) getEthBlockByNumber(value int64, fullTx bool) (map[string]interface{}, error) {
// Remove this check when 0 query is fixed ref: (https://github.com/tendermint/tendermint/issues/4014) // Remove this check when 0 query is fixed ref: (https://github.com/tendermint/tendermint/issues/4014)
var blkNumPtr *int64 var blkNumPtr *int64
if value != 0 { if value != 0 {
@ -363,7 +374,7 @@ func (e *PublicEthAPI) GetBlockByNumber(blockNum BlockNumber, fullTx bool) (map[
if fullTx { if fullTx {
// Populate full transaction data // Populate full transaction data
transactions, gasUsed = convertTransactionsToRPC(e.cliCtx, block.Block.Txs, transactions, gasUsed = convertTransactionsToRPC(e.cliCtx, block.Block.Txs,
common.BytesToHash(header.ConsensusHash.Bytes()), uint64(header.Height)) common.BytesToHash(header.Hash()), uint64(header.Height))
} else { } else {
// TODO: Gas used not saved and cannot be calculated by hashes // TODO: Gas used not saved and cannot be calculated by hashes
// Return slice of transaction hashes // Return slice of transaction hashes
@ -382,7 +393,7 @@ func formatBlock(
) map[string]interface{} { ) map[string]interface{} {
return map[string]interface{}{ return map[string]interface{}{
"number": hexutil.Uint64(header.Height), "number": hexutil.Uint64(header.Height),
"hash": hexutil.Bytes(header.ConsensusHash), "hash": hexutil.Bytes(header.Hash()),
"parentHash": hexutil.Bytes(header.LastBlockID.Hash), "parentHash": hexutil.Bytes(header.LastBlockID.Hash),
"nonce": nil, // PoW specific "nonce": nil, // PoW specific
"sha3Uncles": nil, // No uncles in Tendermint "sha3Uncles": nil, // No uncles in Tendermint
@ -485,7 +496,7 @@ func (e *PublicEthAPI) GetTransactionByHash(hash common.Hash) (*Transaction, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
blockHash := common.BytesToHash(block.BlockMeta.Header.ConsensusHash) blockHash := common.BytesToHash(block.BlockMeta.Header.Hash())
ethTx, err := bytesToEthTx(e.cliCtx, tx.Tx) ethTx, err := bytesToEthTx(e.cliCtx, tx.Tx)
if err != nil { if err != nil {
@ -518,7 +529,7 @@ func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNum BlockNumber,
return nil, err return nil, err
} }
transaction := newRPCTransaction(ethTx, common.BytesToHash(header.ConsensusHash.Bytes()), uint64(header.Height), uint64(idx)) transaction := newRPCTransaction(ethTx, common.BytesToHash(header.Hash()), uint64(header.Height), uint64(idx))
return transaction, nil return transaction, nil
} }
@ -535,7 +546,7 @@ func (e *PublicEthAPI) GetTransactionReceipt(hash common.Hash) (map[string]inter
if err != nil { if err != nil {
return nil, err return nil, err
} }
blockHash := common.BytesToHash(block.BlockMeta.Header.ConsensusHash) blockHash := common.BytesToHash(block.BlockMeta.Header.Hash())
// Convert tx bytes to eth transaction // Convert tx bytes to eth transaction
ethTx, err := bytesToEthTx(e.cliCtx, tx.Tx) ethTx, err := bytesToEthTx(e.cliCtx, tx.Tx)

View File

@ -127,7 +127,7 @@ func completeAndBroadcastETHTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLI
} }
} }
// * This function is overriden to change the keybase reference here // * This function is overridden to change the keybase reference here
passphrase, err := emintkeys.GetPassphrase(fromName) passphrase, err := emintkeys.GetPassphrase(fromName)
if err != nil { if err != nil {
return err return err
@ -151,7 +151,7 @@ func completeAndBroadcastETHTxCLI(txBldr authtypes.TxBuilder, cliCtx context.CLI
// BuildAndSign builds a single message to be signed, and signs a transaction // BuildAndSign builds a single message to be signed, and signs a transaction
// with the built message given a name, passphrase, and a set of messages. // with the built message given a name, passphrase, and a set of messages.
// * overriden from github.com/cosmos/cosmos-sdk/x/auth/types/txbuilder.go // * overridden from github.com/cosmos/cosmos-sdk/x/auth/types/txbuilder.go
// * This is just modified to change the functionality in makeSignature, through sign // * This is just modified to change the functionality in makeSignature, through sign
func buildAndSign(bldr authtypes.TxBuilder, name, passphrase string, msgs []sdk.Msg) ([]byte, error) { func buildAndSign(bldr authtypes.TxBuilder, name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
msg, err := bldr.BuildSignMsg(msgs) msg, err := bldr.BuildSignMsg(msgs)
@ -179,7 +179,7 @@ func sign(bldr authtypes.TxBuilder, name, passphrase string, msg authtypes.StdSi
func makeSignature(keybase crkeys.Keybase, name, passphrase string, func makeSignature(keybase crkeys.Keybase, name, passphrase string,
msg authtypes.StdSignMsg) (sig authtypes.StdSignature, err error) { msg authtypes.StdSignMsg) (sig authtypes.StdSignature, err error) {
if keybase == nil { if keybase == nil {
// * This is overriden to allow ethermint keys, but not used because keybase is set // * This is overridden to allow ethermint keys, but not used because keybase is set
keybase, err = emintkeys.NewKeyBaseFromHomeFlag() keybase, err = emintkeys.NewKeyBaseFromHomeFlag()
if err != nil { if err != nil {
return return
@ -212,7 +212,7 @@ func makeSignature(keybase crkeys.Keybase, name, passphrase string,
ethTx.Sign(chainID, emintKey.ToECDSA()) ethTx.Sign(chainID, emintKey.ToECDSA())
// * This is needed to be overriden to get bytes to sign (RLPSignBytes) with the chainID // * This is needed to be overridden to get bytes to sign (RLPSignBytes) with the chainID
sigBytes, pubkey, err := keybase.Sign(name, passphrase, ethTx.RLPSignBytes(chainID).Bytes()) sigBytes, pubkey, err := keybase.Sign(name, passphrase, ethTx.RLPSignBytes(chainID).Bytes())
if err != nil { if err != nil {
return return
@ -321,7 +321,7 @@ func getFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) {
return addr, "", nil return addr, "", nil
} }
// * This is the line that needed to be overriden, change could be to pass in optional keybase? // * This is the line that needed to be overridden, change could be to pass in optional keybase?
keybase, err := emintkeys.NewKeyBaseFromHomeFlag() keybase, err := emintkeys.NewKeyBaseFromHomeFlag()
if err != nil { if err != nil {
return nil, "", err return nil, "", err

View File

@ -2,11 +2,12 @@ package evm
import ( import (
"fmt" "fmt"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/types"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"math/big"
) )
type ( type (
@ -25,6 +26,7 @@ type (
} }
) )
// ValidateGenesis validates evm genesis config
func ValidateGenesis(data GenesisState) error { func ValidateGenesis(data GenesisState) error {
for _, acct := range data.Accounts { for _, acct := range data.Accounts {
if len(acct.Address.Bytes()) == 0 { if len(acct.Address.Bytes()) == 0 {
@ -37,12 +39,14 @@ func ValidateGenesis(data GenesisState) error {
return nil return nil
} }
// DefaultGenesisState sets default evm genesis config
func DefaultGenesisState() GenesisState { func DefaultGenesisState() GenesisState {
return GenesisState{ return GenesisState{
Accounts: []GenesisAccount{}, Accounts: []GenesisAccount{},
} }
} }
// InitGenesis initializes genesis state based on exported genesis
func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) []abci.ValidatorUpdate { func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) []abci.ValidatorUpdate {
for _, record := range data.Accounts { for _, record := range data.Accounts {
keeper.SetCode(ctx, record.Address, record.Code) keeper.SetCode(ctx, record.Address, record.Code)
@ -51,7 +55,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) []abci.Valid
return []abci.ValidatorUpdate{} return []abci.ValidatorUpdate{}
} }
// TODO: Implement // ExportGenesis exports genesis state
func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState { func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
return GenesisState{Accounts: nil} return GenesisState{Accounts: nil}
} }

View File

@ -1,6 +1,9 @@
package evm package evm
import ( import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
ethvm "github.com/ethereum/go-ethereum/core/vm" ethvm "github.com/ethereum/go-ethereum/core/vm"
@ -17,17 +20,45 @@ import (
// Keeper wraps the CommitStateDB, allowing us to pass in SDK context while adhering // Keeper wraps the CommitStateDB, allowing us to pass in SDK context while adhering
// to the StateDB interface // to the StateDB interface
type Keeper struct { type Keeper struct {
csdb *types.CommitStateDB csdb *types.CommitStateDB
cdc *codec.Codec cdc *codec.Codec
blockKey sdk.StoreKey
} }
func NewKeeper(ak auth.AccountKeeper, storageKey, codeKey sdk.StoreKey, cdc *codec.Codec) Keeper { // NewKeeper generates new evm module keeper
func NewKeeper(ak auth.AccountKeeper, storageKey, codeKey sdk.StoreKey,
blockKey sdk.StoreKey, cdc *codec.Codec) Keeper {
return Keeper{ return Keeper{
csdb: types.NewCommitStateDB(sdk.Context{}, ak, storageKey, codeKey), csdb: types.NewCommitStateDB(sdk.Context{}, ak, storageKey, codeKey),
cdc: cdc, cdc: cdc,
blockKey: blockKey,
} }
} }
// ----------------------------------------------------------------------------
// Block hash mapping functions
// May be removed when using only as module (only required by rpc api)
// ----------------------------------------------------------------------------
// SetBlockHashMapping sets the mapping from block consensus hash to block height
func (k *Keeper) SetBlockHashMapping(ctx sdk.Context, hash []byte, height int64) {
store := ctx.KVStore(k.blockKey)
if !bytes.Equal(hash, []byte{}) {
store.Set(hash, k.cdc.MustMarshalBinaryLengthPrefixed(height))
}
}
// GetBlockHashMapping gets block height from block consensus hash
func (k *Keeper) GetBlockHashMapping(ctx sdk.Context, hash []byte) (height int64) {
store := ctx.KVStore(k.blockKey)
bz := store.Get(hash)
if bytes.Equal(bz, []byte{}) {
panic(fmt.Errorf("block with hash %s not found", ethcmn.Bytes2Hex(hash)))
}
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &height)
return
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Genesis // Genesis
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -47,52 +78,52 @@ func (k *Keeper) CreateGenesisAccount(ctx sdk.Context, account GenesisAccount) {
// Setters // Setters
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Calls CommitStateDB.SetBalance using the passed in context // SetBalance calls CommitStateDB.SetBalance using the passed in context
func (k *Keeper) SetBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) { func (k *Keeper) SetBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) {
k.csdb.WithContext(ctx).SetBalance(addr, amount) k.csdb.WithContext(ctx).SetBalance(addr, amount)
} }
// Calls CommitStateDB.AddBalance using the passed in context // AddBalance calls CommitStateDB.AddBalance using the passed in context
func (k *Keeper) AddBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) { func (k *Keeper) AddBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) {
k.csdb.WithContext(ctx).AddBalance(addr, amount) k.csdb.WithContext(ctx).AddBalance(addr, amount)
} }
// Calls CommitStateDB.SubBalance using the passed in context // SubBalance calls CommitStateDB.SubBalance using the passed in context
func (k *Keeper) SubBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) { func (k *Keeper) SubBalance(ctx sdk.Context, addr ethcmn.Address, amount *big.Int) {
k.csdb.WithContext(ctx).SubBalance(addr, amount) k.csdb.WithContext(ctx).SubBalance(addr, amount)
} }
// Calls CommitStateDB.SetNonce using the passed in context // SetNonce calls CommitStateDB.SetNonce using the passed in context
func (k *Keeper) SetNonce(ctx sdk.Context, addr ethcmn.Address, nonce uint64) { func (k *Keeper) SetNonce(ctx sdk.Context, addr ethcmn.Address, nonce uint64) {
k.csdb.WithContext(ctx).SetNonce(addr, nonce) k.csdb.WithContext(ctx).SetNonce(addr, nonce)
} }
// Calls CommitStateDB.SetState using the passed in context // SetState calls CommitStateDB.SetState using the passed in context
func (k *Keeper) SetState(ctx sdk.Context, addr ethcmn.Address, key, value ethcmn.Hash) { func (k *Keeper) SetState(ctx sdk.Context, addr ethcmn.Address, key, value ethcmn.Hash) {
k.csdb.WithContext(ctx).SetState(addr, key, value) k.csdb.WithContext(ctx).SetState(addr, key, value)
} }
// Calls CommitStateDB.SetCode using the passed in context // SetCode calls CommitStateDB.SetCode using the passed in context
func (k *Keeper) SetCode(ctx sdk.Context, addr ethcmn.Address, code []byte) { func (k *Keeper) SetCode(ctx sdk.Context, addr ethcmn.Address, code []byte) {
k.csdb.WithContext(ctx).SetCode(addr, code) k.csdb.WithContext(ctx).SetCode(addr, code)
} }
// Calls CommitStateDB.AddLog using the passed in context // AddLog calls CommitStateDB.AddLog using the passed in context
func (k *Keeper) AddLog(ctx sdk.Context, log *ethtypes.Log) { func (k *Keeper) AddLog(ctx sdk.Context, log *ethtypes.Log) {
k.csdb.WithContext(ctx).AddLog(log) k.csdb.WithContext(ctx).AddLog(log)
} }
// Calls CommitStateDB.AddPreimage using the passed in context // AddPreimage calls CommitStateDB.AddPreimage using the passed in context
func (k *Keeper) AddPreimage(ctx sdk.Context, hash ethcmn.Hash, preimage []byte) { func (k *Keeper) AddPreimage(ctx sdk.Context, hash ethcmn.Hash, preimage []byte) {
k.csdb.WithContext(ctx).AddPreimage(hash, preimage) k.csdb.WithContext(ctx).AddPreimage(hash, preimage)
} }
// Calls CommitStateDB.AddRefund using the passed in context // AddRefund calls CommitStateDB.AddRefund using the passed in context
func (k *Keeper) AddRefund(ctx sdk.Context, gas uint64) { func (k *Keeper) AddRefund(ctx sdk.Context, gas uint64) {
k.csdb.WithContext(ctx).AddRefund(gas) k.csdb.WithContext(ctx).AddRefund(gas)
} }
// Calls CommitStateDB.SubRefund using the passed in context // SubRefund calls CommitStateDB.SubRefund using the passed in context
func (k *Keeper) SubRefund(ctx sdk.Context, gas uint64) { func (k *Keeper) SubRefund(ctx sdk.Context, gas uint64) {
k.csdb.WithContext(ctx).SubRefund(gas) k.csdb.WithContext(ctx).SubRefund(gas)
} }
@ -101,77 +132,77 @@ func (k *Keeper) SubRefund(ctx sdk.Context, gas uint64) {
// Getters // Getters
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Calls CommitStateDB.GetBalance using the passed in context // GetBalance calls CommitStateDB.GetBalance using the passed in context
func (k *Keeper) GetBalance(ctx sdk.Context, addr ethcmn.Address) *big.Int { func (k *Keeper) GetBalance(ctx sdk.Context, addr ethcmn.Address) *big.Int {
return k.csdb.WithContext(ctx).GetBalance(addr) return k.csdb.WithContext(ctx).GetBalance(addr)
} }
// Calls CommitStateDB.GetNonce using the passed in context // GetNonce calls CommitStateDB.GetNonce using the passed in context
func (k *Keeper) GetNonce(ctx sdk.Context, addr ethcmn.Address) uint64 { func (k *Keeper) GetNonce(ctx sdk.Context, addr ethcmn.Address) uint64 {
return k.csdb.WithContext(ctx).GetNonce(addr) return k.csdb.WithContext(ctx).GetNonce(addr)
} }
// Calls CommitStateDB.TxIndex using the passed in context // TxIndex calls CommitStateDB.TxIndex using the passed in context
func (k *Keeper) TxIndex(ctx sdk.Context) int { func (k *Keeper) TxIndex(ctx sdk.Context) int {
return k.csdb.WithContext(ctx).TxIndex() return k.csdb.WithContext(ctx).TxIndex()
} }
// Calls CommitStateDB.BlockHash using the passed in context // BlockHash calls CommitStateDB.BlockHash using the passed in context
func (k *Keeper) BlockHash(ctx sdk.Context) ethcmn.Hash { func (k *Keeper) BlockHash(ctx sdk.Context) ethcmn.Hash {
return k.csdb.WithContext(ctx).BlockHash() return k.csdb.WithContext(ctx).BlockHash()
} }
// Calls CommitStateDB.GetCode using the passed in context // GetCode calls CommitStateDB.GetCode using the passed in context
func (k *Keeper) GetCode(ctx sdk.Context, addr ethcmn.Address) []byte { func (k *Keeper) GetCode(ctx sdk.Context, addr ethcmn.Address) []byte {
return k.csdb.WithContext(ctx).GetCode(addr) return k.csdb.WithContext(ctx).GetCode(addr)
} }
// Calls CommitStateDB.GetCodeSize using the passed in context // GetCodeSize calls CommitStateDB.GetCodeSize using the passed in context
func (k *Keeper) GetCodeSize(ctx sdk.Context, addr ethcmn.Address) int { func (k *Keeper) GetCodeSize(ctx sdk.Context, addr ethcmn.Address) int {
return k.csdb.WithContext(ctx).GetCodeSize(addr) return k.csdb.WithContext(ctx).GetCodeSize(addr)
} }
// Calls CommitStateDB.GetCodeHash using the passed in context // GetCodeHash calls CommitStateDB.GetCodeHash using the passed in context
func (k *Keeper) GetCodeHash(ctx sdk.Context, addr ethcmn.Address) ethcmn.Hash { func (k *Keeper) GetCodeHash(ctx sdk.Context, addr ethcmn.Address) ethcmn.Hash {
return k.csdb.WithContext(ctx).GetCodeHash(addr) return k.csdb.WithContext(ctx).GetCodeHash(addr)
} }
// Calls CommitStateDB.GetState using the passed in context // GetState calls CommitStateDB.GetState using the passed in context
func (k *Keeper) GetState(ctx sdk.Context, addr ethcmn.Address, hash ethcmn.Hash) ethcmn.Hash { func (k *Keeper) GetState(ctx sdk.Context, addr ethcmn.Address, hash ethcmn.Hash) ethcmn.Hash {
return k.csdb.WithContext(ctx).GetState(addr, hash) return k.csdb.WithContext(ctx).GetState(addr, hash)
} }
// Calls CommitStateDB.GetCommittedState using the passed in context // GetCommittedState calls CommitStateDB.GetCommittedState using the passed in context
func (k *Keeper) GetCommittedState(ctx sdk.Context, addr ethcmn.Address, hash ethcmn.Hash) ethcmn.Hash { func (k *Keeper) GetCommittedState(ctx sdk.Context, addr ethcmn.Address, hash ethcmn.Hash) ethcmn.Hash {
return k.csdb.WithContext(ctx).GetCommittedState(addr, hash) return k.csdb.WithContext(ctx).GetCommittedState(addr, hash)
} }
// Calls CommitStateDB.GetLogs using the passed in context // GetLogs calls CommitStateDB.GetLogs using the passed in context
func (k *Keeper) GetLogs(ctx sdk.Context, hash ethcmn.Hash) []*ethtypes.Log { func (k *Keeper) GetLogs(ctx sdk.Context, hash ethcmn.Hash) []*ethtypes.Log {
return k.csdb.WithContext(ctx).GetLogs(hash) return k.csdb.WithContext(ctx).GetLogs(hash)
} }
// Calls CommitStateDB.Logs using the passed in context // Logs calls CommitStateDB.Logs using the passed in context
func (k *Keeper) Logs(ctx sdk.Context) []*ethtypes.Log { func (k *Keeper) Logs(ctx sdk.Context) []*ethtypes.Log {
return k.csdb.WithContext(ctx).Logs() return k.csdb.WithContext(ctx).Logs()
} }
// Calls CommitStateDB.GetRefund using the passed in context // GetRefund calls CommitStateDB.GetRefund using the passed in context
func (k *Keeper) GetRefund(ctx sdk.Context) uint64 { func (k *Keeper) GetRefund(ctx sdk.Context) uint64 {
return k.csdb.WithContext(ctx).GetRefund() return k.csdb.WithContext(ctx).GetRefund()
} }
// Calls CommitStateDB.Preimages using the passed in context // Preimages calls CommitStateDB.Preimages using the passed in context
func (k *Keeper) Preimages(ctx sdk.Context) map[ethcmn.Hash][]byte { func (k *Keeper) Preimages(ctx sdk.Context) map[ethcmn.Hash][]byte {
return k.csdb.WithContext(ctx).Preimages() return k.csdb.WithContext(ctx).Preimages()
} }
// Calls CommitStateDB.HasSuicided using the passed in context // HasSuicided calls CommitStateDB.HasSuicided using the passed in context
func (k *Keeper) HasSuicided(ctx sdk.Context, addr ethcmn.Address) bool { func (k *Keeper) HasSuicided(ctx sdk.Context, addr ethcmn.Address) bool {
return k.csdb.WithContext(ctx).HasSuicided(addr) return k.csdb.WithContext(ctx).HasSuicided(addr)
} }
// Calls CommitStateDB.StorageTrie using the passed in context // StorageTrie calls CommitStateDB.StorageTrie using the passed in context
func (k *Keeper) StorageTrie(ctx sdk.Context, addr ethcmn.Address) ethstate.Trie { func (k *Keeper) StorageTrie(ctx sdk.Context, addr ethcmn.Address) ethstate.Trie {
return k.csdb.WithContext(ctx).StorageTrie(addr) return k.csdb.WithContext(ctx).StorageTrie(addr)
} }
@ -180,17 +211,17 @@ func (k *Keeper) StorageTrie(ctx sdk.Context, addr ethcmn.Address) ethstate.Trie
// Persistence // Persistence
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Calls CommitStateDB.Commit using the passed in context // Commit calls CommitStateDB.Commit using the passed { in context
func (k *Keeper) Commit(ctx sdk.Context, deleteEmptyObjects bool) (root ethcmn.Hash, err error) { func (k *Keeper) Commit(ctx sdk.Context, deleteEmptyObjects bool) (root ethcmn.Hash, err error) {
return k.csdb.WithContext(ctx).Commit(deleteEmptyObjects) return k.csdb.WithContext(ctx).Commit(deleteEmptyObjects)
} }
// Calls CommitStateDB.Finalise using the passed in context // Finalise calls CommitStateDB.Finalise using the passed in context
func (k *Keeper) Finalise(ctx sdk.Context, deleteEmptyObjects bool) { func (k *Keeper) Finalise(ctx sdk.Context, deleteEmptyObjects bool) {
k.csdb.WithContext(ctx).Finalise(deleteEmptyObjects) k.csdb.WithContext(ctx).Finalise(deleteEmptyObjects)
} }
// Calls CommitStateDB.IntermediateRoot using the passed in context // IntermediateRoot calls CommitStateDB.IntermediateRoot using the passed in context
func (k *Keeper) IntermediateRoot(ctx sdk.Context, deleteEmptyObjects bool) { func (k *Keeper) IntermediateRoot(ctx sdk.Context, deleteEmptyObjects bool) {
k.csdb.WithContext(ctx).IntermediateRoot(deleteEmptyObjects) k.csdb.WithContext(ctx).IntermediateRoot(deleteEmptyObjects)
} }
@ -199,12 +230,12 @@ func (k *Keeper) IntermediateRoot(ctx sdk.Context, deleteEmptyObjects bool) {
// Snapshotting // Snapshotting
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Calls CommitStateDB.Snapshot using the passed in context // Snapshot calls CommitStateDB.Snapshot using the passed in context
func (k *Keeper) Snapshot(ctx sdk.Context) int { func (k *Keeper) Snapshot(ctx sdk.Context) int {
return k.csdb.WithContext(ctx).Snapshot() return k.csdb.WithContext(ctx).Snapshot()
} }
// Calls CommitStateDB.RevertToSnapshot using the passed in context // RevertToSnapshot calls CommitStateDB.RevertToSnapshot using the passed in context
func (k *Keeper) RevertToSnapshot(ctx sdk.Context, revID int) { func (k *Keeper) RevertToSnapshot(ctx sdk.Context, revID int) {
k.csdb.WithContext(ctx).RevertToSnapshot(revID) k.csdb.WithContext(ctx).RevertToSnapshot(revID)
} }
@ -213,57 +244,57 @@ func (k *Keeper) RevertToSnapshot(ctx sdk.Context, revID int) {
// Auxiliary // Auxiliary
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Calls CommitStateDB.Database using the passed in context // Database calls CommitStateDB.Database using the passed in context
func (k *Keeper) Database(ctx sdk.Context) ethstate.Database { func (k *Keeper) Database(ctx sdk.Context) ethstate.Database {
return k.csdb.WithContext(ctx).Database() return k.csdb.WithContext(ctx).Database()
} }
// Calls CommitStateDB.Empty using the passed in context // Empty calls CommitStateDB.Empty using the passed in context
func (k *Keeper) Empty(ctx sdk.Context, addr ethcmn.Address) bool { func (k *Keeper) Empty(ctx sdk.Context, addr ethcmn.Address) bool {
return k.csdb.WithContext(ctx).Empty(addr) return k.csdb.WithContext(ctx).Empty(addr)
} }
// Calls CommitStateDB.Exist using the passed in context // Exist calls CommitStateDB.Exist using the passed in context
func (k *Keeper) Exist(ctx sdk.Context, addr ethcmn.Address) bool { func (k *Keeper) Exist(ctx sdk.Context, addr ethcmn.Address) bool {
return k.csdb.WithContext(ctx).Exist(addr) return k.csdb.WithContext(ctx).Exist(addr)
} }
// Calls CommitStateDB.Error using the passed in context // Error calls CommitStateDB.Error using the passed in context
func (k *Keeper) Error(ctx sdk.Context) error { func (k *Keeper) Error(ctx sdk.Context) error {
return k.csdb.WithContext(ctx).Error() return k.csdb.WithContext(ctx).Error()
} }
// Calls CommitStateDB.Suicide using the passed in context // Suicide calls CommitStateDB.Suicide using the passed in context
func (k *Keeper) Suicide(ctx sdk.Context, addr ethcmn.Address) bool { func (k *Keeper) Suicide(ctx sdk.Context, addr ethcmn.Address) bool {
return k.csdb.WithContext(ctx).Suicide(addr) return k.csdb.WithContext(ctx).Suicide(addr)
} }
// Calls CommitStateDB.Reset using the passed in context // Reset calls CommitStateDB.Reset using the passed in context
func (k *Keeper) Reset(ctx sdk.Context, root ethcmn.Hash) error { func (k *Keeper) Reset(ctx sdk.Context, root ethcmn.Hash) error {
return k.csdb.WithContext(ctx).Reset(root) return k.csdb.WithContext(ctx).Reset(root)
} }
// Calls CommitStateDB.Prepare using the passed in context // Prepare calls CommitStateDB.Prepare using the passed in context
func (k *Keeper) Prepare(ctx sdk.Context, thash, bhash ethcmn.Hash, txi int) { func (k *Keeper) Prepare(ctx sdk.Context, thash, bhash ethcmn.Hash, txi int) {
k.csdb.WithContext(ctx).Prepare(thash, bhash, txi) k.csdb.WithContext(ctx).Prepare(thash, bhash, txi)
} }
// Calls CommitStateDB.CreateAccount using the passed in context // CreateAccount calls CommitStateDB.CreateAccount using the passed in context
func (k *Keeper) CreateAccount(ctx sdk.Context, addr ethcmn.Address) { func (k *Keeper) CreateAccount(ctx sdk.Context, addr ethcmn.Address) {
k.csdb.WithContext(ctx).CreateAccount(addr) k.csdb.WithContext(ctx).CreateAccount(addr)
} }
// Calls CommitStateDB.Copy using the passed in context // Copy calls CommitStateDB.Copy using the passed in context
func (k *Keeper) Copy(ctx sdk.Context) ethvm.StateDB { func (k *Keeper) Copy(ctx sdk.Context) ethvm.StateDB {
return k.csdb.WithContext(ctx).Copy() return k.csdb.WithContext(ctx).Copy()
} }
// Calls CommitStateDB.ForEachStorage using passed in context // ForEachStorage calls CommitStateDB.ForEachStorage using passed in context
func (k *Keeper) ForEachStorage(ctx sdk.Context, addr ethcmn.Address, cb func(key, value ethcmn.Hash) bool) error { func (k *Keeper) ForEachStorage(ctx sdk.Context, addr ethcmn.Address, cb func(key, value ethcmn.Hash) bool) error {
return k.csdb.WithContext(ctx).ForEachStorage(addr, cb) return k.csdb.WithContext(ctx).ForEachStorage(addr, cb)
} }
// Calls CommitStateDB.GetOrNetStateObject using the passed in context // GetOrNewStateObject calls CommitStateDB.GetOrNetStateObject using the passed in context
func (k *Keeper) GetOrNewStateObject(ctx sdk.Context, addr ethcmn.Address) types.StateObject { func (k *Keeper) GetOrNewStateObject(ctx sdk.Context, addr ethcmn.Address) types.StateObject {
return k.csdb.WithContext(ctx).GetOrNewStateObject(addr) return k.csdb.WithContext(ctx).GetOrNewStateObject(addr)
} }

View File

@ -27,6 +27,7 @@ var (
accKey = sdk.NewKVStoreKey("acc") accKey = sdk.NewKVStoreKey("acc")
storageKey = sdk.NewKVStoreKey(evmtypes.EvmStoreKey) storageKey = sdk.NewKVStoreKey(evmtypes.EvmStoreKey)
codeKey = sdk.NewKVStoreKey(evmtypes.EvmCodeKey) codeKey = sdk.NewKVStoreKey(evmtypes.EvmCodeKey)
blockKey = sdk.NewKVStoreKey(evmtypes.EvmBlockKey)
logger = tmlog.NewNopLogger() logger = tmlog.NewNopLogger()
) )
@ -54,12 +55,12 @@ func TestDBStorage(t *testing.T) {
// Set specific supspaces // Set specific supspaces
authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace) authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace)
ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount) ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount)
ek := NewKeeper(ak, storageKey, codeKey, cdc) ek := NewKeeper(ak, storageKey, codeKey, blockKey, cdc)
db := dbm.NewMemDB() db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db) cms := store.NewCommitMultiStore(db)
// mount stores // mount stores
keys := []*sdk.KVStoreKey{accKey, storageKey, codeKey} keys := []*sdk.KVStoreKey{accKey, storageKey, codeKey, blockKey}
for _, key := range keys { for _, key := range keys {
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil)
} }
@ -79,12 +80,19 @@ func TestDBStorage(t *testing.T) {
ek.SetState(ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3")) ek.SetState(ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3"))
ek.SetCode(ctx, address, []byte{0x1}) ek.SetCode(ctx, address, []byte{0x1})
// Test block hash mapping functionality
ek.SetBlockHashMapping(ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"), 7)
ek.SetBlockHashMapping(ctx, []byte{0x43, 0x32}, 8)
// Get those state transitions // Get those state transitions
require.Equal(t, ek.GetBalance(ctx, address).Cmp(big.NewInt(5)), 0) 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.GetNonce(ctx, address), uint64(4))
require.Equal(t, ek.GetState(ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3")) require.Equal(t, ek.GetState(ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3"))
require.Equal(t, ek.GetCode(ctx, address), []byte{0x1}) require.Equal(t, ek.GetCode(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))
// commit stateDB // commit stateDB
_, err = ek.Commit(ctx, false) _, err = ek.Commit(ctx, false)
require.NoError(t, err, "failed to commit StateDB") require.NoError(t, err, "failed to commit StateDB")

View File

@ -104,7 +104,10 @@ func (am AppModule) NewQuerierHandler() sdk.Querier {
} }
// BeginBlock function for module at start of each block // BeginBlock function for module at start of each block
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} func (am AppModule) BeginBlock(ctx sdk.Context, bl abci.RequestBeginBlock) {
// Consider removing this when using evm as module without web3 API
am.keeper.SetBlockHashMapping(ctx, bl.Header.LastBlockId.GetHash(), bl.Header.GetHeight()-1)
}
// EndBlock function for module at end of block // 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 {

View File

@ -19,6 +19,7 @@ const (
QueryStorage = "storage" QueryStorage = "storage"
QueryCode = "code" QueryCode = "code"
QueryNonce = "nonce" QueryNonce = "nonce"
QueryHashToHeight = "hashToHeight"
) )
// NewQuerier is the module level router for state queries // NewQuerier is the module level router for state queries
@ -37,6 +38,8 @@ func NewQuerier(keeper Keeper) sdk.Querier {
return queryCode(ctx, path, keeper) return queryCode(ctx, path, keeper)
case QueryNonce: case QueryNonce:
return queryNonce(ctx, path, keeper) return queryNonce(ctx, path, keeper)
case QueryHashToHeight:
return queryHashToHeight(ctx, path, keeper)
default: default:
return nil, sdk.ErrUnknownRequest("unknown query endpoint") return nil, sdk.ErrUnknownRequest("unknown query endpoint")
} }
@ -113,3 +116,16 @@ func queryNonce(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Erro
return res, nil return res, nil
} }
func queryHashToHeight(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) {
blockHash := ethcmn.FromHex(path[1])
blockNumber := keeper.GetBlockHashMapping(ctx, blockHash)
bRes := types.QueryResBlockNumber{Number: blockNumber}
res, err := codec.MarshalJSONIndent(keeper.cdc, bRes)
if err != nil {
panic("could not marshal result to JSON: " + err.Error())
}
return res, nil
}

View File

@ -1,11 +1,16 @@
package types package types
const ( const (
// module name // ModuleName string name of module
ModuleName = "ethermint" ModuleName = "ethermint"
// EvmStoreKey key for ethereum storage data
EvmStoreKey = "evmstore" EvmStoreKey = "evmstore"
EvmCodeKey = "evmcode" // EvmCodeKey key for ethereum code data
EvmCodeKey = "evmcode"
// EvmBlockKey key for ethereum block data
EvmBlockKey = "evmblock"
// RouterKey uses module name for routing
RouterKey = ModuleName RouterKey = ModuleName
) )