Skip to content

Conversation

@Kbhat1
Copy link
Contributor

@Kbhat1 Kbhat1 commented Feb 3, 2026

Describe your changes and provide context

Add a catch-all LegacyDB to EVM-SS that stores all EVM module keys that don't fit into the optimized databases (Nonce, CodeHash, Code, Storage).

This ensures ALL EVM data is routed to EVM-SS:

  • Optimized keys (nonce, code, codehash, storage) go to specialized DBs
  • All other EVM keys (address mappings, receipts, pointers, bloom, etc.) go to LegacyDB with the full original key preserve

Testing performed to validate your change

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 9, 2026, 3:27 PM

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 57.95455% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.00%. Comparing base (785b74f) to head (9771e18).
⚠️ Report is 1 commits behind head on feature/composite-ss-wal-integration.

Files with missing lines Patch % Lines
sei-db/state_db/ss/composite/store.go 63.49% 19 Missing and 4 partials ⚠️
app/seidb.go 0.00% 10 Missing ⚠️
sei-db/common/evm/keys.go 55.55% 3 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@                            Coverage Diff                            @@
##           feature/composite-ss-wal-integration    #2792       +/-   ##
=========================================================================
+ Coverage                                 41.61%   52.00%   +10.39%     
=========================================================================
  Files                                      1925     1991       +66     
  Lines                                    153324   158670     +5346     
=========================================================================
+ Hits                                      63811    82522    +18711     
+ Misses                                    83484    68410    -15074     
- Partials                                   6029     7738     +1709     
Flag Coverage Δ
sei-chain 41.58% <57.95%> (+0.05%) ⬆️
sei-db 68.72% <ø> (ø)
sei-tendermint 58.10% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sei-db/state_db/ss/evm/types.go 100.00% <100.00%> (ø)
sei-db/common/evm/keys.go 76.00% <55.55%> (-4.96%) ⬇️
app/seidb.go 66.23% <0.00%> (-9.89%) ⬇️
sei-db/state_db/ss/composite/store.go 54.87% <63.49%> (+12.88%) ⬆️

... and 323 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add recovery mechanism ensuring both Cosmos_SS and EVM_SS stay in sync:

- RecoverCompositeStateStore: Syncs EVM_SS if behind, replays new WAL entries
- syncEVMStore: Catches up EVM_SS via WAL replay
- Standard WAL replay goes through ApplyChangesetSync (dual-writes)

Usage: Call RecoverCompositeStateStore after creating CompositeStateStore.
…function

- Replace separate syncEVMStore and recoverStandardWAL functions with
  a single generic replayWAL function that takes a handler callback
- replayWAL(fromVersion, toVersion, handler) handles all WAL replay:
  - fromVersion: start replaying from entries > this version
  - toVersion: stop at this version (-1 = replay to end of WAL)
  - handler: callback to process each entry
- RecoverCompositeStateStore now uses replayWAL for both phases:
  - Phase 1: Sync EVM if behind (replay only to EVM store)
  - Phase 2: Replay new entries (dual-write through CompositeStateStore)
Move newCompositeStateStoreWithStores from store.go to recovery_test.go
since it's only used for testing recovery scenarios.
Since Cosmos_SS and EVM_SS share the same changelog, consolidate recovery
into a single pass that routes each WAL entry appropriately:
- Entries Cosmos needs: dual-write through CompositeStateStore
- Entries only EVM needs (catch-up): write only to EVM store
- Entries both have: skip

This opens the WAL once instead of potentially twice, and the routing
logic is clear and consolidated in one place.
@Kbhat1 Kbhat1 force-pushed the feature/composite-ss-wal-integration branch from b68f249 to f5d8315 Compare February 3, 2026 21:52
@Kbhat1 Kbhat1 force-pushed the feature/composite-ss-legacy-db branch from ddd61fb to 2d1839f Compare February 3, 2026 21:52
Replace EnableRead/EnableWrite with WriteMode/ReadMode enums in test config.
Add a catch-all LegacyDB to EVM-SS that stores all EVM module keys that
don't fit into the optimized databases (Nonce, CodeHash, Code, Storage).

This ensures ALL EVM data is routed to EVM-SS:
- Optimized keys (nonce, code, codehash, storage) go to specialized DBs
- All other EVM keys (address mappings, receipts, pointers, bloom, etc.)
  go to LegacyDB with the full original key preserved

Changes:
- common/evm/keys.go: Add EVMKeyLegacy kind, ParseEVMKey now returns
  EVMKeyLegacy for unrecognized/malformed keys (instead of EVMKeyUnknown)
- evm/types.go: Add StoreLegacy, update NumEVMStoreTypes to 5
- composite/store.go: Route all EVM keys to EVM-SS (only skip empty keys)
- Updated tests to reflect new legacy key routing behavior
@Kbhat1 Kbhat1 force-pushed the feature/composite-ss-legacy-db branch from 2d1839f to 24a9eae Compare February 4, 2026 21:31
EVMKeyNonce
EVMKeyCodeHash
EVMKeyCode
EVMKeyCodeSize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeSize should always goes to legacy because we do not want to store it in EVM eventually right?

// Only returns EVMKeyUnknown for empty keys.
func ParseEVMKey(key []byte) (kind EVMKeyKind, keyBytes []byte) {
if len(key) == 0 {
return EVMKeyUnknown, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to return EVMEmptyKey rather than Unknown here?

Comment on lines +666 to +668
evmStoreType, keyBytes := commonevm.ParseEVMKey(kvPair.Key)
if evmStoreType == evm.StoreUnknown {
continue // Empty key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above, being more explicit about empty key

… KeepRecent

- Add FlagEVMSSWriteMode/FlagEVMSSReadMode to parseEVMSSConfigs so the
  feature is actually activatable via config (previously defaulted to
  CosmosOnly for both, making EVM_SS inert).
- Replace recoverFromWAL with RecoverCompositeStateStore in
  NewCompositeStateStore so EVM_SS catch-up works when it falls behind
  Cosmos_SS after a crash.
- Compute EVM prune version from evmConfig.KeepRecent instead of
  silently using the Cosmos value.
- Add TestConstructorRecoversStalEVM verifying the constructor itself
  recovers EVM_SS from WAL when behind.
ParseEVMKey returns EVMKeyCodeSize for CodeSize-prefixed keys with the
prefix stripped, but no backing database existed. This caused CodeSize
writes to be silently dropped during dual-write.

Add StoreCodeSize to AllEVMStoreTypes so a dedicated PebbleDB is opened
for CodeSize data, matching the key parser's expectations.
… validate config

- Fix 1: SplitWrite now strips EVM data from Cosmos changeset in
  ApplyChangesetSync/Async/Import/RawImport (was identical to DualWrite)
- Fix 2: SplitRead no longer falls back to Cosmos for EVM keys in
  Get/Has (was identical to EVMFirstRead)
- Fix 3: SetLatestVersion respects WriteMode -- CosmosOnlyWrite no
  longer advances EVM version, so WAL catch-up can backfill later.
  Recovery also skips EVM when WriteMode is CosmosOnlyWrite.
- Fix 4: parseEVMSSConfigs now validates WriteMode/ReadMode using
  ParseWriteMode/ParseReadMode, panicking on invalid values instead
  of silently accepting typos.
…ootmulti tests

The NewStore signature was updated to include *config.EVMStateStoreConfig
but store_test.go was not updated. Pass nil for all test calls.
If a crash interrupts SetLatestVersion mid-loop, some sub-DBs may be
one version ahead of others. Using max() would skip WAL replay for
the behind DBs. Using min() ensures replay starts from the furthest-
behind DB. Under normal operation all DBs are in sync so min == max.
Base automatically changed from feature/composite-ss-wal-integration to feature/composite-ss-read-path February 9, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants