Skip to content

Commit f3e1578

Browse files
seidroid[bot]Kbhat1claude
authored
Backport release/v6.4: Unify EVM SS into single DB with store key prefixes (#3211)
Backport of #3134 to `release/v6.4`. --------- Co-authored-by: Kartik Bhat <kartikbhatri@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a562bab commit f3e1578

13 files changed

Lines changed: 283 additions & 54 deletions

File tree

app/seidb.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ const (
4141
FlagSSImportNumWorkers = "state-store.ss-import-num-workers"
4242

4343
// EVM SS optimization (embedded in SS config, controlled via write/read mode)
44-
FlagEVMSSDirectory = "state-store.evm-ss-db-directory"
45-
FlagEVMSSWriteMode = "state-store.evm-ss-write-mode"
46-
FlagEVMSSReadMode = "state-store.evm-ss-read-mode"
44+
FlagEVMSSDirectory = "state-store.evm-ss-db-directory"
45+
FlagEVMSSWriteMode = "state-store.evm-ss-write-mode"
46+
FlagEVMSSReadMode = "state-store.evm-ss-read-mode"
47+
FlagEVMSSSeparateDBs = "state-store.evm-ss-separate-dbs"
4748

4849
// Other configs
4950
FlagSnapshotInterval = "state-sync.snapshot-interval"
@@ -69,7 +70,10 @@ func SetupSeiDB(
6970
}
7071
if ssConfig.EVMEnabled() {
7172
logger.Info("SeiDB EVM StateStore optimization is enabled",
72-
"writeMode", ssConfig.WriteMode, "readMode", ssConfig.ReadMode)
73+
"writeMode", ssConfig.WriteMode,
74+
"readMode", ssConfig.ReadMode,
75+
"separateDBs", ssConfig.SeparateEVMSubDBs,
76+
)
7377
}
7478
validateConfigs(appOpts)
7579
gigaExecutorConfig, err := gigaconfig.ReadConfig(appOpts)
@@ -146,6 +150,7 @@ func parseSSConfigs(appOpts servertypes.AppOptions) config.StateStoreConfig {
146150

147151
// EVM optimization fields (embedded in SS config)
148152
ssConfig.EVMDBDirectory = cast.ToString(appOpts.Get(FlagEVMSSDirectory))
153+
ssConfig.SeparateEVMSubDBs = cast.ToBool(appOpts.Get(FlagEVMSSSeparateDBs))
149154
if wm := cast.ToString(appOpts.Get(FlagEVMSSWriteMode)); wm != "" {
150155
parsedWM, err := config.ParseWriteMode(wm)
151156
if err != nil {

app/seidb_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ func (t TestSeiDBAppOpts) Get(s string) interface{} {
6161
return "" // empty means use default
6262
case FlagEVMSSReadMode:
6363
return "" // empty means use default
64+
case FlagEVMSSSeparateDBs:
65+
return defaultSSConfig.SeparateEVMSubDBs
6466
}
6567
return nil
6668
}
@@ -98,6 +100,24 @@ func TestParseSCConfigs_HistoricalProofFlags(t *testing.T) {
98100
assert.Equal(t, 3, scConfig.HistoricalProofBurst)
99101
}
100102

103+
func TestParseSSConfigs_EVMFlags(t *testing.T) {
104+
appOpts := mapAppOpts{
105+
FlagSSEnable: true,
106+
FlagEVMSSDirectory: "/tmp/evm-ss",
107+
FlagEVMSSWriteMode: string(config.SplitWrite),
108+
FlagEVMSSReadMode: string(config.SplitRead),
109+
FlagEVMSSSeparateDBs: true,
110+
FlagSSAsyncWriterBuffer: 0,
111+
}
112+
113+
ssConfig := parseSSConfigs(appOpts)
114+
assert.True(t, ssConfig.Enable)
115+
assert.Equal(t, "/tmp/evm-ss", ssConfig.EVMDBDirectory)
116+
assert.Equal(t, config.SplitWrite, ssConfig.WriteMode)
117+
assert.Equal(t, config.SplitRead, ssConfig.ReadMode)
118+
assert.True(t, ssConfig.SeparateEVMSubDBs)
119+
}
120+
101121
func TestParseReceiptConfigs_DefaultsToPebbleWhenUnset(t *testing.T) {
102122
receiptConfig, err := config.ReadReceiptConfig(mapAppOpts{})
103123
assert.NoError(t, err)

docker/localnode/config/app.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,12 @@ ss-prune-interval = 60
269269
# defaults to 1
270270
ss-import-num-workers = 1
271271

272+
# EVM state-store DB directory and routing mode controls.
273+
evm-ss-db-directory = ""
274+
evm-ss-write-mode = "cosmos_only"
275+
evm-ss-read-mode = "cosmos_only"
276+
evm-ss-separate-dbs = false
277+
272278
[evm]
273279

274280
# EnableTestAPI enables the EVM test API

docker/rpcnode/config/app.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ ss-prune-interval = 60
257257
# defaults to 1
258258
ss-import-num-workers = 1
259259

260+
# EVM state-store DB directory and routing mode controls.
261+
evm-ss-db-directory = ""
262+
evm-ss-write-mode = "cosmos_only"
263+
evm-ss-read-mode = "cosmos_only"
264+
evm-ss-separate-dbs = false
265+
260266
[evm]
261267

262268
# EnableTestAPI enables the EVM test API

sei-cosmos/server/config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,10 @@ func GetConfig(v *viper.Viper) (Config, error) {
428428
KeepRecent: v.GetInt("state-store.ss-keep-recent"),
429429
PruneIntervalSeconds: v.GetInt("state-store.ss-prune-interval"),
430430
ImportNumWorkers: v.GetInt("state-store.ss-import-num-workers"),
431+
WriteMode: config.WriteMode(v.GetString("state-store.evm-ss-write-mode")),
432+
ReadMode: config.ReadMode(v.GetString("state-store.evm-ss-read-mode")),
433+
EVMDBDirectory: v.GetString("state-store.evm-ss-db-directory"),
434+
SeparateEVMSubDBs: v.GetBool("state-store.evm-ss-separate-dbs"),
431435
},
432436
Genesis: GenesisConfig{
433437
StreamImport: v.GetBool("genesis.stream-import"),

sei-cosmos/server/config/config_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ func TestGetConfigStateStore(t *testing.T) {
332332
v.Set("state-store.ss-keep-recent", 50000)
333333
v.Set("state-store.ss-prune-interval", 1200)
334334
v.Set("state-store.ss-import-num-workers", 4)
335+
v.Set("state-store.evm-ss-db-directory", "/custom/evm/ss/path")
336+
v.Set("state-store.evm-ss-write-mode", "split_write")
337+
v.Set("state-store.evm-ss-read-mode", "split_read")
338+
v.Set("state-store.evm-ss-separate-dbs", true)
335339

336340
cfg, err := GetConfig(v)
337341
require.NoError(t, err)
@@ -344,6 +348,10 @@ func TestGetConfigStateStore(t *testing.T) {
344348
require.Equal(t, 50000, cfg.StateStore.KeepRecent)
345349
require.Equal(t, 1200, cfg.StateStore.PruneIntervalSeconds)
346350
require.Equal(t, 4, cfg.StateStore.ImportNumWorkers)
351+
require.Equal(t, "/custom/evm/ss/path", cfg.StateStore.EVMDBDirectory)
352+
require.Equal(t, seidbconfig.SplitWrite, cfg.StateStore.WriteMode)
353+
require.Equal(t, seidbconfig.SplitRead, cfg.StateStore.ReadMode)
354+
require.True(t, cfg.StateStore.SeparateEVMSubDBs)
347355
}
348356

349357
func TestDefaultStateCommitConfig(t *testing.T) {
@@ -367,4 +375,7 @@ func TestDefaultStateStoreConfig(t *testing.T) {
367375
require.Equal(t, seidbconfig.DefaultSSKeepRecent, cfg.StateStore.KeepRecent)
368376
require.Equal(t, seidbconfig.DefaultSSPruneInterval, cfg.StateStore.PruneIntervalSeconds)
369377
require.Equal(t, seidbconfig.DefaultSSImportWorkers, cfg.StateStore.ImportNumWorkers)
378+
require.Equal(t, seidbconfig.CosmosOnlyWrite, cfg.StateStore.WriteMode)
379+
require.Equal(t, seidbconfig.CosmosOnlyRead, cfg.StateStore.ReadMode)
380+
require.False(t, cfg.StateStore.SeparateEVMSubDBs)
370381
}

sei-db/config/ss_config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ type StateStoreConfig struct {
7676
// EVMDBDirectory defines the directory for EVM state store db files.
7777
// If not set, defaults to <home>/data/evm_ss
7878
EVMDBDirectory string `mapstructure:"evm-db-directory"`
79+
80+
// SeparateEVMSubDBs controls whether EVM data is physically split across
81+
// per-type databases. When false (default), all EVM data stays in one DB.
82+
// When true, data is routed to separate DBs by EVM key family while
83+
// preserving the same logical store key and full key encoding inside each DB.
84+
SeparateEVMSubDBs bool `mapstructure:"evm-separate-dbs"`
7985
}
8086

8187
// EVMEnabled returns true if EVM state stores should be opened.
@@ -106,5 +112,6 @@ func DefaultStateStoreConfig() StateStoreConfig {
106112
UseDefaultComparer: false,
107113
WriteMode: CosmosOnlyWrite,
108114
ReadMode: CosmosOnlyRead,
115+
SeparateEVMSubDBs: false,
109116
}
110117
}

sei-db/config/toml.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,23 @@ ss-prune-interval = {{ .StateStore.PruneIntervalSeconds }}
126126
# ImportNumWorkers defines the concurrency for state sync import
127127
# defaults to 1
128128
ss-import-num-workers = {{ .StateStore.ImportNumWorkers }}
129+
130+
# EVMDBDirectory defines the directory for the optional EVM state-store DB(s).
131+
# If unset, defaults to <home>/data/evm_ss when EVM SS is enabled.
132+
evm-ss-db-directory = "{{ .StateStore.EVMDBDirectory }}"
133+
134+
# WriteMode controls how EVM data writes are routed.
135+
# Supported values: "cosmos_only", "dual_write", "split_write"
136+
evm-ss-write-mode = "{{ .StateStore.WriteMode }}"
137+
138+
# ReadMode controls how EVM data reads are routed.
139+
# Supported values: "cosmos_only", "evm_first", "split_read"
140+
evm-ss-read-mode = "{{ .StateStore.ReadMode }}"
141+
142+
# SeparateEVMSubDBs controls whether EVM data is split across per-type DBs.
143+
# When false, all EVM data stays in one DB using the current unified layout.
144+
# When true, data is routed to separate DBs while preserving the same evm key prefix format.
145+
evm-ss-separate-dbs = {{ .StateStore.SeparateEVMSubDBs }}
129146
`
130147

131148
// ReceiptStoreConfigTemplate defines the configuration template for receipt-store

sei-db/config/toml_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ func TestStateStoreConfigTemplate(t *testing.T) {
8787
require.Contains(t, output, "ss-keep-recent =", "Missing ss-keep-recent")
8888
require.Contains(t, output, "ss-prune-interval =", "Missing ss-prune-interval")
8989
require.Contains(t, output, "ss-import-num-workers =", "Missing ss-import-num-workers")
90+
require.Contains(t, output, `evm-ss-db-directory = ""`, "Missing evm-ss-db-directory")
91+
require.Contains(t, output, `evm-ss-write-mode = "cosmos_only"`, "Missing or incorrect evm-ss-write-mode")
92+
require.Contains(t, output, `evm-ss-read-mode = "cosmos_only"`, "Missing or incorrect evm-ss-read-mode")
93+
require.Contains(t, output, "evm-ss-separate-dbs = false", "Missing or incorrect evm-ss-separate-dbs")
9094
}
9195

9296
// TestReceiptStoreConfigTemplate verifies that all field paths in the receipt-store TOML template

sei-db/state_db/ss/composite/store.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ func NewCompositeStateStore(
6767
return nil, fmt.Errorf("failed to create EVM store: %w", err)
6868
}
6969
cs.evmStore = evmStore
70-
logger.Info("EVM state store enabled", "dir", evmDir, "writeMode", ssConfig.WriteMode, "readMode", ssConfig.ReadMode)
70+
logger.Info("EVM state store enabled",
71+
"dir", evmDir,
72+
"writeMode", ssConfig.WriteMode,
73+
"readMode", ssConfig.ReadMode,
74+
"separateDBs", ssConfig.SeparateEVMSubDBs,
75+
)
7176
}
7277

7378
changelogPath := utils.GetChangelogPath(dbHome)

0 commit comments

Comments
 (0)