Only the SS layer changes for this migration. SC layer config is untouched
and
memiavl remains the authoritative source for the app hash, so this is
invisible to the network.
The SC-layer routing field
sc-write-mode is emitted in the generated
app.toml template under the [state-store] section. It defaults to
memiavl_only, so leaving it at the default keeps the SC layer untouched for
this migration.sc-write-mode— write routing mode for EVM data in the SC layer. Valid values:memiavl_only,migrate_evm,evm_migrated,migrate_all_but_bank,all_migrated_but_bank,migrate_bank,flatkv_only,test_only_dual_write. An invalid value fails at config parse time with a clear error.sc-keys-to-migrate-per-block— the number of keys migrated frommemiavltoflatKVper block while in a migration mode. Defaults to1024and must be greater than0; ignored outside of a migration mode.
sc-read-mode and sc-enable-lattice-hash fields have been
removed. Read routing and lattice-hash participation are now derived
automatically from the write mode and the on-disk migration state — an
app.toml that still references either field is no longer valid.The
sc-write-mode / sc-read-mode fields above configure EVM routing in the
legacy composite commit store and are distinct from the internal
memiavl → flatKV migration state machine used when converting the SC
layer’s state DB from memiavl to flatKV. That migration is driven by its
own WriteMode enum inside the state-migration package, not by
sc-write-mode. Node operators encounter these modes as the migration
progresses through a linear sequence of on-disk migration versions:The appropriate router for a given
WriteMode is constructed by the
state-migration package’s BuildRouter entrypoint, which returns the
steady-state or in-flight migration router for that mode. Router construction
requires a non-nil memiavl handle for every mode except FlatKVOnly, and a
non-nil flatKV handle for every mode except MemiavlOnly.Offline FlatKV EVM import (MigrateEVM)
Theseidb tool ships an offline import path that moves the evm/ module’s
SC-layer data out of memiavl and into FlatKV without running the in-process
migration state machine. This is the operational entrypoint for the
MigrateEVM (V0 → V1) transition on a stopped node.
Reading the latest memiavl version
Before importing, read the latest committedmemiavl version from a stopped
node’s data directory. In a multi-validator cluster, run this on every node
and pick the minimum so the import height is uniform across the cluster:
copy
--data-dir may point at either the data/ directory or the Sei home
directory; if the basename is data, its parent is treated as home. You can
also pass --home <sei_home> instead.
Running the import
copy
The import resets FlatKV before loading the selected
memiavl rows and
refuses to overwrite committed FlatKV data unless --force is supplied. If
an external error interrupts the import (context cancellation, exporter or
translator failure), the import is aborted rather than finalized — FlatKV is
left at its pre-import committed version, so the operation can be retried
without --force.
Configuration constraints across the import boundary
The import moves only the SC-layer EVM data into FlatKV. When restarting the node after the import, two settings must stay off across the import boundary or the node will panic on startup:evm-ss-split = false. SS history for EVM remains in the existing combined cosmos SS database; the import does not populate a separate EVM SS directory. Flippingevm-ss-splittotruetriggers the rootmulti startup panic “EVM SS directory … does not exist but Cosmos SS already has history”. Moving the SS layer to split mode is a separate state-sync workflow (see Step 2) and is out of scope for the offline SC import.sc-enable-lattice-hash = false. Before the import the chain ran without FlatKV, so tendermint persisted app hashes computed frommemiavlalone for every block up to the import height. Enabling the lattice hash now would fold the FlatKV LtHash into the app hash, and the replay check at startup would fail with “state.AppHash does not match AppHash after replay”. Note thatdual_writedoes not require the lattice hash — onlysplit_writedoes.
For the full operational failure-mode catalog and recovery/tooling roadmap for
MigrateEVM, see
sei-db/state_db/sc/migration/OPERATIONS.md
in sei-chain.This guide tracks the canonical procedure in
docs/migration/giga_store_migration.md inside sei-chain. Open an issue there if anything here drifts.Prerequisites
- A
seidbuild with theevm-ss-splitflag wired in (Sei v6.5 or later). Older releases used per-keyevm-ss-write-mode/evm-ss-read-modetoggles; if yourapp.tomlstill has those keys, upgradeseidbefore continuing. sc-enable = trueandss-enable = trueinapp.toml. Both must stay enabled.- A trusted RPC endpoint to state-sync from (chain ID and trust-height source).
- Disk headroom for two SS databases. The EVM split does not duplicate data, but during migration both the old and the new layouts may briefly coexist on disk.
Benefits
- EVM reads are served exclusively from a dedicated EVM SS database.
- Non-EVM modules no longer pay write amplification for EVM state.
- A backend change (PebbleDB ↔ RocksDB) can be combined with the same state
sync, since
ss-backenddrives both the Cosmos SS MVCC DB and every EVM SS sub-DB.
What’s different about EVM SS
EVM SS is point-query only by design (Get / Has). Iteration is
explicitly disabled on the EVM backend for performance: the hot EVM read path
is tuned for direct key lookups, and cross-bucket scans would defeat the
per-type sub-DB layout. Any EVM read that needs iteration must stay on the
Cosmos SS side.
Migration Steps
Step 1: Update app.toml
Apply the following settings in ~/.sei/config/app.toml:
copy
- PebbleDB → RocksDB: set
ss-backend = "rocksdb", buildseidwith-tags rocksdbBackend, and install RocksDB per the RocksDB Backend Guide.ss-backenddrives both the Cosmos SS MVCC DB and every EVM SS sub-DB, so a single setting flips both. - No data migration tool is needed across backends — the state sync populates the new layout.
Step 2: State sync into the new layout
Giga SS Store is fully compatible with the existing state-snapshot format. On import, the composite state store routes each snapshot node based on the importing node’sevm-ss-split:
- With
evm-ss-split = true, EVM snapshot nodes go only into EVM SS and non-EVM nodes go only into Cosmos SS. - The import path normalizes legacy
evm_flatkvsnapshot nodes toevm, so snapshots produced by either the old or new FlatKV module are accepted.
copy
Step 3: Verify the new layout
Once the state sync completes and the node starts producing blocks, confirm Giga SS Store is active in two places. Startup logs. All three lines should appear:debug_traceBlockByNumber is the cleanest end-to-end check —
it forces the node to read EVM state out of the new EVM SS backend:
copy
"result" field rather than an RPC error.
Safety checks
seid runs three DB-state checks at startup and refuses to launch if the EVM
SS and Cosmos SS DBs are inconsistent. They specifically catch the footgun of
flipping evm-ss-split from false to true without state syncing.
- EVM SS directory missing or empty (before the EVM SS is opened). When
evm-ss-split = true, the composite state store refuses to proceed if Cosmos SS already has committed history but the EVM SS directory (data/evm_ss/by default) does not exist or is empty. Failing before the sub-DBs are opened means a rejected config does not leave a confusing emptydata/evm_ss/behind. - EVM SS DB empty post-open, pre-recovery. Belt-and-suspenders for (1)
when the directory exists but its DBs are empty. The WAL only covers the
last
KeepRecentblocks, so replay cannot rebuild a fresh EVM SS from scratch. - Mismatched earliest versions, post-recovery. If the two DBs were populated from different snapshots (or pruned independently), historical reads would be inconsistent. A non-zero earliest-version divergence aborts startup.
evm-ss-split = false and restart. If
data/evm_ss/ is stale from a failed attempt, remove it before state syncing.
Receipt backend default
When Giga Storage is enabled (GIGA_STORAGE=true), the receipt backend now
defaults to pebble. Previously the receipt backend was left unchanged and
had to be set explicitly through the RECEIPT_BACKEND environment variable.
This default is applied implicitly: enabling Giga Storage sets
RECEIPT_BACKEND=pebble unless you have already provided an explicit value.
To use a different receipt backend, set RECEIPT_BACKEND explicitly before
starting the node — an explicit value always takes precedence over the
pebble default.
copy
Rollback
To roll back:- Set
evm-ss-split = falseinapp.toml. - Restart the node. The EVM SS DB under
data/evm_ss/is no longer opened but stays on disk until manually removed.
data/evm_ss/ after reverting the setting.
FAQ
Where do the data files live after migrating?
New nodes use an organized subdirectory layout underdata/. Existing nodes
with data in the legacy flat layout keep using their legacy paths automatically
(legacy takes precedence when present).
- Cosmos SS data lives under
data/state_store/cosmos/{backend}on new nodes (e.g.data/state_store/cosmos/pebbledb/for the defaultpebbledbbackend). Existing nodes with data underdata/{backend}(e.g.data/pebbledb/) continue using that legacy path. - EVM SS data lives under
data/state_store/evm/{backend}on new nodes (e.g.data/state_store/evm/pebbledb/). Existing nodes with data underdata/evm_ss/continue using that legacy path. Theevm-db-directoryconfig, when unset, defaults todata/state_store/evm/{backend}. - SC data (
memiavl+ FlatKV) is untouched by this migration; on new nodes it lives underdata/state_commit/memiavlanddata/state_commit/flatkv, with legacydata/committer.dbanddata/flatkvretained when present.
Does Giga SS Store change the app hash or consensus?
No. The SC layer is unchanged, somemiavl remains the authoritative source
for the app hash. Giga SS Store is a per-node SS change that is invisible to
the network.
Can I migrate a validator node with this guide?
Not yet. This migration guide is for RPC nodes only.Can I migrate an archive node with this guide?
Not yet. Archive-node migration is out of scope for this guide.Can I toggle back to evm-ss-split = false after enabling it?
Yes, but cleanly rolling back requires another state sync — see the
Rollback section above.
Why can’t I just flip evm-ss-split = true on a running node?
Because evm-ss-split = true requires the EVM SS DB to already contain the
full history that Cosmos SS has. A live flip would leave the EVM SS DB empty
while the composite store refuses to fall back to Cosmos SS, which would
translate into missing EVM state at query time. The safety checks above
block this scenario at startup.