Running a Local Node


Running a Local Node

  • Running a Local COMBO Testnet or Mainnet Node

  • If you're looking to build an app on COMBO you'll need access to an COMBO node. You can simply use the public rpc Testnetopen in new window, Mainnetopen in new window or run your own node. This guide will walk you through setting up your own Testnet/Mainnet node.

Hardware requirements​

  • Replicas must store the transaction history of COMBO and run Geth. For optimal performance, they should be powerful machines (real or virtual) with at least 16 GB RAM and an SSD drive with 500 GB free space (for production network).

Run with Docker​

  • There are official Docker images available for the COMBO node. You can use the latest versions of these images from the following links:
  • Additionally, you can find a docker-compose file example in this repositoryopen in new window to run the COMBO node with Docker. This allows you to set up a Testnet/Mainnet node quickly, within minutes. If you use different infrastructure providers, please consult the docker-compose file and adjust the configuration as needed.

Run with Binaries​

Build op-node and op-geth​

export COMBO_WORKSPACE=/tmp/COMBO
mkdir -p $COMBO_WORKSPACE

cd $COMBO_WORKSPACE
git clone git@github.com:combo-labs/optimism.git
cd COMBO/op-node
git checkout develop
make op-node
mkdir -p $COMBO_WORKSPACE/op-node-data
cp ./bin/op-node $COMBO_WORKSPACE/op-node-data

cd $COMBO_WORKSPACE
git clone git@github.com:combo-labs/combo-op-geth.git
cd op-geth
git checkout develop
make geth
mkdir -p $COMBO_WORKSPACE/op-geth-data
cp ./build/bin/geth $COMBO_WORKSPACE/op-geth-data/op-geth

Data Preparation​

cd $COMBO_WORKSPACE
# for testnet
cp $COMBO_WORKSPACE/COMBO/assets/testnet/genesis.json $COMBO_WORKSPACE/op-geth-data
# for mainnet
# cp $COMBO_WORKSPACE/COMBO/assets/mainnet/genesis.json $COMBO_WORKSPACE/op-geth-data

openssl rand -hex 32 > jwt.txt
cp jwt.txt $COMBO_WORKSPACE/op-geth-data
cp jwt.txt $COMBO_WORKSPACE/op-node-data

# init op-geth genesis
cd $COMBO_WORKSPACE/op-geth-data
mkdir datadir
./op-geth --datadir ./datadir init genesis.json

Start components​

  • op-geth
#! /usr/bin/bash
cd $COMBO_WORKSPACE/op-geth-data

# for testnet
export CHAIN_ID=91715
export L2_RPC=https://test-rpc.combonetwork.io
export P2P_BOOTNODES="enr:-KO4QKFOBDW--pF4pFwv3Al_jiLOITj_Y5mr1Ajyy2yxHpFtNcBfkZEkvWUxAKXQjWALZEFxYHooU88JClyzA00e8YeGAYtBOOZig2V0aMfGhE0ZYGqAgmlkgnY0gmlwhDREiqaJc2VjcDI1NmsxoQM8pC_6wwTr5N2Q-yXQ1KGKsgz9i9EPLk8Ata65pUyYG4RzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QFJc0KR09ye818GT2kyN9y6BAGjhz77sYimxn85jJf2hOrNqg4X0b0EsS-_ssdkzVpavqh6oMX7W5Y81xMRuEayGAYtBSiK9g2V0aMfGhE0ZYGqAgmlkgnY0gmlwhANzx96Jc2VjcDI1NmsxoQPwA1XHfWGd4umIt7j3Fc7hKq_35izIWT_9yiN_tX8lR4RzbmFwwIN0Y3CCdl-DdWRwgnZf"

# for mainnet
# export CHAIN_ID=9980
# export L2_RPC=https://rpc.combonetwork.io
# export P2P_BOOTNODES="enr:-KO4QHs5qh_kPFcjMgqkuN9dbxXT4C5Cjad4SAheaUxveCbJQ3XdeMMDHeHilHyqisyYQAByfdhzyKAdUp2SvyzWeBqGAYvRDf80g2V0aMfGhHFtSjqAgmlkgnY0gmlwhDaykUmJc2VjcDI1NmsxoQJUevTL3hJwj21IT2GC6VaNqVQEsJFPtNtO-ld5QTNCfIRzbmFwwIN0Y3CCdl-DdWRwgnZf,enr:-KO4QKIByq-YMjs6IL2YCNZEmlo3dKWNOy4B6sdqE3gjOrXeKdNbwZZGK_JzT1epqCFs3mujjg2vO1lrZLzLy4Rl7PyGAYvRA8bEg2V0aMfGhHFtSjqAgmlkgnY0gmlwhDbjSM6Jc2VjcDI1NmsxoQNQhJ5pqCPnTbK92gEc2F98y-u1OgZVAI1Msx-UiHezY4RzbmFwwIN0Y3CCdl-DdWRwgnZf"


./op-geth \
 --datadir="./datadir" \
 --verbosity=3 \
 --http \
 --http.corsdomain="*" \
 --http.vhosts="*" \
 --http.addr=0.0.0.0 \
 --http.port=8545 \
 --http.api=net,eth,engine \
 --ws \
 --ws.addr=0.0.0.0 \
 --ws.port=8545 \
 --ws.origins="*" \
 --ws.api=eth,engine \
 --syncmode=full \
 --maxpeers=10 \
 --networkid=$CHAIN_ID \
 --miner.gaslimit=150000000 \
 --triesInMemory=32 \
 --txpool.globalslots=10000 \
 --txpool.globalqueue=5000 \
 --txpool.accountqueue=200 \
 --txpool.accountslots=200 \
 --cache 32000 \
 --cache.preimages \
 --allow-insecure-unlock \
 --authrpc.addr="0.0.0.0" \
 --authrpc.port="8551" \
 --authrpc.vhosts="*" \
 --authrpc.jwtsecret=./jwt.txt \
 --gcmode=archive \
 --metrics \
 --metrics.port 6060 \
 --metrics.addr 0.0.0.0 \
 --rollup.sequencerhttp=$L2_RPC \
 --bootnodes=$P2P_BOOTNODES
  • op-node
#! /usr/bin/bash

set -ex

cd op-node-data

export L2_RPC=http://localhost:8551
# replace the p2p private key with yours
# you can generate a new one with `openssl rand -hex 32`
export P2P_PRIV_KEY=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

# for testnet
# it's better to replace the L1_RPC with your own BSC Testnet RPC Endpoint for stability
export L1_RPC=https://test-rpc.combonetwork.io
export P2P_BOOTNODES="enr:-J24QGQBeMsXOaCCaLWtNFSfb2Gv50DjGOKToH2HUTAIn9yXImowlRoMDNuPNhSBZNQGCCE8eAl5O3dsONuuQp5Qix2GAYjB7KHSgmlkgnY0gmlwhDREiqaHb3BzdGFja4PrKwCJc2VjcDI1NmsxoQL4I9wpEVDcUb8bLWu6V8iPoN5w8E8q-GrS5WUCygYUQ4N0Y3CCIyuDdWRwgiMr,enr:-J24QJKXHEkIhy0tmIk2EscMZ2aRrivNsZf_YhgIU51g4ZKHWY0BxW6VedRJ1jxmneW9v7JjldPOPpLkaNSo6cXGFxqGAYpK96oCgmlkgnY0gmlwhANzx96Hb3BzdGFja4PrKwCJc2VjcDI1NmsxoQMOCzUFffz04eyDrmkbaSCrMEvLvn5O4RZaZ5k1GV4wa4N0Y3CCIyuDdWRwgiMr"

# for mainnet
# export L1_RPC=https://rpc.combonetwork.io
# export P2P_BOOTNODES="enr:-J24QA9sgVxbZ0KoJ7-1gx_szfc7Oexzz7xL2iHS7VMHGj2QQaLc_IQZmFthywENgJWXbApj7tw7BiouKDOZD4noWEWGAYppffmvgmlkgnY0gmlwhDbjSM6Hb3BzdGFja4PMAQCJc2VjcDI1NmsxoQKetGQX7sXd4u8hZr6uayTZgHRDvGm36YaryqZkgnidS4N0Y3CCIyuDdWRwgiMs"

./op-node \
 --l1.trustrpc \
 --sequencer.l1-confs=15 \
 --verifier.l1-confs=15 \
 --l1.http-poll-interval 3s \
 --l1.epoch-poll-interval 45s \
 --l1.rpc-max-batch-size 20 \
 --rollup.config=./rollup.json \
 --rpc.addr=0.0.0.0 \
 --rpc.port=8546 \
 --p2p.sync.req-resp \
 --p2p.listen.ip=0.0.0.0 \
 --p2p.listen.tcp=9003 \
 --p2p.listen.udp=9003 \
 --snapshotlog.file=./snapshot.log \
 --p2p.bootnodes=$P2P_BOOTNODES \
 --metrics.enabled \
 --metrics.addr=0.0.0.0 \
 --metrics.port=7300 \
 --pprof.enabled \
 --rpc.enable-admin \
 --l1=${L1_RPC} \
 --l2=${L2_RPC} \
 --l2.jwt-secret=./jwt.txt \
 --l2.engine-sync=true \
 --l2.skip-sync-start-check=true \ 
 --log.level=debug

Run with Snapshots​

  • To improve the synchronization speed of the node, you can utilize snapshots to initialize it. The most recent snapshot is maintained in the repository combo-snapshotopen in new window. Please visit the repository for download links and usage instructions.

Check status​

  • Wait for the node to sync. You'll see log in op-geth if there's any new block.
INFO [11-15|10:10:05.569] Syncing beacon headers                   downloaded=1,762,304 left=11,403,991 eta=27m1.039s
INFO [11-15|10:10:06.440] Forkchoice requested sync to new head    number=13,164,499 hash=d78cb3..a2e94d finalized=unknown
  • You can check the block number with curl:
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8545
  • Once all headers have been downloaded, the node will begin downloading the blocks. You will notice that the block height is increasing.
{"jsonrpc":"2.0","id":1,"result":"0x1a"}
  • To verify if the node has synchronized to the latest height, you can compare the block with the one requested from public endpoints.
# local
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","id": 1, "params": ["0x1a", false]}' http://localhost:8545

# testnet
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","id": 1, "params": ["0x1a", false]}' https://test-rpc.combonetwork.io

# mainnet
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","id": 1, "params": ["0x1a", false]}' https://rpc.combonetwork.io

Troubleshooting​

  • If the problem you are facing is not addressed here, please open an issue on GitHub by visiting this link: open an issueopen in new window. Not synced for a long time​
  • The default sync mechanism involves two P2P networks, the op-node network and op-geth network. If you are not connected to the op-node network, you can not receive the latest blocks from broadcast, and can't trigger the engine sync of op-geth. If you are not connected to the op-geth network, you can receive the latest blocks from broadcast, but can't get the historical blocks from op-geth P2P network. Check the op-geth logs. If you can find the following logs, it means that the op-node network is connected successfully and you are receiving the latest blocks from broadcast.

Not synced for a long time​

  • The default sync mechanism involves two P2P networks, the op-node network and op-geth network. If you are not connected to the op-node network, you can not receive the latest blocks from broadcast, and can't trigger the engine sync of op-geth. If you are not connected to the op-geth network, you can receive the latest blocks from broadcast, but can't get the historical blocks from op-geth P2P network.

  • Check the op-geth logs.

    • If you can find the following logs, it means that the op-node network is connected successfully and you are receiving the latest blocks from broadcast.
    INFO [11-15|10:32:02.801] Forkchoice requested sync to new head    number=8,290,596 hash=1dbff3..9a306a finalized=unknown
    
    • If you can find the following logs, it means that the op-geth network is connected successfully and you are receiving the historical block headers from op-geth P2P network.
    INFO [11-15|10:32:52.240] Syncing beacon headers                   downloaded=210,432 left=8,084,773 eta=31m39.748s
    
    • Check the op-node p2p network with the command below:
    $ curl -X POST -H "Content-Type: application/json" --data \
    '{"method":"opp2p_peers","params":[true],"id":1,"jsonrpc":"2.0"}'  \
    http://localhost:8546
    
    • Check the op-geth p2p network with the command below. You have to enable admin API in op-geth to use this API. Refer to https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-admin for more details.
    $ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_peers","params":[],"id":1}' http://localhost:8545 | jq .
    

The local node's chain has forked from the canonical chain​

  • If your local node is already running and tracking blocks, the following situations may indicate that your local node's chain has forked from the canonical chain:
    1. The block hash at the same height obtained through the eth_getBlockByNumber method does not match the data returned by the public node.
    2. Your local chain consistently lags behind a fixed number of blocks and cannot catch up with the latest block height.
  • In this case, we recommend that you check the code version of the running node through the following steps:
$ op-node -v
op-node version v0.0.0-515ebd51-1698742099

$ op-geth version
Geth
Version: 0.1.0-unstable
Git Commit: f8871fc80dbf2aa0178b504e76c20c21b890c6d5
Git Commit Date: 20231026
Upstream Version: 1.11.5-stable
Architecture: arm64
Go Version: go1.20.2
Operating System: darwin
GOPATH=
  • Please make sure to use the latest code version. If the code version is incorrect, please completely clear the node data and run the new node again according to this guide. You also need to check if the genesis.json and rollup.json files are up to date. In the latest code, we hardcoded the configuration of rollup.json. Instead of using --rollup.config=./rollup.json, you just need to use --network=COMBOTestnet (for the mainnet network it is COMBO Mainnet). This change ensures that the contents of rollup.json will not be incorrect.