This migration changes only the SS layer. It does not change the SC layer or
the app hash, so the change is invisible to the network.
This guide follows the canonical procedure in the
sei-chain repository: docs/migration/giga_store_migration.md. If anything here drifts, open an issue there.Prerequisites
- A
seidbuild that supports theevm-ss-splitflag (Sei v6.5 or later). Older releases used the per-keyevm-ss-write-modeandevm-ss-read-modetoggles. If yourapp.tomlstill has those keys, upgradeseidbefore you continue. sc-enable = trueandss-enable = trueinapp.toml. Both must stay enabled.- A trusted RPC endpoint for state sync (the chain ID and trust-height source).
- Disk headroom for two SS databases. The EVM split does not duplicate data, but the old and new layouts may briefly coexist on disk during the migration.
Benefits
- The node serves EVM reads only from a dedicated EVM SS database.
- Non-EVM modules no longer pay write amplification for EVM state.
What’s different about EVM SS
EVM SS is point-query only by design (Get and Has). For performance,
iteration is explicitly disabled on the EVM backend. 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 these settings in ~/.sei/config/app.toml:
copy
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 it accepts snapshots from either the old or the new FlatKV module.
copy
Step 3: Verify the new layout
After the state sync completes and the node starts producing blocks, confirm that 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 from the new EVM SS backend:
copy
"result" field, not an RPC error.
Safety checks
seid runs three DB-state checks at startup and refuses to start if the EVM SS
and Cosmos SS DBs are inconsistent. They specifically catch the mistake of
flipping evm-ss-split from false to true without a state sync.
- EVM SS directory missing or empty (before the EVM SS is opened). This
check applies when
evm-ss-split = true. If Cosmos SS already has committed history but the configured EVM SS directory is missing or empty, the composite state store refuses to proceed. The check fails before the sub-DBs are opened, so a rejected config does not leave a confusing empty directory behind. - EVM SS DB empty post-open, pre-recovery. This second safeguard for check 1
covers the case where the directory exists but its DBs are empty. The WAL
covers only 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 the configured
EVM SS directory is stale from a failed attempt, remove it before the state sync.
Rollback
To roll back:- Set
evm-ss-split = falseinapp.toml. - Restart the node. The EVM SS DB is no longer opened but stays on disk until you remove it.
FlatKV EVM SC migration flow
Everything above concerns the SS (State Store) layer. The SC (State Commit) layer has a separate migration path. It moves the hotevm/ data out
of memiavl and into FlatKV in place, without a state sync.
Unlike the SS split, the SC migration changes how evm/ data contributes to
the app hash. The contribution moves from the memiavl IAVL root to the FlatKV
lattice hash. Every validator must therefore switch at the same block, or
consensus halts.
How the migration starts
Since v6.7.0, governance controls the migration, and nodes follow it without config changes:- By default, every node runs in the
autowrite mode. The node derives its mode from the migration state on disk. It checks thatsc-write-modehas a valid value, but it does not use the value. - The
NumKeysToMigratePerBlockparameter in themigrationparams subspace sets how many keys move per block. The default,0, keeps the migration paused. AParameterChangeProposalcan raise it to at most 1,000,000. - When the parameter becomes greater than
0, everyautonode switches frommemiavl_onlytomigrate_evmat the same height and starts to move keys. The node does not restart.
migrate_all_but_bank, all_migrated_but_bank, migrate_bank, and
flatkv_only) exist, but no parameter starts them.
During the migration, the node reads and iterates over both backends. The
migration deletes a key from memiavl when it copies the key to FlatKV. If both
backends report a key, the node uses the memiavl value. The migration boundary
advances at most once per block. When the migration starts, the node stops
serving state proofs for the evm store, because FlatKV has no proof builder.
Proofs for other modules still work.
Pinning a write mode
To pin a write mode, set both keys in the[state-commit] section of
app.toml. The generated app.toml does not include
sc-write-mode-enable-auto, so add it yourself:
copy
memiavl_only does not take part in the migration. When
governance starts the migration, the pinned node diverges from the network.
Since v6.7.1, a node also refuses to start if a pinned evm_migrated,
all_migrated_but_bank, or flatkv_only mode disagrees with the migration
state on disk. The error starts with write mode is pinned to. The cosmos_only value from v6.4 and v6.5 app.toml files is
still accepted as an alias for memiavl_only.
Write modes
For the local Docker devnet,
GIGA_MIGRATE_FROM_MEMIAVL=true pins every node to
memiavl_only (with sc-write-mode-enable-auto = false), the starting point of
the devnet migration test. Do not set it together with
GIGA_STORAGE. If you set both, GIGA_MIGRATE_FROM_MEMIAVL takes precedence.
copy
Checking migration status
Theseidb migrate-evm-status subcommand reports the on-disk FlatKV EVM
migrate state of a FlatKV directory as JSON. It clones the latest snapshot and
WAL into a temporary directory before it reads. You can therefore run it against
a live node’s data directory without contending for the FlatKV writer lock.
copy
--db-dir (short -d) points at the FlatKV data directory. --height selects
a target version. The default, 0, selects the latest available version. The
JSON includes migrate_evm_complete (true after the migration finishes),
migration_version, version_at, and whether an in-flight boundary is still
present.
When the migration finishes, each node also emits a migration complete summary
log line and seidb_migration_* OpenTelemetry counters for the migrated keys
and bytes.
Importing EVM state from memIAVL into FlatKV
Theseidb import-flatkv-from-memiavl command populates a FlatKV store from an existing memIAVL tree. It is for nodes that move to the FlatKV EVM commit store without a state sync. Two safety properties matter:
- The import height must equal the latest memIAVL version. The command refuses a lower height, because the composite store’s version reconciliation would silently roll memIAVL back and truncate blocks. It also refuses a higher height. First, check the current version with
seidb memiavl-latest-version. If needed, roll memIAVL back to the target height before you import. - Overwriting existing committed FlatKV data requires the explicit
--forceflag.
auto write mode, the node does not use a FlatKV store that this
command creates. The store has no migration metadata, so the node starts in
memiavl_only.
FAQ
Where do the data files live after migrating?
- Cosmos SS data uses
data/pebbledb/in the legacy layout anddata/state_store/cosmos/pebbledb/in the current layout. - EVM SS data uses
data/evm_ss/in the legacy layout anddata/state_store/evm/pebbledb/in the current layout. - Nodes created before the layout change keep their legacy paths automatically. A legacy directory takes precedence when it is present. New nodes use the current layout.
- A non-empty
ss-db-directoryorevm-ss-db-directoryoverrides the corresponding default path. - This migration does not change SC data (
memiavland FlatKV).
Does Giga SS Store change the app hash or consensus?
No. Giga SS Store changes only the SS layer, which does not affect the app hash. It is a per-node 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 a clean rollback requires another state sync. See the
Rollback section above.
Why can’t I just flip evm-ss-split = true on a running node?
The evm-ss-split = true setting 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,
and the composite store refuses to fall back to Cosmos SS. The result would be
missing EVM state at query time. The safety checks above block this scenario at
startup.
Does Giga SS Store support historical proofs?
No, and neither does SeiDB. SS stores raw KVs and does not reconstruct IAVL-style proofs.Does enabling Giga Storage change the receipt backend?
In thelocalnode and rpcnode configuration scripts, setting
GIGA_STORAGE=true defaults RECEIPT_BACKEND to pebble unless you set
RECEIPT_BACKEND explicitly. To use a different value with Giga Storage, set the
RECEIPT_BACKEND environment variable explicitly. The explicit value takes
precedence over the default.
The supported receipt-store backends are pebbledb (also called pebble) and
littidx. For details on littidx, see the
node operations guide. The former parquet option was
removed. The node rejects an unsupported value for RECEIPT_BACKEND (or
rs-backend in app.toml) with an error
(unsupported receipt-store backend "parquet"; supported: pebbledb, littidx).