evm: replace block hash storage (#80)
* evm: replace block hash storage * c++
This commit is contained in:
parent
e639cb4a82
commit
1ff3c46663
@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
### State Machine Breaking
|
||||
|
||||
* (evm) [tharsis#72](https://github.com/tharsis/ethermint/issues/72) Update `AccessList` to use `TransientStore` instead of map.
|
||||
* (evm) [tharsis#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`.
|
||||
|
||||
### API Breaking
|
||||
|
||||
|
@ -311,7 +311,8 @@ func NewEthermintApp(
|
||||
|
||||
// Create Ethermint keepers
|
||||
app.EvmKeeper = evmkeeper.NewKeeper(
|
||||
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
||||
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
|
||||
app.AccountKeeper, app.BankKeeper, app.StakingKeeper,
|
||||
)
|
||||
|
||||
// Create IBC Keeper
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
paramkeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
|
||||
"github.com/cosmos/ethermint/encoding/codec"
|
||||
"github.com/cosmos/ethermint/types"
|
||||
@ -183,13 +185,14 @@ func TestImportBlocks(t *testing.T) {
|
||||
|
||||
authStoreKey := sdk.NewKVStoreKey(authtypes.StoreKey)
|
||||
bankStoreKey := sdk.NewKVStoreKey(banktypes.StoreKey)
|
||||
stakingStoreKey := sdk.NewKVStoreKey(stakingtypes.StoreKey)
|
||||
evmStoreKey := sdk.NewKVStoreKey(evmtypes.StoreKey)
|
||||
paramsStoreKey := sdk.NewKVStoreKey(paramtypes.StoreKey)
|
||||
evmTransientStoreKey := sdk.NewTransientStoreKey(evmtypes.TransientKey)
|
||||
paramsTransientStoreKey := sdk.NewTransientStoreKey(paramtypes.TStoreKey)
|
||||
|
||||
// mount stores
|
||||
keys := []*sdk.KVStoreKey{authStoreKey, bankStoreKey, evmStoreKey, paramsStoreKey}
|
||||
keys := []*sdk.KVStoreKey{authStoreKey, bankStoreKey, stakingStoreKey, evmStoreKey, paramsStoreKey}
|
||||
tkeys := []*sdk.TransientStoreKey{paramsTransientStoreKey, evmTransientStoreKey}
|
||||
for _, key := range keys {
|
||||
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil)
|
||||
@ -204,12 +207,14 @@ func TestImportBlocks(t *testing.T) {
|
||||
// Set specific subspaces
|
||||
authSubspace := paramsKeeper.Subspace(authtypes.ModuleName)
|
||||
bankSubspace := paramsKeeper.Subspace(banktypes.ModuleName)
|
||||
stakingSubspace := paramsKeeper.Subspace(stakingtypes.ModuleName)
|
||||
evmSubspace := paramsKeeper.Subspace(evmtypes.ModuleName).WithKeyTable(evmtypes.ParamKeyTable())
|
||||
|
||||
// create keepers
|
||||
ak := authkeeper.NewAccountKeeper(cdc, authStoreKey, authSubspace, types.ProtoAccount, nil)
|
||||
bk := bankkeeper.NewBaseKeeper(cdc, bankStoreKey, ak, bankSubspace, nil)
|
||||
evmKeeper := evmkeeper.NewKeeper(cdc, evmStoreKey, evmTransientStoreKey, evmSubspace, ak, bk)
|
||||
sk := stakingkeeper.NewKeeper(cdc, stakingStoreKey, ak, bk, stakingSubspace)
|
||||
evmKeeper := evmkeeper.NewKeeper(cdc, evmStoreKey, evmTransientStoreKey, evmSubspace, ak, bk, sk)
|
||||
|
||||
cms.SetPruning(sdkstore.PruneNothing)
|
||||
|
||||
|
@ -20,20 +20,7 @@ import (
|
||||
func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
|
||||
k.WithContext(ctx)
|
||||
|
||||
if req.Header.Height < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
// Gas costs are handled within msg handler so costs should be ignored
|
||||
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
|
||||
k.headerHash = common.BytesToHash(req.Hash)
|
||||
|
||||
// set height -> hash
|
||||
|
||||
// TODO: prune
|
||||
k.SetHeaderHash(ctx, req.Header.Height, k.headerHash)
|
||||
}
|
||||
|
||||
// EndBlock updates the accounts and commits state objects to the KV Store, while
|
||||
|
@ -35,6 +35,7 @@ type Keeper struct {
|
||||
paramSpace paramtypes.Subspace
|
||||
accountKeeper types.AccountKeeper
|
||||
bankKeeper types.BankKeeper
|
||||
stakingKeeper types.StakingKeeper
|
||||
|
||||
ctx sdk.Context
|
||||
// chain ID number obtained from the context's chain id
|
||||
@ -52,7 +53,7 @@ type Keeper struct {
|
||||
// NewKeeper generates new evm module keeper
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryMarshaler, storeKey, transientKey sdk.StoreKey, paramSpace paramtypes.Subspace,
|
||||
ak types.AccountKeeper, bankKeeper types.BankKeeper,
|
||||
ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper,
|
||||
) *Keeper {
|
||||
// set KeyTable if it has not already been set
|
||||
if !paramSpace.HasKeyTable() {
|
||||
@ -65,6 +66,7 @@ func NewKeeper(
|
||||
paramSpace: paramSpace,
|
||||
accountKeeper: ak,
|
||||
bankKeeper: bankKeeper,
|
||||
stakingKeeper: sk,
|
||||
storeKey: storeKey,
|
||||
transientKey: transientKey,
|
||||
CommitStateDB: types.NewCommitStateDB(sdk.Context{}, storeKey, transientKey, paramSpace, ak, bankKeeper),
|
||||
@ -146,26 +148,6 @@ func (k Keeper) SetBlockBloomTransient(bloom *big.Int) {
|
||||
// Block
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// GetHeaderHash gets the header hash from a given height
|
||||
func (k Keeper) GetHeaderHash(ctx sdk.Context, height int64) common.Hash {
|
||||
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixHeightToHeaderHash)
|
||||
key := sdk.Uint64ToBigEndian(uint64(height))
|
||||
|
||||
bz := store.Get(key)
|
||||
if len(bz) == 0 {
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
return common.BytesToHash(bz)
|
||||
}
|
||||
|
||||
// SetBlockHash sets the mapping from heigh -> header hash
|
||||
func (k Keeper) SetHeaderHash(ctx sdk.Context, height int64, hash common.Hash) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixHeightToHeaderHash)
|
||||
key := sdk.Uint64ToBigEndian(uint64(height))
|
||||
store.Set(key, hash.Bytes())
|
||||
}
|
||||
|
||||
// SetTxReceiptToHash sets the mapping from tx hash to tx receipt
|
||||
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
|
||||
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
@ -176,16 +158,6 @@ func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *t
|
||||
store.Set(types.KeyHashTxReceipt(hash), data)
|
||||
}
|
||||
|
||||
// GetHeightHash returns the block header hash associated with a given block height and chain epoch number.
|
||||
func (k Keeper) GetHeightHash(ctx sdk.Context, height uint64) common.Hash {
|
||||
return k.CommitStateDB.WithContext(ctx).GetHeightHash(height)
|
||||
}
|
||||
|
||||
// SetHeightHash sets the block header hash associated with a given height.
|
||||
func (k Keeper) SetHeightHash(ctx sdk.Context, height uint64, hash common.Hash) {
|
||||
k.CommitStateDB.WithContext(ctx).SetHeightHash(height, hash)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tx
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
@ -58,18 +60,30 @@ func (k Keeper) VMConfig() vm.Config {
|
||||
// 3. The requested height is from a height greater than the latest one
|
||||
func (k Keeper) GetHashFn() vm.GetHashFunc {
|
||||
return func(height uint64) common.Hash {
|
||||
h := int64(height)
|
||||
switch {
|
||||
case k.ctx.BlockHeight() == int64(height):
|
||||
case k.ctx.BlockHeight() == h:
|
||||
// Case 1: The requested height matches the one from the context so we can retrieve the header
|
||||
// hash directly from the context.
|
||||
// TODO: deprecate field from the keeper on next SDK release
|
||||
return k.headerHash
|
||||
|
||||
case k.ctx.BlockHeight() > int64(height):
|
||||
case k.ctx.BlockHeight() > h:
|
||||
// Case 2: if the chain is not the current height we need to retrieve the hash from the store for the
|
||||
// current chain epoch. This only applies if the current height is greater than the requested height.
|
||||
return k.GetHeightHash(k.ctx, height)
|
||||
histInfo, found := k.stakingKeeper.GetHistoricalInfo(k.ctx, h)
|
||||
if !found {
|
||||
k.Logger(k.ctx).Debug("historical info not found", "height", h)
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
header, err := tmtypes.HeaderFromProto(&histInfo.Header)
|
||||
if err != nil {
|
||||
k.Logger(k.ctx).Error("failed to cast tendermint header from proto", "error", err)
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
return common.BytesToHash(header.Hash())
|
||||
default:
|
||||
// Case 3: heights greater than the current one returns an empty hash.
|
||||
return common.Hash{}
|
||||
|
@ -3,6 +3,7 @@ package types
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// AccountKeeper defines the expected account keeper interface
|
||||
@ -24,3 +25,8 @@ type BankKeeper interface {
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error
|
||||
SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) error
|
||||
}
|
||||
|
||||
// StakingKeeper returns the historical headers kept in store.
|
||||
type StakingKeeper interface {
|
||||
GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user