From 01ff367cbe27a9396eeb2d916a64d82ad0dfcddc Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:25:33 +0000
Subject: [PATCH 01/63] docs: The EVM RPC methods eth_getBlockByHash and
eth_getBlockTransactionCountByHash now recognize the genesis block hash and
return the genesis block (and a tx count of 0), keeping hash-based lookups
consistent with eth_getBlockByNumber("0x0"). (sei-protocol/sei-chain#3069)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index aef1579..9d08651 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -554,7 +554,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns block information by block hash, with full transactions when fullTx is true.
-**Sei-specific behavior:** Block hashes are CometBFT block hashes (computed from the Tendermint header), so they differ from Ethereum block hashes and are not interchangeable across chains. Under the eth namespace synthetic txs and bank transfers are excluded. The genesis hash returns a synthetic genesis block; unknown/zero hash returns null. Uncles array is always empty.
+**Sei-specific behavior:** Block hashes are CometBFT block hashes (computed from the Tendermint header), so they differ from Ethereum block hashes and are not interchangeable across chains. Under the eth namespace synthetic txs and bank transfers are excluded. The genesis block hash (`0xF9D3845DF25B43B1C6926F3CEDA6845C17F5624E12212FD8847D0BA01DA1AB9E`) is recognized and returns the encoded genesis block directly, keeping hash-based lookups consistent with `eth_getBlockByNumber("0x0")`; other unknown/zero hashes return null. Uncles array is always empty.
**Parameters:**
From 29f034eeb6d1d4acb07b91fb09e73a1d6ce6a1a5 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:25:58 +0000
Subject: [PATCH 02/63] docs: eth_getBlockByHash and eth_getBlockReceipts now
return result:null (instead of an error) for empty or non-existent block
hashes, matching Ethereum RPC spec. (sei-protocol/sei-chain#3067)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 9d08651..8a8ec35 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -631,7 +631,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns all EVM transaction receipts for a given block.
-**Sei-specific behavior:** Under the eth namespace synthetic/shell receipts are excluded (includeShellReceipts=false). Genesis returns an empty array; zero hash returns null. transactionIndex is recomputed sequentially over the compacted receipt list.
+**Sei-specific behavior:** Under the eth namespace synthetic/shell receipts are excluded (includeShellReceipts=false). Genesis returns an empty array. An empty (zero) or non-existent/unknown block hash returns `result: null` rather than an error, matching the Ethereum RPC spec. transactionIndex is recomputed sequentially over the compacted receipt list.
**Parameters:**
From 26f9889ac40c78c9ceb49c2aa7b21c46e065ef1b Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:28:01 +0000
Subject: [PATCH 03/63] docs: The Tendermint P2P layer was reworked with a new
peer manager: the config field 'max-outbound-connections' changed
type/behavior and its default logic, and the RouterOptions
MaxPeers/MaxConnected/MaxConcurrentDials fields were replaced by
MaxInbound/MaxOutbound, affecting node connection tuning.
(sei-protocol/sei-chain#3037)
---
node/node-operators.mdx | 12 ++++++++++++
node/technical-reference.mdx | 5 ++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 386e9a5..1190ac7 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -963,6 +963,18 @@ upnp = false
# Maximum number of connections (inbound and outbound).
max-connections = 100
+# Maximum number of outbound connections to regular (non-persistent) peers.
+# Inbound and outbound connections are now managed in separate pools, so this
+# field caps the outbound pool while the inbound pool is derived as
+# max-connections - max-outbound-connections. Persistent and unconditional
+# peers bypass both limits.
+#
+# This field is optional: when it is left unset, max-outbound-connections
+# defaults to 20, or to half of max-connections (rounded up) when
+# max-connections is below 40. When it is set explicitly, the effective value
+# is min(max-connections, max-outbound-connections).
+# max-outbound-connections = 20
+
# Rate limits the number of incoming connection attempts per IP address.
max-incoming-connection-attempts = 100
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 186396a..9d276e9 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -135,9 +135,8 @@ external-address = ""
seeds = ""
persistent_peers = ""
upnp = false
-max_num_inbound_peers = 40
-max_num_outbound_peers = 10
-allowed_pools = ""
+max-connections = 100
+max-outbound-connections = 20
max_packet_msg_payload_size = 10240
handshake_timeout = "20s"
dial_timeout = "3s"
From e5eef6b6048f0b38d1b15cba500293e2834b2641 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:30:24 +0000
Subject: [PATCH 04/63] docs: EVM transaction validation was tightened with
stricter semantic checks on signature values, access lists, auth lists, and
Cosmos wrapper fields, plus a new transaction body bloat rejection that may
reject previously-accepted transactions. (sei-protocol/sei-chain#3073)
---
evm/differences-with-ethereum.mdx | 29 ++++++++++++++++++++++++++++
evm/evm-parity/transaction-types.mdx | 12 ++++++++++++
evm/transactions.mdx | 25 ++++++++++++++++++++++++
3 files changed, 66 insertions(+)
diff --git a/evm/differences-with-ethereum.mdx b/evm/differences-with-ethereum.mdx
index d3500f8..a5008b4 100644
--- a/evm/differences-with-ethereum.mdx
+++ b/evm/differences-with-ethereum.mdx
@@ -137,6 +137,35 @@ updated by both native Cosmos bank send transactions and EVM send transactions.
As a result, if certain offchain applications only parse EVM transactions, they
may find certain state changes unattributable to any EVM transaction.
+
+
+## EVM Transaction Envelope Restrictions
+
+On Sei, EVM transactions are carried inside a Cosmos transaction envelope, but that envelope must remain empty of Cosmos-specific fields. This introduces two Sei-specific divergences from a plain Ethereum transaction that tooling constructing raw transactions should be aware of:
+
+### No Cosmos wrapper fields on EVM transactions
+
+An EVM transaction must not populate any of the Cosmos wrapper fields. If any of the following are set, the transaction is rejected:
+
+- `memo`
+- `timeout_height`
+- extension options (`extension_options` / `non_critical_extension_options`)
+- `signer_infos`
+- fee amount, fee `payer`, and fee `granter`
+- top-level `signatures`
+
+The EVM transaction's own signature (`v`, `r`, `s`) lives inside the EVM payload itself, so none of these Cosmos-level fields are needed. This check is applied uniformly to all EVM transactions.
+
+### Rejection of bloated (non-canonical) transaction bodies
+
+The transaction decoder now rejects "bloated" transaction bodies — those whose raw protobuf wire encoding is larger than the canonical re-marshal of the decoded body. Non-canonical encodings (for example, padded fields or an oversized `Any.Value`) that were previously silently canonicalized and accepted are now rejected on decode with a decode error.
+
+
+
+These are consensus-level validation changes. Transactions that were previously accepted may now be rejected if they carry Cosmos wrapper fields or use a non-canonical protobuf encoding. Ensure your transaction-signing tooling produces a minimal, canonical envelope with no Cosmos wrapper fields populated.
+
+
+
## Finality
Sei has instant finality — a transaction is final as soon as its block is
diff --git a/evm/evm-parity/transaction-types.mdx b/evm/evm-parity/transaction-types.mdx
index badc49d..dd7ead2 100644
--- a/evm/evm-parity/transaction-types.mdx
+++ b/evm/evm-parity/transaction-types.mdx
@@ -23,6 +23,18 @@ Type 4 (EIP-7702) SetCode transactions must include a non-empty authorization li
Each authorization entry must also carry a valid (non-nil) chain ID. If you are constructing SetCode transactions directly, ensure at least one authorization is present before submitting.
+
+### Access List and Auth List Entry Validation
+
+EVM transactions now undergo stricter semantic validation during `ValidateBasic`. Malformed transactions that were previously accepted may now be rejected.
+
+**Access list entries (type 1 and type 2):** Each access list tuple is validated for well-formed hex encoding. Every address must be a canonical hex address of the correct length, and every storage key must be a canonical hex hash of the correct length. Entries with wrong-length or non-hex values are rejected.
+
+**Auth list entries (type 4):** In addition to the non-empty auth list and non-nil chain ID requirements above, each authorization entry is validated for a canonical hex address and well-formed signature values.
+
+**Signature values:** The `v`, `r`, and `s` signature values (for both the transaction itself and, for type 4, each auth list entry) must not exceed their maximum byte length and must not contain a leading zero byte. Non-canonical signature encodings are rejected.
+
+
## Not Supported
| Type | EIP | Name | Notes |
diff --git a/evm/transactions.mdx b/evm/transactions.mdx
index d9eacbe..39d321f 100644
--- a/evm/transactions.mdx
+++ b/evm/transactions.mdx
@@ -285,6 +285,31 @@ EVM transactions in Sei follow the Ethereum transaction format with standard pro
| Out of Gas | Gas limit too low for the operation | Use `eth_estimateGas` to set appropriate limit |
| Contract Execution Failed | Contract function reverted | Test with `eth_call` before sending transaction |
+
+## Transaction Validation
+
+Before an EVM transaction is accepted, Sei performs strict semantic validation of the transaction's fields. Transactions that are malformed at the encoding level are rejected during basic validation, even if they were accepted by older node versions. If you construct and sign transactions manually, make sure they are well-formed to avoid rejection.
+
+The following checks are enforced:
+
+| Field | Requirement |
+| --- | --- |
+| Signature values (`v`, `r`, `s`) | Each value must not exceed its maximum byte length (32 bytes for `r`/`s`) and must not contain a leading zero byte. |
+| `accessList` addresses | Each access-list address must be a valid, correctly-sized hex-encoded address. |
+| `accessList` storage keys | Each storage key must be a valid, correctly-sized hex-encoded 32-byte hash. |
+| Authorization list (EIP-7702 `setCode` txs) | Each entry must include a non-nil chain ID, a valid hex address, and well-formed `v`/`r`/`s` signature values. |
+
+
+ Transactions with malformed signature values, access-list entries, or authorization-list entries that previously passed validation may now be rejected. Ensure your signing tooling produces canonical, correctly-encoded values.
+
+
+### Cosmos wrapper fields
+
+EVM transactions must not carry any Cosmos SDK wrapper fields. A transaction is rejected if it populates a memo, timeout height, extension options, signer infos, fee amount/payer/granter, or Cosmos-level signatures. This validation is applied uniformly across the transaction pipeline.
+
+Additionally, the transaction decoder now rejects "bloated" transaction bodies whose raw wire encoding is larger than the canonical re-marshaled form (for example, padded fields or oversized `Any.Value` entries). Non-canonical encodings that previously decoded successfully will now fail with a decode error, so tooling should always emit canonical protobuf encodings.
+
+
## Additional Resources
From 6460e9259604299b96e85bfa485c51d900c558ea Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:33:02 +0000
Subject: [PATCH 05/63] docs: The Tendermint RPC ValidatorInfo JSON response
now always includes a pub_key field (with a zero/empty public key for
non-validator nodes) for CosmJS compatibility, changing the status response
output. (sei-protocol/sei-chain#3114)
---
evm/reference.mdx | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 8a8ec35..3ec07c5 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1413,3 +1413,32 @@ Sei-Legacy-RPC-Deprecation: All sei_* and sei2_* JSON-RPC methods are deprecated
```
Clients can use this header to detect legacy API usage and plan migration.
+
+
+
+## Tendermint RPC status response
+
+The underlying Tendermint (CometBFT) RPC also exposes a `/status` endpoint whose response includes a `validator_info` object. This is separate from the EVM JSON-RPC surface but is often consumed by tooling such as CosmJS.
+
+The `validator_info` object always includes both a `pub_key` and an `address` field. For nodes that are not validators, `pub_key` is returned as a zero (empty) public key and `address` is derived from it, rather than the fields being omitted. This guarantees a stable response shape so that clients like CosmJS can parse the `/status` response without special-casing non-validator nodes.
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "validator_info": {
+ "address": "...",
+ "pub_key": {
+ "type": "tendermint/PubKeyEd25519",
+ "value": "..."
+ },
+ "voting_power": "0"
+ }
+ }
+}
+```
+
+
+On validator nodes, `pub_key` contains the node's actual validator public key and `voting_power` reflects its voting power. On non-validator nodes, `pub_key` carries a zero public key and `voting_power` is `0`.
+
From 9b66605fbb25265c48a106e1ad2984f111bfbe80 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:35:00 +0000
Subject: [PATCH 06/63] docs: Sei EVM JSON-RPC now conforms to Ethereum spec
behavior: eth_getBlockByNumber returns null (not an error) for
future/non-existent numeric block heights, and eth_getProof works across
additional store backends (tracekv, Giga cache, other proof-capable stores)
instead of only classic IAVL. (sei-protocol/sei-chain#3119)
---
evm/evm-parity/state-proofs.mdx | 10 ++++++++++
evm/reference.mdx | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/evm/evm-parity/state-proofs.mdx b/evm/evm-parity/state-proofs.mdx
index 8fa8462..c8684ee 100644
--- a/evm/evm-parity/state-proofs.mdx
+++ b/evm/evm-parity/state-proofs.mdx
@@ -13,6 +13,16 @@ Ethereum stores state in a Merkle Patricia Trie (MPT) and `eth_getProof` returns
The RPC method exists and responds correctly, but the proof data structure is not compatible with Ethereum MPT proof verifiers.
+### Store backends
+
+`eth_getProof` resolves the underlying account store by unwrapping known KVStore wrappers until it reaches a proof-capable queryable store. This means proofs are served across a broader range of node configurations, not just a classic IAVL store. Supported roots include:
+
+- Classic IAVL stores
+- store/v2 memiavl commitment stores
+- Any other proof-capable (queryable) store reached through `tracekv`, Giga cache, or prefix store wrappers
+
+If none of these can be reached, the call returns a `cannot find a proof-capable queryable KV store` error. In all cases the returned proof data is IAVL-format, not Ethereum MPT.
+
## What This Affects
Most applications do not call `eth_getProof` directly. It is primarily used by:
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 3ec07c5..7f79484 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -485,7 +485,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Limited.** Returns a Merkle proof for an account and the requested storage slots.
-**Sei-specific behavior:** Sei stores state in an IAVL tree, not an Ethereum Merkle-Patricia trie. The result is a Sei-specific ProofResult{address, hexValues, storageProof} where storageProof entries are CometBFT/IAVL crypto.ProofOps, NOT eth-style MPT proof nodes. There is no accountProof, balance, codeHash, nonce, or storageHash field (Sei has no per-account state root); standard eth_getProof verifiers will not work.
+**Sei-specific behavior:** Sei stores state in an IAVL-style tree, not an Ethereum Merkle-Patricia trie. The handler unwraps the EVM store through any intervening wrappers (cache, tracing, Giga cache, prefix stores) until it reaches an underlying proof-capable queryable store — classic IAVL, a store/v2 memiavl commitment, or any other proof-capable root — so proofs work across these backends rather than only classic IAVL. If no proof-capable queryable store can be reached it returns `cannot find a proof-capable queryable KV store`. The result is a Sei-specific ProofResult{address, hexValues, storageProof} where storageProof entries are CometBFT/IAVL crypto.ProofOps, NOT eth-style MPT proof nodes. There is no accountProof, balance, codeHash, nonce, or storageHash field (Sei has no per-account state root); standard eth_getProof verifiers will not work.
**Parameters:**
From 58a5cc1de9797b1dfeabacdc7599c1ce18c8b1c4 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:36:09 +0000
Subject: [PATCH 07/63] docs: The eth_getBlockTransactionCountByNumber and
eth_getBlockTransactionCountByHash RPC methods now return counts consistent
with getBlockByNumber, filtering EVM txs by receipt availability and
including wasm execute and bank send messages. (sei-protocol/sei-chain#3125)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 7f79484..9bd75d2 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -581,7 +581,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns the number of EVM transactions in a block by number, as a hex quantity.
-**Sei-specific behavior:** Counts EVM transactions only (via getEvmTxCount); synthetic/bank-transfer txs are excluded. Genesis returns 0x0; non-existent/future blocks return null.
+**Sei-specific behavior:** Counts the same transactions that appear in `eth_getBlockByNumber`'s transaction list: EVM transactions are counted only when a receipt exists for them, and `MsgExecuteContract` (wasm execute-contract) and `MsgSend` (bank send) messages are also included. Genesis returns 0x0; non-existent/future blocks return null.
**Parameters:**
From d35c5a4d25dbefffde539b114dae0141e0023bca Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:37:04 +0000
Subject: [PATCH 08/63] docs: Three state-commit config fields (sc-write-mode,
sc-read-mode, sc-enable-lattice-hash) were removed from the node config TOML
template, and split_write mode now requires lattice hash to be enabled.
(sei-protocol/sei-chain#3128)
---
node/node-operators.mdx | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 1190ac7..6101158 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -230,19 +230,6 @@ sc-snapshot-prefetch-threshold = 0.8
# Maximum snapshot write rate in MB/s (global across all trees). 0 = unlimited. Default 100.
sc-snapshot-write-rate-mbps = 100
-# WriteMode defines the 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
-sc-write-mode = "memiavl_only"
-
-# KeysToMigratePerBlock controls how many EVM keys the in-flight migration
-# (sc-write-mode = migrate_evm / migrate_bank / migrate_all_but_bank) drains
-# from memiavl into flatkv per block. Default 1024 is appropriate for
-# production drains; lower it (e.g. 256) to spread the migration across more
-# blocks for test runs that need to observe the resume / hybrid-read path.
-# Must be > 0; ignored entirely when not in a migration mode.
-sc-keys-to-migrate-per-block = 1024
-
###############################################################################
### FlatKV (EVM) Configuration ###
###############################################################################
From 2bd1b975c55af719a05e240f2e2e9396368fc310 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:38:11 +0000
Subject: [PATCH 09/63] docs: The oracle module's default MinValidPerWindow
parameter changed from 5% to 0% because the Oracle Price Feeder is retired.
(sei-protocol/sei-chain#3157)
---
node/technical-reference.mdx | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 9d276e9..ad034fe 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -186,6 +186,11 @@ Slashing Parameters:
- slash_fraction_downtime: 0% (no stake slash; jail only)
- slash_fraction_double_sign: 0% (no stake slash; double-signing still triggers
permanent tombstoning)
+
+Oracle Parameters:
+ - min_valid_per_window: 0% (default changed from 5% now that the Oracle
+ Price Feeder is retired; distinct from the
+ slashing module's min_signed_per_window above)
```
From b6b5b2cc35d6504f318f8f84e76bdbd35c44429c Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:38:37 +0000
Subject: [PATCH 10/63] docs: IAVL is being signaled for upcoming deprecation,
with new log warnings urging users to migrate to SeiDB to avoid data
corruption or panic. (sei-protocol/sei-chain#3159)
---
node/troubleshooting.mdx | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx
index 2d129dd..041ca05 100644
--- a/node/troubleshooting.mdx
+++ b/node/troubleshooting.mdx
@@ -102,6 +102,18 @@ systemctl restart seid
seid debug dump-iavl
```
+
+
+**IAVL is being deprecated.** Nodes still running on Legacy IAVL now emit deprecation warnings on startup and at commit time, such as:
+
+```text
+IAVL will be deprecated soon, please migrate to SeiDB to avoid data corruption or panic
+```
+
+Remaining on IAVL risks data corruption or panic. Migrate to SeiDB by enabling SeiDB State Commit (SC) in `app.toml` to avoid these issues.
+
+
+
Always include the app hash, commit hash, and block height from your logs when reporting issues.
### Identifying AppHash Errors
From 1ce13c36ae2fa5c02066c4a0a80ea79f95d9dca7 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:39:39 +0000
Subject: [PATCH 11/63] docs: The legacy sei_*/sei2_* JSON-RPC gate now handles
JSON-RPC batch requests by forwarding only the allowed subset and merging
responses by id, and the HTTP request body limit was lowered from 32MiB to
5MiB to match go-ethereum's default. (sei-protocol/sei-chain#3160)
---
evm/reference.mdx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 9bd75d2..6fb3d8a 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1240,7 +1240,9 @@ Sei extends the standard Ethereum JSON-RPC API with custom endpoints that enhanc
**Deprecation Notice:** All `sei_*` and `sei2_*` JSON-RPC methods are deprecated and scheduled for removal. Do not build new integrations on these endpoints. Use standard `eth_*` and `debug_*` methods instead.
-Access is controlled by the `enabled_legacy_sei_apis` setting under `[evm]` in `app.toml`. Only methods explicitly listed in this allowlist are available. Disabled methods return a standard JSON-RPC error (code `-32601`, data `"legacy_sei_deprecated"`). Allowed methods pass through unchanged, with an optional `Sei-Legacy-RPC-Deprecation` HTTP response header signaling deprecation.
+Access is controlled by the `enabled_legacy_sei_apis` setting under `[evm]` in `app.toml`. Only methods explicitly listed in this allowlist are available. Disabled methods return a standard JSON-RPC error (code `-32601`, data `"legacy_sei_deprecated"`). Allowed single-object calls pass through unchanged, with an optional `Sei-Legacy-RPC-Deprecation` HTTP response header signaling deprecation.
+
+**Batch requests:** JSON-RPC batches (a top-level JSON array) are handled by the gate rather than passed through wholesale. Only the allowed methods in the batch are forwarded to the inner handler as a filtered subset, and the inner responses are then merged back into the original batch order by matching each response's JSON-RPC `id`. Disallowed methods yield the usual `-32601` legacy deprecation error in their slot, and any batch element that is not a JSON object returns a JSON-RPC `-32600` `"Invalid Request"` error in its slot — a malformed element no longer causes the whole batch body to bypass the gate and reach the inner handler.
### Legacy API Configuration
From ff273017e7b2df6c96b1d9a90424bd8b14fa8f65 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:41:02 +0000
Subject: [PATCH 12/63] docs: The legacy IAVL backend has been fully removed
and SeiDB state-commit (SC) is now mandatory; multiple CLI commands and
config fields tied to IAVL/pruning have been removed, and the node will panic
if SC is not enabled. (sei-protocol/sei-chain#3146)
---
evm/installing-seid-cli.mdx | 3 ---
node/node-operators.mdx | 4 +++-
node/troubleshooting.mdx | 11 ++++-------
3 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/evm/installing-seid-cli.mdx b/evm/installing-seid-cli.mdx
index d4d5dce..0a090fc 100644
--- a/evm/installing-seid-cli.mdx
+++ b/evm/installing-seid-cli.mdx
@@ -97,7 +97,6 @@ Available Commands:
add-wasm-genesis-message Wasm genesis subcommands
blocktest run EF blocktest
collect-gentxs Collect genesis txs and output a genesis.json file
- compact Compact the application DB fully (only if it is a levelDB)
config Create or query an application CLI configuration file
debug Tool for helping with debugging your application
ethreplay replay EVM transactions
@@ -106,9 +105,7 @@ Available Commands:
help Help about any command
init Initialize private validator, p2p, genesis, and application configuration files
keys Manage your application's keys
- latest_version Prints the latest version of the app DB
migrate Migrate genesis to a specified target version
- prune Prune app history states by keeping the recent heights and deleting old heights
query Querying subcommands
rollback rollback cosmos-sdk and tendermint state by one height
start Run the full node
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 6101158..6960f02 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -83,7 +83,9 @@ enable = true
max-open-connections = 1000
[state-commit]
-# SeiDB state-commit (memiavl + FlatKV). Recommended on every node.
+# SeiDB state-commit (memiavl + FlatKV) is mandatory. The legacy IAVL backend
+# has been fully removed; if sc-enable is false the node panics at startup with
+# "SeiDB state-commit (SC) must be enabled; IAVL backend has been fully deprecated".
sc-enable = true
[state-store]
diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx
index 041ca05..f8f3c22 100644
--- a/node/troubleshooting.mdx
+++ b/node/troubleshooting.mdx
@@ -90,27 +90,24 @@ top -p $(pgrep seid)
If you encounter an AppHash mismatch, you'll need to capture the state for comparison with a known good version:
```bash
-# For SeiDB (most non-archive nodes):
+# For SeiDB (all supported nodes):
git clone https://github.com/sei-protocol/sei-db.git
cd sei-db/tools
make install
systemctl stop seid
seidb dump-iavl -d $HOME/.sei/data/committer.db -o /home/ubuntu/iavl-dump
systemctl restart seid
-
-# For Legacy IAVL DB:
-seid debug dump-iavl
```
-**IAVL is being deprecated.** Nodes still running on Legacy IAVL now emit deprecation warnings on startup and at commit time, such as:
+**The legacy IAVL backend has been fully removed and SeiDB State Commit (SC) is now mandatory.** SC must be enabled via `sc-enable = true` in the `[state-commit]` section of `app.toml`. If SC is not enabled, the node no longer falls back to IAVL — it panics at startup with:
```text
-IAVL will be deprecated soon, please migrate to SeiDB to avoid data corruption or panic
+SeiDB state-commit (SC) must be enabled; IAVL backend has been fully deprecated
```
-Remaining on IAVL risks data corruption or panic. Migrate to SeiDB by enabling SeiDB State Commit (SC) in `app.toml` to avoid these issues.
+The `seid debug dump-iavl` command has also been removed along with the IAVL backend. To inspect state, use the `seidb dump-iavl` tool shown above.
From 5bb5ef5549b52a532107aea0998326ac8e6dc2bf Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:47:47 +0000
Subject: [PATCH 13/63] docs: Adds a new `seid tendermint gen-autobahn-config`
CLI command to generate an Autobahn (GigaRouter) JSON config from node pubkey
files, plus new side-effect files (validator_pubkey.txt, node_pubkey.txt)
written when saving keys. (sei-protocol/sei-chain#3220)
---
node/technical-reference.mdx | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index ad034fe..87d97ae 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -37,6 +37,30 @@ seid tendermint show-validator
seid query node info
```
+
+### Autobahn (GigaRouter) Config Generation
+
+When running with the Autobahn (GigaRouter) networking layer, you can generate the Autobahn JSON config from a set of node directories. Each directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, and `autobahn_address.txt`.
+
+```bash
+# Generate an autobahn JSON config from one or more node directories
+seid tendermint gen-autobahn-config [node-dirs...] --output
+
+# The --output flag may be abbreviated as -o
+seid tendermint gen-autobahn-config ./node0 ./node1 ./node2 -o autobahn.json
+```
+
+The command reads the following files from each node directory:
+
+- `validator_pubkey.txt` — the validator public key in `validator:` format.
+- `node_pubkey.txt` — the p2p node public key in `node:ed25519:public:` format.
+- `autobahn_address.txt` — the network address (`host:port`) the node advertises to peers.
+
+The `validator_pubkey.txt` and `node_pubkey.txt` files are written automatically alongside `priv_validator_key.json` and `node_key.json` whenever those keys are saved, so they are typically already present in each node's config directory.
+
+The generated `autobahn.json` file describes the validator set along with gas and transaction limits, mempool size, block interval, view timeout, and dial interval. To have a node consume it, reference the file from `config.toml` using the `autobahn-config-file` key.
+
+
### Key Management
Proper key management is crucial for security. These commands help you manage
@@ -210,7 +234,9 @@ $HOME/.sei/
│ ├── config.toml # Tendermint configuration
│ ├── genesis.json # Chain genesis file
│ ├── node_key.json # Node identity key
-│ └── priv_validator_key.json # Validator signing key
+│ ├── node_pubkey.txt # Node public key in autobahn format ("node:ed25519:public:"), written when the node key is saved
+│ ├── priv_validator_key.json # Validator signing key
+│ └── validator_pubkey.txt # Validator public key in autobahn format ("validator:"), written when the validator key is saved
├── data/
│ ├── application.db # Application state
│ ├── blockstore.db # Block data
From 8711551d2020dffbc798c0c82932c12d8701f509 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:49:10 +0000
Subject: [PATCH 14/63] docs: The `receipt-store.keep-recent` config field has
been removed; receipt store retention is now always derived from the global
`min-retain-blocks` flag. (sei-protocol/sei-chain#3237)
---
node/node-operators.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 6960f02..9a5fc7d 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -128,6 +128,8 @@ minimum-gas-prices = "0.01usei"
# MinRetainBlocks defines the minimum block height offset from the current block
# for pruning Tendermint blocks. Set to 0 to disable pruning. This only affects
# Tendermint block pruning, not application state (see "pruning-*" configs).
+# This value also drives receipt store retention: the receipt store's KeepRecent
+# is derived from min-retain-blocks (0 means keep everything / no pruning).
min-retain-blocks = 100000
# ConcurrencyWorkers defines how many workers to run for concurrent transaction execution.
From 7cae2f32612d6f383b831fafa0578dca086455c4 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:49:55 +0000
Subject: [PATCH 15/63] docs: When Giga/Autobahn mode is enabled (autobahn
config file set), the node now disables the mempool gossip reactor, consensus
reactor, state sync, and block sync, and the Autobahn block producer sources
transactions directly from the mempool with new per-block limits (max 2000
txs, ~2MB total). (sei-protocol/sei-chain#3224)
---
node/technical-reference.mdx | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 87d97ae..da67e63 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -61,6 +61,23 @@ The `validator_pubkey.txt` and `node_pubkey.txt` files are written automatically
The generated `autobahn.json` file describes the validator set along with gas and transaction limits, mempool size, block interval, view timeout, and dial interval. To have a node consume it, reference the file from `config.toml` using the `autobahn-config-file` key.
+
+#### Giga Mode Behavior and Per-Block Limits
+
+When a node is started in Giga mode — that is, when `autobahn-config-file` is set in `config.toml` — the block production and networking behavior differs significantly from standard Tendermint consensus:
+
+- **Mempool gossip reactor is disabled.** Mempool gossiping is not compatible with Giga, so transactions are not broadcast over the standard mempool p2p channel. The mempool itself still runs and accepts transactions locally.
+- **Consensus reactor, state sync, and block sync are disabled.** In Giga mode these reactors are skipped entirely, and both state sync and block sync are forced off regardless of other configuration.
+- **The Autobahn block producer sources transactions directly from the mempool.** Instead of relying on a separate transaction channel, the producer reaps transactions straight from the local mempool when building each block payload.
+
+Each Autobahn block payload is subject to fixed per-block limits enforced by the block producer:
+
+- **Maximum transactions per block:** 2,000 transactions.
+- **Maximum total transaction bytes per block:** approximately 2 MB (2,000 × 1,024 bytes). This total can be distributed arbitrarily across transactions (for example, one large transaction, or up to 2,000 smaller ones), so long as neither the transaction count nor the total byte limit is exceeded.
+
+These limits are in addition to the gas limits configured in `autobahn.json`. When building a block, the producer stops reaping transactions once any of the transaction-count, byte, or gas limits is reached. Payload construction fails if either the transaction count or total byte limit would be exceeded.
+
+
### Key Management
Proper key management is crucial for security. These commands help you manage
From dde570e699f2d3f025acf40af031a1abf74e6161 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:50:24 +0000
Subject: [PATCH 16/63] docs: Legacy sei_*/sei2_* JSON-RPC batch handling now
follows JSON-RPC 2.0 notification rules: notifications (requests without an
id) produce no response entries, so merged batch responses are no longer 1:1
with the request, and an all-notification/empty result returns an empty HTTP
body instead of an empty array []. (sei-protocol/sei-chain#3246)
---
evm/reference.mdx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 6fb3d8a..154280d 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1242,7 +1242,9 @@ Sei extends the standard Ethereum JSON-RPC API with custom endpoints that enhanc
Access is controlled by the `enabled_legacy_sei_apis` setting under `[evm]` in `app.toml`. Only methods explicitly listed in this allowlist are available. Disabled methods return a standard JSON-RPC error (code `-32601`, data `"legacy_sei_deprecated"`). Allowed single-object calls pass through unchanged, with an optional `Sei-Legacy-RPC-Deprecation` HTTP response header signaling deprecation.
-**Batch requests:** JSON-RPC batches (a top-level JSON array) are handled by the gate rather than passed through wholesale. Only the allowed methods in the batch are forwarded to the inner handler as a filtered subset, and the inner responses are then merged back into the original batch order by matching each response's JSON-RPC `id`. Disallowed methods yield the usual `-32601` legacy deprecation error in their slot, and any batch element that is not a JSON object returns a JSON-RPC `-32600` `"Invalid Request"` error in its slot — a malformed element no longer causes the whole batch body to bypass the gate and reach the inner handler.
+**Batch requests:** JSON-RPC batches (a top-level JSON array) are handled by the gate rather than passed through wholesale. Only the allowed methods in the batch are forwarded to the inner handler as a filtered subset, and the inner responses are then merged back by matching each response's JSON-RPC `id`. Disallowed methods yield the usual `-32601` legacy deprecation error in their slot, and any batch element that is not a JSON object returns a JSON-RPC `-32600` `"Invalid Request"` error in its slot — a malformed element no longer causes the whole batch body to bypass the gate and reach the inner handler.
+
+Per JSON-RPC 2.0, **notifications** (requests with no `id`) do not produce a response entry, including within a batch. As a result, the merged response array is **not** 1:1 with the request batch when notifications are present — it is ordered like the batch minus the notification slots. If a batch would produce no response objects at all (for example, an all-notification batch, or an empty result), the gateway returns an **empty HTTP body** with HTTP 200 rather than an empty JSON array (`[]`).
### Legacy API Configuration
From c821349749f10b9df64aaca2a31ee72212654a16 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:53:18 +0000
Subject: [PATCH 17/63] docs: eth_getFilterChanges and eth_getFilterLogs now
return an empty array [] instead of null when there are no matching logs,
aligning with the Ethereum JSON-RPC spec. (sei-protocol/sei-chain#3292)
---
evm/reference.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 154280d..3f85087 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -786,6 +786,8 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Polls a filter and returns new logs (log filters) or block hashes (block filters) since the last poll.
+**Sei-specific behavior:** For log filters, returns an empty array (`[]`) rather than `null` when no logs match or a bounded filter's block range has been fully consumed, in line with the Ethereum JSON-RPC spec.
+
**Parameters:**
| # | Name | Type | Description |
From 06a94534480ac66c66ab6b7281c08638a3e529e2 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:54:45 +0000
Subject: [PATCH 18/63] docs: Sei database storage paths were reorganized into
a structured subdirectory layout (data/state_commit, data/state_store,
data/ledger, data/tendermint) for new nodes, with automatic
backward-compatible fallback to legacy flat paths for existing nodes.
(sei-protocol/sei-chain#3155)
---
node/giga-storage-migration.mdx | 13 ++++++++++---
node/node-operators.mdx | 2 +-
node/technical-reference.mdx | 16 +++++++++++-----
3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/node/giga-storage-migration.mdx b/node/giga-storage-migration.mdx
index 755f614..6dfce53 100644
--- a/node/giga-storage-migration.mdx
+++ b/node/giga-storage-migration.mdx
@@ -209,9 +209,16 @@ To fully reclaim the disk used by EVM SS, stop the node and delete
### Where do the data files live after migrating?
-- Cosmos SS data lives under the same directory as before, typically
- `data/pebbledb/` for the default `pebbledb` backend.
-- EVM SS data lives under `data/evm_ss/`.
+As of Sei v6.6, new nodes use a structured subdirectory layout. Existing nodes
+with legacy flat paths automatically keep using them (the legacy path 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 default `pebbledb` backend).
+ Existing nodes with legacy `data/pebbledb/` continue using it.
+- EVM SS data lives under `data/state_store/evm/{backend}` on new nodes
+ (e.g. `data/state_store/evm/pebbledb`). Existing nodes with legacy
+ `data/evm_ss/` continue using it.
- SC data (`memiavl` + FlatKV) is untouched by this migration.
### Does Giga SS Store change the app hash or consensus?
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 9a5fc7d..adb9a4d 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -295,7 +295,7 @@ ss-prune-interval = 600
ss-import-num-workers = 1
# EVMDBDirectory defines the directory for the optional EVM state-store DB(s).
-# If unset, defaults to /data/evm_ss when EVM SS is enabled.
+# If unset, defaults to /data/state_store/evm/{backend} when EVM SS is enabled.
evm-ss-db-directory = ""
# EVMSplit controls whether EVM data is routed to a dedicated SS backend.
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index da67e63..c1e2e35 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -256,14 +256,20 @@ $HOME/.sei/
│ └── validator_pubkey.txt # Validator public key in autobahn format ("validator:"), written when the validator key is saved
├── data/
│ ├── application.db # Application state
-│ ├── blockstore.db # Block data
-│ ├── cs.wal/ # Consensus write-ahead logs
-│ ├── evidence.db # Evidence of misbehavior
-│ ├── state.db # Tendermint state
-│ └── tx_index.db # Transaction index
+│ └── tendermint/ # Tendermint consensus DBs (new subdirectory layout)
+│ ├── blockstore.db # Block data
+│ ├── cs.wal/ # Consensus write-ahead logs
+│ ├── evidence.db # Evidence of misbehavior
+│ ├── peerstore.db # Peer store
+│ ├── state.db # Tendermint state
+│ └── tx_index.db # Transaction index
└── keyring-file/ # Local key storage
```
+
+ New nodes place the Tendermint consensus databases (blockstore, state, tx_index, evidence, peerstore, and cs.wal) under `data/tendermint/`. Existing nodes that already have these databases in the legacy flat layout directly under `data/` (e.g. `data/blockstore.db`, `data/cs.wal/`) continue using those legacy paths automatically — the legacy location takes precedence when present, so no migration is required.
+
+
This reference guide provides essential technical information for operating Sei
nodes and validators. For API documentation and other detailed specifications,
please refer to the respective sections in our documentation set.
From 1c48fc79e0197bdcb41f92aed80b361e445cfdf3 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:55:28 +0000
Subject: [PATCH 19/63] docs: When the parquet receipt store's pebble tx hash
index is disabled, receipt-by-tx-hash lookups that miss the cache now fail
fast with an error instead of falling back to a full parquet scan, affecting
operators who run nodes with the tx index disabled.
(sei-protocol/sei-chain#3294)
---
node/node-operators.mdx | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index adb9a4d..d4250ec 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -99,6 +99,19 @@ ss-keep-recent = 100000
rs-backend = "pebbledb"
```
+
+The `parquet` backend maintains a pebble-based tx hash index that maps a
+transaction hash to the parquet file that holds its receipt. When this index
+is disabled (`TxIndexBackend = ""`), a receipt-by-tx-hash lookup such as
+`eth_getTransactionReceipt` that misses the in-memory receipt cache fails fast
+with a not-found result instead of performing a full parquet file scan (a scan
+would require reading every file on disk and is prohibitively expensive at
+production scale). Block-range queries such as `FilterLogs` (log filtering by
+block range) do not use the tx hash index and are unaffected. If you serve
+receipt-by-tx-hash lookups for historical transactions, keep the tx hash index
+enabled.
+
+
### Default Configurations
The full unmodified `app.toml`, `config.toml`, and `client.toml` produced by
From 96346707952a96c86fc36c1bb5961eaa7799f2aa Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:55:59 +0000
Subject: [PATCH 20/63] docs: When GIGA_STORAGE=true, the receipt backend now
defaults to parquet (previously unchanged), though callers can still override
with an explicit RECEIPT_BACKEND env var. (sei-protocol/sei-chain#3298)
---
node/giga-storage-migration.mdx | 11 +++++++++++
node/node-operators.mdx | 9 +++++++++
2 files changed, 20 insertions(+)
diff --git a/node/giga-storage-migration.mdx b/node/giga-storage-migration.mdx
index 6dfce53..0af8779 100644
--- a/node/giga-storage-migration.mdx
+++ b/node/giga-storage-migration.mdx
@@ -252,3 +252,14 @@ block this scenario at startup.
No, same as SeiDB. SS stores raw KVs and does not reconstruct IAVL-style
proofs.
+
+
+
+### Does enabling Giga Storage change the receipt backend?
+
+Yes. In the `localnode` and `rpcnode` configuration scripts, setting
+`GIGA_STORAGE=true` now also defaults `RECEIPT_BACKEND` to `parquet` unless you
+set `RECEIPT_BACKEND` explicitly. Previously the receipt backend was left
+unchanged and had to be set explicitly to use parquet. To keep a different
+receipt backend while running with Giga Storage, provide an explicit
+`RECEIPT_BACKEND` env var, which takes precedence over the parquet default.
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index d4250ec..ab7ead0 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -99,6 +99,15 @@ ss-keep-recent = 100000
rs-backend = "pebbledb"
```
+
+Enabling Giga Storage (`GIGA_STORAGE=true`) in the localnode and rpcnode
+configuration scripts now defaults the receipt backend to `parquet` rather than
+leaving `rs-backend` at its `pebbledb` default. This applies only when
+`RECEIPT_BACKEND` is not set; you can still keep pebbledb (or select any other
+supported backend) by exporting `RECEIPT_BACKEND` explicitly before running the
+scripts.
+
+
The `parquet` backend maintains a pebble-based tx hash index that maps a
transaction hash to the parquet file that holds its receipt. When this index
From 6be5c621596164f18db5dec1ba0b17955d99fd78 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:56:59 +0000
Subject: [PATCH 21/63] docs: Adds a new debug_traceTransactionProfile JSON-RPC
method that returns trace results with detailed timing/store-access
profiling, plus a new seidb trace-profile-report CLI command to run it across
a block range. (sei-protocol/sei-chain#3267)
---
evm/reference.mdx | 39 +++++++++++++++++++++++++++++++++++++++
evm/tracing/index.mdx | 1 +
2 files changed, 40 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 3f85087..15295de 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1233,6 +1233,45 @@ The `filter` object applies only to `logs` subscriptions. For `newHeads`, pass t
}
```
+
+
+#### `debug_traceTransactionProfile`
+
+**Limited.** Sei extension that replays a transaction by hash and returns its execution trace alongside a detailed timing and store-access profile.
+
+**Sei-specific behavior:** Sei-specific extension (not part of upstream go-ethereum's debug namespace). HTTP-only and subject to historical-debug-trace availability guards. In addition to the standard trace result, it returns a `profile` object breaking down where time was spent — total wall time, historical DB lookup time, and per-phase timings (transaction lookup, block load, historical tx replay, block-context build, tx prepare, execution, and trace-result assembly) — plus a per-module `store` access trace (reads, iterators with the keys they surfaced, and per-operation `stats` roll-ups). Per-tx caps bound the trace size: at most 16 iterators and 64 keys per iterator are retained per module, with overflow flagged via `truncated`. To run this method across a whole block range and generate aggregate reports, use the `seidb trace-profile-report` command.
+
+**Parameters:**
+
+| # | Name | Type | Description |
+| :- | :- | :- | :- |
+| 1 | `hash` | DATA, 32 bytes | Transaction hash to trace and profile. |
+| 2 | `config` | object | Optional tracer config (tracer name, tracerConfig, timeout, reexec, disableStorage/Stack/Memory). |
+
+The response `result` contains a `trace` field (the standard tracer output) and a `profile` object shaped as follows:
+
+- `totalNanos` — total wall-clock nanoseconds for the profiled trace.
+- `historicalDbLookupNanos` — nanoseconds spent in historical store lookups (get/has/iterator/iteratorNext).
+- `otherNanos` — remaining time not attributed to historical lookups or execution.
+- `phases` — per-phase timings: `lookupTransactionNanos`, `loadBlockNanos`, `replayHistoricalTxsNanos`, `buildBlockContextNanos`, `prepareTxNanos`, `executionNanos`, `traceResultNanos`.
+- `store` — per-module store access trace: `modules` (each with `reads`, `has`, `iterators`, and per-op `stats`) and top-level `stats`.
+
+**Example request:**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_traceTransactionProfile",
+ "params": [
+ "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
+ {
+ "timeout": "60s"
+ }
+ ]
+}
+```
+
## Sei Custom Endpoints
diff --git a/evm/tracing/index.mdx b/evm/tracing/index.mdx
index 3473127..c12eb2b 100644
--- a/evm/tracing/index.mdx
+++ b/evm/tracing/index.mdx
@@ -56,6 +56,7 @@ Debug tracing is your primary tool for understanding EVM transaction execution o
| `debug_traceBlockByNumber` | Trace entire block | Block-level analysis |
| `debug_traceCall` | Simulate and trace | Testing before execution |
| `debug_traceStateAccess` | State access patterns | Performance optimization |
+| `debug_traceTransactionProfile` | Trace plus timing/store-access profiling | Latency breakdown and DB-access analysis |
## Transaction Analysis Example
From ab3464f3a1d24111e9d83be945ef5d06a9ed15d3 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:58:35 +0000
Subject: [PATCH 22/63] docs: The /status RPC response now includes a new
`last_committed_block_height` field in SyncInfo, and under Autobahn the
status endpoint populates height/app-hash from the app layer instead of the
CometBFT block store. (sei-protocol/sei-chain#3309)
---
evm/reference.mdx | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 15295de..ab46068 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -59,6 +59,31 @@ All endpoints follow the standard JSON-RPC format:
For additional public and commercial endpoints, see [RPC providers](/learn/rpc-providers) and [Chains & endpoints](/learn/dev-chains).
+
+### Tendermint `/status` endpoint
+
+Alongside the EVM JSON-RPC surface, Sei nodes expose the underlying Tendermint/CometBFT RPC, including the `/status` endpoint. Its `SyncInfo` object reports a `last_committed_block_height` field: the height of the last block finalized by consensus.
+
+```bash
+curl -s $SEI_TENDERMINT_RPC/status | jq '.result.sync_info.last_committed_block_height'
+```
+
+The field is JSON-serialized as a string (`last_committed_block_height`), matching the other height fields in `SyncInfo`.
+
+| Field | JSON | Description |
+| :- | :- | :- |
+| `last_committed_block_height` | string | Height of the last block finalized by consensus. |
+
+**Consensus-engine behavior:**
+
+- **Under CometBFT** — commit and app-apply happen in a single step, so `last_committed_block_height` is guaranteed to equal `latest_block_height`.
+- **Under Autobahn** — the value is derived from the latest `CommitQC`. Because consensus finalizes a block before the app executes it, the invariant is `last_committed_block_height >= latest_block_height`; the two can briefly differ while the app catches up.
+
+
+Under Autobahn (`AutobahnConfigFile` set) the CometBFT block store is not populated, so `/status` derives `latest_block_height` and `latest_app_hash` from the app layer (`ABCIInfo`) instead of the block store. Several other `SyncInfo` fields (block hash/time, earliest-block metadata, `catching_up`, and peer-height fields) remain unpopulated in this mode.
+
+
+
### Filter and subscription limits
From 33594452b23eb4bd83ada06fc05c12a330df1bc6 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:58:56 +0000
Subject: [PATCH 23/63] docs: Changed JSON-RPC batch handling so that requests
with "id": null are now treated as normal requests (receiving a response)
instead of as notifications; only requests omitting the "id" member are
treated as notifications. (sei-protocol/sei-chain#3303)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index ab46068..a5a820d 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1310,7 +1310,7 @@ Access is controlled by the `enabled_legacy_sei_apis` setting under `[evm]` in `
**Batch requests:** JSON-RPC batches (a top-level JSON array) are handled by the gate rather than passed through wholesale. Only the allowed methods in the batch are forwarded to the inner handler as a filtered subset, and the inner responses are then merged back by matching each response's JSON-RPC `id`. Disallowed methods yield the usual `-32601` legacy deprecation error in their slot, and any batch element that is not a JSON object returns a JSON-RPC `-32600` `"Invalid Request"` error in its slot — a malformed element no longer causes the whole batch body to bypass the gate and reach the inner handler.
-Per JSON-RPC 2.0, **notifications** (requests with no `id`) do not produce a response entry, including within a batch. As a result, the merged response array is **not** 1:1 with the request batch when notifications are present — it is ordered like the batch minus the notification slots. If a batch would produce no response objects at all (for example, an all-notification batch, or an empty result), the gateway returns an **empty HTTP body** with HTTP 200 rather than an empty JSON array (`[]`).
+Per JSON-RPC 2.0, **notifications** — requests that fully omit the `id` member — do not produce a response entry, including within a batch. A request that includes `"id": null` is **not** a notification: `null` is a valid id, so the request receives a response like any other id. Only requests with no `id` member at all are treated as notifications and omitted from the batch response. As a result, the merged response array is **not** 1:1 with the request batch when notifications are present — it is ordered like the batch minus the notification slots. If a batch would produce no response objects at all (for example, an all-notification batch, or an empty result), the gateway returns an **empty HTTP body** with HTTP 200 rather than an empty JSON array (`[]`).
### Legacy API Configuration
From 1984198066c66bed1af7b958c7b835f963f81ae1 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 04:59:58 +0000
Subject: [PATCH 24/63] docs: A new consensus config field
`stateless-leader-election` was added to sei-tendermint as a temporary
disaster-recovery mechanism for chain stalls, requiring validator majority
coordination to enable. (sei-protocol/sei-chain#3305)
---
node/technical-reference.mdx | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index c1e2e35..2cd562c 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -206,6 +206,12 @@ double_sign_check_height = 0
+
+
+
+ The `[consensus]` section also supports `stateless-leader-election` (default `false`). This is a **temporary disaster recovery mechanism** intended for use only when the chain stalls, and enabling it requires coordination among a majority of validators. Setting `stateless-leader-election = true` on a single node in isolation will prevent that node from participating in consensus. Do not enable it unless a majority of validators are coordinating to do so together.
+
+
## Network Parameters
Understanding network parameters helps you operate your node effectively.
From 75aa90be9e630870c015033f9fec839d895b59a2 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:00:22 +0000
Subject: [PATCH 25/63] docs: The consensus config field
'stateless-leader-election' now defaults to true, and the coordination
semantics are inverted so validators must coordinate to set it to false.
(sei-protocol/sei-chain#3318)
---
node/technical-reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 2cd562c..3bafca4 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -209,7 +209,7 @@ double_sign_check_height = 0
- The `[consensus]` section also supports `stateless-leader-election` (default `false`). This is a **temporary disaster recovery mechanism** intended for use only when the chain stalls, and enabling it requires coordination among a majority of validators. Setting `stateless-leader-election = true` on a single node in isolation will prevent that node from participating in consensus. Do not enable it unless a majority of validators are coordinating to do so together.
+ The `[consensus]` section also supports `stateless-leader-election` (default `true`). This is a **temporary disaster recovery mechanism** intended for use only when the chain stalls, and disabling it requires coordination among a majority of validators. Setting `stateless-leader-election = false` on a single node in isolation will prevent that node from participating in consensus. Do not disable it unless a majority of validators are coordinating to do so together.
## Network Parameters
From 0285c17168e76400cef5f54a6e20cd7152fd1894 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:01:01 +0000
Subject: [PATCH 26/63] docs: Adds a new seidb `dump-flatkv` CLI command and a
`--flatkv-dir` flag to the `state-size` command for analyzing FlatKV stores.
(sei-protocol/sei-chain#3312)
---
node/troubleshooting.mdx | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx
index f8f3c22..57c40dd 100644
--- a/node/troubleshooting.mdx
+++ b/node/troubleshooting.mdx
@@ -100,6 +100,29 @@ systemctl restart seid
```
+On Giga Storage nodes, EVM state lives in a FlatKV store rather than in the memIAVL trees, so an AppHash comparison there requires dumping the FlatKV state as well. Use the `dump-flatkv` command to iterate and dump the physical `(key, value)` pairs into per-bucket files (formatted to match `dump-iavl` so the same diff tooling works on both):
+
+```bash
+# For FlatKV (Giga Storage nodes hold EVM state in FlatKV):
+systemctl stop seid
+seidb dump-flatkv --db-dir $HOME/.sei/data/flatkv --output-dir /home/ubuntu/flatkv-dump
+systemctl restart seid
+```
+
+The `dump-flatkv` command accepts the following flags:
+
+- `--db-dir` / `-d`: FlatKV database directory.
+- `--output-dir` / `-o`: output directory; one file is written per bucket.
+- `--height`: FlatKV target version; `0` (the default) selects the latest available version.
+- `--bucket` / `-b`: restrict the dump to a single bucket (`account`, `code`, `storage`, or `legacy`). Defaults to all buckets.
+
+For example, to dump only the `storage` bucket at a specific version:
+
+```bash
+seidb dump-flatkv --db-dir $HOME/.sei/data/flatkv --output-dir /home/ubuntu/flatkv-dump --height 12345678 --bucket storage
+```
+
+
**The legacy IAVL backend has been fully removed and SeiDB State Commit (SC) is now mandatory.** SC must be enabled via `sc-enable = true` in the `[state-commit]` section of `app.toml`. If SC is not enabled, the node no longer falls back to IAVL — it panics at startup with:
From adb14769064203aa593c29b22e8004d3da3c9991 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:02:12 +0000
Subject: [PATCH 27/63] docs: The `stateless-leader-election` consensus config
field is now deprecated and ignored; stateless leader election is always
enabled regardless of the value set. (sei-protocol/sei-chain#3319)
---
node/technical-reference.mdx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 3bafca4..46391c0 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -208,9 +208,9 @@ double_sign_check_height = 0
-
- The `[consensus]` section also supports `stateless-leader-election` (default `true`). This is a **temporary disaster recovery mechanism** intended for use only when the chain stalls, and disabling it requires coordination among a majority of validators. Setting `stateless-leader-election = false` on a single node in isolation will prevent that node from participating in consensus. Do not disable it unless a majority of validators are coordinating to do so together.
-
+
+ The `[consensus]` section may still parse a `stateless-leader-election` field, but it is **deprecated and ignored**. Stateless (seed-based) leader election is now always enabled regardless of the value set, so this field no longer has any effect. It is retained only for config-parsing compatibility and can be safely omitted.
+
## Network Parameters
From da055e06eaf19fb2ac5da376d04f09d11eb542b7 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:02:56 +0000
Subject: [PATCH 28/63] docs: The eth_feeHistory JSON-RPC endpoint now returns
baseFeePerGas with one extra element (the projected child base fee for the
block after the newest block), matching go-ethereum/execution-apis semantics.
(sei-protocol/sei-chain#3321)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index a5a820d..30ab695 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -724,7 +724,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns base fees, gas-used ratios, and reward percentile data over a range of blocks.
-**Sei-specific behavior:** Base fees and rewards reflect Sei's x/evm fee market (GetNextBaseFee), not an Ethereum EIP-1559 mempool, and Sei does not burn the base fee. Watermark-aware: pruned/historical blocks may not be available as far back as on Ethereum archive nodes.
+**Sei-specific behavior:** Base fees and rewards reflect Sei's x/evm fee market (GetNextBaseFee), not an Ethereum EIP-1559 mempool, and Sei does not burn the base fee. Watermark-aware: pruned/historical blocks may not be available as far back as on Ethereum archive nodes. Matching go-ethereum/execution-apis semantics, `baseFeePerGas` contains one more element than `gasUsedRatio` (`len(baseFeePerGas) == len(gasUsedRatio) + 1`): the trailing element is the projected base fee for the child of the newest block in the range. Each block's base fee uses header base fee semantics (the same value reported in the block header — `GetNextBaseFee` at the parent's committed height) with a `DefaultMinFeePerGas` fallback for early blocks. Note that when some heights in the range have pruned/partial base-fee data, `baseFeePerGas` may still be shorter than `gasUsedRatio + 1` for those rows.
**Parameters:**
From a82a527a40dcc1213668040fae672885ced7c3a2 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:05:12 +0000
Subject: [PATCH 29/63] docs: Under Autobahn consensus, the Tendermint RPC
endpoints /block, /block_by_hash, /block_results, and /validators now serve
data via the GigaRouter's in-memory state instead of returning empty/failing
responses when the CometBFT BlockStore/StateStore is unpopulated.
(sei-protocol/sei-chain#3310)
---
evm/reference.mdx | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 30ab695..1f74090 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -84,6 +84,25 @@ Under Autobahn (`AutobahnConfigFile` set) the CometBFT block store is not popula
+
+### Tendermint block and validator endpoints under Autobahn
+
+Under Autobahn (`AutobahnConfigFile` set) the CometBFT `BlockStore` and `StateStore` are not populated. Rather than returning empty or failing responses, the `/block`, `/block_by_hash`, `/block_results`, and `/validators` Tendermint RPC endpoints route through the GigaRouter's in-memory state (the finalized global blocks retained by the Autobahn data layer). This keeps downstream consumers — including evmrpc, block explorers, and monitoring tooling — working without individually branching on the consensus engine.
+
+Responses are served only for heights still inside Autobahn's retained window (heights pruned per `RetainHeight` are no longer available). Requests are validated against the current ABCI head, so out-of-range heights return the same `ErrHeightNotAvailable`/`ErrHeightExceedsChainHead`-class errors as the CometBFT path.
+
+| Endpoint | Autobahn behavior |
+| :- | :- |
+| `/block` | Returns the fully-populated translated block at the requested height: `BlockID.Hash` (the Autobahn header hash), the header (`ChainID`, `Height`, `Time`), and `Data.Txs`. Other header fields (`AppHash`, `ProposerAddress`, `LastCommit`, …) stay at zero values. |
+| `/block_by_hash` | Resolves the block by its Autobahn header hash via an in-memory hash index. An unknown or wrong-size hash returns `{Block: nil}` with no error, matching CometBFT semantics for a missing block. |
+| `/block_results` | Returns a valid-but-empty `ResultBlockResults` at the requested height. `ConsensusParamUpdates.Block.MaxGas` is populated from the producer config; `TxsResults` (per-tx `ExecTxResult` details) is intentionally empty because `FinalizeBlock` responses are not persisted under Autobahn. Populating these is a separate follow-up. |
+| `/validators` | Returns the genesis committee at any retained height — the committee is fixed at genesis under Autobahn (no validator-updates path). `block_height` matches the requested height, and pagination (`page`/`per_page`) behaves the same as the CometBFT path. |
+
+
+Because `FinalizeBlock` responses are not stored on disk under Autobahn, `/block_results` cannot surface per-transaction execution results (`TxsResults` is empty). For per-transaction EVM data, use the EVM JSON-RPC methods (`eth_getTransactionReceipt`, `eth_getBlockReceipts`) instead.
+
+
+
### Filter and subscription limits
From 369cb7ca4c66c8f47181c7a410645e49ce4f0c99 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 05:08:21 +0000
Subject: [PATCH 30/63] docs: The mempool Update recheck flag was changed to
false in the GigaRouter block execution path to prevent valid out-of-order
EVM nonce transactions from being evicted and stalling throughput to one tx
per block per sender. (sei-protocol/sei-chain#3372)
---
node/technical-reference.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 46391c0..28abc5b 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -70,6 +70,8 @@ When a node is started in Giga mode — that is, when `autobahn-config-file` is
- **Consensus reactor, state sync, and block sync are disabled.** In Giga mode these reactors are skipped entirely, and both state sync and block sync are forced off regardless of other configuration.
- **The Autobahn block producer sources transactions directly from the mempool.** Instead of relying on a separate transaction channel, the producer reaps transactions straight from the local mempool when building each block payload.
+- **Mempool `Update` runs with recheck disabled after each block.** When the Autobahn block producer executes a block, it updates the mempool with rechecking turned off. Re-running `CheckTx` on every remaining transaction after each block would cause the EVM antehandler to mark any still-ahead-of-nonce transaction as pending, which in turn evicts these perfectly valid queued transactions. With recheck disabled, valid out-of-order EVM nonce transactions from a sender remain in the priority index and can all be mined in subsequent blocks. Leaving recheck enabled would stall throughput to roughly one transaction per block per sender when a sender submits many sequential nonces out of order. This also matches CometBFT's default of `false` for `ConsensusParams.ABCI.RecheckTx`, since state-dependent invalidation is already caught during proposal processing and block execution.
+
Each Autobahn block payload is subject to fixed per-block limits enforced by the block producer:
- **Maximum transactions per block:** 2,000 transactions.
From af4dff9470f11dc988f476980ef7d982659ebf05 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:01:45 +0000
Subject: [PATCH 31/63] docs: The EVM RPC layer adds new OpenTelemetry metrics
(evmrpc_request_latency_seconds histogram and evmrpc_websocket_connects_total
counter) alongside legacy Prometheus metrics, which node operators monitoring
dashboards should know about. (sei-protocol/sei-chain#3265)
---
node/advanced-config-monitoring.mdx | 35 +++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index 4fc13d9..b030eb0 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -504,6 +504,41 @@ scrape_configs:
- targets: ['localhost:9100']
```
+
+
+## EVM RPC OpenTelemetry Metrics
+
+The EVM RPC layer emits OpenTelemetry metrics through the process-wide `MeterProvider` (for example, a Prometheus exporter). These are emitted in parallel with the legacy `sei_*` metrics so you can migrate dashboards incrementally.
+
+### Available Metrics
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `evmrpc_request_latency_seconds` | Histogram | EVM RPC request latency in seconds. |
+| `evmrpc_websocket_connects_total` | Counter | Number of new websocket connections. |
+
+The `evmrpc_request_latency_seconds` histogram carries the following labels:
+
+| Label | Description |
+| --- | --- |
+| `endpoint` | The RPC method being served (for example, `eth_getBalance`). |
+| `connection` | The connection type serving the request (for example, `http` or `websocket`). |
+| `success` | Boolean indicating whether the request succeeded. |
+| `error_class` | A low-cardinality classification of the failure. An empty string denotes success. Possible values include `panic`, `execution_reverted`, `evm_not_supported`, `sei_legacy_disabled`, `association_missing`, `jsonrpc_error`, and `unknown`. |
+| `jsonrpc_code` | A low-cardinality bucket for the JSON-RPC error code: `spec` (predefined range `-32700..-32600`), `server` (server-defined range `-32099..-32000`), or `other`. An empty string denotes no code (success or an untyped error). |
+
+### Migrating from Legacy Metrics
+
+The following legacy `sei_*` metrics remain available today but are deprecated and scheduled for removal once dashboards migrate to the `evmrpc_*` OpenTelemetry metrics:
+
+| Legacy metric | Replacement |
+| --- | --- |
+| `sei_rpc_request_latency_ms` | `evmrpc_request_latency_seconds` |
+| `sei_websocket_connect` | `evmrpc_websocket_connects_total` |
+| `sei_rpc_request` | `evmrpc_request_latency_seconds` (use the histogram count with the `success` and `error_class` labels) |
+
+Update your Prometheus and Grafana dashboards to consume the `evmrpc_*` metrics before the legacy metrics are removed. Note that latency changed units from milliseconds (`sei_rpc_request_latency_ms`) to seconds (`evmrpc_request_latency_seconds`), so adjust any thresholds and panel formatting accordingly.
+
## Performance Testing
From 10ab0cd385743842bfb248f58d0fb3741ab1c13f Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:03:10 +0000
Subject: [PATCH 32/63] docs: Adds OpenTelemetry metrics instrumentation across
the FlatKV state store and introduces an EnablePebbleMetrics config knob that
overrides per-DB EnableMetrics settings. (sei-protocol/sei-chain#3366)
---
node/advanced-config-monitoring.mdx | 44 +++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index b030eb0..9c33416 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -539,6 +539,50 @@ The following legacy `sei_*` metrics remain available today but are deprecated a
Update your Prometheus and Grafana dashboards to consume the `evmrpc_*` metrics before the legacy metrics are removed. Note that latency changed units from milliseconds (`sei_rpc_request_latency_ms`) to seconds (`evmrpc_request_latency_seconds`), so adjust any thresholds and panel formatting accordingly.
+
+
+## FlatKV OpenTelemetry Metrics
+
+The FlatKV state store emits OpenTelemetry metrics through the process-wide `MeterProvider` (for example, a Prometheus exporter). These metrics let node operators observe commit throughput, catchup progress, snapshotting, rollbacks, and snapshot imports.
+
+### Available Metrics
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `flatkv_open_latency` | Histogram | Time taken to open the FlatKV store (seconds). |
+| `flatkv_apply_changesets_latency` | Histogram | Time taken to apply changesets to FlatKV (seconds). |
+| `flatkv_commit_latency` | Histogram | Time taken to commit FlatKV changes (seconds). |
+| `flatkv_commit_batch_latency` | Histogram | Time taken to commit a FlatKV data DB batch (seconds). |
+| `flatkv_batch_read_old_values_latency` | Histogram | Time taken to batch read old FlatKV values (seconds). |
+| `flatkv_num_kv_pairs` | Counter | Number of key-value pairs applied to FlatKV. |
+| `flatkv_pending_writes` | Gauge | Current number of pending FlatKV writes. |
+| `flatkv_current_version` | Gauge | Current committed FlatKV version. |
+| `flatkv_catchup_latency` | Histogram | Time taken to replay FlatKV WAL entries (seconds). |
+| `flatkv_catchup_replay_num_blocks` | Counter | Number of FlatKV WAL entries replayed during catchup. |
+| `flatkv_snapshot_write_latency` | Histogram | Time taken to write a FlatKV snapshot (seconds). |
+| `flatkv_snapshot_prune_latency` | Histogram | Time taken to prune FlatKV snapshots (seconds). |
+| `flatkv_snapshot_prune_attempts` | Counter | Total number of FlatKV snapshot prune attempts. |
+| `flatkv_current_snapshot_height` | Gauge | Current FlatKV snapshot height. |
+| `flatkv_rollback_latency` | Histogram | Time taken to rollback FlatKV state (seconds). |
+| `flatkv_import_latency` | Histogram | Time taken to import FlatKV snapshot data (seconds). |
+| `flatkv_import_kv_pairs` | Counter | Number of key-value pairs imported into FlatKV. |
+| `flatkv_import_worker_flush_latency` | Histogram | Time taken to flush a FlatKV import worker batch (seconds). |
+| `flatkv_flush_latency` | Histogram | Time taken to flush a FlatKV data DB (seconds). |
+
+### Labels
+
+FlatKV metrics carry the following labels where applicable:
+
+| Label | Description |
+| --- | --- |
+| `db` | The data DB the measurement applies to (for example, `accountDB`, `storageDB`, `codeDB`, or `legacyDB`). Present on per-DB metrics such as `flatkv_commit_batch_latency`, `flatkv_flush_latency`, `flatkv_num_kv_pairs`, `flatkv_pending_writes`, `flatkv_import_kv_pairs`, and `flatkv_import_worker_flush_latency`. |
+| `success` | Boolean indicating whether the operation succeeded. Present on latency and attempt metrics that can fail. |
+| `read_only` | Boolean present on `flatkv_open_latency` indicating whether the store was opened read-only. |
+
+### Enabling Pebble Internal Metrics
+
+Pebble's internal (per-DB) metrics are governed by a single FlatKV-level knob, `EnablePebbleMetrics`. When set, this value is propagated to every data DB (account, code, storage, legacy, and metadata) during initialization and overrides any per-DB `EnableMetrics` settings, so configure Pebble metrics through `EnablePebbleMetrics` rather than the individual per-DB knobs.
+
## Performance Testing
From 98e64d2f209a57d5d5ff287daa1be0fcb6c27ef8 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:03:42 +0000
Subject: [PATCH 33/63] docs: Giga executor now writes a status=0 receipt for
EVM transactions that fail during state transition (e.g. EIP-7623
floor-data-gas check), so eth_getTransactionReceipt returns a receipt instead
of null for nonce-bumping failed txs. (sei-protocol/sei-chain#3383)
---
evm/reference.mdx | 2 +-
evm/transactions.mdx | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 1f74090..0b8c659 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -264,7 +264,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns the receipt of a transaction by hash, or null if not found.
-**Sei-specific behavior:** Receipt is reconstructed from keeper.GetReceipt + CometBFT block data rather than from a native MPT receipt trie; status/logs are standard Ethereum format.
+**Sei-specific behavior:** Receipt is reconstructed from keeper.GetReceipt + CometBFT block data rather than from a native MPT receipt trie; status/logs are standard Ethereum format. An EVM transaction that bumps the sender's nonce but then fails during state transition — for example an EIP-7623 floor-data-gas shortfall (post-Pectra), which fails inside go-ethereum's `Execute()` before any opcode runs — now returns a `status=0` failed-tx receipt (with `gasUsed` equal to the tx's `gasLimit` and a populated `VmError` reason) under the Giga executor, rather than returning null indefinitely and hanging clients that poll for it.
**Parameters:**
diff --git a/evm/transactions.mdx b/evm/transactions.mdx
index 39d321f..7368ac9 100644
--- a/evm/transactions.mdx
+++ b/evm/transactions.mdx
@@ -310,6 +310,18 @@ EVM transactions must not carry any Cosmos SDK wrapper fields. A transaction is
Additionally, the transaction decoder now rejects "bloated" transaction bodies whose raw wire encoding is larger than the canonical re-marshaled form (for example, padded fields or oversized `Any.Value` entries). Non-canonical encodings that previously decoded successfully will now fail with a decode error, so tooling should always emit canonical protobuf encodings.
+### Receipts for nonce-bumping failed transactions
+
+Some EVM transactions pass basic validation and bump the sender's nonce, yet still fail during state transition — for example, a transaction whose gas limit clears the intrinsic-gas check but falls short of the EIP-7623 floor-data-gas requirement (which can occur in normal operation after Pectra). Because these transactions bump the nonce, they are considered to have happened and therefore produce a receipt.
+
+For such failures, Sei writes a `status=0` (failed) receipt with `gasUsed` equal to the transaction's gas limit and a `VmError` describing the state-transition reason. `eth_getTransactionReceipt` returns this failed-tx receipt instead of `null`.
+
+
+ Previously, a nonce-bumping transaction that failed during state transition could return `null` from `eth_getTransactionReceipt` indefinitely, causing clients that poll for a receipt to hang. Clients should now expect a `status=0` receipt for these transactions and treat it as a normal failed-transaction result.
+
+
+
+
## Additional Resources
From 196e0092e33efb82f135118335a689f32e5da154 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:04:11 +0000
Subject: [PATCH 34/63] docs: Introduces a new `mock_block_validation` Go build
tag that bypasses AppHash and DataHash block validation, producing a separate
`seid` Docker image tagged `mock_block_validation-*` for testing
environments. (sei-protocol/sei-chain#3401)
---
node/index.mdx | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/node/index.mdx b/node/index.mdx
index dd84036..10b1307 100644
--- a/node/index.mdx
+++ b/node/index.mdx
@@ -171,6 +171,17 @@ See the Network Versions table above for the current recommended version.
```
Available architectures: linux/amd64 and linux/arm64.
+
+
+
+
+ Some builds are published as testing-only image variants and must **never** be used in production. These are compiled with special Go build tags:
+
+ - `mock_balances-*` — mocks account balances.
+ - `mock_block_validation-*` — bypasses `AppHash` and `DataHash` block validation.
+
+ Production images are built with full validation enabled. The `mock_block_validation` variant is intended solely for testing environments where skipping block validation checks is required; running it on a production network is unsafe.
+
From 745845455c0497ef4c21434cef817fb210d5643f Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:05:44 +0000
Subject: [PATCH 35/63] docs: Adds a new opt-in trace-baking feature
configurable via new [evm] app.toml fields that pre-computes and caches
debug_trace* results for RPC nodes. (sei-protocol/sei-chain#3359)
---
evm/tracing/index.mdx | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/evm/tracing/index.mdx b/evm/tracing/index.mdx
index c12eb2b..f4dec49 100644
--- a/evm/tracing/index.mdx
+++ b/evm/tracing/index.mdx
@@ -409,6 +409,42 @@ debug_traceStateAccess(hash)
- **`opcodeTracer`**: Opcode-level execution
- **Custom JS**: Custom analysis logic
+
+
+## Pre-Baked Trace Cache
+
+RPC nodes can optionally pre-compute and cache `debug_trace*` results in the background so that trace requests are served from a local on-disk cache instead of re-executing the block live on every call. This is an opt-in feature configured through new `[evm]` fields in `app.toml` and is recommended for RPC nodes only.
+
+When enabled, a background worker re-executes each committed block with the configured tracers and stores the results in a Pebble database at `/data/trace_db`. The following methods serve from this cache on hit, and otherwise fall through to live re-execution:
+
+- `debug_traceTransaction`
+- `debug_traceBlockByNumber` and `debug_traceBlockByHash`
+- The `*ExcludeTraceFail` variants of the block-trace methods
+
+### When the cache is used
+
+A request is only served from cache when trace baking is enabled **and** the request uses a *bakeable* tracer configuration:
+
+- The tracer is one of `callTracer`, `prestateTracer`, or `flatCallTracer`.
+- No custom `tracerConfig` is supplied. A per-call `tracerConfig` (for example `{"withLog": true}`) is not part of the cache key, so any custom tracer config makes the request un-bakeable and it falls through to live re-execution.
+
+Requests that use the struct logger (no tracer), a JavaScript tracer, or any other named tracer are always executed live.
+
+### Configuration
+
+Trace baking is controlled by these `[evm]` fields in `app.toml`:
+
+| Field | Default | Description |
+| ----- | ------- | ----------- |
+| `trace_bake_enabled` | `false` | Enables the background trace-baking worker that caches results at `/data/trace_db`. RPC nodes only. |
+| `trace_bake_workers` | `1` | Number of re-execution worker goroutines. |
+| `trace_bake_queue_size` | `4096` | Bounds the in-flight height queue. Heights are dropped when the queue is full so consensus never blocks; dropped blocks fall through to live re-execution. |
+| `trace_bake_tracers` | `["callTracer"]` | Which tracers to bake per block. Eligible values: `callTracer`, `prestateTracer`, `flatCallTracer`. |
+| `trace_bake_window_blocks` | `0` | Rolling prune window: blocks older than `(latest - window)` are pruned. `0` disables pruning, so the cache grows forever. |
+
+Enabling trace baking adds a persistent on-disk store at `/data/trace_db` and increases disk usage. The store's write-ahead log is flushed when the node shuts down cleanly.
+
+
## Next Steps
1. **[JavaScript Tracers](/evm/tracing/javascript-tracers)** - Custom analysis scripts
From f35be2cc85c486d232a1c42da049ba5383df54d1 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:09:13 +0000
Subject: [PATCH 36/63] docs: Adds a new `seidb import-flatkv-from-memiavl` CLI
command (plus `memiavl-latest-version`) and a new `dump-flatkv --bucket`
option for migrating/importing EVM state from memiavl into FlatKV, along with
the KVImporter Abort/Err lifecycle used by that tool.
(sei-protocol/sei-chain#3417)
---
node/troubleshooting.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx
index 57c40dd..e311d42 100644
--- a/node/troubleshooting.mdx
+++ b/node/troubleshooting.mdx
@@ -105,7 +105,7 @@ On Giga Storage nodes, EVM state lives in a FlatKV store rather than in the memI
```bash
# For FlatKV (Giga Storage nodes hold EVM state in FlatKV):
systemctl stop seid
-seidb dump-flatkv --db-dir $HOME/.sei/data/flatkv --output-dir /home/ubuntu/flatkv-dump
+seidb dump-flatkv --db-dir $HOME/.sei/data/state_commit/flatkv --output-dir /home/ubuntu/flatkv-dump
systemctl restart seid
```
From dfad6c143cb5f6d835296db66d8f44cf6cf180b0 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:11:58 +0000
Subject: [PATCH 37/63] docs: Out-of-process ABCI support was removed
(deprecating the --proxy-app/--abci/--address/--transport flags and
proxy-app/abci config fields), the EVM mempool nonce/pending logic was
reworked, and eth_getTransactionCount pending nonce is now served via a new
mempool endpoint. (sei-protocol/sei-chain#3410)
---
node/node-operators.mdx | 6 ++++++
node/technical-reference.mdx | 8 ++++++++
2 files changed, 14 insertions(+)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index ab7ead0..7cbbdc1 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -825,6 +825,12 @@ genesis-file = "config/genesis.json"
# Path to the JSON file containing the private key to use for node authentication in the p2p protocol
node-key-file = "config/node_key.json"
+# NOTE: Out-of-process ABCI support has been removed. The full node now runs
+# only with Tendermint in-process, so the legacy `proxy-app` and `abci` base
+# config fields no longer appear in the generated template and have no effect.
+# When upgrading, remove any `proxy-app` and `abci` lines from your existing
+# config.toml.
+
#######################################################################
### Advanced Configuration Options ###
#######################################################################
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 28abc5b..d5e8329 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -214,6 +214,14 @@ double_sign_check_height = 0
The `[consensus]` section may still parse a `stateless-leader-election` field, but it is **deprecated and ignored**. Stateless (seed-based) leader election is now always enabled regardless of the value set, so this field no longer has any effect. It is retained only for config-parsing compatibility and can be safely omitted.
+
+ Out-of-process ABCI support has been removed. The full node now runs only with Tendermint in-process; external stand-alone ABCI processes (socket or gRPC) are no longer supported. As a result:
+
+ - The `seid start` flags `--address` and `--transport` are **deprecated and ignored**.
+ - The Tendermint node flags `--proxy-app` and `--abci` are **deprecated and ignored**.
+ - The `proxy-app` and `abci` fields in `config.toml` have been removed and no longer have any effect. Node operators upgrading should delete these lines from their `config.toml` if present.
+
+
## Network Parameters
Understanding network parameters helps you operate your node effectively.
From 0d327ace3fdbfdced438679d0a42d24739a6de87 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:13:58 +0000
Subject: [PATCH 38/63] docs: The sei_getTransactionReceiptExcludeTraceFail and
*ExcludeTraceFail trace endpoints changed their filtering logic so that
reverted/OOG transactions (which ran in the VM and produce traces) are now
included, while only ante-rejected and synthetic txs are excluded.
(sei-protocol/sei-chain#3450)
---
evm/reference.mdx | 1 +
evm/tracing/index.mdx | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 0b8c659..2ece66d 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1368,6 +1368,7 @@ To enable additional legacy methods, add them to this array. All other `sei_*` a
| `sei_getTransactionByHash` | Get transaction by hash (includes synthetic txs) |
| `sei_getTransactionCount` | Get account transaction count |
| `sei_getTransactionReceipt` | Get transaction receipt (includes synthetic txs) |
+| `sei_getTransactionReceiptExcludeTraceFail` | Get transaction receipt, excluding only txs that never executed. Ante-rejected txs (rejected before reaching the VM, identified by `EffectiveGasPrice=0`) and chain-generated synthetic txs (`ShellEVMTxType`) are filtered out; reverted and out-of-gas transactions are now included, because they ran in the VM and produce real traces. (Previously any receipt with `status=0` was excluded, which over-filtered reverts and OOG failures.) The `*ExcludeTraceFail` trace variants (e.g. `debug_traceBlockByHash`/`debug_traceBlockByNumber` exclude-trace-fail forms) apply the same filtering. |
| `sei_getFilterLogs` | Get filter logs (includes synthetic logs) |
| `sei_getLogs` | Get logs (includes synthetic logs) |
| `sei_getFilterChanges` | Get filter changes (includes synthetic events) |
diff --git a/evm/tracing/index.mdx b/evm/tracing/index.mdx
index f4dec49..53ccba2 100644
--- a/evm/tracing/index.mdx
+++ b/evm/tracing/index.mdx
@@ -421,6 +421,17 @@ When enabled, a background worker re-executes each committed block with the conf
- `debug_traceBlockByNumber` and `debug_traceBlockByHash`
- The `*ExcludeTraceFail` variants of the block-trace methods
+### `*ExcludeTraceFail` filtering semantics
+
+The `*ExcludeTraceFail` endpoints (for example `sei_getTransactionReceiptExcludeTraceFail` and the `ExcludeTraceFail` block-trace variants) filter out transactions whose trace would be empty or meaningless — specifically, transactions that were included in a block but never actually executed in the VM. Two classes are excluded:
+
+- **Ante-rejected transactions**: txs rejected before reaching the VM (for example nonce mismatch or insufficient funds). These are identified from the receipt store — an ante-deferred receipt carries `EffectiveGasPrice = 0`.
+- **Chain-generated synthetic transactions**: txs with the internal `ShellEVMTxType`, which have no real EVM execution.
+
+Everything that ran in the VM is **included**, even if it failed. Reverted and out-of-gas (OOG) transactions have `Status == 0` but `EffectiveGasPrice > 0` and produce a real trace (the `REVERT` or OOG condition simply appears inside that trace), so they are returned rather than filtered out.
+
+Earlier behavior excluded any receipt with `Status == 0`, which over-filtered reverts and OOG failures that actually produced traces. The current logic excludes only ante-error and synthetic txs.
+
### When the cache is used
A request is only served from cache when trace baking is enabled **and** the request uses a *bakeable* tracer configuration:
From 3509e2f81ac74baf283d95bac1ed63c4000e309c Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:15:30 +0000
Subject: [PATCH 39/63] docs: The sei_getBlockBy*ExcludeTraceFail and
sei_traceBlockBy*ExcludeTraceFail endpoints now use a broader discriminator
so they drop ante-deferred stub transactions (e.g. insufficient-funds/fee
failures with EffectiveGasPrice==0 && GasUsed==0), whereas regular
eth_getBlockBy* responses still include them. (sei-protocol/sei-chain#3459)
---
evm/reference.mdx | 2 ++
evm/tracing/index.mdx | 6 +++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 2ece66d..1a9a1e3 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1359,7 +1359,9 @@ To enable additional legacy methods, add them to this array. All other `sei_*` a
| `sei_getTransactionErrorByHash` | Get error message for a failed transaction |
| `sei_getVMError` | Get VM error details for a transaction |
| `sei_getBlockByHash` | Get block by hash (includes synthetic txs) |
+| `sei_getBlockByHashExcludeTraceFail` | Get block by hash, excluding untraceable txs — synthetic txs **and** ante-deferred stub transactions (correct-nonce ante failures such as insufficient funds/fee, whose stub receipts carry `EffectiveGasPrice == 0` and `GasUsed == 0`). Note this differs from the regular `eth_getBlockByHash`, which still includes these ante-failure stubs. |
| `sei_getBlockByNumber` | Get block by number (includes synthetic txs) |
+| `sei_getBlockByNumberExcludeTraceFail` | Get block by number, excluding untraceable txs — synthetic txs **and** ante-deferred stub transactions (correct-nonce ante failures such as insufficient funds/fee, whose stub receipts carry `EffectiveGasPrice == 0` and `GasUsed == 0`). Note this differs from the regular `eth_getBlockByNumber`, which still includes these ante-failure stubs. |
| `sei_getBlockReceipts` | Get block receipts (includes synthetic txs) |
| `sei_getBlockTransactionCountByHash` | Get tx count by block hash (includes synthetic txs) |
| `sei_getBlockTransactionCountByNumber` | Get tx count by block number (includes synthetic txs) |
diff --git a/evm/tracing/index.mdx b/evm/tracing/index.mdx
index 53ccba2..09c89c7 100644
--- a/evm/tracing/index.mdx
+++ b/evm/tracing/index.mdx
@@ -425,12 +425,12 @@ When enabled, a background worker re-executes each committed block with the conf
The `*ExcludeTraceFail` endpoints (for example `sei_getTransactionReceiptExcludeTraceFail` and the `ExcludeTraceFail` block-trace variants) filter out transactions whose trace would be empty or meaningless — specifically, transactions that were included in a block but never actually executed in the VM. Two classes are excluded:
-- **Ante-rejected transactions**: txs rejected before reaching the VM (for example nonce mismatch or insufficient funds). These are identified from the receipt store — an ante-deferred receipt carries `EffectiveGasPrice = 0`.
+- **Ante-deferred stub transactions**: txs that passed the nonce check but failed a later ante step (for example insufficient funds or insufficient fee) and so never reached the VM. The chain writes a stub receipt for these, identified by `EffectiveGasPrice == 0 && GasUsed == 0` (both fields unset because the tx never executed).
- **Chain-generated synthetic transactions**: txs with the internal `ShellEVMTxType`, which have no real EVM execution.
-Everything that ran in the VM is **included**, even if it failed. Reverted and out-of-gas (OOG) transactions have `Status == 0` but `EffectiveGasPrice > 0` and produce a real trace (the `REVERT` or OOG condition simply appears inside that trace), so they are returned rather than filtered out.
+Everything that ran in the VM is **included**, even if it failed. Reverted and out-of-gas (OOG) transactions have `Status == 0` but `EffectiveGasPrice > 0` and `GasUsed > 0`, and produce a real trace (the `REVERT` or OOG condition simply appears inside that trace), so they are returned rather than filtered out.
-Earlier behavior excluded any receipt with `Status == 0`, which over-filtered reverts and OOG failures that actually produced traces. The current logic excludes only ante-error and synthetic txs.
+This filter applies to both the block endpoints (`sei_getBlockByNumberExcludeTraceFail` and `sei_getBlockByHashExcludeTraceFail`) and the block-trace endpoints (`sei_traceBlockByNumberExcludeTraceFail` and `sei_traceBlockByHashExcludeTraceFail`): both now drop these ante-deferred stub transactions. The regular `eth_getBlockBy*` endpoints continue to **include** them, so a tx that appears in a normal block response may be absent from the `*ExcludeTraceFail` variant. The trace-side filter also catches stubs whose tracer embeds the error in the returned JSON while leaving the trace's `Error` field empty — it checks the underlying receipt shape rather than relying on `Error` alone.
### When the cache is used
From 697ff66526432152f51db943225724904f8de522 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:16:34 +0000
Subject: [PATCH 40/63] docs: Adds EVM RPC transaction proxying/sharding across
autobahn validators, requiring a new evmrpc_url.txt file per node and a new
evmrpc field in the autobahn config, plus a new
evmrpc_redirected_requests_total metric. (sei-protocol/sei-chain#3438)
---
node/advanced-config-monitoring.mdx | 1 +
node/technical-reference.mdx | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index 9c33416..6b382bf 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -516,6 +516,7 @@ The EVM RPC layer emits OpenTelemetry metrics through the process-wide `MeterPro
| --- | --- | --- |
| `evmrpc_request_latency_seconds` | Histogram | EVM RPC request latency in seconds. |
| `evmrpc_websocket_connects_total` | Counter | Number of new websocket connections. |
+| `evmrpc_redirected_requests_total` | Counter | Number of EVM RPC requests forwarded to another validator. Labeled by `endpoint` and `connection`. |
The `evmrpc_request_latency_seconds` histogram carries the following labels:
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index d5e8329..3245fb8 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -40,7 +40,7 @@ seid query node info
### Autobahn (GigaRouter) Config Generation
-When running with the Autobahn (GigaRouter) networking layer, you can generate the Autobahn JSON config from a set of node directories. Each directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, and `autobahn_address.txt`.
+When running with the Autobahn (GigaRouter) networking layer, you can generate the Autobahn JSON config from a set of node directories. Each directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, `autobahn_address.txt`, and `evmrpc_url.txt`.
```bash
# Generate an autobahn JSON config from one or more node directories
From 0cbf64a72923f59eb3e929a9071bcfe66ff34253 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:18:25 +0000
Subject: [PATCH 41/63] docs: The distribution module now validates withdraw
addresses against bank's CanSendTo check, rejecting SetWithdrawAddr for
recipients not allowed to receive external funds and falling back to the
delegator address when a stored withdraw address becomes invalid.
(sei-protocol/sei-chain#3463)
---
evm/precompiles/distribution.mdx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/evm/precompiles/distribution.mdx b/evm/precompiles/distribution.mdx
index 877bd1f..21c209f 100644
--- a/evm/precompiles/distribution.mdx
+++ b/evm/precompiles/distribution.mdx
@@ -164,6 +164,10 @@ bool success = DISTR_CONTRACT.setWithdrawAddress(0x742d35Cc6634C0532925a3b8D4C9d
require(success, "Failed to set withdraw address");
```
+**Recipient Validation**: The withdrawal address must be able to receive external funds. If the target address cannot receive external funds — for example, an unassociated EVM-cast address — the call is rejected with `ErrInvalidRecipient` and fails. Ensure the withdrawal address is associated (or otherwise permitted to receive funds) before setting it.
+
+Additionally, if a previously set withdrawal address later becomes invalid (blocked or no longer able to receive external funds), reward withdrawals automatically fall back to sending rewards to the delegator's own address instead.
+
### withdrawDelegationRewards
Withdraws accumulated rewards from a specific validator.
From dc738d554b3dffaae62b3b1c8ce323b9f2701313 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:19:03 +0000
Subject: [PATCH 42/63] docs: Adds a new --persistent-state-dir flag to the
tendermint gen-autobahn-config command that controls where autobahn consensus
and data WALs are persisted, defaulting to data/autobahn (persistence on)
with an empty value disabling persistence for in-memory-only operation.
(sei-protocol/sei-chain#3483)
---
node/technical-reference.mdx | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 3245fb8..8a0bdc5 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -48,8 +48,16 @@ seid tendermint gen-autobahn-config [node-dirs...] --output
# The --output flag may be abbreviated as -o
seid tendermint gen-autobahn-config ./node0 ./node1 ./node2 -o autobahn.json
+
+# Choose where autobahn consensus and data WALs are persisted (default: data/autobahn)
+seid tendermint gen-autobahn-config ./node0 ./node1 --output autobahn.json --persistent-state-dir data/autobahn
+
+# Pass an empty value to disable persistence and run in-memory only
+seid tendermint gen-autobahn-config ./node0 ./node1 --output autobahn.json --persistent-state-dir=
```
+The `--persistent-state-dir` flag controls where autobahn persists its consensus and data write-ahead logs (WALs) across restarts. It defaults to `data/autobahn`, so persistence is enabled by default without any operator action; the consensus and data layers write to distinct subdirectories under this shared on-disk root. A relative path is resolved against the node's `--home` directory at config load time, while absolute paths are used as-is. Passing an empty value (`--persistent-state-dir=`) disables persistence entirely, running both the consensus and data layers in-memory only. When set, the flag populates the `PersistentStateDir` field in the generated config.
+
The command reads the following files from each node directory:
- `validator_pubkey.txt` — the validator public key in `validator:` format.
From 56fd397a6f76946fc6e61b58fdac7391b133366d Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:20:37 +0000
Subject: [PATCH 43/63] docs: LittDB metrics were migrated from Prometheus
client to the global OTel MeterProvider, removing the MetricsNamespace and
MetricsRegistry config fields and renaming/re-unitting all exported metric
names. (sei-protocol/sei-chain#3466)
---
node/advanced-config-monitoring.mdx | 48 +++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index 6b382bf..2f6158e 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -584,6 +584,54 @@ FlatKV metrics carry the following labels where applicable:
Pebble's internal (per-DB) metrics are governed by a single FlatKV-level knob, `EnablePebbleMetrics`. When set, this value is propagated to every data DB (account, code, storage, legacy, and metadata) during initialization and overrides any per-DB `EnableMetrics` settings, so configure Pebble metrics through `EnablePebbleMetrics` rather than the individual per-DB knobs.
+
+
+## LittDB OpenTelemetry Metrics
+
+LittDB now emits its metrics through the process-wide OpenTelemetry `MeterProvider` instead of a private Prometheus client. When `MetricsEnabled` is set, LittDB configures a Prometheus exporter on the global provider and serves `/metrics` on `MetricsPort` (default `9101`). The previous `MetricsNamespace` and `MetricsRegistry` config fields have been removed; all metric names now use a fixed `litt_` prefix.
+
+### Available Metrics
+
+| Metric | Type | Unit | Description |
+| --- | --- | --- | --- |
+| `litt_table_size_bytes` | Gauge | bytes | The size of individual tables in the database. |
+| `litt_table_key_count` | Gauge | count | The number of keys in individual tables in the database. |
+| `litt_bytes_read` | Counter | bytes | The number of bytes read from disk since startup. |
+| `litt_keys_read` | Counter | count | The number of keys read from disk since startup. |
+| `litt_cache_hits` | Counter | count | The number of cache hits since startup. |
+| `litt_cache_misses` | Counter | count | The number of cache misses since startup. |
+| `litt_read_latency_seconds` | Histogram | seconds | Read latency of the database, including both cache hits and cache misses. |
+| `litt_cache_miss_latency_seconds` | Histogram | seconds | Read latency measured only when a cache miss occurs. |
+| `litt_bytes_written` | Counter | bytes | The number of bytes written to disk since startup (values only, not metadata). |
+| `litt_keys_written` | Counter | count | The number of keys written to disk since startup. |
+| `litt_write_latency_seconds` | Histogram | seconds | Write latency of the database. |
+| `litt_flush_count` | Counter | count | The number of times a flush operation has been performed. |
+| `litt_flush_latency_seconds` | Histogram | seconds | Latency of a flush operation. |
+| `litt_segment_flush_latency_seconds` | Histogram | seconds | Segment flush latency; a subset of the time spent during a flush operation. |
+| `litt_keymap_flush_latency_seconds` | Histogram | seconds | Keymap flush latency; a subset of the time spent during a flush operation. |
+| `litt_garbage_collection_latency_seconds` | Histogram | seconds | Latency of garbage collection operations. |
+| `litt_chunk_cache_key_count` | Gauge | count | The number of keys in the chunk cache. |
+| `litt_chunk_cache_weight_bytes` | Gauge | bytes | The weight of the chunk cache in bytes. |
+| `litt_chunk_cache_keys_added` | Counter | count | The number of keys added to the chunk cache. |
+| `litt_chunk_cache_weight_added_bytes` | Counter | bytes | The weight of the entries added to the chunk cache. |
+| `litt_chunk_cache_eviction_latency_seconds` | Histogram | seconds | Eviction latency of the chunk cache. |
+
+### Attributes
+
+| Attribute | Description |
+| --- | --- |
+| `table` | The table the observation applies to. Present on per-table metrics such as `litt_bytes_read`, `litt_read_latency_seconds`, `litt_table_size_bytes`, and the flush/GC latency histograms. |
+| `cache` | The cache instance the observation applies to (`chunk_read` or `chunk_write`). Present on the `litt_chunk_cache_*` metrics, which distinguish read and write caches by this attribute rather than by separate metric names. |
+
+### Migrating from Legacy Metrics
+
+Metric names, units, and shape changed with the OpenTelemetry migration, so existing Prometheus and Grafana dashboards must be updated:
+
+- Latency metrics moved from millisecond summaries (for example `{namespace}_read_latency_ms`) to second histograms (`litt_read_latency_seconds`). Adjust thresholds and panel formatting from milliseconds to seconds accordingly.
+- Counters and gauges gained a fixed `litt_` prefix and explicit units, for example `bytes_read` became `litt_bytes_read` and the cache weight gauge became `litt_chunk_cache_weight_bytes`.
+- The per-cache series that were previously separate metric names (for example `chunk_read_cache_*` and `chunk_write_cache_*`) are now the shared `litt_chunk_cache_*` metrics distinguished by the `cache` attribute.
+- The `MetricsNamespace` and `MetricsRegistry` config fields no longer exist. Metric names are fixed, and metrics are always backed by the global OTel provider; supply the scrape port via `MetricsPort`.
+
## Performance Testing
From 5de14cb738bf62487397f22b5a259d6eac67863c Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:21:12 +0000
Subject: [PATCH 44/63] docs: ProcessProposal now rejects blocks when any
transaction fails to decode, and nil (decode-failure) transactions cause
block gas checks to reject the proposal rather than being skipped.
(sei-protocol/sei-chain#3464)
---
evm/differences-with-ethereum.mdx | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/evm/differences-with-ethereum.mdx b/evm/differences-with-ethereum.mdx
index a5008b4..5afff91 100644
--- a/evm/differences-with-ethereum.mdx
+++ b/evm/differences-with-ethereum.mdx
@@ -156,6 +156,20 @@ An EVM transaction must not populate any of the Cosmos wrapper fields. If any of
The EVM transaction's own signature (`v`, `r`, `s`) lives inside the EVM payload itself, so none of these Cosmos-level fields are needed. This check is applied uniformly to all EVM transactions.
+
+
+### Whole-block rejection on transaction decode failure
+
+During proposal processing, Sei decodes every transaction in a proposed block. If any transaction fails to decode — or panics during decode — the **entire block proposal is rejected** rather than the offending transaction being silently skipped (treated as nil) while the rest of the block proceeds.
+
+This also affects block gas accounting: a transaction that could not be decoded no longer contributes zero gas and gets skipped; instead its presence causes the block proposal to be rejected outright.
+
+
+
+This is a consensus-level behavior change. Tooling that produces malformed or non-canonical transactions can no longer rely on such transactions being individually dropped from an otherwise-valid block — a single undecodable transaction now invalidates the whole proposal. Ensure your signing and broadcast tooling only submits transactions that decode cleanly.
+
+
+
### Rejection of bloated (non-canonical) transaction bodies
The transaction decoder now rejects "bloated" transaction bodies — those whose raw protobuf wire encoding is larger than the canonical re-marshal of the decoded body. Non-canonical encodings (for example, padded fields or an oversized `Any.Value`) that were previously silently canonicalized and accepted are now rejected on decode with a decode error.
From 3ae29fa7dd15ca50c204b35168999a566002778f Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:21:53 +0000
Subject: [PATCH 45/63] docs: eth_getTransactionReceipt now returns null
(instead of an error) when a transaction's block is above the safe-latest
watermark, aligning with the Ethereum JSON-RPC spec's 'not yet mined' signal.
(sei-protocol/sei-chain#3501)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 1a9a1e3..6d10315 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -264,7 +264,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns the receipt of a transaction by hash, or null if not found.
-**Sei-specific behavior:** Receipt is reconstructed from keeper.GetReceipt + CometBFT block data rather than from a native MPT receipt trie; status/logs are standard Ethereum format. An EVM transaction that bumps the sender's nonce but then fails during state transition — for example an EIP-7623 floor-data-gas shortfall (post-Pectra), which fails inside go-ethereum's `Execute()` before any opcode runs — now returns a `status=0` failed-tx receipt (with `gasUsed` equal to the tx's `gasLimit` and a populated `VmError` reason) under the Giga executor, rather than returning null indefinitely and hanging clients that poll for it.
+**Sei-specific behavior:** Receipt is reconstructed from keeper.GetReceipt + CometBFT block data rather than from a native MPT receipt trie; status/logs are standard Ethereum format. An EVM transaction that bumps the sender's nonce but then fails during state transition — for example an EIP-7623 floor-data-gas shortfall (post-Pectra), which fails inside go-ethereum's `Execute()` before any opcode runs — now returns a `status=0` failed-tx receipt (with `gasUsed` equal to the tx's `gasLimit` and a populated `VmError` reason) under the Giga executor, rather than returning null indefinitely and hanging clients that poll for it. If a receipt exists but its block height is above the safe-latest watermark (for example when Tendermint status momentarily lags the receipt store), the method returns JSON null rather than an error — the Ethereum JSON-RPC 'not yet mined' signal — so clients simply poll again, matching `eth_getBlockByNumber` behavior.
**Parameters:**
From 1b1f2ea00683a7bdc334c401fc5cbb243ce2eb23 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:22:43 +0000
Subject: [PATCH 46/63] docs: The Tendermint mempool was substantially
rewritten, changing TTL config semantics and behavior around expired-tx
pruning, cache handling, and recheck; TTLDuration/TTLNumBlocks now default to
being disabled when zero and RemoveExpiredTxsFromQueue behavior is clarified.
(sei-protocol/sei-chain#3476)
---
node/node-operators.mdx | 24 ++++++++++++++++++------
node/technical-reference.mdx | 6 ++++++
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 7cbbdc1..0c476bf 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -1071,20 +1071,32 @@ max-tx-bytes = 1048576
# XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796
max-batch-bytes = 0
-# ttl-duration, if non-zero, defines the maximum amount of time a transaction
-# can exist for in the mempool.
+# ttl-duration defines the maximum amount of time a transaction can exist in
+# the mempool. A zero value now disables time-based TTL purging entirely
+# (the field is treated as an optional/disabled setting when unset or zero).
#
# Note, if ttl-num-blocks is also defined, a transaction will be removed if it
-# has existed in the mempool at least ttl-num-blocks number of blocks or if it's
+# has existed in the mempool at least ttl-num-blocks number of blocks or if its
# insertion time into the mempool is beyond ttl-duration.
ttl-duration = "5s"
-# ttl-num-blocks, if non-zero, defines the maximum number of blocks a transaction
-# can exist for in the mempool.
+# ttl-num-blocks defines the maximum number of blocks a transaction can exist
+# for in the mempool. A zero value now disables block-based TTL purging entirely
+# (the field is treated as an optional/disabled setting when unset or zero).
#
# Note, if ttl-duration is also defined, a transaction will be removed if it
# has existed in the mempool at least ttl-num-blocks number of blocks or if
-# it's insertion time into the mempool is beyond ttl-duration.
+# its insertion time into the mempool is beyond ttl-duration.
+#
+# Expiration behavior: expired PENDING transactions are always pruned. Expired
+# READY transactions are pruned only when keep-invalid-txs-in-cache-related
+# removal is enabled via the mempool's RemoveExpiredTxsFromQueue setting.
+#
+# NOTE: The Tendermint mempool was substantially rewritten. Transaction
+# admission, ordering, eviction, and gossip are now driven by a unified
+# transaction store with inclusion-ordering, soft/hard size limits, and
+# cache-based deduplication. After upgrading, node operators may observe
+# different mempool ordering, eviction, and gossip behavior than before.
ttl-num-blocks = 10
tx-notify-threshold = 0
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 8a0bdc5..268dc71 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -162,6 +162,12 @@ snapshot-keep-recent = 2
size = 5000
max-txs-bytes = 1073741824
cache-size = 10000
+# ttl-duration and ttl-num-blocks now treat zero (or unset) as "TTL purging disabled".
+# A non-zero value defines the time / number of blocks after which a transaction
+# is removed from the mempool; leaving them unset or set to zero disables TTL-based
+# purging entirely.
+ttl-duration = "0s"
+ttl-num-blocks = 0
# State store configuration
[state-store]
From eebf39a418985e1426cd5879ba76f81dbf8cb99e Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:24:23 +0000
Subject: [PATCH 47/63] docs: Adds a new seidb `migrate-evm-status` CLI
subcommand, a new `sc-keys-to-migrate-per-block` app.toml config field, a
`GIGA_MIGRATE_FROM_MEMIAVL` cluster env var, and a `-mode` flag to the
evm_stress tool, all supporting the FlatKV EVM migration flow.
(sei-protocol/sei-chain#3473)
---
node/giga-storage-migration.mdx | 83 +++++++++++++++++++++++++++++++++
node/technical-reference.mdx | 33 +++++++++++++
2 files changed, 116 insertions(+)
diff --git a/node/giga-storage-migration.mdx b/node/giga-storage-migration.mdx
index 0af8779..85b18a5 100644
--- a/node/giga-storage-migration.mdx
+++ b/node/giga-storage-migration.mdx
@@ -213,6 +213,89 @@ As of Sei v6.6, new nodes use a structured subdirectory layout. Existing nodes
with legacy flat paths automatically keep using them (the legacy path takes
precedence when present).
+
+
+## FlatKV EVM SC migration flow
+
+Everything above concerns the **SS** (State Store) layer. The **SC** (State
+Commit) layer has its own, separate migration path that moves the hot `evm/`
+data out of `memiavl` and into FlatKV in place, without a state sync. It is
+driven entirely by `app.toml`'s `sc-write-mode` and is coordinated across a
+quorum by stopping the nodes, editing config, and restarting.
+
+Unlike the SS split, the SC-side migration **does change how `evm/` data
+contributes to the app hash** (memiavl IAVL root before the migration; FlatKV
+lattice hash after). Because of that, every validator in a quorum must flip at
+the same coordinated stop — a node flipped while its peers are still on the old
+mode will produce a different AppHash on the very next block and consensus will
+halt. The safe sequence is always: stop everyone, rewrite `app.toml`
+everywhere, restart everyone.
+
+This SC-side FlatKV EVM migration flow is exercised by the cluster/devnet integration harness. Do not run it against testnet/mainnet nodes unless the release notes for your version explicitly call it out as supported.
+
+### Write modes
+
+The migration is a transition from the `memiavl_only` write mode (v0, where
+memiavl is the sole SC backend and FlatKV is not allocated) to `migrate_evm`
+(the in-flight mode that drains `evm/` keys from memiavl into FlatKV). Once the
+migration completes, operators flip `sc-write-mode` again to `evm_migrated` so
+subsequent restarts don't spin up the migration manager.
+
+While in a migration mode:
+
+- Caller reads of not-yet-migrated keys fall back to FlatKV for brand-new keys
+ written after the migration started, and to memiavl otherwise.
+- Iteration is forwarded to memiavl (with a completeness caveat: keys already
+ migrated out of memiavl are skipped). This is only safe for best-effort
+ callers.
+- The migration boundary advances at most once per block.
+
+### Operator-facing knobs
+
+**`sc-keys-to-migrate-per-block`** (`app.toml`, `[state-commit]` section)
+controls how many EVM keys the in-flight migration drains from memiavl into
+FlatKV per block. It defaults to `1024`, which is appropriate for production
+drains. Lowering it spreads the migration across more blocks. It must be `> 0`,
+and it is ignored entirely when `sc-write-mode` is not a migration mode.
+
+```toml copy
+[state-commit]
+sc-write-mode = "migrate_evm"
+sc-keys-to-migrate-per-block = 1024
+```
+
+**`GIGA_MIGRATE_FROM_MEMIAVL`** is a cluster/docker environment variable used by
+the local devnet setup. When set to `true` it boots every node in
+`memiavl_only` mode — the v0 starting point for the FlatKV EVM migrate flow. It
+is mutually exclusive with `GIGA_STORAGE`; if both are set,
+`GIGA_MIGRATE_FROM_MEMIAVL` takes precedence.
+
+```bash copy
+GIGA_MIGRATE_FROM_MEMIAVL=true make docker-cluster-start
+```
+
+### Checking migration status
+
+The `seidb 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 temp dir before reading, so it can be run against a live node's data
+directory without contending for the FlatKV writer lock.
+
+```bash copy
+seidb migrate-evm-status --db-dir [--height ]
+```
+
+`--db-dir` (short `-d`) points at the FlatKV data directory; `--height` selects
+a target version (`0`, the default, selects the latest available version). The
+emitted JSON includes `migrate_evm_complete` (true once the migration finishes),
+`migration_version`, `version_at`, and whether an in-flight boundary is still
+present. Poll it until `migrate_evm_complete` reports `true` on every validator
+before flipping `sc-write-mode` to `evm_migrated`.
+
+When the migration finishes, each node also emits a `migration complete` summary
+log line and a set of `seidb_migration_*` OpenTelemetry counters covering keys
+and bytes migrated.
+
- Cosmos SS data lives under `data/state_store/cosmos/{backend}` on new nodes
(e.g. `data/state_store/cosmos/pebbledb` for the default `pebbledb` backend).
Existing nodes with legacy `data/pebbledb/` continue using it.
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 268dc71..9d2181f 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -38,6 +38,39 @@ seid query node info
```
+
+### seidb Tooling Commands
+
+The `seidb` binary provides low-level tooling for inspecting and maintaining a node's on-disk state.
+
+#### Reporting FlatKV EVM Migration Status
+
+The `migrate-evm-status` subcommand reads the on-disk FlatKV EVM migration state from a FlatKV data directory and prints a JSON summary. It is primarily intended for integration and operator tooling that polls each validator to determine whether the FlatKV EVM migration has completed, without needing a custom RPC handler or having to grep through node logs.
+
+```bash
+# Report FlatKV EVM migration status at the latest available version
+seidb migrate-evm-status --db-dir
+
+# The --db-dir flag may be abbreviated as -d
+seidb migrate-evm-status -d /root/.sei/data/state_commit/flatkv
+
+# Report status at a specific FlatKV version (0 selects the latest)
+seidb migrate-evm-status --db-dir --height
+```
+
+The command opens FlatKV read-only — it hardlink-clones the latest snapshot and copies the WAL into a temporary directory before opening — so it can be run safely against a directory that a live node is still writing to.
+
+The emitted JSON contains the following fields:
+
+- `version_at` — the FlatKV version that was read.
+- `migration_version` — the on-disk migration version (`0` means the FlatKV EVM migration has not yet completed).
+- `migrate_evm_complete` — `true` once the migration version has reached the FlatKV EVM (v1) target.
+- `boundary_present` — `true` while the migration is in flight (the in-progress resume cursor is still present).
+- `boundary_hex` — hex-encoded migration boundary cursor, included only when a boundary is present.
+- `version_raw_hex` — hex-encoded raw migration-version bytes, included only when a migration version is present.
+
+
+
### Autobahn (GigaRouter) Config Generation
When running with the Autobahn (GigaRouter) networking layer, you can generate the Autobahn JSON config from a set of node directories. Each directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, `autobahn_address.txt`, and `evmrpc_url.txt`.
From 17fa5c875c0250a093025ced8d5456211b2621c2 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:27:25 +0000
Subject: [PATCH 48/63] docs: The max block lookback guard for debug_trace* RPC
methods now applies consistently across debug_traceTransaction,
debug_traceBlockByNumber, debug_traceBlockByHash, debug_traceCall,
debug_traceStateAccess, and debug_traceTransactionProfile, rejecting requests
targeting historical blocks beyond the configured lookback.
(sei-protocol/sei-chain#3515)
---
evm/reference.mdx | 2 +-
node/advanced-config-monitoring.mdx | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 6d10315..3a3fa5d 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -1135,7 +1135,7 @@ The `filter` object applies only to `logs` subscriptions. For `newHeads`, pass t
**Supported.** Replays a transaction by hash and returns an execution trace using the configured tracer.
-**Sei-specific behavior:** HTTP-only (the debug namespace is not registered on the WebSocket server). Supports geth tracers (callTracer, prestateTracer, flatCallTracer, struct/opcode logger); callTracer/prestateTracer/flatCallTracer results are pre-baked/cached via TraceBaker. Requires trace-enabled/archive state for the target height.
+**Sei-specific behavior:** HTTP-only (the debug namespace is not registered on the WebSocket server). Supports geth tracers (callTracer, prestateTracer, flatCallTracer, struct/opcode logger); callTracer/prestateTracer/flatCallTracer results are pre-baked/cached via TraceBaker. Requires trace-enabled/archive state for the target height. Subject to the max block lookback guard (`max_trace_lookback_blocks`): a request whose target block is older than the configured lookback is rejected with an error of the form `block number X is beyond max lookback of Y`. This guard now applies consistently across all `debug_trace*` endpoints, and such attempts increment the `evmrpc_historical_debug_trace_attempts_total` metric.
**Parameters:**
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index 2f6158e..e0bd070 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -517,6 +517,7 @@ The EVM RPC layer emits OpenTelemetry metrics through the process-wide `MeterPro
| `evmrpc_request_latency_seconds` | Histogram | EVM RPC request latency in seconds. |
| `evmrpc_websocket_connects_total` | Counter | Number of new websocket connections. |
| `evmrpc_redirected_requests_total` | Counter | Number of EVM RPC requests forwarded to another validator. Labeled by `endpoint` and `connection`. |
+| `evmrpc_historical_debug_trace_attempts_total` | Counter | Number of `debug_trace*` requests targeting historical blocks beyond the configured max block lookback. Labeled by `endpoint` and `connection`. |
The `evmrpc_request_latency_seconds` histogram carries the following labels:
From 0704b9b3605898a93b35866b77e154a67918b909 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:29:23 +0000
Subject: [PATCH 49/63] docs: The eth_getTransactionByHash RPC now looks up
mempool transactions via an indexed EVM-hash store instead of paginating
unconfirmed txs, and UnconfirmedTxs RPC now reads from a recent mempool
snapshot changing pagination/total-bytes semantics.
(sei-protocol/sei-chain#3546)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 3a3fa5d..4c9a2d7 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -239,7 +239,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns the EVM transaction matching the given hash, or null if not found.
-**Sei-specific behavior:** Sees EVM transactions only; if the hash resolves to a non-EVM Cosmos tx it errors. Pending lookups read from the CometBFT mempool, not a geth txpool. Use the legacy sei_getTransactionByHash to also surface Cosmos txs with synthetic representations.
+**Sei-specific behavior:** Sees EVM transactions only; if the hash resolves to a non-EVM Cosmos tx it errors. Pending lookups resolve the transaction directly from the CometBFT mempool via an EVM-hash index (rather than a geth txpool), so a pending EVM tx is found by its hash without scanning through unconfirmed-transaction pages. Use the legacy sei_getTransactionByHash to also surface Cosmos txs with synthetic representations.
**Parameters:**
From a70ee2230492db536e217bcf832790b80bfb8fa0 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:30:34 +0000
Subject: [PATCH 50/63] docs: The Autobahn (giga) config removes the
mempool_size field and reworks gas params into wanted/estimated variants, and
the giga RPC path now rejects unsafe_flush_mempool and changes some
mempool-related behaviors. (sei-protocol/sei-chain#3522)
---
evm/reference.mdx | 2 ++
node/technical-reference.mdx | 21 +++++++++++++--------
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 4c9a2d7..3046a54 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -125,6 +125,8 @@ Every method below is also browsable interactively in the explorer above; this s
**Sei-specific behavior:** Decodes to an ethtypes.Transaction, wraps it in a Cosmos MsgEVMTransaction, and broadcasts via CometBFT (async BroadcastTx by default; slow mode uses BroadcastTxCommit). Non-zero CheckTx codes surface as ABCI errors, not geth mempool errors. Legacy (non-1559) txs must set gasPrice at or above the governance minimum (currently 50 gwei on mainnet); blob (EIP-4844) txs are not enabled. Supports per-sender EvmProxy forwarding.
+**Under Autobahn (`AutobahnConfigFile` set):** transaction broadcast routes through Autobahn's producer-backed mempool instead of CometBFT's `TxMempool`. This mempool admits EVM transactions strictly in sequential per-sender nonce order: a transaction whose nonce does not match the sender's next expected nonce is rejected with a bad-nonce error, so senders must submit nonces contiguously. Synchronous broadcast (`broadcast_tx` / `BroadcastTx`) blocks while the mempool is full and only returns once capacity is available, whereas the async path may drop the transaction if the mempool is full. The `unsafe_flush_mempool` Tendermint RPC endpoint is not supported under Autobahn and returns `unsafe_flush_mempool is not supported with autobahn mempool`.
+
**Parameters:**
| # | Name | Type | Description |
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 9d2181f..68ad264 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -99,7 +99,7 @@ The command reads the following files from each node directory:
The `validator_pubkey.txt` and `node_pubkey.txt` files are written automatically alongside `priv_validator_key.json` and `node_key.json` whenever those keys are saved, so they are typically already present in each node's config directory.
-The generated `autobahn.json` file describes the validator set along with gas and transaction limits, mempool size, block interval, view timeout, and dial interval. To have a node consume it, reference the file from `config.toml` using the `autobahn-config-file` key.
+The generated `autobahn.json` file describes the validator set along with gas and transaction limits, block interval, view timeout, and dial interval. To have a node consume it, reference the file from `config.toml` using the `autobahn-config-file` key.
@@ -107,18 +107,23 @@ The generated `autobahn.json` file describes the validator set along with gas an
When a node is started in Giga mode — that is, when `autobahn-config-file` is set in `config.toml` — the block production and networking behavior differs significantly from standard Tendermint consensus:
-- **Mempool gossip reactor is disabled.** Mempool gossiping is not compatible with Giga, so transactions are not broadcast over the standard mempool p2p channel. The mempool itself still runs and accepts transactions locally.
+- **The CometBFT `TxMempool` is not used.** Under Giga the standard mempool (and its gossip reactor) is disabled entirely. Transactions instead route through the Autobahn producer-backed mempool.
- **Consensus reactor, state sync, and block sync are disabled.** In Giga mode these reactors are skipped entirely, and both state sync and block sync are forced off regardless of other configuration.
-- **The Autobahn block producer sources transactions directly from the mempool.** Instead of relying on a separate transaction channel, the producer reaps transactions straight from the local mempool when building each block payload.
+- **Transactions are admitted through the producer mempool.** The RPC broadcast endpoints call the producer's `InsertTx`/`TryInsertTx` rather than the CometBFT mempool's `CheckTx`. `BroadcastTx` uses `InsertTx`, which blocks while the mempool is full; the async path uses `TryInsertTx`, which returns a `mempool is full` error instead of blocking.
+- **Sequential EVM nonce ordering is enforced.** For EVM transactions, the producer mempool admits transactions strictly in nonce order per sender. A transaction whose nonce does not match the next expected nonce is rejected with a `bad nonce` error. Because admission is sequential, the mempool can track pending nonces (`EvmNextPendingNonce`) as callers submit them.
-- **Mempool `Update` runs with recheck disabled after each block.** When the Autobahn block producer executes a block, it updates the mempool with rechecking turned off. Re-running `CheckTx` on every remaining transaction after each block would cause the EVM antehandler to mark any still-ahead-of-nonce transaction as pending, which in turn evicts these perfectly valid queued transactions. With recheck disabled, valid out-of-order EVM nonce transactions from a sender remain in the priority index and can all be mined in subsequent blocks. Leaving recheck enabled would stall throughput to roughly one transaction per block per sender when a sender submits many sequential nonces out of order. This also matches CometBFT's default of `false` for `ConsensusParams.ABCI.RecheckTx`, since state-dependent invalidation is already caught during proposal processing and block execution.
+Each Autobahn block payload is bounded by the following limits, enforced by the producer as it fills a block:
-Each Autobahn block payload is subject to fixed per-block limits enforced by the block producer:
+- **Maximum transactions per block:** the lower of the configured `max_txs_per_block` and the built-in maximum.
+- **Maximum total transaction bytes per block:** a fixed per-block byte cap; a single transaction larger than this cap is rejected with a `transaction too large` error.
+- **Wanted gas per block (`MaxGasWantedPerBlock`):** derived from the genesis `MaxGasWanted` block param. A transaction whose `GasWanted` exceeds this per-block limit is rejected as too large.
+- **Estimated gas per block (`MaxGasEstimatedPerBlock`):** derived from the genesis `MaxGas` block param. A transaction whose (normalized) estimated gas exceeds this per-block limit is rejected as too large.
-- **Maximum transactions per block:** 2,000 transactions.
-- **Maximum total transaction bytes per block:** approximately 2 MB (2,000 × 1,024 bytes). This total can be distributed arbitrarily across transactions (for example, one large transaction, or up to 2,000 smaller ones), so long as neither the transaction count nor the total byte limit is exceeded.
+When filling a block the producer seals the current block and starts a new one as soon as adding the next transaction would exceed any of the transaction-count, byte, wanted-gas, or estimated-gas limits.
-These limits are in addition to the gas limits configured in `autobahn.json`. When building a block, the producer stops reaping transactions once any of the transaction-count, byte, or gas limits is reached. Payload construction fails if either the transaction count or total byte limit would be exceeded.
+
+ Because Giga replaces the CometBFT mempool, the `unsafe_flush_mempool` RPC endpoint is not supported under Giga and returns `unsafe_flush_mempool is not supported with autobahn mempool`.
+
### Key Management
From 3d0a2ea431b53870a63ce2193072acda88ba8b07 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:32:07 +0000
Subject: [PATCH 51/63] docs: Introduces a new mock_chain_validation build tag
(with new Docker images) that swallows most consensus validation failures,
and adds a new sei_unsafe_validation_skipped_total metric emitted by
non-default consensus policies. (sei-protocol/sei-chain#3429)
---
node/index.mdx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/node/index.mdx b/node/index.mdx
index 10b1307..8b5b97a 100644
--- a/node/index.mdx
+++ b/node/index.mdx
@@ -179,8 +179,9 @@ See the Network Versions table above for the current recommended version.
- `mock_balances-*` — mocks account balances.
- `mock_block_validation-*` — bypasses `AppHash` and `DataHash` block validation.
+ - `mock_chain_validation-*` — swallows most halting consensus validation failures (every swallow-eligible check except `ErrLastCommitVerify`), computing each check authentically but continuing instead of halting. Combines `mock_balances` and `mock_chain_validation`.
- Production images are built with full validation enabled. The `mock_block_validation` variant is intended solely for testing environments where skipping block validation checks is required; running it on a production network is unsafe.
+ Production images are built with full validation enabled. The `mock_block_validation` and `mock_chain_validation` variants are intended solely for testing environments where relaxing validation checks is required; running either on a production network is unsafe.
From 5a55a5656162fc4ab405af766f7a22924ea64c67 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:32:54 +0000
Subject: [PATCH 52/63] docs: Adds full support for the `flatkv_only` value of
the `sc-write-mode` config field, enabling nodes to boot directly in the
post-migration FlatKV-only steady state with correct state-sync and snapshot
behavior. (sei-protocol/sei-chain#3545)
---
node/giga-storage-migration.mdx | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/node/giga-storage-migration.mdx b/node/giga-storage-migration.mdx
index 85b18a5..80c0b0b 100644
--- a/node/giga-storage-migration.mdx
+++ b/node/giga-storage-migration.mdx
@@ -241,6 +241,24 @@ memiavl is the sole SC backend and FlatKV is not allocated) to `migrate_evm`
migration completes, operators flip `sc-write-mode` again to `evm_migrated` so
subsequent restarts don't spin up the migration manager.
+
+
+Beyond `evm_migrated`, `flatkv_only` is the fully-supported **terminal**
+steady-state write mode: FlatKV is the sole SC backend and `memiavl` is not
+allocated at all. In this mode every module's SC state is served from FlatKV,
+and state-sync snapshot export/restore plus app-hash parity work correctly, so
+a node can boot directly into the post-migration shape without ever running the
+migration manager. Use `flatkv_only` when you want a node to come up already in
+the post-migration steady state rather than draining keys out of memiavl at
+runtime.
+
+A correctness bug in the WAL replay path — where empty (zero-length)
+values written with no delete flag were dropped on replay (catchup, read-only
+clone, snapshot export, and state-sync restore), diverging the FlatKV state and
+the consensus AppHash from the live chain — is fixed. Empty-value writes are now
+preserved across a WAL round-trip and state-sync, which is what makes
+`flatkv_only` state-sync reliable.
+
While in a migration mode:
- Caller reads of not-yet-migrated keys fall back to FlatKV for brand-new keys
From 24eb5a478daa2586a55e2b44523c2bca19e3fb7a Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:34:12 +0000
Subject: [PATCH 53/63] docs: Two mempool config fields (pending-ttl-duration
and pending-ttl-num-blocks) are now deprecated and have no effect, and
BroadcastTxCommit now respects the timeout-broadcast-tx-commit config value.
(sei-protocol/sei-chain#3567)
---
node/index.mdx | 6 ++++++
node/node-operators.mdx | 4 ++++
node/technical-reference.mdx | 3 +++
3 files changed, 13 insertions(+)
diff --git a/node/index.mdx b/node/index.mdx
index 8b5b97a..344f767 100644
--- a/node/index.mdx
+++ b/node/index.mdx
@@ -307,11 +307,17 @@ pending-size = 5000
max-pending-txs-bytes = 1073741824
+# Deprecated: these fields no longer have any effect and are ignored.
pending-ttl-duration = "3s"
+# Deprecated: these fields no longer have any effect and are ignored.
pending-ttl-num-blocks = 5
```
+
+ `pending-ttl-duration` and `pending-ttl-num-blocks` are deprecated and now have no effect. They are ignored regardless of the value you set.
+
+
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 0c476bf..db6208a 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -1109,8 +1109,12 @@ pending-size = 5000
max-pending-txs-bytes = 1073741824
+# Deprecated: pending-ttl-duration is no longer used and this field has no
+# effect. Pending transactions are no longer purged based on a time-based TTL.
pending-ttl-duration = "0s"
+# Deprecated: pending-ttl-num-blocks is no longer used and this field has no
+# effect. Pending transactions are no longer purged based on a block-count TTL.
pending-ttl-num-blocks = 0
# Defines the percentage of transactions with the lowest priority hint
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index 68ad264..f09e5ac 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -243,6 +243,9 @@ cors_allowed_origins = []
cors_allowed_methods = ["HEAD", "GET", "POST"]
cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time"]
max_open_connections = 900
+# timeout_broadcast_tx_commit is now enforced by the BroadcastTxCommit RPC: when set
+# greater than 0 it is applied as a context timeout on the request, so a
+# BroadcastTxCommit call will be cancelled if it does not complete within this duration.
timeout_broadcast_tx_commit = "10s"
# Consensus Configuration
From ef05bb1c8277866b5847f4ecd98ab7fe09221baf Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:37:22 +0000
Subject: [PATCH 54/63] docs: Adds new OpenTelemetry metrics for IBC transfer,
client, connection, channel, and core packet operations that node operators
can scrape for observability. (sei-protocol/sei-chain#3543)
---
node/advanced-config-monitoring.mdx | 58 +++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index e0bd070..1b6a56f 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -633,6 +633,64 @@ Metric names, units, and shape changed with the OpenTelemetry migration, so exis
- The per-cache series that were previously separate metric names (for example `chunk_read_cache_*` and `chunk_write_cache_*`) are now the shared `litt_chunk_cache_*` metrics distinguished by the `cache` attribute.
- The `MetricsNamespace` and `MetricsRegistry` config fields no longer exist. Metric names are fixed, and metrics are always backed by the global OTel provider; supply the scrape port via `MetricsPort`.
+
+
+## IBC OpenTelemetry Metrics
+
+The IBC modules emit OpenTelemetry metrics through the process-wide `MeterProvider` (for example, a Prometheus exporter). These are emitted in parallel with the legacy `ibc_*` and `tx_msg_*` telemetry counters so you can migrate dashboards incrementally. The metrics are grouped by meter, one per IBC module.
+
+### Transfer Metrics (`ibc_transfer_keeper` meter)
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `ibc_transfer_tx_msg` | Gauge | Last amount of tokens transferred via IBC per denom class. |
+| `ibc_transfer_packet_receive` | Gauge | Last amount of tokens received in an IBC packet per denom class. |
+| `ibc_transfer_send` | Counter | Total number of IBC transfers sent. |
+| `ibc_transfer_receive` | Counter | Total number of IBC transfers received. |
+
+The transfer gauges carry a `denom_class` attribute. `ibc_transfer_send` carries `destination_port`, `destination_channel`, and a boolean `source` attribute indicating whether the sending chain is the token source. `ibc_transfer_receive` carries `source_port`, `source_channel`, and the boolean `source` attribute.
+
+### Core Client Metrics (`ibc_core_client_keeper` meter)
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `ibc_client_create` | Counter | Total number of IBC client creates. |
+| `ibc_client_update` | Counter | Total number of IBC client updates. |
+| `ibc_client_upgrade` | Counter | Total number of IBC client upgrades. |
+| `ibc_client_misbehaviour` | Counter | Total number of IBC client misbehaviour events. |
+
+These metrics carry a `client_type` attribute. `ibc_client_update`, `ibc_client_upgrade`, and `ibc_client_misbehaviour` also carry a `client_id` attribute. `ibc_client_update` additionally carries an `update_type` attribute (`msg` or `proposal`).
+
+### Connection Metrics (`ibc_connection` meter)
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `ibc_connection_open_init` | Counter | Total number of IBC connection open-init handshakes. |
+| `ibc_connection_open_try` | Counter | Total number of IBC connection open-try handshakes. |
+| `ibc_connection_open_ack` | Counter | Total number of IBC connection open-ack handshakes. |
+| `ibc_connection_open_confirm` | Counter | Total number of IBC connection open-confirm handshakes. |
+
+### Channel Metrics (`ibc_channel` meter)
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `ibc_channel_open_init` | Counter | Total number of IBC channel open-init handshakes. |
+| `ibc_channel_open_try` | Counter | Total number of IBC channel open-try handshakes. |
+| `ibc_channel_open_ack` | Counter | Total number of IBC channel open-ack handshakes. |
+| `ibc_channel_open_confirm` | Counter | Total number of IBC channel open-confirm handshakes. |
+| `ibc_channel_close_init` | Counter | Total number of IBC channel close-init handshakes. |
+| `ibc_channel_close_confirm` | Counter | Total number of IBC channel close-confirm handshakes. |
+
+### Core Packet Metrics (`ibc_core` meter)
+
+| Metric | Type | Description |
+| --- | --- | --- |
+| `ibc_core_tx_msg_recv_packet` | Counter | Total number of IBC recv packet messages. |
+| `ibc_core_timeout_packet` | Counter | Total number of IBC timeout packets. |
+| `ibc_core_tx_msg_acknowledge_packet` | Counter | Total number of IBC acknowledge packet messages. |
+
+These packet metrics carry `source_port`, `source_channel`, `destination_port`, and `destination_channel` attributes. `ibc_core_timeout_packet` additionally carries a `timeout_type` attribute (`height` or `channel-closed`).
+
## Performance Testing
From 61b30ce73bd3343d76237f29784860aab4607155 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:39:35 +0000
Subject: [PATCH 55/63] docs: The parquet/DuckDB receipt store backend and its
associated config fields have been removed; pebbledb is now the only
supported receipt-store backend. (sei-protocol/sei-chain#3580)
---
node/giga-storage-migration.mdx | 16 ++++++++++------
node/node-operators.mdx | 28 ++++++++--------------------
2 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/node/giga-storage-migration.mdx b/node/giga-storage-migration.mdx
index 80c0b0b..ca2bf3a 100644
--- a/node/giga-storage-migration.mdx
+++ b/node/giga-storage-migration.mdx
@@ -358,9 +358,13 @@ proofs.
### Does enabling Giga Storage change the receipt backend?
-Yes. In the `localnode` and `rpcnode` configuration scripts, setting
-`GIGA_STORAGE=true` now also defaults `RECEIPT_BACKEND` to `parquet` unless you
-set `RECEIPT_BACKEND` explicitly. Previously the receipt backend was left
-unchanged and had to be set explicitly to use parquet. To keep a different
-receipt backend while running with Giga Storage, provide an explicit
-`RECEIPT_BACKEND` env var, which takes precedence over the parquet default.
+In the `localnode` and `rpcnode` configuration scripts, setting
+`GIGA_STORAGE=true` defaults `RECEIPT_BACKEND` to `pebble` unless you set
+`RECEIPT_BACKEND` explicitly. To use a different value while running with Giga
+Storage, provide an explicit `RECEIPT_BACKEND` env var, which takes precedence
+over the default.
+
+`pebbledb` (aka `pebble`) is now the only supported receipt-store backend. The
+former `parquet` option has been removed: setting `RECEIPT_BACKEND=parquet` (or
+`rs-backend = "parquet"` in `app.toml`) is rejected with an error
+(`unsupported receipt-store backend; supported: pebbledb`).
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index db6208a..56f6841 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -95,30 +95,18 @@ ss-enable = true
ss-keep-recent = 100000
[receipt-store]
-# Storage backend for EVM transaction receipts (pebbledb or parquet).
+# Storage backend for EVM transaction receipts. pebbledb (aka pebble) is the
+# only supported backend.
rs-backend = "pebbledb"
```
-Enabling Giga Storage (`GIGA_STORAGE=true`) in the localnode and rpcnode
-configuration scripts now defaults the receipt backend to `parquet` rather than
-leaving `rs-backend` at its `pebbledb` default. This applies only when
-`RECEIPT_BACKEND` is not set; you can still keep pebbledb (or select any other
-supported backend) by exporting `RECEIPT_BACKEND` explicitly before running the
-scripts.
-
-
-
-The `parquet` backend maintains a pebble-based tx hash index that maps a
-transaction hash to the parquet file that holds its receipt. When this index
-is disabled (`TxIndexBackend = ""`), a receipt-by-tx-hash lookup such as
-`eth_getTransactionReceipt` that misses the in-memory receipt cache fails fast
-with a not-found result instead of performing a full parquet file scan (a scan
-would require reading every file on disk and is prohibitively expensive at
-production scale). Block-range queries such as `FilterLogs` (log filtering by
-block range) do not use the tx hash index and are unaffected. If you serve
-receipt-by-tx-hash lookups for historical transactions, keep the tx hash index
-enabled.
+`pebbledb` (aka `pebble`) is the only supported receipt-store backend. Setting
+`rs-backend = "parquet"` (or `RECEIPT_BACKEND=parquet`) is rejected with the
+error `unsupported receipt-store backend; supported: pebbledb`. Enabling Giga
+Storage (`GIGA_STORAGE=true`) in the localnode and rpcnode configuration scripts
+defaults the receipt backend to `pebble` when `RECEIPT_BACKEND` is not set. The
+former `receipt-store.tx-index-backend` config field has been removed.
### Default Configurations
From 3484e7d3d6cbafa46ca54f5be961cdb7edf4a8ad Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:41:44 +0000
Subject: [PATCH 56/63] docs: The EVM RPC methods
eth_getBlockTransactionCountByNumber and eth_getBlockTransactionCountByHash
now return a 'receipts have been pruned' error when the requested block's
receipts have been pruned from the receipt store.
(sei-protocol/sei-chain#3216)
---
evm/reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/reference.mdx b/evm/reference.mdx
index 3046a54..1e66aaa 100644
--- a/evm/reference.mdx
+++ b/evm/reference.mdx
@@ -627,7 +627,7 @@ Every method below is also browsable interactively in the explorer above; this s
**Supported.** Returns the number of EVM transactions in a block by number, as a hex quantity.
-**Sei-specific behavior:** Counts the same transactions that appear in `eth_getBlockByNumber`'s transaction list: EVM transactions are counted only when a receipt exists for them, and `MsgExecuteContract` (wasm execute-contract) and `MsgSend` (bank send) messages are also included. Genesis returns 0x0; non-existent/future blocks return null.
+**Sei-specific behavior:** Counts the same transactions that appear in `eth_getBlockByNumber`'s transaction list: EVM transactions are counted only when a receipt exists for them, and `MsgExecuteContract` (wasm execute-contract) and `MsgSend` (bank send) messages are also included. Genesis returns 0x0; non-existent/future blocks return null. Because the receipt store can be configured with a smaller `KeepRecent` than the block/state stores, this method now verifies that the requested block's receipts have not been pruned before counting: if they have, it returns an error of the form `requested height N receipts have been pruned; earliest available is M` rather than a count. This means the call can fail for older blocks even when the block data itself is still available.
**Parameters:**
From 43c4fd0f3290f11e3e2466799dee7924a625442c Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:42:11 +0000
Subject: [PATCH 57/63] docs: Adds a new Iterator API plus
GetOldestKey/GetNewestKey methods to the LittDB Table interface, along with a
new litt_open_iterator_count metric, enabling developers to scan keys/values
and query boundary keys. (sei-protocol/sei-chain#3593)
---
node/advanced-config-monitoring.mdx | 1 +
1 file changed, 1 insertion(+)
diff --git a/node/advanced-config-monitoring.mdx b/node/advanced-config-monitoring.mdx
index 1b6a56f..2c81b72 100644
--- a/node/advanced-config-monitoring.mdx
+++ b/node/advanced-config-monitoring.mdx
@@ -597,6 +597,7 @@ LittDB now emits its metrics through the process-wide OpenTelemetry `MeterProvid
| --- | --- | --- | --- |
| `litt_table_size_bytes` | Gauge | bytes | The size of individual tables in the database. |
| `litt_table_key_count` | Gauge | count | The number of keys in individual tables in the database. |
+| `litt_open_iterator_count` | Gauge | count | The number of currently-open iterators for individual tables in the database. A persistently nonzero value indicates a leaked iterator, which suspends garbage collection for the table. |
| `litt_bytes_read` | Counter | bytes | The number of bytes read from disk since startup. |
| `litt_keys_read` | Counter | count | The number of keys read from disk since startup. |
| `litt_cache_hits` | Counter | count | The number of cache hits since startup. |
From a8f847bf7ae2ae59b93e579d91848b6ecb5cc6a9 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:44:21 +0000
Subject: [PATCH 58/63] docs: Added a hard cap of 100 validators to the
Autobahn/sei-tendermint committee and introduced wireguard size/count limits
on consensus protobuf messages, changing acceptance/rejection behavior for
oversized network payloads. (sei-protocol/sei-chain#3609)
---
node/technical-reference.mdx | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index f09e5ac..ffa3815 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -121,6 +121,24 @@ Each Autobahn block payload is bounded by the following limits, enforced by the
When filling a block the producer seals the current block and starts a new one as soon as adding the next transaction would exceed any of the transaction-count, byte, wanted-gas, or estimated-gas limits.
+
+
+#### Autobahn Committee and Network Message Limits
+
+Beyond the per-block payload limits, Giga mode enforces structural limits on the validator committee and on incoming consensus network messages:
+
+- **Maximum validators per committee:** the Autobahn committee is capped at a hard limit of 100 validators (`MaxValidators`). Committee creation rejects any validator set exceeding this limit — building a committee from more than 100 validators fails with a `too many validators` error rather than being silently truncated.
+- **Bounded consensus network messages.** Autobahn consensus protobuf messages carry declared size and count constraints that are checked against the raw wire bytes before the message is decoded. Payloads that violate these constraints are rejected during decoding, before any allocation, which protects nodes from oversized or malformed inputs that could otherwise decode into much larger in-memory structures.
+
+The enforced message constraints include:
+
+- **Per-field maximum sizes** on fixed-width fields such as hashes, signatures, and public keys.
+- **Maximum repeated-field counts** on validator-related lists — signature and quorum-certificate lists are capped at 100 entries (matching the 100-validator committee cap).
+- **Transaction payload caps:** a block payload may carry at most 2000 transactions, with a combined transaction byte budget of roughly 2 MB across all transactions in the payload.
+
+Any message whose fields exceed these limits is rejected at decode time, so an oversized network payload never reaches the consensus logic.
+
+
Because Giga replaces the CometBFT mempool, the `unsafe_flush_mempool` RPC endpoint is not supported under Giga and returns `unsafe_flush_mempool is not supported with autobahn mempool`.
From 2aba5f2b0c2807481c99dc90797e2a7831eec148 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:44:58 +0000
Subject: [PATCH 59/63] docs: A new consensus config field
`unsafe-overrides-enabled` was added that gates whether the
Unsafe*TimeoutOverride fields take effect, changing how timeout overrides
behave on nodes. (sei-protocol/sei-chain#3601)
---
node/node-operators.mdx | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/node/node-operators.mdx b/node/node-operators.mdx
index 56f6841..53566ee 100644
--- a/node/node-operators.mdx
+++ b/node/node-operators.mdx
@@ -1216,9 +1216,22 @@ peer-query-maj23-sleep-duration = "2s"
# For additional information, see ADR-74:
# https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-074-timeout-params.md
+# If false, all of the Unsafe*TimeoutOverride fields below are ignored.
+# Defaults to false.
+#
+# As of v6.6.0, the timeout overrides below only take effect when this field is
+# set to true, OR when the onchain timeout params still equal the legacy
+# pacific-1 "badParams" values (a backward-compatibility carve-out during
+# migration). When unsafe-overrides-enabled is false and the onchain timeout
+# params differ from those legacy values, the overrides are ignored and the
+# onchain (or default) timeout params are used instead.
+unsafe-overrides-enabled = false
+
# This field provides an unsafe override of the Propose timeout consensus parameter.
# This field configures how long the consensus engine will wait for a proposal block before prevoting nil.
-# If this field is set to a value greater than 0, it will take effect.
+# The override is applied only when unsafe-overrides-enabled = true (or the onchain
+# timeout params still equal the legacy badParams values) and this field is set to a
+# value greater than 0.
unsafe-propose-timeout-override = "0s"
# This field provides an unsafe override of the ProposeDelta timeout consensus parameter.
From 60898807d58e66b4d4134853bf6df869ec48c3b5 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 06:45:30 +0000
Subject: [PATCH 60/63] docs: The JSON-RPC endpoints
sei_traceBlockByNumberExcludeTraceFail and
sei_traceBlockByHashExcludeTraceFail have been removed from the EVM RPC
server and legacy sei API allowlist. (sei-protocol/sei-chain#3618)
---
evm/tracing/index.mdx | 1 -
1 file changed, 1 deletion(-)
diff --git a/evm/tracing/index.mdx b/evm/tracing/index.mdx
index 09c89c7..dfd4248 100644
--- a/evm/tracing/index.mdx
+++ b/evm/tracing/index.mdx
@@ -419,7 +419,6 @@ When enabled, a background worker re-executes each committed block with the conf
- `debug_traceTransaction`
- `debug_traceBlockByNumber` and `debug_traceBlockByHash`
-- The `*ExcludeTraceFail` variants of the block-trace methods
### `*ExcludeTraceFail` filtering semantics
From 5776c3b2a68e1f50baa8d36ecbfe7d337583c306 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 23:58:47 +0000
Subject: [PATCH 61/63] docs: Adds a new `seidb evm-logical-digest` command
that computes a backend-independent digest of EVM logical state
(account/code/storage) so memiavl and flatkv nodes can be compared at the
same height. (sei-protocol/sei-chain#3611)
---
node/technical-reference.mdx | 42 +++++++++++++++++++++++++++++++
node/troubleshooting.mdx | 48 ++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+)
diff --git a/node/technical-reference.mdx b/node/technical-reference.mdx
index ffa3815..4399a13 100644
--- a/node/technical-reference.mdx
+++ b/node/technical-reference.mdx
@@ -71,6 +71,48 @@ The emitted JSON contains the following fields:
+#### Comparing EVM State Across Backends
+
+The `evm-logical-digest` subcommand computes a backend-independent digest of the EVM logical state (the account, code, and storage buckets) so that a memIAVL node and a FlatKV node can be compared at the same chain height. Because a freshly migrated FlatKV node stamps a per-key `blockHeight` into each value that differs from the memIAVL leaf versions, a raw byte-for-byte digest would diverge even when the underlying EVM state is identical. This command strips the serialization-version and `blockHeight` header on both sides and digests only the height-independent logical payload (storage word, bytecode, or balance+nonce+codehash), producing a comparable `FINAL_DIGEST` per backend.
+
+```bash
+# FlatKV digest at a height (WAL-replays to it). Prints per-bucket
+# bucket_digest values and one FINAL_DIGEST line for backend comparison.
+seidb evm-logical-digest --backend flatkv \
+ --db-dir /root/.sei/data/state_commit/flatkv --height 213200000
+
+# memIAVL digest at the same height (0 = current symlink), using the default
+# semantic normalization. memiavl resolves snapshot-/evm or current/evm
+# and does not replay WAL in this tool.
+seidb evm-logical-digest --backend memiavl \
+ --db-dir /root/.sei/data/state_commit/memiavl --height 213200000
+
+# Translator-based memIAVL digest, which feeds each leaf through the current
+# migration mapping (flatkv.ImportTranslator).
+seidb evm-logical-digest --backend memiavl \
+ --db-dir /root/.sei/data/state_commit/memiavl --height 213200000 \
+ --memiavl-normalization translator
+```
+
+Two backends match when the FlatKV `FINAL_DIGEST` equals the memIAVL `FINAL_DIGEST`. FlatKV also writes an internal migration-version marker row that a memiavl-only node never owns, so the command omits that row from the final comparison automatically.
+
+The command accepts the following flags:
+
+- `--backend` — backend to read: `flatkv` or `memiavl`.
+- `--db-dir` (`-d`) — for FlatKV, the FlatKV data directory; for memIAVL, the memIAVL root directory containing `current/` and `snapshot-*`.
+- `--height` — target version. FlatKV WAL-replays to it; memIAVL resolves `snapshot-/evm` (`0` selects the `current` symlink).
+- `--memiavl-normalization` — memIAVL normalization mode: `semantic`/`independent` (raw EVM key/value decoder, the default `semantic`) or `translator` (current migration mapping).
+- `--inspect-bucket` — inspect one normalized bucket (`account`, `code`, `storage`, or `legacy`) instead of printing the global digest.
+- `--key-offset` — inspect mode: byte offset into the physical key before applying `--key-prefix` or sharding.
+- `--key-prefix` — inspect mode: hex prefix, relative to `--key-offset`, used to filter physical keys.
+- `--shard-next-bytes` — inspect mode: group matching keys by this many bytes after `--key-prefix`.
+- `--list` — inspect mode: list matching key/logical-value pairs instead of shard `bucket_digest` values.
+- `--list-limit` — inspect mode: maximum pairs to print with `--list` (default `1000`; a value `<= 0` means unlimited).
+- `--details` — inspect list mode: include backend-specific version metadata.
+- `--find-hash` — optional 32-byte hex per-entry hash to hunt for. When two `bucket_digest` values differ by exactly one entry, their XOR is that entry's hash; this prints every matching entry so a single diverging row can be located.
+
+
+
### Autobahn (GigaRouter) Config Generation
When running with the Autobahn (GigaRouter) networking layer, you can generate the Autobahn JSON config from a set of node directories. Each directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, `autobahn_address.txt`, and `evmrpc_url.txt`.
diff --git a/node/troubleshooting.mdx b/node/troubleshooting.mdx
index e311d42..da4f6ea 100644
--- a/node/troubleshooting.mdx
+++ b/node/troubleshooting.mdx
@@ -123,6 +123,54 @@ seidb dump-flatkv --db-dir $HOME/.sei/data/flatkv --output-dir /home/ubuntu/flat
```
+
+### Comparing EVM State Between memIAVL and FlatKV
+
+When debugging an AppHash mismatch that involves EVM state, a byte-for-byte physical dump can diverge between backends even when the underlying state is identical. This is because every FlatKV value embeds a per-key block-height stamp (the height the key was last written or migrated), which differs from the memIAVL leaf versions on a freshly migrated node.
+
+The `evm-logical-digest` command works around this by computing a backend-independent digest of the EVM *logical* state — it strips the serialization-version and block-height header on both sides and digests only the logical payload (account balance/nonce/code hash, bytecode, and storage words). This lets a memIAVL node and a FlatKV node be compared at the same chain height:
+
+```bash
+# FlatKV digest at a height (WAL-replays to it):
+seidb evm-logical-digest --backend flatkv \
+ --db-dir $HOME/.sei/data/state_commit/flatkv --height 213200000
+
+# memIAVL digest at the same height (0 = current symlink):
+seidb evm-logical-digest --backend memiavl \
+ --db-dir $HOME/.sei/data/state_commit/memiavl --height 213200000
+```
+
+Each run prints per-bucket `bucket_digest` values and a single `FINAL_DIGEST` line covering the `account`, `code`, `storage`, and `legacy` buckets. Compare the `FINAL_DIGEST` lines from both backends at the same height — they should match. Because FlatKV can contain a FlatKV-only migration-version marker that a memIAVL-only node never owns, that row is automatically omitted from the FlatKV final result so the comparison is apples-to-apples.
+
+The `evm-logical-digest` command accepts the following flags:
+
+- `--backend`: backend to read (`flatkv` or `memiavl`).
+- `--db-dir` / `-d`: for FlatKV, the FlatKV data directory; for memIAVL, the memIAVL root directory (containing `current/` and `snapshot-*`).
+- `--height`: target version. FlatKV WAL-replays to it; memIAVL resolves `snapshot-/evm` (`0` selects the `current` symlink).
+- `--memiavl-normalization`: memIAVL normalization mode — `semantic`/`independent` (raw EVM key/value decoder, the default) or `translator` (routes each leaf through the current migration mapping).
+
+For targeted debugging, the command also supports inspecting a single normalized bucket instead of printing the global digest:
+
+- `--inspect-bucket`: inspect one bucket (`account`, `code`, `storage`, or `legacy`) instead of the global digest.
+- `--key-offset`: byte offset into the physical key before applying `--key-prefix` and sharding.
+- `--key-prefix`: hex prefix, relative to `--key-offset`, used to filter physical keys.
+- `--shard-next-bytes`: group matching keys by this many bytes after `--key-prefix`.
+- `--list`: list matching key/logical-value pairs instead of shard digests.
+- `--list-limit`: maximum pairs to print with `--list` (default `1000`; `<=0` means unlimited).
+- `--details`: include backend-specific version metadata in list mode.
+- `--find-hash`: a 32-byte hex per-entry hash to hunt for. When two `bucket_digest` values differ by exactly one entry, their XOR is that entry's hash; passing it prints every matching entry as a `FOUND-HASH` line.
+
+For example, to list the first 50 `account` rows with version metadata, or to shard the `storage` bucket under a key prefix by the next 2 bytes:
+
+```bash
+seidb evm-logical-digest --backend flatkv -d $HOME/.sei/data/state_commit/flatkv --height 213200000 \
+ --inspect-bucket account --list --list-limit 50 --details
+
+seidb evm-logical-digest --backend flatkv -d $HOME/.sei/data/state_commit/flatkv --height 213200000 \
+ --inspect-bucket storage --key-prefix 03 --shard-next-bytes 2
+```
+
+
**The legacy IAVL backend has been fully removed and SeiDB State Commit (SC) is now mandatory.** SC must be enabled via `sc-enable = true` in the `[state-commit]` section of `app.toml`. If SC is not enabled, the node no longer falls back to IAVL — it panics at startup with:
From 72199d3f790dfda97e60a9410ea3227b8f90bd58 Mon Sep 17 00:00:00 2001
From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com>
Date: Thu, 13 Aug 2026 00:00:25 +0000
Subject: [PATCH 62/63] docs: A new v6.6 upgrade version is introduced across
all EVM precompiles, and the oracle precompile is now retired so its on-chain
queries (getExchangeRates, getOracleTwaps) revert with an error.
(sei-protocol/sei-chain#3625)
---
evm/precompiles/oracle.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/evm/precompiles/oracle.mdx b/evm/precompiles/oracle.mdx
index 6ee1132..778c47b 100644
--- a/evm/precompiles/oracle.mdx
+++ b/evm/precompiles/oracle.mdx
@@ -6,4 +6,4 @@ keywords: ['oracle precompile', 'ethers.js', 'price feeds', 'exchange rates', 't
---
**Address:** `0x0000000000000000000000000000000000001008`
-**Deprecation Notice:** The native Sei Oracle is deprecated and will be shut off soon. We strongly recommend migrating to one of the third-party oracle providers, such as [Chainlink](/evm/oracles/chainlink), [Pyth](/evm/oracles/pyth-network), [Redstone](/evm/oracles/redstone), or [API3](/evm/oracles/api3).
+**Retired as of v6.6:** The native Sei Oracle precompile has been retired. On-chain oracle data queries are disabled — calling `getExchangeRates` or `getOracleTwaps` now reverts with the error `oracle precompile is retired; oracle data queries are disabled`. You must migrate to one of the third-party oracle providers, such as [Chainlink](/evm/oracles/chainlink), [Pyth](/evm/oracles/pyth-network), [Redstone](/evm/oracles/redstone), or [API3](/evm/oracles/api3).
From 4ad60b8181032f3ad415818ccbd51809c861d876 Mon Sep 17 00:00:00 2001
From: monty-sei
Date: Thu, 13 Aug 2026 10:25:23 +1000
Subject: [PATCH 63/63] docs: fix unclosed in distribution.mdx
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
mint broken-links failed:
Syntax error - Unable to parse evm/precompiles/distribution.mdx -
167:1-167:364: Expected a closing tag for `` (167:1-167:10)
before the end of `paragraph`
The callout opened inline on 167, a blank line on 168 ended the MDX
paragraph, and the closing tag sat on 169 — so the element was never closed
within its paragraph. Tag counts balanced 3:3, which is why nothing caught it
before the Mintlify parser.
Restructured to put the tags on their own lines, the multi-paragraph form MDX
accepts and the form already used by the other multi-paragraph Warning in this
same file.
---
evm/precompiles/distribution.mdx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/evm/precompiles/distribution.mdx b/evm/precompiles/distribution.mdx
index 21c209f..666a9bb 100644
--- a/evm/precompiles/distribution.mdx
+++ b/evm/precompiles/distribution.mdx
@@ -164,9 +164,11 @@ bool success = DISTR_CONTRACT.setWithdrawAddress(0x742d35Cc6634C0532925a3b8D4C9d
require(success, "Failed to set withdraw address");
```
-**Recipient Validation**: The withdrawal address must be able to receive external funds. If the target address cannot receive external funds — for example, an unassociated EVM-cast address — the call is rejected with `ErrInvalidRecipient` and fails. Ensure the withdrawal address is associated (or otherwise permitted to receive funds) before setting it.
+
+ **Recipient Validation**: The withdrawal address must be able to receive external funds. If the target address cannot receive external funds — for example, an unassociated EVM-cast address — the call is rejected with `ErrInvalidRecipient` and fails. Ensure the withdrawal address is associated (or otherwise permitted to receive funds) before setting it.
-Additionally, if a previously set withdrawal address later becomes invalid (blocked or no longer able to receive external funds), reward withdrawals automatically fall back to sending rewards to the delegator's own address instead.
+ Additionally, if a previously set withdrawal address later becomes invalid (blocked or no longer able to receive external funds), reward withdrawals automatically fall back to sending rewards to the delegator's own address instead.
+
### withdrawDelegationRewards