Skip to content

Commit 98161d9

Browse files
author
HuangYi
committed
Problem: params not cached in object store
Solution: - save the cost of repeated encoding/decoding during the block execution - also migrate existing transient stores to object stores Update CHANGELOG.md Signed-off-by: yihuang <[email protected]> Update x/feemarket/types/keys.go Signed-off-by: yihuang <[email protected]> renmae fix test
1 parent 4b57117 commit 98161d9

File tree

12 files changed

+121
-80
lines changed

12 files changed

+121
-80
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
5050
* (evm) [#447](https://github.com/crypto-org-chain/ethermint/pull/447) Deduct fee through virtual bank transfer.
5151
* (evm) [#448](https://github.com/crypto-org-chain/ethermint/pull/448) Refactor the evm transfer to be more efficient.
5252
* (evm) [#450](https://github.com/crypto-org-chain/ethermint/pull/450) Refactor transient stores to be compatible with parallel tx execution.
53+
* (evm) [#454](https://github.com/crypto-org-chain/ethermint/pull/454) Migrate transient stores to object stores.
5354

5455
### State Machine Breaking
5556

app/app.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ func NewEthermintApp(
331331
)
332332

333333
// Add the EVM transient store key
334-
tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
334+
tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey)
335335
memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
336-
okeys := storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey)
336+
okeys := storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey, evmtypes.ObjectStoreKey, feemarkettypes.ObjectStoreKey)
337337

338338
// load state streaming if enabled
339339
if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil {
@@ -495,17 +495,16 @@ func NewEthermintApp(
495495
feeMarketSs := app.GetSubspace(feemarkettypes.ModuleName)
496496
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
497497
appCodec,
498-
runtime.NewKVStoreService(keys[feemarkettypes.StoreKey]),
499498
authtypes.NewModuleAddress(govtypes.ModuleName),
500-
keys[feemarkettypes.StoreKey],
499+
keys[feemarkettypes.StoreKey], okeys[feemarkettypes.ObjectStoreKey],
501500
)
502501

503502
// Set authority to x/gov module account to only expect the module account to update params
504503
evmSs := app.GetSubspace(evmtypes.ModuleName)
505504
app.EvmKeeper = evmkeeper.NewKeeper(
506505
appCodec,
507506
runtime.NewKVStoreService(keys[evmtypes.StoreKey]),
508-
keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName),
507+
keys[evmtypes.StoreKey], okeys[evmtypes.ObjectStoreKey], authtypes.NewModuleAddress(govtypes.ModuleName),
509508
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper,
510509
tracer,
511510
nil,

x/evm/keeper/abci.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import (
2424
// BeginBlock sets the sdk Context and EIP155 chain id to the Keeper.
2525
func (k *Keeper) BeginBlock(ctx sdk.Context) error {
2626
k.WithChainID(ctx)
27+
28+
// cache params object
29+
_ = k.GetParams(ctx)
30+
2731
return nil
2832
}
2933

x/evm/keeper/bloom.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ import (
88
"github.com/evmos/ethermint/x/evm/types"
99
)
1010

11-
func (k Keeper) SetTxBloom(ctx sdk.Context, bloom []byte) {
12-
store := ctx.KVStore(k.transientKey)
13-
store.Set(types.TransientBloomKey(ctx.TxIndex(), ctx.MsgIndex()), bloom)
11+
func (k Keeper) SetTxBloom(ctx sdk.Context, bloom *big.Int) {
12+
store := ctx.ObjectStore(k.objectKey)
13+
store.Set(types.ObjectBloomKey(ctx.TxIndex(), ctx.MsgIndex()), bloom)
1414
}
1515

1616
func (k Keeper) CollectTxBloom(ctx sdk.Context) {
17-
store := prefix.NewStore(ctx.KVStore(k.transientKey), types.KeyPrefixTransientBloom)
17+
store := prefix.NewObjStore(ctx.ObjectStore(k.objectKey), types.KeyPrefixObjectBloom)
1818
it := store.Iterator(nil, nil)
1919
defer it.Close()
2020

2121
bloom := new(big.Int)
2222
for ; it.Valid(); it.Next() {
23-
bloom.Or(bloom, big.NewInt(0).SetBytes(it.Value()))
23+
bloom.Or(bloom, it.Value().(*big.Int))
2424
}
2525

2626
k.EmitBlockBloomEvent(ctx, bloom.Bytes())

x/evm/keeper/keeper.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type Keeper struct {
5050
storeKey storetypes.StoreKey
5151

5252
// key to access the transient store, which is reset on every block during Commit
53-
transientKey storetypes.StoreKey
53+
objectKey storetypes.StoreKey
5454

5555
// the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account.
5656
authority sdk.AccAddress
@@ -79,7 +79,7 @@ type Keeper struct {
7979
func NewKeeper(
8080
cdc codec.Codec,
8181
storeService corestoretypes.KVStoreService,
82-
storeKey, transientKey storetypes.StoreKey,
82+
storeKey, objectKey storetypes.StoreKey,
8383
authority sdk.AccAddress,
8484
ak types.AccountKeeper,
8585
bankKeeper types.BankKeeper,
@@ -108,7 +108,7 @@ func NewKeeper(
108108
stakingKeeper: sk,
109109
feeMarketKeeper: fmk,
110110
storeKey: storeKey,
111-
transientKey: transientKey,
111+
objectKey: objectKey,
112112
tracer: tracer,
113113
customContractFns: customContractFns,
114114
}
@@ -287,19 +287,18 @@ func (k Keeper) getBaseFee(ctx sdk.Context, london bool) *big.Int {
287287

288288
// GetTransientGasUsed returns the gas used by current cosmos tx.
289289
func (k Keeper) GetTransientGasUsed(ctx sdk.Context) uint64 {
290-
store := ctx.TransientStore(k.transientKey)
291-
bz := store.Get(types.TransientGasUsedKey(ctx.TxIndex()))
292-
if len(bz) == 0 {
290+
store := ctx.ObjectStore(k.objectKey)
291+
v := store.Get(types.ObjectGasUsedKey(ctx.TxIndex()))
292+
if v == nil {
293293
return 0
294294
}
295-
return sdk.BigEndianToUint64(bz)
295+
return v.(uint64)
296296
}
297297

298298
// SetTransientGasUsed sets the gas used by current cosmos tx.
299299
func (k Keeper) SetTransientGasUsed(ctx sdk.Context, gasUsed uint64) {
300-
store := ctx.TransientStore(k.transientKey)
301-
bz := sdk.Uint64ToBigEndian(gasUsed)
302-
store.Set(types.TransientGasUsedKey(ctx.TxIndex()), bz)
300+
store := ctx.ObjectStore(k.objectKey)
301+
store.Set(types.ObjectGasUsedKey(ctx.TxIndex()), gasUsed)
303302
}
304303

305304
// AddTransientGasUsed accumulate gas used by each eth msgs included in current cosmos tx.

x/evm/keeper/params.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@ import (
2121
)
2222

2323
// GetParams returns the total set of evm parameters.
24-
func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) {
25-
store := k.storeService.OpenKVStore(ctx)
26-
bz, err := store.Get(types.KeyPrefixParams)
27-
if err != nil {
28-
panic(err)
29-
}
30-
if bz == nil {
31-
return p
24+
func (k Keeper) GetParams(ctx sdk.Context) types.Params {
25+
var params *types.Params
26+
objStore := ctx.ObjectStore(k.objectKey)
27+
v := objStore.Get(types.KeyPrefixObjectParams)
28+
if v == nil {
29+
store := k.storeService.OpenKVStore(ctx)
30+
bz, err := store.Get(types.KeyPrefixParams)
31+
if err != nil {
32+
panic(err)
33+
}
34+
params = new(types.Params)
35+
if bz != nil {
36+
k.cdc.MustUnmarshal(bz, params)
37+
}
38+
39+
objStore.Set(types.KeyPrefixObjectParams, params)
40+
} else {
41+
params = v.(*types.Params)
3242
}
33-
k.cdc.MustUnmarshal(bz, &p)
34-
return p
43+
44+
return *params
3545
}
3646

3747
// SetParams sets the EVM params each in their individual key for better get performance
@@ -41,5 +51,14 @@ func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error {
4151
}
4252
store := k.storeService.OpenKVStore(ctx)
4353
bz := k.cdc.MustMarshal(&p)
44-
return store.Set(types.KeyPrefixParams, bz)
54+
if err := store.Set(types.KeyPrefixParams, bz); err != nil {
55+
return err
56+
}
57+
58+
// set to cache as well, decode again to be compatible with the previous behavior
59+
var params types.Params
60+
k.cdc.MustUnmarshal(bz, &params)
61+
ctx.ObjectStore(k.objectKey).Set(types.KeyPrefixObjectParams, &params)
62+
63+
return nil
4564
}

x/evm/keeper/state_transition.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx)
200200

201201
// Compute block bloom filter
202202
if len(logs) > 0 {
203-
k.SetTxBloom(tmpCtx, ethtypes.LogsBloom(logs))
203+
k.SetTxBloom(tmpCtx, new(big.Int).SetBytes(ethtypes.LogsBloom(logs)))
204204
}
205205

206206
var contractAddr common.Address

x/evm/statedb/statedb_test.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ func (suite *StateDBTestSuite) TestIterateStorage() {
592592
func (suite *StateDBTestSuite) TestNativeAction() {
593593
_, ctx, keeper := setupTestEnv(suite.T())
594594
storeKey := testStoreKeys["testnative"]
595-
transientKey := testTransientKeys[evmtypes.TransientKey]
595+
objStoreKey := testObjKeys[evmtypes.ObjectStoreKey]
596596
memKey := testMemKeys[capabilitytypes.MemStoreKey]
597597

598598
eventConverter := func(event sdk.Event) (*ethtypes.Log, error) {
@@ -619,8 +619,8 @@ func (suite *StateDBTestSuite) TestNativeAction() {
619619
store.Set([]byte("success1"), []byte("value"))
620620
ctx.EventManager().EmitEvent(sdk.NewEvent("success1"))
621621

622-
transient := ctx.KVStore(transientKey)
623-
transient.Set([]byte("transient"), []byte("value"))
622+
objStore := ctx.ObjectStore(objStoreKey)
623+
objStore.Set([]byte("transient"), "value")
624624

625625
mem := ctx.KVStore(memKey)
626626
mem.Set([]byte("mem"), []byte("value"))
@@ -632,8 +632,8 @@ func (suite *StateDBTestSuite) TestNativeAction() {
632632
store.Set([]byte("failure1"), []byte("value"))
633633
ctx.EventManager().EmitEvent(sdk.NewEvent("failure1"))
634634

635-
transient := ctx.KVStore(transientKey)
636-
suite.Require().Equal([]byte("value"), transient.Get([]byte("transient")))
635+
objStore := ctx.ObjectStore(objStoreKey)
636+
suite.Require().Equal("value", objStore.Get([]byte("transient")).(string))
637637

638638
mem := ctx.KVStore(memKey)
639639
suite.Require().Equal([]byte("value"), mem.Get([]byte("mem")))
@@ -771,10 +771,9 @@ func CollectContractStorage(db vm.StateDB, address common.Address) statedb.Stora
771771
}
772772

773773
var (
774-
testStoreKeys = storetypes.NewKVStoreKeys(authtypes.StoreKey, banktypes.StoreKey, evmtypes.StoreKey, "testnative")
775-
testObjKeys = storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey)
776-
testTransientKeys = storetypes.NewTransientStoreKeys(evmtypes.TransientKey)
777-
testMemKeys = storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
774+
testStoreKeys = storetypes.NewKVStoreKeys(authtypes.StoreKey, banktypes.StoreKey, evmtypes.StoreKey, "testnative")
775+
testObjKeys = storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey, evmtypes.ObjectStoreKey)
776+
testMemKeys = storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
778777
)
779778

780779
func cloneRawState(t *testing.T, cms storetypes.MultiStore) map[string]map[string][]byte {
@@ -822,7 +821,7 @@ func newTestKeeper(t *testing.T, cms storetypes.MultiStore) (sdk.Context, *evmke
822821
evmKeeper := evmkeeper.NewKeeper(
823822
appCodec,
824823
runtime.NewKVStoreService(testStoreKeys[evmtypes.StoreKey]),
825-
testStoreKeys[evmtypes.StoreKey], testTransientKeys[evmtypes.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName),
824+
testStoreKeys[evmtypes.StoreKey], testObjKeys[evmtypes.ObjectStoreKey], authtypes.NewModuleAddress(govtypes.ModuleName),
826825
accountKeeper, bankKeeper, nil, nil,
827826
"",
828827
nil,
@@ -838,9 +837,6 @@ func setupTestEnv(t *testing.T) (storetypes.MultiStore, sdk.Context, *evmkeeper.
838837
for _, key := range testStoreKeys {
839838
cms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, nil)
840839
}
841-
for _, key := range testTransientKeys {
842-
cms.MountStoreWithDB(key, storetypes.StoreTypeTransient, nil)
843-
}
844840
for _, key := range testMemKeys {
845841
cms.MountStoreWithDB(key, storetypes.StoreTypeMemory, nil)
846842
}

x/evm/types/key.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ const (
3030
// The EVM module should use a prefix store.
3131
StoreKey = ModuleName
3232

33-
// TransientKey is the key to access the EVM transient store, that is reset
33+
// ObjectStoreKey is the key to access the EVM object store, that is reset
3434
// during the Commit phase.
35-
TransientKey = "transient_" + ModuleName
35+
ObjectStoreKey = "object:" + ModuleName
3636

3737
// RouterKey uses module name for routing
3838
RouterKey = ModuleName
@@ -45,10 +45,11 @@ const (
4545
prefixParams
4646
)
4747

48-
// prefix bytes for the EVM transient store
48+
// prefix bytes for the EVM object store
4949
const (
50-
prefixTransientBloom = iota + 1
51-
prefixTransientGasUsed
50+
prefixObjectBloom = iota + 1
51+
prefixObjectGasUsed
52+
prefixObjectParams
5253
)
5354

5455
// KVStore key prefixes
@@ -58,10 +59,11 @@ var (
5859
KeyPrefixParams = []byte{prefixParams}
5960
)
6061

61-
// Transient Store key prefixes
62+
// Object Store key prefixes
6263
var (
63-
KeyPrefixTransientBloom = []byte{prefixTransientBloom}
64-
KeyPrefixTransientGasUsed = []byte{prefixTransientGasUsed}
64+
KeyPrefixObjectBloom = []byte{prefixObjectBloom}
65+
KeyPrefixObjectGasUsed = []byte{prefixObjectGasUsed}
66+
KeyPrefixObjectParams = []byte{prefixObjectParams}
6567
)
6668

6769
// AddressStoragePrefix returns a prefix to iterate over a given account storage.
@@ -74,16 +76,16 @@ func StateKey(address common.Address, key []byte) []byte {
7476
return append(AddressStoragePrefix(address), key...)
7577
}
7678

77-
func TransientGasUsedKey(txIndex int) []byte {
78-
var key [9]byte
79-
key[0] = prefixTransientGasUsed
79+
func ObjectGasUsedKey(txIndex int) []byte {
80+
var key [1 + 8]byte
81+
key[0] = prefixObjectGasUsed
8082
binary.BigEndian.PutUint64(key[1:], uint64(txIndex))
8183
return key[:]
8284
}
8385

84-
func TransientBloomKey(txIndex, msgIndex int) []byte {
86+
func ObjectBloomKey(txIndex, msgIndex int) []byte {
8587
var key [1 + 8 + 8]byte
86-
key[0] = prefixTransientBloom
88+
key[0] = prefixObjectBloom
8789
binary.BigEndian.PutUint64(key[1:], uint64(txIndex))
8890
binary.BigEndian.PutUint64(key[9:], uint64(msgIndex))
8991
return key[:]

x/feemarket/keeper/keeper.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package keeper
1818
import (
1919
"math/big"
2020

21-
corestoretypes "cosmossdk.io/core/store"
2221
"cosmossdk.io/log"
2322
storetypes "cosmossdk.io/store/types"
2423
"github.com/cosmos/cosmos-sdk/codec"
@@ -33,31 +32,29 @@ var KeyPrefixBaseFeeV1 = []byte{2}
3332
// Keeper grants access to the Fee Market module state.
3433
type Keeper struct {
3534
// Protobuf codec
36-
cdc codec.BinaryCodec
37-
storeService corestoretypes.KVStoreService
35+
cdc codec.BinaryCodec
3836
// Store key required for the Fee Market Prefix KVStore.
39-
storeKey storetypes.StoreKey
37+
storeKey, objectKey storetypes.StoreKey
4038
// the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account.
4139
authority sdk.AccAddress
4240
}
4341

4442
// NewKeeper generates new fee market module keeper
4543
func NewKeeper(
4644
cdc codec.BinaryCodec,
47-
storeService corestoretypes.KVStoreService,
4845
authority sdk.AccAddress,
49-
storeKey storetypes.StoreKey,
46+
storeKey, objectKey storetypes.StoreKey,
5047
) Keeper {
5148
// ensure authority account is correctly formatted
5249
if err := sdk.VerifyAddressFormat(authority); err != nil {
5350
panic(err)
5451
}
5552

5653
return Keeper{
57-
cdc: cdc,
58-
storeService: storeService,
59-
storeKey: storeKey,
60-
authority: authority,
54+
cdc: cdc,
55+
storeKey: storeKey,
56+
objectKey: objectKey,
57+
authority: authority,
6158
}
6259
}
6360

0 commit comments

Comments
 (0)