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:
parent
f7ad8f53f0
commit
09a71a2a3a
@ -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])
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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}
|
||||||
}
|
}
|
||||||
|
123
x/evm/keeper.go
123
x/evm/keeper.go
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user