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
|
### State Machine Breaking
|
||||||
|
|
||||||
* (evm) [tharsis#72](https://github.com/tharsis/ethermint/issues/72) Update `AccessList` to use `TransientStore` instead of map.
|
* (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
|
### API Breaking
|
||||||
|
|
||||||
|
@ -311,7 +311,8 @@ func NewEthermintApp(
|
|||||||
|
|
||||||
// Create Ethermint keepers
|
// Create Ethermint keepers
|
||||||
app.EvmKeeper = evmkeeper.NewKeeper(
|
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
|
// Create IBC Keeper
|
||||||
|
@ -27,6 +27,8 @@ import (
|
|||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
paramkeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
paramkeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
||||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
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/encoding/codec"
|
||||||
"github.com/cosmos/ethermint/types"
|
"github.com/cosmos/ethermint/types"
|
||||||
@ -183,13 +185,14 @@ func TestImportBlocks(t *testing.T) {
|
|||||||
|
|
||||||
authStoreKey := sdk.NewKVStoreKey(authtypes.StoreKey)
|
authStoreKey := sdk.NewKVStoreKey(authtypes.StoreKey)
|
||||||
bankStoreKey := sdk.NewKVStoreKey(banktypes.StoreKey)
|
bankStoreKey := sdk.NewKVStoreKey(banktypes.StoreKey)
|
||||||
|
stakingStoreKey := sdk.NewKVStoreKey(stakingtypes.StoreKey)
|
||||||
evmStoreKey := sdk.NewKVStoreKey(evmtypes.StoreKey)
|
evmStoreKey := sdk.NewKVStoreKey(evmtypes.StoreKey)
|
||||||
paramsStoreKey := sdk.NewKVStoreKey(paramtypes.StoreKey)
|
paramsStoreKey := sdk.NewKVStoreKey(paramtypes.StoreKey)
|
||||||
evmTransientStoreKey := sdk.NewTransientStoreKey(evmtypes.TransientKey)
|
evmTransientStoreKey := sdk.NewTransientStoreKey(evmtypes.TransientKey)
|
||||||
paramsTransientStoreKey := sdk.NewTransientStoreKey(paramtypes.TStoreKey)
|
paramsTransientStoreKey := sdk.NewTransientStoreKey(paramtypes.TStoreKey)
|
||||||
|
|
||||||
// mount stores
|
// mount stores
|
||||||
keys := []*sdk.KVStoreKey{authStoreKey, bankStoreKey, evmStoreKey, paramsStoreKey}
|
keys := []*sdk.KVStoreKey{authStoreKey, bankStoreKey, stakingStoreKey, evmStoreKey, paramsStoreKey}
|
||||||
tkeys := []*sdk.TransientStoreKey{paramsTransientStoreKey, evmTransientStoreKey}
|
tkeys := []*sdk.TransientStoreKey{paramsTransientStoreKey, evmTransientStoreKey}
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil)
|
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil)
|
||||||
@ -204,12 +207,14 @@ func TestImportBlocks(t *testing.T) {
|
|||||||
// Set specific subspaces
|
// Set specific subspaces
|
||||||
authSubspace := paramsKeeper.Subspace(authtypes.ModuleName)
|
authSubspace := paramsKeeper.Subspace(authtypes.ModuleName)
|
||||||
bankSubspace := paramsKeeper.Subspace(banktypes.ModuleName)
|
bankSubspace := paramsKeeper.Subspace(banktypes.ModuleName)
|
||||||
|
stakingSubspace := paramsKeeper.Subspace(stakingtypes.ModuleName)
|
||||||
evmSubspace := paramsKeeper.Subspace(evmtypes.ModuleName).WithKeyTable(evmtypes.ParamKeyTable())
|
evmSubspace := paramsKeeper.Subspace(evmtypes.ModuleName).WithKeyTable(evmtypes.ParamKeyTable())
|
||||||
|
|
||||||
// create keepers
|
// create keepers
|
||||||
ak := authkeeper.NewAccountKeeper(cdc, authStoreKey, authSubspace, types.ProtoAccount, nil)
|
ak := authkeeper.NewAccountKeeper(cdc, authStoreKey, authSubspace, types.ProtoAccount, nil)
|
||||||
bk := bankkeeper.NewBaseKeeper(cdc, bankStoreKey, ak, bankSubspace, 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)
|
cms.SetPruning(sdkstore.PruneNothing)
|
||||||
|
|
||||||
|
@ -20,20 +20,7 @@ import (
|
|||||||
func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
|
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
|
||||||
k.WithContext(ctx)
|
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)
|
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
|
// EndBlock updates the accounts and commits state objects to the KV Store, while
|
||||||
|
@ -35,6 +35,7 @@ type Keeper struct {
|
|||||||
paramSpace paramtypes.Subspace
|
paramSpace paramtypes.Subspace
|
||||||
accountKeeper types.AccountKeeper
|
accountKeeper types.AccountKeeper
|
||||||
bankKeeper types.BankKeeper
|
bankKeeper types.BankKeeper
|
||||||
|
stakingKeeper types.StakingKeeper
|
||||||
|
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
// chain ID number obtained from the context's chain id
|
// chain ID number obtained from the context's chain id
|
||||||
@ -52,7 +53,7 @@ type Keeper struct {
|
|||||||
// NewKeeper generates new evm module keeper
|
// NewKeeper generates new evm module keeper
|
||||||
func NewKeeper(
|
func NewKeeper(
|
||||||
cdc codec.BinaryMarshaler, storeKey, transientKey sdk.StoreKey, paramSpace paramtypes.Subspace,
|
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 {
|
) *Keeper {
|
||||||
// set KeyTable if it has not already been set
|
// set KeyTable if it has not already been set
|
||||||
if !paramSpace.HasKeyTable() {
|
if !paramSpace.HasKeyTable() {
|
||||||
@ -65,6 +66,7 @@ func NewKeeper(
|
|||||||
paramSpace: paramSpace,
|
paramSpace: paramSpace,
|
||||||
accountKeeper: ak,
|
accountKeeper: ak,
|
||||||
bankKeeper: bankKeeper,
|
bankKeeper: bankKeeper,
|
||||||
|
stakingKeeper: sk,
|
||||||
storeKey: storeKey,
|
storeKey: storeKey,
|
||||||
transientKey: transientKey,
|
transientKey: transientKey,
|
||||||
CommitStateDB: types.NewCommitStateDB(sdk.Context{}, storeKey, transientKey, paramSpace, ak, bankKeeper),
|
CommitStateDB: types.NewCommitStateDB(sdk.Context{}, storeKey, transientKey, paramSpace, ak, bankKeeper),
|
||||||
@ -146,26 +148,6 @@ func (k Keeper) SetBlockBloomTransient(bloom *big.Int) {
|
|||||||
// Block
|
// 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
|
// SetTxReceiptToHash sets the mapping from tx hash to tx receipt
|
||||||
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
|
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
|
||||||
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
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)
|
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
|
// Tx
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
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
|
// 3. The requested height is from a height greater than the latest one
|
||||||
func (k Keeper) GetHashFn() vm.GetHashFunc {
|
func (k Keeper) GetHashFn() vm.GetHashFunc {
|
||||||
return func(height uint64) common.Hash {
|
return func(height uint64) common.Hash {
|
||||||
|
h := int64(height)
|
||||||
switch {
|
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
|
// Case 1: The requested height matches the one from the context so we can retrieve the header
|
||||||
// hash directly from the context.
|
// hash directly from the context.
|
||||||
// TODO: deprecate field from the keeper on next SDK release
|
// TODO: deprecate field from the keeper on next SDK release
|
||||||
return k.headerHash
|
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
|
// 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.
|
// 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:
|
default:
|
||||||
// Case 3: heights greater than the current one returns an empty hash.
|
// Case 3: heights greater than the current one returns an empty hash.
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
|
@ -3,6 +3,7 @@ package types
|
|||||||
import (
|
import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/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
|
// 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
|
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error
|
||||||
SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) 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