From b7a2eca64ea2f8c07fe4da9ac8873ecc0df8bd23 Mon Sep 17 00:00:00 2001 From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:24:07 +0000 Subject: [PATCH 1/4] skills: Adds a new '--freeze-height' CLI flag and 'freeze-height' app.toml config field that stops a node before executing a target block while continuing to serve RPC, with validation constraints against halt-height/halt-time, grpc-only, state sync, seed mode, and Autobahn. (sei-protocol/sei-chain#3978) --- skill/references/cli/seid-cli.md | 30 ++++++++++++++++ skill/references/ecosystem/node-operations.md | 36 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/skill/references/cli/seid-cli.md b/skill/references/cli/seid-cli.md index 9e25ca7..d2b1c07 100644 --- a/skill/references/cli/seid-cli.md +++ b/skill/references/cli/seid-cli.md @@ -202,6 +202,36 @@ seid tx evm call-precompile [args...] Available precompile names: `distribution`, `json`, `p256`, `staking`. See [EVM Precompiles](https://docs.sei.io/evm/precompiles) for method signatures. + + +## Node Start (`seid start`) + +### `--freeze-height` + +Stops the node *before* executing a target block while keeping the process and RPC servers running (unlike `--halt-height`, which gracefully shuts the node down). Block sync and consensus stop before executing the block at the configured height and do not advance beyond it. + +```bash +seid start --freeze-height +``` + +- Default `0` disables freeze mode. +- Also settable via the `freeze-height` field in the `[base]` section of `app.toml` (`freeze-height = 0` by default). + +Constraints: +- Must not exceed `MaxInt64`. +- Cannot be combined with `--halt-height`/`halt-height` or `--halt-time`/`halt-time`. +- Cannot be combined with grpc-only mode (`--grpc-only`). +- State sync is disabled under freeze mode and falls back to block sync. +- Not supported with seed mode or Autobahn. +- The target height must be above the node's initial height and must not already be reached by the application, block store, or state store — otherwise the node refuses to start. +- Auto-remediation restart halts at the freeze boundary rather than restarting past it. + +Example — freeze a node just before executing block 5,000,000 while continuing to serve RPC: + +```bash +seid start --freeze-height 5000000 +``` + ## curl and JSON-RPC Use `curl` when the user wants raw EVM RPC access, debug methods, or JSON-RPC examples. Use `seid` for everything else. diff --git a/skill/references/ecosystem/node-operations.md b/skill/references/ecosystem/node-operations.md index 8ba5010..cecb359 100644 --- a/skill/references/ecosystem/node-operations.md +++ b/skill/references/ecosystem/node-operations.md @@ -287,6 +287,42 @@ make install sudo systemctl restart seid ``` + + +--- + +## Freeze Height (`--freeze-height` / `freeze-height`) + +Stops the node **before executing** a target block while **continuing to serve RPC** (the process and gRPC/JSON-RPC servers keep running). Unlike `halt-height`, which gracefully shuts the node down, freeze mode keeps the node alive and queryable at `freeze-height - 1`. + +Enable it via the start flag or the `app.toml` `BaseConfig` field (both default `0` = disabled): + +```bash +# CLI flag on the start command +seid start --chain-id pacific-1 --freeze-height 12345678 +``` + +```toml +# app.toml (BaseConfig section, alongside halt-height / halt-time) +freeze-height = 12345678 +``` + +### Behavior + +- Block sync and consensus stop before executing the block at `freeze-height` and never advance beyond it — the node settles at `freeze-height - 1`. +- The node keeps serving RPC while frozen (no WAL writes, no new consensus rounds). +- **State sync is disabled** when freeze mode is active and the node falls back to block sync. +- Auto-remediation restart halts at the freeze boundary rather than restarting past it. + +### Validation constraints (startup fails if violated) + +- `freeze-height` **cannot be combined with `halt-height` or `halt-time`**. +- `--freeze-height` **cannot be used with grpc-only mode**. +- **Not supported in seed mode** (`mode = seed`). +- **Not supported with Autobahn** (fails if `autobahn-config-file` is set). +- Must **not exceed `MaxInt64`** (`9223372036854775807`). +- Must be **above the genesis initial height** and **above the current application, block store, and state store heights** — you cannot freeze at a height the node has already reached or passed. + --- ## Database Management From 89829db348f3cefac3fda0e546c886af8047b251 Mon Sep 17 00:00:00 2001 From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:26:03 +0000 Subject: [PATCH 2/4] skills: Adds a new `frozen-rpc-router` binary that proxies EVM JSON-RPC requests to live and freeze-height-frozen nodes based on block number, plus a new `--freeze-height` flag on `seid start`. (sei-protocol/sei-chain#4024) --- skill/references/cli/frozen-rpc-router.md | 67 +++++++++++++++++++++++ skill/references/cli/seid-cli.md | 4 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 skill/references/cli/frozen-rpc-router.md diff --git a/skill/references/cli/frozen-rpc-router.md b/skill/references/cli/frozen-rpc-router.md new file mode 100644 index 0000000..624ff4b --- /dev/null +++ b/skill/references/cli/frozen-rpc-router.md @@ -0,0 +1,67 @@ +# frozen-rpc-router + +`frozen-rpc-router` exposes an HTTP EVM JSON-RPC endpoint that proxies requests to a live node and any number of freeze-height-frozen nodes, routing each request by block number (added in sei-chain #frozen-rpc-router, v6.6.3). + +## Freeze height model + +A freeze height is an **exclusive** boundary. A node started with `seid start ... --freeze-height 100` serves blocks through height 99. The router therefore sends height 99 to that node and height 100 to the next configured interval (or to the live node). + +To run a frozen node, start `seid` with the `--freeze-height` flag: + +```sh +seid start --chain-id sei --inv-check-period 0 --freeze-height 100 +``` + +## Usage + +```sh +go run ./cmd/frozen-rpc-router \ + --listen-address 0.0.0.0:8545 \ + --live-node localhost:9545 \ + --frozen-node 1000000=localhost:9546 \ + --frozen-node 2000000=10.0.0.12:8545 +``` + +Or build and run the binary: + +```sh +make build-frozen-rpc-router +./build/frozen-rpc-router --live-node localhost:9545 --frozen-node 1000000=localhost:9546 +``` + +## Flags + +| Flag | Default | Description | +|------|---------|-------------| +| `--listen-address` | `127.0.0.1:8545` | Address on which the router listens. | +| `--live-node` | (required) | HTTP RPC address of the live node. | +| `--frozen-node` | — | `freeze-height=ip:port` pair; repeat once per frozen node. | +| `--max-request-body-bytes` | `5242880` (5 MiB) | Maximum JSON-RPC request body size. Must be positive. | +| `--shutdown-timeout` | `10s` | Graceful shutdown timeout. Must be positive. | + +- `--live-node` is required; omitting it fails with `--live-node is required`. +- Each `--frozen-node` value must be `freeze-height=ip:port`; the freeze height must be a positive integer no greater than `math.MaxInt64`, and freeze heights must be unique (duplicates fail with `duplicate freeze height `). +- Node addresses may include an explicit `http://` or `https://` scheme; a bare `ip:port` is treated as `http://`. +- Frozen nodes may be listed in any order; the router sorts them by freeze height internally. + +## Routing behaviour + +- **Methods with explicit numeric block parameters** (e.g. `eth_getBlockByNumber`, `eth_getBalance`, `eth_call`, `eth_getStorageAt`, `debug_traceBlockByNumber`, and others) are routed to the frozen interval whose freeze height is greater than the requested height, or to the live node if no frozen interval covers it. The `earliest` tag routes to the lowest frozen interval (height 0). +- **`eth_getLogs` and `eth_feeHistory`** are routed only when their entire explicit block range falls within one interval. A range crossing an interval boundary returns JSON-RPC error `-32000` (`block ranges spanning multiple frozen-node intervals are not supported`). For a notification (no `id`), no error is returned. +- **Latest-style block tags** (`latest`, `pending`, `safe`, `finalized`), methods without block numbers, `eth_getLogs` by `blockHash`, EIP-1898 `blockHash` references, stateful filter methods, subscriptions, and WebSocket / non-POST requests all go to the **live** node. + +## Sei-RPC-Route response header + +Every HTTP response carries a `Sei-RPC-Route` header describing where the request was served: + +- `frozen:` — served entirely by the frozen node with that freeze height. +- `live` — served entirely by the live node. +- `mixed` — a batch request split across multiple backends. + +## Other error codes + +- `-32700` parse error (invalid JSON). +- `-32600` invalid request. +- `-32000` unsupported (range spanning intervals). +- `-32001` upstream request failed. +- Requests exceeding `--max-request-body-bytes` return HTTP `413 Request Entity Too Large`. diff --git a/skill/references/cli/seid-cli.md b/skill/references/cli/seid-cli.md index d2b1c07..0873677 100644 --- a/skill/references/cli/seid-cli.md +++ b/skill/references/cli/seid-cli.md @@ -226,7 +226,9 @@ Constraints: - The target height must be above the node's initial height and must not already be reached by the application, block store, or state store — otherwise the node refuses to start. - Auto-remediation restart halts at the freeze boundary rather than restarting past it. -Example — freeze a node just before executing block 5,000,000 while continuing to serve RPC: +The freeze height is an *exclusive* boundary: a node started with `--freeze-height 100` serves blocks through height 99 and never executes block 100. This is the interval semantics the `frozen-rpc-router` relies on when routing requests by block number (see [Frozen RPC Router](frozen-rpc-router.md)). + +Example — freeze a node just before executing block 5,000,000 while continuing to serve RPC (the node serves blocks through height 4,999,999): ```bash seid start --freeze-height 5000000 From 4ec22116227435656ad42090359e8740b462c664 Mon Sep 17 00:00:00 2001 From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:26:34 +0000 Subject: [PATCH 3/4] skills: The frozen-rpc-router command adds a new --max-block-reference-depth CLI flag (default 16) to bound nested block reference parsing depth. (sei-protocol/sei-chain#4034) --- skill/references/cli/frozen-rpc-router.md | 1 + 1 file changed, 1 insertion(+) diff --git a/skill/references/cli/frozen-rpc-router.md b/skill/references/cli/frozen-rpc-router.md index 624ff4b..3229094 100644 --- a/skill/references/cli/frozen-rpc-router.md +++ b/skill/references/cli/frozen-rpc-router.md @@ -37,6 +37,7 @@ make build-frozen-rpc-router | `--live-node` | (required) | HTTP RPC address of the live node. | | `--frozen-node` | — | `freeze-height=ip:port` pair; repeat once per frozen node. | | `--max-request-body-bytes` | `5242880` (5 MiB) | Maximum JSON-RPC request body size. Must be positive. | +| `--max-block-reference-depth` | `16` | Maximum nested block reference depth when parsing block references. Must be positive. | | `--shutdown-timeout` | `10s` | Graceful shutdown timeout. Must be positive. | - `--live-node` is required; omitting it fails with `--live-node is required`. From cdd8e3903d2f6f690fc389dac4e147c6db7d740f Mon Sep 17 00:00:00 2001 From: "seidroid[bot]" <257742136+seidroid[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:27:13 +0000 Subject: [PATCH 4/4] skills: The frozen-rpc-router adds two new CLI flags, --batch-request-limit and --write-timeout, to configure JSON-RPC batch size limits and HTTP response write timeouts. (sei-protocol/sei-chain#4048) --- skill/references/cli/frozen-rpc-router.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/skill/references/cli/frozen-rpc-router.md b/skill/references/cli/frozen-rpc-router.md index 3229094..11737ff 100644 --- a/skill/references/cli/frozen-rpc-router.md +++ b/skill/references/cli/frozen-rpc-router.md @@ -38,6 +38,10 @@ make build-frozen-rpc-router | `--frozen-node` | — | `freeze-height=ip:port` pair; repeat once per frozen node. | | `--max-request-body-bytes` | `5242880` (5 MiB) | Maximum JSON-RPC request body size. Must be positive. | | `--max-block-reference-depth` | `16` | Maximum nested block reference depth when parsing block references. Must be positive. | + + +| `--batch-request-limit` | `1000` | Maximum number of calls in a JSON-RPC batch. Must be positive. | +| `--write-timeout` | `30s` | Maximum duration for writing an HTTP response. Must be positive. | | `--shutdown-timeout` | `10s` | Graceful shutdown timeout. Must be positive. | - `--live-node` is required; omitting it fails with `--live-node is required`.