Node Flags
node-deploy sets these for you in each role's Compose file. This page is for
reading what is already there, or diverging from it deliberately.
Common flags
| Flag | Description | Default |
|---|---|---|
--chain | Chain specification | dev |
--base-path | Data directory | platform-specific |
--name | Node name, shown in telemetry | random |
--port | P2P port | 30333 |
--rpc-port | RPC port — serves both HTTP and WebSocket | 9944 |
--validator | Author blocks | false |
--state-pruning | How much state to keep (archive, or a block count) | 256 |
--blocks-pruning | How many block bodies to keep | 256 |
--sync | Sync mode: full, fast, fast-unsafe, warp | full |
--database | Database backend; paritydb is experimental | RocksDB |
--prometheus-port | Metrics port | 9615 |
--ws-portSubstrate unified HTTP and WebSocket onto one port. --pruning still parses, but
only as an alias for --state-pruning — it does not control block-body
pruning, so use the canonical pair.
What each role sets
| Flag | Public RPC | Validator |
|---|---|---|
--validator | — | ✅ |
--experimental-rpc-endpoint | ✅ two, methods=safe (see below) | — |
--rpc-external | — | optional, empty by default |
--rpc-max-connections | 3500 HTTP + 1500 WS | default |
--state-pruning archive | ✅ | — (default pruning) |
--blocks-pruning archive | ✅ | — |
SYNC_MODE (--sync) | ❌ cannot warp | optional, empty by default |
--prometheus-external | ✅ | ✅ |
--in-peers / --out-peers | 64 / 16 | default |
--no-mdns | ✅ | ✅ |
Bootnodes come from the chain spec, so no role passes --bootnodes.
--sync warp and archive nodes are incompatibleAn archive node exits at startup with Warp sync doesn't work for archive nodes
and, under restart: unless-stopped, crash-loops. Only the validator roles
expose SYNC_MODE, and only they can use it.
On a validator it also applies just once: the node ignores it as soon as it
holds finalized state, logging Can't use warp sync mode with a partially synced database. Reverting to full sync mode. And because the validator is not an
archive node, what warp skips is backfilled headers only — no block bodies
before the sync point, permanently.
RPC methods
Unsafe RPC methods — author_rotateKeys, author_insertKey,
author_removeExtrinsic, system_addReservedPeer, offchain_* and the like —
change the node itself, so a public endpoint must not serve them.
orbinum-node 0.4.0 and earlier force --rpc-methods Unsafe on every role,
so --rpc-methods Safe has no effect there. 0.5.0 and later leave the choice to
the operator. ISMP queries (ismp_*) and grandpa_proveFinality work under
Safe, so the Hyperbridge relayer does not need unsafe methods.
The public RPC therefore declares its endpoints with --experimental-rpc-endpoint,
which carries its own method set and is not affected by the forced flag:
--experimental-rpc-endpoint "listen-addr=0.0.0.0:9944,methods=safe,max-request-size=150,max-response-size=150,max-connections=3500"
--experimental-rpc-endpoint "listen-addr=127.0.0.1:9945,methods=safe,max-request-size=150,max-response-size=150,max-connections=1500,rate-limit=1200"
| Endpoint | Serves | Limits |
|---|---|---|
9944 (RPC_BIND) | Caddy's HTTPS upstream, and hosts on the private network (the Hyperbridge relayer) | 3500 connections |
9945 (loopback) | Caddy's WSS upstream | 1500 connections, 1200 calls/min per socket |
An unsafe call on either answers RPC call is unsafe to be called externally.
cors= to an endpointSetting cors on an --experimental-rpc-endpoint also turns on the node's Host
filter, which admits only localhost. Every request Caddy forwards carries the
public domain as its Host and is refused with Provided Host header is not whitelisted. Caddy sets the CORS headers itself.
An endpoint also does not inherit the 150 MiB request and response limits the
binary sets for --rpc-port; without max-request-size / max-response-size
it falls back to 15 MiB, which truncates large GRANDPA proofs.
The validator keeps the classic flags and stays on loopback, so its unsafe methods are unreachable from outside the host. See Ports & Endpoints for where each role binds.
Peering
| Variable | Effect |
|---|---|
PUBLIC_ADDR | Advertise a specific address to peers |
RESERVED_NODES is not additiveA non-empty value activates --reserved-only: the node refuses every peer not on
the list — the bootnodes included — so a public node silently ends up with zero
peers. Leave it empty unless you are running a private network or a validator
behind sentries.
A validator behind its own sentry nodes lists every sentry in RESERVED_NODES,
so it peers with, and takes transactions from, them alone. A peer that sends
shielded-pool spends with invalid proofs loses too little reputation to get
banned, so a validator open to every peer keeps verifying whatever that peer
sends; behind sentries, only the sentries reach it.
Logging
ORB=ghcr.io/orbinum/node:testnet-latest
# raise verbosity
docker run --rm -e RUST_LOG=debug $ORB --dev --tmp
# one module only
docker run --rm -e RUST_LOG=pallet_shielded_pool=trace $ORB --dev --tmp
Chain spec
All three testnet roles mount the same file read-only and point --chain at it:
../chainspec/testnet-spec.json → /chain-specs/testnet-spec.json
The spec is generated in the node repo and copied into node-deploy, which
only consumes it. It carries the bootnodes.
For a custom spec, export one, edit it, convert it to raw and run it:
docker run --rm $ORB build-spec --chain local > custom-spec.json
docker run --rm -v "$PWD:/specs" $ORB build-spec --chain /specs/custom-spec.json --raw > custom-spec-raw.json
docker run --rm -v "$PWD:/specs" $ORB --chain /specs/custom-spec-raw.json