Skip to main content

How to run a normal sequencer node for an Orbit chain

caution

The following instructions are meant for Arbitrum Orbit chains only. This article only applies to test environments. If you need support spinning up a production Orbit chain, we recommend contacting a provider.

We also provide a guide for running a high-availability sequencer node for an Orbit chain. You can find it here.

This how-to provides step-by-step instructions for running a sequencer node on your local machine.

Minimum hardware configuration

The following are the minimum hardware configurations required to set up a Nitro full node (not archival):

ResourceRecommended
RAM16 GB
CPU4 core CPU (for AWS, a t3 xLarge instance)
Storage typeNVMe SSD drives are recommended
Storage sizeDepends on the chain and its traffic overtime

Please note that:

  • These minimum requirements for RAM and CPU are recommended for nodes that process a small amount of RPC requests. For nodes that require processing multiple simultaneous requests, both RAM and the number of CPU cores will need to scale with the amount of traffic served.
  • Single core performance is important. If the node is falling behind and a single core is 100% busy, it is recommended to update to a faster processor
  • The minimum storage requirements will change over time as the chain grows. Using more than the minimum requirements to run a robust full node is recommended.
caution

Even though there are alpha and beta versions of the Arbitrum Nitro software, only use release versions when running your node. Running alpha or beta versions is unsupported and might lead to unexpected behaviors.

Latest Docker image: offchainlabs/nitro-node:v3.5.5-90ee45c

Required parameters

1. Sequencer node parameters

The following parameters are required to run a sequencer node:

1. Enable sequencer

Enable the sequencer mode:

--node.sequencer=true

2. Make the node act as a sequencer and post to L1

Enable the sequencer execution:

--execution.sequencer.enable=true
--execution.sequencer.max-tx-data-size=85000

3. Enable delayed sequencer

Enable your node to read and include transactions from the parent chain delayed inbox.

--node.delayed-sequencer.enable=true
--node.delayed-sequencer.use-merge-finality=false
--node.delayed-sequencer.finalize-distance=1

4. Enable batch poster

Enable your node to send batches to the parent chain:

--node.batch-poster.enable=true
--node.batch-poster.max-size=90000
--node.batch-poster.parent-chain-wallet.private-key=<Your Parent Chain Wallet Private Key>

4. Disable transaction forwarding

Disable your sequencer's forwarding transactions, as the node will queue the transaction directly:

--execution.forwarding-target=""

5. Enable feed-out queued transactions

Enable your node to feed out transactions so full node can receive queued transactions:

--node.feed.output.enable=true
--node.feed.output.addr=0.0.0.0
--node.feed.output.port=<Sequencer feed port>

5. Connect the node to data availability servers

note

This step is only required in Anytrust mode.

Enable your node to send batches to DAS and get DACerts from them.

--node.data-availability.enable=true
--node.data-availability.sequencer-inbox-address=<Sequencer Inbox Address>
--node.data-availability.parent-chain-node-url=<Parent Chain Node URL>
--node.data-availability.rest-aggregator.enable=true
--node.data-availability.rest-aggregator.urls=<A list of DAS REST endpoints, can be only one URL>
--node.data-availability.rpc-aggregator.enable=true
--node.data-availability.rpc-aggregator.assumed-honest=1
--node.data-availability.rpc-aggregator.backends=<A list of RPC backends>

2. Putting it all together

  • When running a Docker image, an external volume should be mounted to persist the database across restarts. The mount point inside the Docker image should be /home/user/.arbitrum

  • Example:

    docker run --rm -it -v /some/local/dir/arbitrum:/home/user/.arbitrum -p 0.0.0.0:8547:8547 -p 0.0.0.0:8548:8548 offchainlabs/nitro-node:v3.5.5-90ee45c --node.sequencer=true --node.delayed-sequencer.enable=true --node.delayed-sequencer.use-merge-finality=false --node.delayed-sequencer.finalize-distance=1 --node.batch-poster.enable=true --node.batch-poster.max-size=90000 --node.batch-poster.parent-chain-wallet.private-key=<Your Parent Chain Wallet Private Key> --node.staker.enable=true --node.staker.strategy=MakeNodes --node.staker.parent-chain-wallet.private-key=<Your Parent Chain Wallet Private Key> --node.data-availability.enable=true --node.data-availability.sequencer-inbox-address=<Sequencer Inbox Address> --node.data-availability.parent-chain-node-url=<Parent Chain Node URL> --node.data-availability.rest-aggregator.enable=true --node.data-availability.rest-aggregator.urls=<A list of DAS REST endpoints, can be only one URL> --node.data-availability.rpc-aggregator.enable=true --node.data-availability.rpc-aggregator.assumed-honest=1 --node.data-availability.rpc-aggregator.backends=<A list of RPC backends> --execution.sequencer.enable=true --execution.sequencer.max-tx-data-size=85000
    • Ensure that /some/local/dir/arbitrum already exists; otherwise, the directory might be created with root as owner, and the Docker container won't be able to write to it.
  • Json Example:

    {
    "node": {
    "sequencer": true,
    "delayed-sequencer": {
    "enable": true,
    "use-merge-finality": false,
    "finalize-distance": 1
    },
    "batch-poster": {
    "max-size": 90000,
    "enable": true,
    "parent-chain-wallet": {
    "private-key": "<batch post key>"
    }
    },
    "feed": {
    "output": {
    "enable": true,
    "addr": "0.0.0.0",
    "port": "<Sequencer feed port>"
    }
    },
    "data-availability": {
    "enable": true,
    "sequencer-inbox-address": "<Sequencer inbox address>",
    "parent-chain-node-url": "https://sepolia-rollup.arbitrum.io/rpc",
    "rest-aggregator": {
    "enable": true,
    "urls": ["http://das-server:9877"]
    },
    "rpc-aggregator": {
    "enable": true,
    "assumed-honest": 1,
    "backends": "[{\"url\":\"http://das-server:9876\",\"pubkey\":\"YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"signermask\":1}]"
    }
    }
    },
    "execution": {
    "forwarding-target": "",
    "sequencer": {
    "enable": true,
    "max-tx-data-size": 85000
    }
    }
    }

Note on permissions

  • The Docker image is configured to run as non-root UID 1000. If you are running Linux or macOS and you are getting permission errors when trying to run the Docker image, run this command to allow all users to update the persistent folders:
mkdir /data/arbitrum
chmod -fR 777 /data/arbitrum

Optional parameters

Here's a list of the parameters that are most commonly used when running your Orbit sequencer node. You can also use the flag --help for a comprehensive list of available parameters.

FlagDescription
--execution.rpc.classic-redirect=<RPC>Redirects archive requests for pre-nitro blocks to this RPC of an Arbitrum Classic node with an archive database, only for Arbitrum One.
--execution.rpc.classic-redirect=<RPC>Redirects archive requests for pre-nitro blocks to this RPC from an Arbitrum Classic node with an archive database, only for Arbitrum One.
--http.apiWhich APIs need to be opened over the HTTP-RPC interface. Default: net,web3,eth,arb. Add debug for tracing.
--http.corsdomainAccepts cross origin requests from these comma-separated domains (browser enforced).
--http.vhostsAccepts requests from these comma-separated virtual hostnames (server enforced). Default: localhost. Accepts *.
--http.addrAddress to bind RPC to. May require 0.0.0.0 for Docker networking.
--execution.caching.archiveWill retain past block state. For archive nodes.
--node.feed.input.url=<feed address>Default: wss://<chainName>.arbitrum.io/feed. ⚠️ One feed relay per datacenter is advised. See feed relay guide.
--execution.rpc.evm-timeoutDefault: 5s. Timeout for eth_call. (0 == no timeout).
--execution.rpc.gas-capDefault: 50000000. Gas cap for eth_call/estimateGas. (0 = no cap).
--execution.rpc.tx-fee-capDefault: 1. Transaction fee cap (in ETH) for RPC APIs. (0 = no cap).
--ipc.pathFilename for IPC socket/pipe within datadir. Not supported on macOS. Note: The path is within the Docker container.
--init.prunePrunes database before starting the node. It can be used for full or validator nodes.
--init.url="<snapshot file>"Non-Orbit Nitro nodes only: URL from which to download the genesis database. Required only for the first startup of an Arbitrum One node. Reference to snapshots and archive node guide.
--init.download-path="/path/to/dir"Non-Orbit Nitro nodes only: Temporarily saves the downloaded database snapshot. Defaults to /tmp/. Used with --init.url.
--node.batch-poster.post-4844-blobsBoolean. Default: false. Used to enable or disable the posting of transaction data using Blobs to Ethereum mainnet. If using calldata is more expensive and the parent chain supports EIP4844 blobs, the batch poster will use blobs when this flag is set to true. It can be set to true or false.
--node.batch-poster.ignore-blob-priceBoolean. Default: false. If the parent chain supports EIP4844 blobs and ignore-blob-price is set to true, the batch poster will use EIP4844 blobs even if using calldata is cheaper. It can be set to true or false.
--execution.sequencer.enableAct as sequencer and post to L1.
--execution.sequencer.enable-profilingEnable CPU profiling and tracing.
--execution.sequencer.expected-surplus-hard-thresholdIf the expected surplus is lower than this value, new incoming transactions will be denied (default "default").
--execution.sequencer.expected-surplus-soft-thresholdWarnings are posted if the expected surplus is lower than this value (default "default").
--execution.sequencer.forwarder.connection-timeoutTotal time to wait before canceling connection (default 30s).
--execution.sequencer.forwarder.idle-connection-timeoutTime until idle connections are closed (default 1m0s).
--execution.sequencer.forwarder.max-idle-connectionsMaximum number of idle connections to keep open (default 100).
--execution.sequencer.forwarder.redis-urlThe recommended Redis URL to use as target.
--execution.sequencer.forwarder.retry-intervalMinimal time between update retries (default 100ms).
--execution.sequencer.forwarder.update-intervalForwarding target update interval (default 1s).
--execution.sequencer.max-acceptable-timestamp-deltaMaximum acceptable time difference between the local time and the latest L1 block's timestamp (default 1h0m0s).
--execution.sequencer.max-block-speedMinimum delay between blocks (sets a maximum speed of block production) (default 250ms).
--execution.sequencer.max-revert-gas-rejectMaximum gas executed in a revert for the sequencer to reject the transaction instead of posting it (anti-DOS).
--execution.sequencer.max-tx-data-sizeMaximum transaction size the sequencer will accept (default 95000).
--execution.sequencer.nonce-cache-sizeSize of the transaction sender nonce cache (default 1024).
--execution.sequencer.nonce-failure-cache-expiryMaximum time to wait for a predecessor before rejecting a transaction whose nonce is too high (default 1s).
--execution.sequencer.nonce-failure-cache-sizeNumber of transactions whose nonce is too high to keep in memory while waiting for their predecessor (default 1024).
--execution.sequencer.queue-sizeSize of the pending transaction queue (default 1024).
--execution.sequencer.queue-timeoutMaximum time a transaction can wait in a queue (default 12s).
--execution.sequencer.sender-whitelistComma-separated allowlist of authorized senders (if empty, every sender is allowed).
--node.delayed-sequencer.finalize-distanceNumber of blocks in the past L1 block for the transaction to be considered final. This value is ignored when using merge finality. Default: 20.
--node.delayed-sequencer.require-full-finalityWhether to wait for full finality before sequencing delayed messages.
--node.delayed-sequencer.use-merge-finalityWhether to use The Merge's notion of finality before sequencing delayed messages (default to true).