> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-bridge-release-v6-6-0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Sei Technical Reference

> Access detailed command syntax, configuration parameters, and troubleshooting procedures for node operators and validators running Sei network infrastructure.

This guide serves as a comprehensive reference for Sei node operators and
validators, providing detailed command syntax, configuration parameters, and
troubleshooting procedures. For API documentation, please refer to our API
Documentation section.

## Command Line Interface Reference

The `seid` binary provides extensive functionality for managing your Sei node.
Understanding these commands is essential for effective node operation and
troubleshooting.

### Node Management Commands

These commands help you control and monitor your node's operation:

<Danger>
  If you see an error such as `panic: recovered: runtime error: integer divide by zero` it means you can’t start nodes straight from the genesis file. Instead, sync to the block tip via [state sync](/node/statesync) or using a [snapshot](/node/snapshot).
</Danger>

```bash theme={"dark"}
# Start the node
seid start [flags]

# Show node status
seid status

# Show validator consensus key
seid tendermint show-validator

# Query node information
seid query node info
```

### Autobahn Config Generation

Generate an Autobahn (GigaRouter) JSON config from a set of node directories. Each node directory must contain `validator_pubkey.txt`, `node_pubkey.txt`, `autobahn_address.txt`, and `evmrpc_url.txt`. These pubkey files are written automatically alongside the key files when the validator key and node key are saved (in `validator:<pubkey>` and `node:ed25519:public:<hex>` formats, respectively). The `evmrpc_url.txt` file must contain the node's EVM RPC HTTP URL (e.g. `http://<host>:8545`), which is used to proxy EVM RPC requests to the validator that owns the sender's EVM address shard.

```bash theme={"dark"}
# Generate an autobahn config from one or more node directories
seid tendermint gen-autobahn-config [node-dirs...] --output <path>

# Using the short flag for the output path
seid tendermint gen-autobahn-config node_0 node_1 node_2 -o autobahn.json
```

The `--output` / `-o` flag is required and specifies the destination file path for the generated config. The command reads the following files from each supplied node directory:

| File                   | Description                                                   |
| ---------------------- | ------------------------------------------------------------- |
| `validator_pubkey.txt` | Autobahn validator public key in `validator:<pubkey>` format. |
| `node_pubkey.txt`      | p2p node public key in `node:ed25519:public:<hex>` format.    |
| `autobahn_address.txt` | Network address (`host:port`) for the node.                   |
| `evmrpc_url.txt`       | The node's EVM RPC HTTP URL (e.g. `http://<host>:8545`).      |

The command also accepts an optional `--persistent-state-dir` flag:

| Flag                     | Description                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--persistent-state-dir` | Directory to persist the Autobahn consensus and data-layer WALs across restarts. Defaults to `data/autobahn`, so persistence is enabled by default without operator action. Relative paths are resolved against the node's `--home` directory at load time; absolute paths are used unchanged. Pass `--persistent-state-dir=` (empty) to disable persistence and run both the consensus and data layers in-memory only. |

The resulting JSON file can then be referenced from `config.toml` via the `autobahn-config-file` field to enable Autobahn wiring at node startup.

### Key Management

Proper key management is crucial for security. These commands help you manage
your keys effectively:

```bash theme={"dark"}
# Create new key
seid keys add <name> [flags]

# List all keys
seid keys list

# Delete key
seid keys delete <name>

# Export key (encrypted)
seid keys export <name>

# Import key
seid keys import <name> <keyfile>

# Show key address
seid keys show <name> -a
```

### Transaction Commands

These commands allow you to interact with the blockchain:

```bash theme={"dark"}
# Send tokens
seid tx bank send <from-key> <to-address> <amount>usei [flags]

# Delegate tokens
seid tx staking delegate <validator-addr> <amount>usei --from <delegator-key>

# Withdraw rewards
seid tx distribution withdraw-rewards <validator-addr> --from <delegator-key>

# Edit validator
seid tx staking edit-validator [flags] --from <validator-key>
```

## Configuration Parameters

Understanding configuration parameters is essential for optimizing your node's
performance and security.

### App.toml Parameters

The app.toml file controls application-specific settings:

<Accordion title="Complete app.toml Configuration">
  ```toml theme={"dark"}
  # Minimum gas prices for transaction acceptance
  minimum-gas-prices = "0.02usei"

  # API configuration
  [api]
  enable = true
  swagger = true
  address = "tcp://0.0.0.0:1317"
  max-open-connections = 1000

  # State sync configuration
  [state-sync]
  snapshot-interval = 1000
  snapshot-keep-recent = 2

  # Memory management
  [mempool]
  size = 5000
  max-txs-bytes = 1073741824
  cache-size = 10000



  #### Block-Failed Transaction Re-Entry Protection

  The mempool tracks transactions that fail during block execution to prevent them from re-entering the mempool indefinitely. Some transactions consistently fail before fee charging in `DeliverTx`, which historically let them be re-submitted without limit and waste block and proxy-app resources.

  The mempool now applies the following policy on top of the existing `keep-invalid-txs-in-cache` setting:

  - When a committed transaction succeeds (`Code == OK`), it is kept in the cache and its entry in the block-failure tracker is cleared.
  - When a committed transaction fails and `keep-invalid-txs-in-cache` is `false`:
    - **First block failure:** the transaction is removed from the cache, allowing it to be re-submitted and retried once.
    - **Second (and subsequent) block failure:** the transaction is left in the cache. Any attempt to re-submit it is rejected by `CheckTx` with `ErrTxInCache`, preventing infinite re-entry.
  - A successful block inclusion resets the failure tracker, so a transaction that later succeeds regains its first-failure grace period.

  The block-failure tracker uses an LRU cache sized to match the mempool `cache-size`. When `cache-size` is `0`, tracking is disabled. This behavior is automatic and requires no additional configuration.


  # State commit configuration (SeiDB). State-commit is mandatory:
  # the node will panic on startup if sc-enable is false.
  [state-commit]
  sc-enable = true

  # State store configuration
  [state-store]
  ss-enable = true
  ss-backend = "pebbledb"
  ss-keep-recent = 100000
  ss-prune-interval = 600

  # Receipt store configuration
  [state-store.receipt-store]
  # Backend defines the receipt store backend.
  # The only supported backend is pebbledb (aka pebble), which is also the
  # default. The parquet/DuckDB backend has been removed; setting rs-backend to
  # "parquet" now returns an error.
  rs-backend = "pebbledb"

  # AsyncWriteBuffer defines the async queue length for commits applied to the
  # receipt store. Applies only when rs-backend = "pebbledb". Set <= 0 for
  # synchronous writes. Defaults to 100.
  async-write-buffer = 100

  # Interval in seconds to trigger pruning. Receipt retention is controlled by
  # the global min-retain-blocks flag. Defaults to 600 seconds.
  prune-interval-seconds = 600
  ```

  <Warning>
    The legacy IAVL backend has been fully removed. SeiDB state-commit is now required, so `sc-enable` must be `true` or the node will panic on startup. The former `iavl-cache-size` field, the entire `[iavl]` config section, and the IAVL-related base fields (`iavl-disable-fastnode`, `no-versioning`, `separate-orphan-storage`, `separate-orphan-versions-to-keep`, `num-orphan-per-file`, `orphan-dir`) are no longer valid and have no effect. The removed `compact`, `prune`, `latest_version`, and `debug dump-iavl` CLI commands and their IAVL/orphan-related start flags are also gone. Ensure `sc-enable = true` before upgrading.
  </Warning>
</Accordion>

### Config.toml Parameters

The config.toml file controls the core consensus engine and networking:

<Accordion title="Complete config.toml Configuration">
  ```toml theme={"dark"}
  # P2P Configuration
  [p2p]
  laddr = "tcp://0.0.0.0:26656"
  external-address = ""
  seeds = ""
  persistent_peers = ""
  upnp = false
  # Total connection budget. Inbound and outbound connections are now tracked in
  # fully separate pools, so a single peer may hold both an inbound and an
  # outbound connection at the same time.
  max-connections = 100
  # Maximum number of outbound connections to regular (non-persistent) peers.
  # Defaults to min(20, (max-connections+1)/2). Inbound capacity is derived as
  # max-connections - max-outbound-connections. Persistent and unconditional
  # peers are not counted against either limit.
  max-outbound-connections = 20
  allowed_pools = ""
  max_packet_msg_payload_size = 10240
  handshake_timeout = "20s"
  dial_timeout = "3s"

  # RPC Configuration
  [rpc]
  laddr = "tcp://0.0.0.0:26657"
  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
  # Maximum time to wait for a BroadcastTxCommit request to complete. When set to
  # a value greater than 0, the BroadcastTxCommit RPC now enforces this as a
  # context deadline on the request: if CheckTx and DeliverTx do not complete
  # within this duration, the request context is cancelled and the call returns a
  # timeout error. Set to "0s" to disable the timeout.
  timeout_broadcast_tx_commit = "10s"
  # Timeout to read HTTP request headers; mitigates slowloris attacks by limiting
  # the time allowed to read request headers. Set to "0s" to disable (not
  # recommended). Defaults to 10s.
  timeout-read-header = "10s"
  # HTTP write timeout; acts as a hard backstop for all handlers. Must be greater
  # than timeout_broadcast_tx_commit when non-zero. Set to "0s" to disable (not
  # recommended). Defaults to 30s.
  timeout-write = "30s"


  # Maximum number of results returned by the tx_search and block_search RPC
  # endpoints. The cap is applied after results are sorted, so the top matches
  # (per order_by) are preserved, and TotalCount reflects the post-cap count.
  # Must not be negative. Set to 0 to disable the cap (not recommended on public
  # nodes). Defaults to 10000.
  max-tx-search-results = 10000

  # Consensus Configuration
  [consensus]
  wal_file = "data/cs.wal/wal"
  timeout_propose = "3s"
  timeout_propose_delta = "500ms"
  timeout_prevote = "1s"
  timeout_prevote_delta = "500ms"
  timeout_precommit = "1s"
  timeout_precommit_delta = "500ms"
  timeout_commit = "1s"
  double_sign_check_height = 0
  ```

  <Note>
    The `[consensus]` section also accepts an `unsafe-overrides-enabled` field (defaults to `false`). This flag gates whether the `Unsafe*TimeoutOverride` fields (`UnsafeProposeTimeoutOverride`, `UnsafeProposeTimeoutDeltaOverride`, `UnsafeVoteTimeoutOverride`, `UnsafeVoteTimeoutDeltaOverride`, `UnsafeCommitTimeoutOverride`, and `UnsafeBypassCommitTimeoutOverride`) are actually applied to the resolved consensus timeouts.

    When `unsafe-overrides-enabled = false`, the unsafe timeout overrides are ignored and the node uses the on-chain timeout parameters (falling back to Tendermint defaults for any unset field). As a transitional exception, the overrides are still applied while the on-chain timeout params remain equal to the legacy "bad params" values — this preserves prior behavior until those params are corrected via a governance proposal.

    When `unsafe-overrides-enabled = true`, the unsafe overrides are applied on top of the resolved timeouts. In this mode `UnsafeBypassCommitTimeoutOverride` can also override `BypassCommitTimeout` to `false` (a nil override leaves the resolved value untouched).

    ```toml theme={"dark"}
    [consensus]
    # Gates whether the Unsafe*TimeoutOverride fields are applied. Defaults to false.
    unsafe-overrides-enabled = false
    ```
  </Note>

  <Warning>
    The `[consensus]` section still parses a `stateless-leader-election` field, but it is now **deprecated and ignored**. Stateless leader election is always enabled: the consensus engine always selects each round's leader via a deterministic seeded stateless computation. The former stateful proposer-priority leader-election mode is no longer supported.

    Historically `stateless-leader-election` defaulted to `false`, selecting leaders via the stateful proposer-priority mode. As of v6.5 stateless leader election defaults to `true`, and the field is now retained only for config-parsing compatibility. Setting it to `false` no longer has any effect — it will not fall back to proposer-priority selection. You can safely remove any `stateless-leader-election` line from existing `config.toml` files.

    ```toml theme={"dark"}
    [consensus]
    # Deprecated and ignored. Stateless leader election is always enabled;
    # setting this to false has no effect.
    stateless-leader-election = true
    ```
  </Warning>

  <Note>
    ABCI peer filtering has been removed. The deprecated `filter-peers` field in `config.toml` (under `[base]`) no longer has any effect and is no longer emitted in generated config templates. Tendermint no longer sends `/p2p/filter/addr/<IP:PORT>` or `/p2p/filter/id/<ID>` queries to the application, so peers can no longer be filtered by IP or node ID through the ABCI app. You can safely remove any `filter-peers` line from existing configs.
  </Note>
</Accordion>

### Autobahn (GigaRouter) Configuration

The `autobahn-config-file` field in `config.toml` enables the Autobahn (GigaRouter) feature. It specifies the path to a JSON file containing the Autobahn configuration, which defines the validator committee and the consensus/producer parameters. Leave it empty to disable Autobahn.

```toml theme={"dark"}
# Path to a JSON file containing the Autobahn (GigaRouter) configuration.
# Leave empty to disable Autobahn.
autobahn-config-file = ""
```

#### Giga Executor EVM Library (`SEI_EVMONE_LIB_DIR`)

The Giga executor loads the platform-specific `evmone` shared library from a fixed, trusted absolute path and verifies its SHA-256 digest against the value pinned for the current platform before handing it to the dynamic linker. Loading from an absolute path (rather than relying on the dynamic linker's search path) prevents the library from being substituted by planting a file earlier in the loader's search order.

The optional `SEI_EVMONE_LIB_DIR` environment variable lets operators override the directory the library is loaded from. It must be an absolute path to a root-owned, non-writable directory containing the trusted, integrity-verified `evmone` library.

The library directory is resolved in the following order — the first directory that actually contains the library wins:

1. `$SEI_EVMONE_LIB_DIR` — operator override, when set.
2. `/usr/lib` — the canonical install location used by release Docker images.
3. The source-tree directory — used for local development and tests.

```bash theme={"dark"}
# Point the Giga executor at a custom directory holding the trusted evmone library
export SEI_EVMONE_LIB_DIR=/opt/sei/lib
```

<Note>
  Release Docker images install the `evmone` library to `/usr/lib` and add the `libstdc++6` runtime dependency, so no additional configuration is required for standard deployments. If the resolved library's SHA-256 digest does not match the pinned value, the node fails to start with a digest-mismatch error.
</Note>

When Autobahn is enabled, the referenced JSON file supports the following fields:

```json theme={"dark"}
{
  "validators": [
    {
      "validator_key": "<autobahn validator public key>",
      "node_key": "node:ed25519:public:<hex>",
      "address": "host:port"
    }
  ],
  "max_txs_per_block": 5000,
  "max_txs_per_second": 1000,
  "block_interval": "400ms",
  "allow_empty_blocks": false,
  "view_timeout": "1500ms",
  "persistent_state_dir": "/path/to/state",
  "dial_interval": "10s"
}
```

<Note>
  The `max_gas_per_block` field has been removed from the Autobahn config file. The producer's max-gas-per-block is now derived from the chain's genesis `consensus_params.block.max_gas` — the same gas-limit consensus rule the EVM runtime reads. This value must be greater than 0, otherwise the node fails to start with an `ErrGenesisMaxGasInvalid` error (`genesis consensus_params.block.max_gas must be > 0`). Node operators upgrading from an earlier release must remove any `max_gas_per_block` line from their Autobahn config file.
</Note>

<Note>
  The `mempool_size` field has been removed from the Autobahn config file. The mempool capacity is now derived automatically from the number of unexecuted blocks the local lane may hold (`BlocksPerLane`), so it no longer needs to be configured. Node operators upgrading from an earlier release must remove any `mempool_size` line from their Autobahn config file.
</Note>

| Field                  | Description                                                                                           |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| `validators`           | List of committee members, each with a `validator_key`, `node_key`, and `address`. Must not be empty. |
| `max_txs_per_block`    | Maximum number of transactions per block. Must be greater than 0.                                     |
| `max_txs_per_second`   | Optional cap on transactions per second.                                                              |
| `block_interval`       | Target interval between blocks (e.g. `400ms`). Must be greater than 0.                                |
| `allow_empty_blocks`   | Whether to produce empty blocks.                                                                      |
| `view_timeout`         | Consensus view timeout. Must be greater than 0.                                                       |
| `persistent_state_dir` | Optional directory for persistent consensus state.                                                    |
| `dial_interval`        | Interval between peer dial attempts. Must be greater than 0.                                          |

<Warning>
  When Autobahn is enabled, remote validator signers are not supported: the node fails to start if `priv-validator.laddr` is set. A local validator key is required — non-validator (observer) nodes are not yet supported. The node must be a committee member, so its own validator key and node key must appear in the `validators` list.
</Warning>

#### Block Production and Disabled Reactors

When Autobahn is enabled, block production and network wiring change significantly:

* **Shared mempool as the block source:** The Autobahn producer builds blocks by reaping transactions directly from the shared `TxMempool` (the same mempool used for `CheckTx`), rather than from a separate producer mempool channel. Transactions that are included in a block are popped from the shared mempool.
* **Disabled reactors:** Because Autobahn drives consensus and block dissemination itself, the node skips starting the mempool gossip reactor, the consensus reactor, statesync, and blocksync when Autobahn is enabled. As a result, transactions are not gossiped over the standard mempool p2p channel, and the node does not perform block sync or state sync.

#### RPC Behavior Under Autobahn

Because the CometBFT block store and consensus reactor are not fed under Autobahn, some RPC responses behave differently:

* **`/status` derives height and app hash from the app layer:** With Autobahn enabled the CometBFT block store height stays at 0, so the `/status` handler pulls `SyncInfo.latest_block_height` and `SyncInfo.latest_app_hash` from the application layer (via `ABCIInfo`) instead of the block store. This reports the last height the app committed in `FinalizeBlock` and its matching app hash.
* **New `last_committed_block_height` field:** The `SyncInfo` object in the `/status` response now includes a `last_committed_block_height` field (JSON string-encoded int64) reporting the last block finalized by consensus. Under CometBFT this always equals `latest_block_height` (commit and app-apply happen in one step). Under Autobahn it is derived from the latest CommitQC and may briefly lead `latest_block_height`, since consensus finalizes a block before the app executes it.
* **Unpopulated `/status` fields:** Several `SyncInfo` fields remain unpopulated under Autobahn: `latest_block_hash`, `latest_block_time`, the `earliest_*` fields, and `max_peer_block_height`. `catching_up` is currently hardcoded to `true` because the consensus reactor is nil.
* **Block-data endpoints now serve data via the GigaRouter:** Because the CometBFT block store and state store are not populated under Autobahn, `/block`, `/block_by_hash`, `/block_results`, and `/validators` are routed through the GigaRouter's in-memory state instead of the block store. This keeps these endpoints — and the EVM RPC endpoints that walk through them (e.g. `eth_getBlockByNumber`) — working, with the following caveats:

  * **`/block`** returns the finalized global block at the requested height, translated into the CometBFT `ResultBlock` shape (populating `BlockID.Hash`, `ChainID`, `Height`, `Time`, and `Data.Txs`). Requests for pruned heights return an `ErrHeightNotAvailable`-class error.
  * **`/block_by_hash`** resolves a block by its Autobahn header hash via an in-memory hash index. Matching CometBFT semantics, an unknown hash — or a hash below the pruning watermark — returns `{Block: nil}` with no error.
  * **`/block_results`** returns a valid-but-empty result at the requested height. `ConsensusParamUpdates.Block.MaxGas` is populated from the producer's configured `max_gas_per_block`, but `TxsResults` is intentionally empty because `FinalizeBlock` responses are not persisted under Autobahn (no per-tx `ExecTxResult` details).
  * **`/validators`** returns the genesis committee for any retained height, with `block_height` matching the requested height (fixing the prior behavior where the height could get stuck at 1).

  Note that these endpoints read from the GigaRouter's in-memory state, which is pruned according to the node's retain height; historical queries below the retain window are not available. Endpoints that still depend on the unpopulated CometBFT block/state store — such as `/commit` — remain unaffected by this routing and behave as before.

#### Hard Per-Block Limits

In addition to the configurable `max_gas_per_block` and `max_txs_per_block` fields, Autobahn enforces on-chain hard limits when building a block's payload. These are protocol-level caps and always apply, regardless of the values set in the config file:

| Limit                           | Value                      | Description                                                                                                                                                                                                            |
| ------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Maximum transactions per block  | 2000                       | No more than 2000 transactions may be included in a single Autobahn block.                                                                                                                                             |
| Maximum total transaction bytes | \~2 MB (2000 × 1024 bytes) | The combined size of all transactions in a block may not exceed roughly 2 MB. This budget can be distributed arbitrarily across transactions (e.g. one large tx or many small ones) up to the transaction-count limit. |

<Note>
  The effective per-block transaction count is the smaller of the configured `max_txs_per_block` and the hard limit of 2000. If you configure a larger value, the 2000-tx cap still applies. The block proto size upper bound used for p2p message sizing is derived from these limits.
</Note>

#### Committee Size Ceiling

Autobahn enforces a hard upper bound of **100 validators** per committee. Committee construction (`NewCommittee`) rejects any validator set larger than this ceiling, returning an error rather than starting consensus. This `MaxValidators = 100` limit is a protocol-level invariant and applies regardless of how many entries appear in the `validators` list of the Autobahn config file.

<Warning>
  A validator set exceeding 100 members will cause committee creation to fail. Ensure the `validators` list in your Autobahn config file contains no more than 100 members.
</Warning>

#### Wire-Format Message Limits

Autobahn also enforces structural size and count limits on its protobuf messages during deserialization. These bounds are checked while scanning the raw wire bytes — *before* a message is fully decoded — so that oversized or malformed payloads are rejected without allocating unbounded memory. A message that violates any of these limits is dropped and the sending peer is disconnected.

The enforced field limits include:

| Field                                 | Limit                    | Description                                                                                                                                                                                                                 |
| ------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ed25519 public key                    | 32 bytes                 | `PublicKey.ed25519` is bounded to a fixed 32-byte length.                                                                                                                                                                   |
| Signature bytes                       | 64 bytes                 | `Signature.sig` is bounded to a fixed 64-byte length.                                                                                                                                                                       |
| Block / payload / parent / app hashes | 32 bytes                 | Hash fields (e.g. `parent_hash`, `payload_hash`, `last_hash`, `app_hash`) are bounded to 32 bytes each.                                                                                                                     |
| Payload transaction count             | 2000                     | `Payload.txs` may contain at most 2000 transactions.                                                                                                                                                                        |
| Payload total transaction size        | \~2 MB (2,048,000 bytes) | The combined byte size of all transactions in a payload may not exceed 2,048,000 bytes.                                                                                                                                     |
| QC signature lists                    | 100                      | Signature lists on quorum certificates (`PrepareQC`, `CommitQC`, `AppQC`, `LaneQC`) and vote lists on `TimeoutQC` and `FullProposal.lane_qcs` are each capped at 100 entries, matching the 100-validator committee ceiling. |

<Note>
  These wire-format bounds are applied to every Autobahn consensus and data-layer message on receipt. They are protocol-level invariants and are not configurable. Because they are enforced during message scanning rather than after decoding, they protect nodes from resource-exhaustion attacks that rely on the decoded representation being far larger than the encoded bytes.
</Note>

## Network Parameters

### Query Pagination Limits

Queries that support pagination now enforce hard caps to protect nodes from unbounded store walks. Requests that exceed any of these bounds are rejected with an `InvalidArgument` gRPC error.

| Parameter      | Value | Description                                                                                                                                                                                 |
| -------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MaxLimit`     | 1000  | Maximum page size. A `limit` above this returns an `exceeds maximum allowed limit` error.                                                                                                   |
| `MaxOffset`    | 10000 | Maximum offset allowed in a `PageRequest`. An `offset` above this returns an `exceeds maximum allowed offset` error.                                                                        |
| `MaxScanLimit` | 10000 | Maximum number of store entries offset-based (lazy) pagination will scan past the page end. Exceeding it returns a `scanned more than 10000 entries` error suggesting key-based pagination. |

<Note>
  For datasets larger than a single page, use **key-based pagination** (`pagination.key`) rather than offset-based pagination. With offset-based pagination over a sparse filter, the scan limit may be reached before the page fills, in which case the returned `next_key` can be `nil` even when more results exist.
</Note>

<Warning>
  `count_total` is no longer automatically enabled when `limit` is omitted or set to zero. Previously an empty or zero-limit page request would populate the `total` field; now `total` is `0` unless you explicitly set `pagination.count_total = true`. Requesting `count_total` on a large dataset can also hit the `MaxScanLimit` and fail — prefer key-based pagination for full traversals.
</Warning>

### Build Tags

The `seid` binary can be compiled with optional Go build tags that alter consensus behavior. Build tags are passed via the `GO_BUILD_TAGS` build argument.

The `seid` binary decides how to react to a halting validation failure at compile time via the `ConsensusPolicy` type. Each build variant compiles in exactly one policy through its `ConsensusPolicy.HandleError(err)` method, so there is no runtime branch:

* **Default (production):** `HandleError` returns the error for every validation-failure kind, so production halting semantics are unchanged.
* **`mock_block_validation`:** `HandleError` swallows only `ErrAppHash` and `ErrDataHash` failures (the same effective set the tag has always relaxed) and halts on everything else.
* **`mock_chain_validation`:** `HandleError` swallows every swallow-eligible halting validation failure except `ErrLastCommitVerify` (excluded to avoid a downstream panic in `buildLastCommitInfo`).

When a non-default policy swallows a failure, it increments the `sei_unsafe_validation_skipped_total` counter (labeled with the failure via the `validation_error` attribute) instead of halting. This metric is only emitted by the non-default (mock) build variants.

#### `mock_block_validation`

Building with `GO_BUILD_TAGS=mock_block_validation` produces a `seid` binary whose `ConsensusPolicy.HandleError` swallows `AppHash` and `DataHash` block validation failures during block execution and validation, incrementing `sei_unsafe_validation_skipped_total` for each swallowed failure instead of halting. All other validation-failure kinds halt as in production.

<Warning>
  The `mock_block_validation` build is intended for testing and mock environments only. It disables cryptographic block-content validation and must never be used for a production or mainnet node.
</Warning>

A corresponding Docker image is published to ECR for this build:

```text theme={"dark"}
sei/sei-chain:mock_block_validation-<tag/ref/sha>
```

This image is built with `GO_BUILD_TAGS=mock_block_validation` and is distinct from the standard `sei/sei-chain` image tags.

#### `mock_chain_validation`

Building with `GO_BUILD_TAGS=mock_balances mock_chain_validation` produces a `seid` binary whose `ConsensusPolicy.HandleError` swallows every swallow-eligible halting validation failure except `ErrLastCommitVerify`. The chain still computes every check authentically; a swallowed failure increments `sei_unsafe_validation_skipped_total{kind=...}` and continues instead of halting. `ErrLastCommitVerify` is the exception — it always halts and is not counted, because swallowing it would trigger a downstream panic in `buildLastCommitInfo`. This variant is intended for forked-state replays.

<Warning>
  The `mock_chain_validation` build is intended for testing and forked-state replay environments only. It swallows nearly all halting consensus validation failures and must never be used for a production or mainnet node.
</Warning>

Corresponding Docker images are published to ECR for this build:

```text theme={"dark"}
sei/sei-chain:mock_chain_validation-<tag/ref/sha>
sei/sei-chain:mock_chain_validation-nightly-<date>-<sha7>
```

These images are built with `GO_BUILD_TAGS=mock_balances mock_chain_validation` and are distinct from the standard `sei/sei-chain` image tags.

Understanding network parameters helps you operate your node effectively.

### Chain Parameters

These parameters define the network's behavior:

```text theme={"dark"}
Block Time: ~400ms target
Max Validators: 40
Unbonding Period: 21 days
Minimum Self Delegation: 1 SEI

Slashing Parameters:
  - signed_blocks_window:        108,000 blocks
  - min_signed_per_window:       5%   (validator must sign ≥5% of blocks in the window)
  - downtime_jail_duration:      10 minutes
  - slash_fraction_downtime:     0%   (no stake slash; jail only)
  - slash_fraction_double_sign:  0%   (no stake slash; double-signing still triggers
                                       permanent tombstoning)

Oracle Slashing Parameters:
  - min_valid_per_window:        0%   (default now 0% — no oracle vote slashing,
                                       since the Oracle Price Feeder is retired)
```

<Info>
  These values reflect the current on-chain parameters. Query them directly with `seid query staking params` and `seid query slashing params` for the source of truth. Per-validator settings (e.g. commission rate, commission max change rate) are configured per validator and are not chain-level parameters.
</Info>

## File Locations

Understanding the purpose and location of important files helps with maintenance
and troubleshooting:

```text theme={"dark"}
$HOME/.sei/
├── config/
│   ├── app.toml         # Application configuration
│   ├── client.toml      # Client configuration
│   ├── config.toml      # Tendermint configuration
│   ├── genesis.json     # Chain genesis file
│   ├── node_key.json    # Node identity key
│   └── priv_validator_key.json  # Validator signing key
├── data/
│   ├── application.db      # Application state
│   └── tendermint/         # Tendermint databases (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
```

<Note>
  New nodes place the Tendermint databases (`blockstore.db`, `state.db`, `tx_index.db`, `evidence.db`, `peerstore.db`, and `cs.wal`) under `data/tendermint/`. Existing nodes that already have these databases in the legacy flat `data/` layout are detected automatically and continue using the legacy paths — no migration is required. This automatic legacy-path fallback also applies to `reset`, `reindex-event`, and consensus WAL path resolution.
</Note>

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.
