Skip to content

Run a Robinhood Chain full node

Robinhood Chain is an Arbitrum Chain running Arbitrum Nitro. This guide walks through deploying and syncing your own full node.

Running a node is time consuming, resource intensive, and potentially costly. If you don't already know why you need your own node, you probably don't.

If you just need an RPC endpoint, use the public endpoints or a provider:

  • Public Mainnet: https://rpc.mainnet.chain.robinhood.com
  • Alchemy: https://robinhood-mainnet.g.alchemy.com/v2/{API_KEY}

Download the config files for your target network:

Testnet does not use a custom genesis file, so its start command omits the --init.genesis-json-file flag.

Hardware requirements

ComponentRequirement
CPUModern multi-core (8+) CPU with strong single-core performance
RAM64 GB RAM (128 GB recommended)
StorageLocally attached NVMe SSD; (2 × current chain size) + 20% buffer. Several TBs of data
Node TypeFull node (Archive nodes require substantially more disk capacity)

Prerequisites

Because Robinhood Chain posts its data to Ethereum, your node needs access to an Ethereum (L1) endpoint — your own or via a provider.

You need both:

  • An L1 execution RPC endpoint
  • An L1 beacon (consensus) endpoint — required to read blob data

If you run your own L1 node, it must be fully synced before Robinhood Chain can finish syncing.

You'll also need Docker installed and running.

RPC Providers

If you just need an RPC endpoint without running a node, see Connecting to Robinhood Chain for the full list of supported providers.

Running the node

Start the node with Docker, supplying your L1 endpoints and the Robinhood Chain config. The commands differ by network: Mainnet initializes from a custom genesis file, while Testnet does not.

Place the config files you downloaded above into a local directory (e.g. $HOME/rh/config) and mount it into the container at /home/nitro/config, which the commands reference. Mount your data directory to /home/nitro/.arbitrum — the nitro-node image runs as the nitro user, so mounting elsewhere leaves the node unable to persist chain data. Substitute your own L1 endpoints for parent-chain.connection.url and parent-chain.blob-client.beacon-url.

Mainnet

DATA_DIR="$HOME/rh/robinhood-nitro-data"
docker run --rm -it \
    -v "$DATA_DIR":/home/nitro/.arbitrum \
    -v "$HOME/rh/config":/home/nitro/config \
    -p 8547:8547 -p 8548:8548 \
    offchainlabs/nitro-node:v3.11.2-3599aca \
      --chain.info-files=/home/nitro/config/robinhood-chain-info.json \
      --parent-chain.connection.url=... \
      --parent-chain.blob-client.beacon-url=... \
      --init.genesis-json-file=/home/nitro/config/robinhood-genesis.json \
      --http.addr=0.0.0.0 --http.port=8547 \
      --http.api=net,web3,eth

To subscribe to the sequencer feed for low-latency updates, add --node.feed.input.url to your start command. The feed URL must be wss://, not https://.

Recommended: run both feeds simultaneously

Robinhood Chain provides a delayed backup feed at wss://delayed-feed.mainnet.chain.robinhood.com. It runs ~500ms behind the primary feed on separate, hardened capacity.

We recommend running both feeds at once by passing both URLs to --node.feed.input.url:

--node.feed.input.url=wss://feed.mainnet.chain.robinhood.com \
--node.feed.input.url=wss://delayed-feed.mainnet.chain.robinhood.com

Your node connects to both and deduplicates by sequence number — there is no added latency in normal operation and no reconnect gap if the primary degrades.

Alternative: strict standby

If you prefer the delayed feed to activate only after the primary drops, set it as --node.feed.input.secondary-url instead:

--node.feed.input.url=wss://feed.mainnet.chain.robinhood.com \
--node.feed.input.secondary-url=wss://delayed-feed.mainnet.chain.robinhood.com

See Multiple primaries vs. secondary URL fallback in the Arbitrum docs for the trade-offs between the two modes.

Note: The public feed endpoint is unchanged and real-time, but it is best-effort and carries no uptime guarantee. The delayed feed is the supported fallback if the public feed degrades.

Testnet

Testnet has no custom genesis, so its start command omits the --init.genesis-json-file flag.

DATA_DIR="$HOME/rh/robinhood-nitro-data"
docker run --rm -it \
    -v "$DATA_DIR":/home/nitro/.arbitrum \
    -v "$HOME/rh/config":/home/nitro/config \
    -p 8547:8547 -p 8548:8548 \
    offchainlabs/nitro-node:v3.11.2-3599aca \
      --chain.info-files=/home/nitro/config/robinhood-chain-testnet-info.json \
      --parent-chain.connection.url=... \
      --parent-chain.blob-client.beacon-url=... \
      --http.addr=0.0.0.0 --http.port=8547 \
      --http.api=net,web3,eth

For the testnet sequencer feed, add --node.feed.input.url=wss://feed.testnet.chain.robinhood.com.

Once running, confirm the node responds:

curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" http://localhost:8547

Initial sync can take a long time and will consume significant L1 request quota — monitor your L1 provider usage.

Running a validator

Robinhood Chain utilizes BoLD for dispute resolution through a permissioned set of validators. Operating a validator necessitates being included in the allowlist and staking a 1 WETH bond (defensive validators are highly encouraged).

Syncing

Check sync progress with eth_syncing. A fully synced node returns false:

curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_syncing","params":[]}' \
  -H "Content-Type: application/json" http://localhost:8547

You can also watch the node logs for block production messages.

If you try to send transactions before the node is fully synced, you may see nonce has already been used — wait for sync to complete.

Database Snapshots

Database snapshots let you sync a new node faster by starting from a recent state instead of from genesis. Browse available snapshots:

To restore from a snapshot, pass its URL to the node with --init.url=<snapshot-url> on first start (see Running the node). Snapshots currently published are pruned full-node snapshots; archive nodes must sync from scratch. For how the snapshot system works, see the Arbitrum Nitro database snapshots documentation.

Node configuration

Robinhood Chain requires the chain info file provided by Robinhood, passed to the node via --chain.info-files (see Running the node). On Mainnet, also pass the custom genesis configuration via --init.genesis-json-file; Testnet does not use a custom genesis.

Robinhood Chain runs ArbOS 61. Confirm the current Nitro/ArbOS version before starting. On ArbOS upgrades, un-upgraded nodes stop cleanly and resume after updating — with no data loss.

Troubleshooting

General checks

  • View logs via docker logs -f <container> to identify errors.
  • Confirm the container status is healthy and not in a restart loop.
  • Verify network connectivity to L1 execution and beacon endpoints from the host.
  • Confirm your L1 node is fully synced; an unsynced L1 will stall L2 syncing.

Syncing issues

  • Check the L1 connection and beacon URL; most failures are due to unreachable beacon endpoints.
  • Ensure the server clock is accurate using ntp or chrony.

Sync is slow:

  • Verify disk I/O performance; networked storage will significantly throttle sync speed.

Connectivity issues

  • Verify container ports (8547 for HTTP, 8548 for WS) are correctly mapped and open.
  • Ensure --http.addr=0.0.0.0 is set to allow external RPC access.

Support

Robinhood Chain Support