Skip to content

Commit d25456d

Browse files
[EVM] Add transient receipts with eventual flush to store (#1742)
* add transient receipts * add state store to keeper * avoid using ctx evm store * goimports * Merge conflicts * Update cosmos * Add backend * add close function * add debug lines * include prefix on write * Fix initialization logic * rename close to handle close * remove transient deletion * Update seidb version * update sei-cosmos * add in-memory state store for tests * Set KeepLastVersion to false * fix mocking of receipts * flush after receipts exist * add transient->pebble->legacy fallback * make error name consistent * avoid reading from transient store * use latest version * fix goimports * add test coverage for test state store * tick sei-cosmos --------- Co-authored-by: yzang2019 <zymfrank@gmail.com>
1 parent 6e9257d commit d25456d

26 files changed

+682
-63
lines changed

app/app.go

+68-24
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import (
1414
"sync"
1515
"time"
1616

17+
"github.com/cosmos/cosmos-sdk/server"
1718
"github.com/gorilla/mux"
1819
"github.com/rakyll/statik/fs"
20+
"github.com/sei-protocol/sei-db/ss"
1921

2022
"github.com/ethereum/go-ethereum/ethclient"
2123
ethrpc "github.com/ethereum/go-ethereum/rpc"
@@ -26,14 +28,6 @@ import (
2628

2729
storetypes "github.com/cosmos/cosmos-sdk/store/types"
2830

29-
"github.com/sei-protocol/sei-chain/aclmapping"
30-
aclutils "github.com/sei-protocol/sei-chain/aclmapping/utils"
31-
appparams "github.com/sei-protocol/sei-chain/app/params"
32-
"github.com/sei-protocol/sei-chain/app/upgrades"
33-
v0upgrade "github.com/sei-protocol/sei-chain/app/upgrades/v0"
34-
"github.com/sei-protocol/sei-chain/utils"
35-
"github.com/sei-protocol/sei-chain/wasmbinding"
36-
3731
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
3832
"github.com/cosmos/cosmos-sdk/baseapp"
3933
"github.com/cosmos/cosmos-sdk/client"
@@ -47,27 +41,26 @@ import (
4741
"github.com/cosmos/cosmos-sdk/simapp"
4842
sdk "github.com/cosmos/cosmos-sdk/types"
4943
sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol"
44+
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
5045
"github.com/cosmos/cosmos-sdk/types/module"
5146
"github.com/cosmos/cosmos-sdk/version"
52-
"github.com/cosmos/cosmos-sdk/x/auth"
53-
"github.com/cosmos/cosmos-sdk/x/auth/ante"
54-
"github.com/cosmos/cosmos-sdk/x/authz"
55-
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
56-
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
57-
58-
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
5947
aclmodule "github.com/cosmos/cosmos-sdk/x/accesscontrol"
6048
aclclient "github.com/cosmos/cosmos-sdk/x/accesscontrol/client"
6149
aclconstants "github.com/cosmos/cosmos-sdk/x/accesscontrol/constants"
6250
aclkeeper "github.com/cosmos/cosmos-sdk/x/accesscontrol/keeper"
6351
acltypes "github.com/cosmos/cosmos-sdk/x/accesscontrol/types"
52+
"github.com/cosmos/cosmos-sdk/x/auth"
53+
"github.com/cosmos/cosmos-sdk/x/auth/ante"
6454
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
6555
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
6656
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
6757
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
6858
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
6959
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
7060
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
61+
"github.com/cosmos/cosmos-sdk/x/authz"
62+
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
63+
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
7164
"github.com/cosmos/cosmos-sdk/x/bank"
7265
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
7366
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@@ -118,18 +111,25 @@ import (
118111
ibcporttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types"
119112
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
120113
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
121-
"github.com/sei-protocol/sei-chain/x/mint"
122-
mintclient "github.com/sei-protocol/sei-chain/x/mint/client/cli"
123-
mintkeeper "github.com/sei-protocol/sei-chain/x/mint/keeper"
124-
minttypes "github.com/sei-protocol/sei-chain/x/mint/types"
125-
114+
"github.com/sei-protocol/sei-chain/aclmapping"
115+
aclutils "github.com/sei-protocol/sei-chain/aclmapping/utils"
116+
appparams "github.com/sei-protocol/sei-chain/app/params"
117+
"github.com/sei-protocol/sei-chain/app/upgrades"
118+
v0upgrade "github.com/sei-protocol/sei-chain/app/upgrades/v0"
119+
"github.com/sei-protocol/sei-chain/utils"
120+
"github.com/sei-protocol/sei-chain/wasmbinding"
126121
"github.com/sei-protocol/sei-chain/x/evm"
127122
evmante "github.com/sei-protocol/sei-chain/x/evm/ante"
128123
"github.com/sei-protocol/sei-chain/x/evm/blocktest"
129124
evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
130125
"github.com/sei-protocol/sei-chain/x/evm/querier"
131126
"github.com/sei-protocol/sei-chain/x/evm/replay"
132127
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
128+
"github.com/sei-protocol/sei-chain/x/mint"
129+
mintclient "github.com/sei-protocol/sei-chain/x/mint/client/cli"
130+
mintkeeper "github.com/sei-protocol/sei-chain/x/mint/keeper"
131+
minttypes "github.com/sei-protocol/sei-chain/x/mint/types"
132+
seidb "github.com/sei-protocol/sei-db/ss/types"
133133
"github.com/spf13/cast"
134134
abci "github.com/tendermint/tendermint/abci/types"
135135
tmcfg "github.com/tendermint/tendermint/config"
@@ -166,6 +166,8 @@ import (
166166

167167
// unnamed import of statik for openapi/swagger UI support
168168
_ "github.com/sei-protocol/sei-chain/docs/swagger"
169+
170+
ssconfig "github.com/sei-protocol/sei-db/config"
169171
)
170172

171173
// this line is used by starport scaffolding # stargate/wasm/app/enabledProposals
@@ -264,7 +266,8 @@ var (
264266
// EmptyAclmOpts defines a type alias for a list of wasm options.
265267
EmptyACLOpts []aclkeeper.Option
266268
// EnableOCC allows tests to override default OCC enablement behavior
267-
EnableOCC = true
269+
EnableOCC = true
270+
EmptyAppOptions []AppOption
268271
)
269272

270273
var (
@@ -382,8 +385,12 @@ type App struct {
382385
encodingConfig appparams.EncodingConfig
383386
evmRPCConfig evmrpc.Config
384387
lightInvarianceConfig LightInvarianceConfig
388+
389+
receiptStore seidb.StateStore
385390
}
386391

392+
type AppOption func(*App)
393+
387394
// New returns a reference to an initialized blockchain app
388395
func New(
389396
logger log.Logger,
@@ -400,13 +407,15 @@ func New(
400407
appOpts servertypes.AppOptions,
401408
wasmOpts []wasm.Option,
402409
aclOpts []aclkeeper.Option,
410+
appOptions []AppOption,
403411
baseAppOptions ...func(*baseapp.BaseApp),
404412
) *App {
405413
appCodec := encodingConfig.Marshaler
406414
cdc := encodingConfig.Amino
407415
interfaceRegistry := encodingConfig.InterfaceRegistry
408416

409417
bAppOptions := SetupSeiDB(logger, homePath, appOpts, baseAppOptions)
418+
410419
bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), tmConfig, appOpts, bAppOptions...)
411420
bApp.SetCommitMultiStoreTracer(traceStore)
412421
bApp.SetVersion(version.Version)
@@ -423,7 +432,7 @@ func New(
423432
tokenfactorytypes.StoreKey,
424433
// this line is used by starport scaffolding # stargate/app/storeKey
425434
)
426-
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
435+
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientStoreKey)
427436
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, dexmoduletypes.MemStoreKey, banktypes.DeferredCacheStoreKey, evmtypes.MemStoreKey, oracletypes.MemStoreKey)
428437

429438
app := &App{
@@ -440,6 +449,11 @@ func New(
440449
metricCounter: &map[string]float32{},
441450
encodingConfig: encodingConfig,
442451
}
452+
453+
for _, option := range appOptions {
454+
option(app)
455+
}
456+
443457
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
444458

445459
// set the BaseApp's parameter store
@@ -596,9 +610,26 @@ func New(
596610
wasmOpts...,
597611
)
598612

613+
receiptStorePath := filepath.Join(homePath, "data", "receipt.db")
614+
ssConfig := ssconfig.DefaultStateStoreConfig()
615+
ssConfig.DedicatedChangelog = true
616+
ssConfig.KeepRecent = cast.ToInt(appOpts.Get(server.FlagMinRetainBlocks))
617+
ssConfig.DBDirectory = receiptStorePath
618+
ssConfig.KeepLastVersion = false
619+
if app.receiptStore == nil {
620+
app.receiptStore, err = ss.NewStateStore(logger, receiptStorePath, ssConfig)
621+
if err != nil {
622+
panic(fmt.Sprintf("error while creating receipt store: %s", err))
623+
}
624+
}
599625
app.EvmKeeper = *evmkeeper.NewKeeper(keys[evmtypes.StoreKey], memKeys[evmtypes.MemStoreKey],
600-
app.GetSubspace(evmtypes.ModuleName), app.BankKeeper, &app.AccountKeeper, &app.StakingKeeper,
601-
app.TransferKeeper, wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper), &app.WasmKeeper)
626+
tkeys[evmtypes.TransientStoreKey], app.GetSubspace(evmtypes.ModuleName), app.receiptStore, app.BankKeeper,
627+
&app.AccountKeeper, &app.StakingKeeper, app.TransferKeeper,
628+
wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper), &app.WasmKeeper)
629+
630+
bApp.SetPreCommitHandler(app.HandlePreCommit)
631+
bApp.SetCloseHandler(app.HandleClose)
632+
602633
app.evmRPCConfig, err = evmrpc.ReadConfig(appOpts)
603634
if err != nil {
604635
panic(fmt.Sprintf("error reading EVM config due to %s", err))
@@ -970,6 +1001,19 @@ func New(
9701001
return app
9711002
}
9721003

1004+
// HandlePreCommit happens right before the block is committed
1005+
func (app *App) HandlePreCommit(ctx sdk.Context) error {
1006+
return app.EvmKeeper.FlushTransientReceipts(ctx)
1007+
}
1008+
1009+
// Close closes all items that needs closing (called by baseapp)
1010+
func (app *App) HandleClose() error {
1011+
if app.receiptStore != nil {
1012+
return app.receiptStore.Close()
1013+
}
1014+
return nil
1015+
}
1016+
9731017
// Add (or remove) keepers when they are introduced / removed in different versions
9741018
func (app *App) SetStoreUpgradeHandlers() {
9751019
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()

app/test_helpers.go

+17
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ func Setup(isCheckTx bool, enableEVMCustomPrecompiles bool, baseAppOptions ...fu
177177
db := dbm.NewMemDB()
178178
encodingConfig := MakeEncodingConfig()
179179
cdc := encodingConfig.Marshaler
180+
181+
options := []AppOption{
182+
func(app *App) {
183+
app.receiptStore = NewInMemoryStateStore()
184+
},
185+
}
186+
180187
res = New(
181188
log.NewNopLogger(),
182189
db,
@@ -192,6 +199,7 @@ func Setup(isCheckTx bool, enableEVMCustomPrecompiles bool, baseAppOptions ...fu
192199
TestAppOpts{},
193200
EmptyWasmOpts,
194201
EmptyACLOpts,
202+
options,
195203
baseAppOptions...,
196204
)
197205
if !isCheckTx {
@@ -220,6 +228,13 @@ func SetupWithSc(isCheckTx bool, enableEVMCustomPrecompiles bool, baseAppOptions
220228
db := dbm.NewMemDB()
221229
encodingConfig := MakeEncodingConfig()
222230
cdc := encodingConfig.Marshaler
231+
232+
options := []AppOption{
233+
func(app *App) {
234+
app.receiptStore = NewInMemoryStateStore()
235+
},
236+
}
237+
223238
res = New(
224239
log.NewNopLogger(),
225240
db,
@@ -235,6 +250,7 @@ func SetupWithSc(isCheckTx bool, enableEVMCustomPrecompiles bool, baseAppOptions
235250
TestAppOpts{true},
236251
EmptyWasmOpts,
237252
EmptyACLOpts,
253+
options,
238254
baseAppOptions...,
239255
)
240256
if !isCheckTx {
@@ -285,6 +301,7 @@ func SetupTestingAppWithLevelDb(isCheckTx bool, enableEVMCustomPrecompiles bool)
285301
TestAppOpts{},
286302
EmptyWasmOpts,
287303
EmptyACLOpts,
304+
nil,
288305
)
289306
if !isCheckTx {
290307
genesisState := NewDefaultGenesisState(cdc)

0 commit comments

Comments
 (0)