fleet-router 0.6.0

Reverse proxy and load balancer for the Antelope SHiP (State History Plugin) WebSocket protocol.
fleet-router-0.6.0 is not a library.

fleet-router

A reverse proxy and load balancer for the Antelope SHiP (State History Plugin) WebSocket protocol.

CI Crates.io License: MIT

Homepage · Configuration · Operations · Observability · Dashboard & API · Changelog

Run more than one SHiP node? Put fleet-router in front of them and give your clients (Hyperion, other indexers, custom consumers) one resilient endpoint instead of pinning each consumer to one node.

Clients open a single WebSocket connection to the router. The router picks a healthy upstream, forwards its ABI, and proxies the stream. If that upstream drops, the router fails over to another suitable node, resumes get_blocks at the next block, and de-duplicates blocks the client already has. The client connection stays open.

                                    +-----------------------+
                                    |  upstream SHiP node A | (active)
                            +-----> |  ws://hostA:port      |
                            |       +-----------------------+
+--------+   WebSocket   +--+-----------+
| client | ============> | fleet-router |   range-aware / least-connections
+--------+               +--+-----------+   selection + health monitoring
                            |       +-----------------------+
                            +-----> |  upstream SHiP node B | (failover target:
       on upstream A failure,       |  ws://hostB:port      |  resume at next block,
       transparent swap to B  ----> +-----------------------+  de-duplicate blocks)

Features

  • Failover without reconnecting. On upstream loss the session moves to another node, resumes at the next block, drops replayed blocks, and replays client frames sent during the swap.
  • Range-aware, least-connections routing. Requests go to an upstream whose trace range covers the requested block, otherwise to the least-loaded healthy one. Optional per-node priority and weight mark preferred and last-resort nodes and split load. fetch_finality_data requests go only to nodes whose finality range covers the block.
  • Stale nodes are deprioritized, not excluded. Upstreams that stop advancing drop down the list.
  • Bounded failure on corrupted SHiP logs. A block that breaks every upstream ends the session with close code 1011 and a clear reason instead of a silent stall. Opt-in quarantine skips one node for just the bad block range.
  • Several networks in one process. Each listener has its own port, upstream pool, chain_id, connection cap, and /ready/<name> check.
  • chain_id verification. Upstreams that report the wrong chain stay offline. Older nodes that omit chain_id (FIO and other EOSIO 2.0-based builds) stay usable unless you require it.
  • Operable. Prometheus metrics, health and readiness endpoints, tracing logs, graceful shutdown, upstream wss://, and connection, timeout and message-size limits.
  • Live dashboard and control API (opt-in). See every upstream's block range, load and health in real time, and drain a node for maintenance: its sessions move to other nodes without the clients reconnecting.

Installation

cargo install fleet-router              # from crates.io
docker pull ghcr.io/eosrio/fleet-router  # container image

Prebuilt archives for Linux x86_64, macOS (arm64 and x86_64) and Windows x86_64 are attached to each GitHub Release. To build from source:

git clone https://github.com/eosrio/fleet-router.git
cd fleet-router
cargo install --path .

Requirements and supported platforms

fleet-router builds on Linux, macOS, and Windows (x86_64 and arm64).

  • Rust ≥ 1.99 (MSRV). Install it with rustup if needed.
  • A C compiler and CMake on PATH, to build aws-lc-rs for upstream wss://. Not needed at runtime.

ABI handling uses the pure-Rust rs_abieos backend, so libclang is not required.

Quick start

fleet-router config init ./config.json   # 1. write a sample config
#                                          2. list your SHiP nodes in config.json
fleet-router config test ./config.json   # 3. validate and test upstream connectivity
fleet-router run --config ./config.json  # 4. start the proxy

To start fleet-router at boot and restart it after a crash, run it as a service: systemd, Docker, launchd or Windows.

A minimal config with two SHiP nodes:

{
  "listen_address": "0.0.0.0",
  "listen_port": 17000,
  "upstream_reconnect_ms": 3000,
  "upstream_monitoring_ms": 5000,
  "upstream_status_ms": 5000,
  "servers": [
    { "name": "SHiP Node 1", "endpoint": "127.0.0.1:18080", "enabled": true },
    { "name": "SHiP Node 2", "endpoint": "127.0.0.1:28080", "enabled": true }
  ]
}

A bare host:port is dialed as ws://; use wss://host:port for nodes that serve TLS. Then point your client's SHiP URL at the router (ws://<router-host>:17000) instead of a single node.

On startup the router validates the config and logs its upstream monitors:

configuration is valid.
INFO starting upstream monitor name="SHiP Node 1" upstream=127.0.0.1:18080
INFO listening for clients address=0.0.0.0 port=17000

Commands

fleet-router config init <path>     Write a sample config file to <path>.
fleet-router config test <path>     Parse and validate a config, then test upstream connectivity.
fleet-router run [--config <path>]  Run the proxy.
fleet-router check [--port <port>]  Exit 0 if 127.0.0.1:<port> accepts TCP (default 17000).
fleet-router --version              Print the version.
fleet-router --help                 Print help.

--config is global and defaults to ./config.json.

Documentation

Security

The client listener is plaintext ws:// and unauthenticated. Run fleet-router on a trusted network or behind a TLS-terminating reverse proxy that adds access control. Do not expose it directly to the public internet. See Security for details.

To report a vulnerability, follow SECURITY.md. Please do not open public issues for security reports.

Contributing

Contributions are welcome. CONTRIBUTING.md covers the development setup, the CI checks, and the pre-PR checklist. Tests run against an in-repo mock SHiP double and need no external services. This project follows the Code of Conduct.

Release notes are in CHANGELOG.md (Keep a Changelog format).

License

Licensed under the MIT License. © EOS Rio.