TwitterDiscordGitHub logo

Running a Redstone node

A Garnet (or Redstone) node is an OP Stack node. For more information about running OP Stack nodes, see the Optimism documentation.

Running a node with docker compose

The Docker images provided by Optimism include the software for Redstone's data availability model. We can use them to run a node using docker compose.

Installation

  1. Make sure you have docker compose installed.

  2. Clone the GitHub repository and enter the directory.

    git clone https://github.com/latticexyz/redstone-node.git
    cd redstone-node/docker-compose/
    
  3. Edit .env to have an L1_URL parameter with a URL to access the L1 blockchain (Ethereum Mainnet).

    L1_URL=https:// <node provider address here>
    
  4. Download the snapshot. Note that you need about 400 GB of free space.

    mkdir data
    cd data
    wget -c https://pub-985e2ed0323e4a29b1c7babaf4e60092.r2.dev/geth-latest.tar.gz
    tar xvzf geth-latest.tar.gz
    rm geth-latest.tar.gz
    
  5. Run the node and wait for it to synchronize.

    docker compose -f redstone-compose.yml up -d
    

    Note that synchronization is a slow process. First, op-node takes time to figure out exactly where the rollup started, so for a few hours you might not see the block number progress beyond zero. Then, the process appears stuck because in the early days input commitments were five hours apart, and later an hour apart. Synchronization for a snapshot is much faster but still starts with a few hours during which there is no visible progress except for the logs.

  6. Subscribe to the mailing list to be informed when you need to change rollup.json or one of the other files.

Usage

Start

docker compose -f redstone-compose.yml up -d

Will start the node in a detatched shell (-d), meaning the node will continue to run in the background.

View logs

docker compose -f redstone-compose.yml logs -f --tail 10

To view logs of all containers.

docker compose -f redstone-compose.yml logs <CONTAINER_NAME> -f --tail 10

To view logs for a specific container. There are two containers:

  • op-geth
  • op-node

Stop

docker compose -f redstone-compose.yml down

Will shut down the node without wiping any data. You can safely run this command and then restart the node again.

Restart

docker compose -f redstone-compose.yml restart

Will restart the node safely with minimal downtime.

File access

The files used by op-node and op-geth are stored under redstone-node/docker-compose/data. You can view and delete them there.

Running a node directly on the operating system

Note: These steps were tested on a GCP n2-standard-4 VM running Debian GNU/Linux 12 (bookworm) with a 10 GB disk. You might need to modify them for other OS versions.

  1. Verify you have the correct software versions. If using Debian GNU/Linux 12, you can use these commands:

    sudo apt install -y git make jq
    wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
    sudo rm -rf /usr/local/go
    sudo tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz
    (echo ; echo 'export PATH=$PATH:/usr/local/go/bin') >> ~/.bashrc
    curl -L https://foundry.paradigm.xyz | bash
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    source ~/.bashrc
    nvm install 20
    foundryup
    
  2. Build the rollup client, op-node:

    git clone https://github.com/ethereum-optimism/optimism.git
    cd optimism
    git checkout v1.7.3
    make op-node
    
  3. Build the execution client, op-geth:

    cd ..
    git clone https://github.com/ethereum-optimism/op-geth.git
    cd op-geth
    git reset --hard 966c43537e49f7936bb57a426079fb0da9baf03b
    make geth
    
  4. Create a directory for configuration files.

    mkdir ~/redstone-node
    cd ~/redstone-node
    
  5. Create ~/redstone-node/rollup.json:

    {
      "genesis": {
        "l1": {
          "hash": "0xb9ec694afdde2e2ed661ed8ec56dace5cf8723801342fa1229e693f2a98af672",
          "number": 19578374
        },
        "l2": {
          "hash": "0xa4f55631013577464810893a05b18f07fe483885a6ef93e0060e7128bdf4ca3b",
          "number": 0
        },
        "l2_time": 1712185091,
        "system_config": {
          "batcherAddr": "0xa31cb9bc414601171d4537580f98f66c03aecd43",
          "overhead": "0x0000000000000000000000000000000000000000000000000000000000000001",
          "scalar": "0x0000000000000000000000000000000000000000000000000000000000001def",
          "gasLimit": 100000000
        }
      },
      "block_time": 2,
      "max_sequencer_drift": 600,
      "seq_window_size": 3600,
      "channel_timeout": 300,
      "l1_chain_id": 1,
      "l2_chain_id": 690,
      "regolith_time": 0,
      "canyon_time": 0,
      "delta_time": 0,
      "ecotone_time": 0,
      "batch_inbox_address": "0xff00000000000000000000000000000000000690",
      "deposit_contract_address": "0xc7bcb0e8839a28a1cfadd1cf716de9016cda51ae",
      "l1_system_config_address": "0x8f2428f7189c0d92d1c4a5358903a8c80ec6a69d",
      "protocol_versions_address": "0x0000000000000000000000000000000000000000",
      "da_challenge_address": "0x97a2da87d3439b172e6dd027220e01c9cb565b80",
      "da_challenge_window": 3600,
      "da_resolve_window": 3600,
      "use_plasma": true
    }
    
  6. Download l2-genesis.json.

    curl https://redstone-spec.s3.eu-west-1.amazonaws.com/l2-genesis.json > l2-genesis.json
    
  7. Initialize the data directory.

    cd ~/redstone-node
    ~/op-geth/build/bin/geth init ~/redstone-node/l2-genesis.json
    
  8. Create a file, ~/redstone-node/run-execution-layer.sh.

    #! /usr/bin/bash
    
    cd ~/redstone-node
    
    ~/op-geth/build/bin/geth \
      --gcmode archive \
      --syncmode full \
      --networkid 690 \
      --ipcdisable \
      --http \
      --http.port=8545 \
      --http.api="admin,engine,eth,web3,txpool,net,debug" \
      --http.addr="0.0.0.0" \
      --http.corsdomain="*" \
      --http.vhosts="*" \
      --ws \
      --ws.api="debug,eth,txpool,net,web3,engine" \
      --ws.port=8546 \
      --ws.addr="0.0.0.0" \
      --ws.origins="*" \
      --networkid=690 \
      --verbosity=3 \
      --authrpc.addr="0.0.0.0" \
      --authrpc.port=8551 \
      --authrpc.vhosts="*" \
      --rpc.allow-unprotected-txs \
      --rollup.sequencerhttp=https://rpc.redstonechain.com \
      --gpo.minsuggestedpriorityfee=1000000 \
      --nodiscover
    
  9. Create a file, ~/redstone-node/run-consensus-layer.sh. Note the 3 bootnode addresses, they will allow your node to connect to the Redstone P2P network for the unsafe head. Make sure to set ETHEREUM_MAINNET_URL to an RPC endpoint that accesses the Ethereum Mainnet, which stores the data availability commitments and the state root proposals for Redstone.

    #! /usr/bin/bash
    
    ETHEREUM_MAINNET_URL=<RPC to Ethereum Mainnet, the chaind ID 1 network>
    
    cd ~/redstone-node
    
    ~/optimism/op-node/bin/op-node \
      --l1=$ETHEREUM_MAINNET_URL \
      --l1.beacon.ignore \
      --l2=http://localhost:8551 \
      --l2.jwt-secret=../.ethereum/geth/jwtsecret \
      --plasma.enabled \
      --plasma.da-server=https://da.redstonechain.com \
      --rpc.addr=0.0.0.0 \
      --rpc.port=8547 \
      --rpc.enable-admin \
      --p2p.bootnodes=enr:-J24QIpQjoWf3sSMiDk3CGkA3FaUVadLzMxuJHfEvkE5Q9FbFRFG5RPFxCIw0b7boSCjJ_vVc8pX4Ue-tVjsu4ou7-qGAY8vobQSgmlkgnY0gmlwhDTWuneHb3BzdGFja4OyBQCJc2VjcDI1NmsxoQMTlWaih1oq9kVe5yYJ5N1C0IAqx4mpxJyl8L17-y4csYN0Y3CCJAaDdWRwgiQG,enr:-J24QF7mHVOC1BiVPXWl2IC_FUbSHeuci1NyCd78M7465KOIWeSwViFJePXBManyOebiwk-SA5hESbORtXKWYtw73WOGAY8vnYXtgmlkgnY0gmlwhDaqpwSHb3BzdGFja4OyBQCJc2VjcDI1NmsxoQLNE3bfX7m_0n1lEitv4YKTTsTvZr0jmTXJS2x6rGSI9IN0Y3CCJAaDdWRwgiQG,enr:-J24QPBqZvUSnkzKgjnkYB_VvLaFW3xTMvOZeYIX1d5PAnKYIeIGCU206MOdVs_WyYmSUvaPIwXmRvyaKZWlJJYh0KGGAY8vlbMHgmlkgnY0gmlwhCLwOnqHb3BzdGFja4OyBQCJc2VjcDI1NmsxoQIW0taIKXJ_N2bUMmUL2QQzj6l9rk9sR_9YaWY2lazOwoN0Y3CCJAaDdWRwgiQG \
      --rollup.config=./rollup.json
    
  10. Make the run scripts executables.

    chmod +x ~/redstone-node/run*
    
  11. In one terminal, run geth, the execution layer.

    ~/redstone-node/run-execution-layer.sh
    
  12. In another command line window run op-node, the consensus layer.

    ~/redstone-node/run-consensus-layer.sh
    

    Note that synchronization is a slow process. First, op-node takes time to figure out exactly where the rollup started, so for a few hours you might not see the block number progress beyond zero. Then, the process appears stuck because in the early days of Redstone input commitments were five hours apart, and later an hour apart,

Activating peer to peer

The L1 connection is sufficient to synchronize up to the safe L2 head. To synchronize beyond that, all the way to the unsafe L2 head, you need to use peer-to-peer synchronization.

In addition to the --p2p.bootnodes flag on op-node, it is necessary to open bidirectional access for port 9222 on both TCP and UDP. This may require changes in firewall configuration, address translation, etc. Ideally, this access should be universal to allow your node to update and be updated by other nodes. However, if you have to restrict access due to security policies, you can use an ENR decoder to see which IP addresses are the bootnodes, and at least allow access to them.

Currently, those addresses are 34.240.58.122, 52.214.186.119, and 54.170.167.4.