Testnet Guide: Multi-Machine SetupΒΆ
This guide walks you through testing the Optimism Fault Proof Challenger on the Sepolia testnet using a multi-machine setup connected via PiVPN/WireGuard.
Important
This guide is for testing purposes only. For mainnet operation, see Running a Guardian Node (Optimism Challenger).
PrerequisitesΒΆ
This guide assumes you have:
3 ARM devices running Ethereum on ARM (Rock 5B, Orange Pi 5 Plus, NanoPC-T6, etc.)
PiVPN/WireGuard configured per PiVPN and WireGuard: βIntra-VPNβ (10.1.25.0/24 subnet)
L1 clients pre-installed (Nethermind, Lighthouse come with the image)
Architecture OverviewΒΆ
We use 3 machines connected via WireGuard VPN:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β WireGuard VPN (10.1.25.0/24) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Machine 1 β β Machine 2 β β Machine 3 β
β L1 NODE β β L2 NODE β β CHALLENGER β
β 10.1.25.11 β β 10.1.25.9 β β 10.1.25.10 β
βββββββββββββββββββ€ βββββββββββββββββββ€ βββββββββββββββββββ€
β β’ Nethermind β β β’ op-geth β β β’ op-challenger β
β (EL :8545) β β (EL :9545) β β β’ cannon β
β β’ Lighthouse β β β’ op-node β β β’ op-program β
β (CL :5052) β β (RPC :8545) β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β
βββββββββββββββββββββββββββ
Ethereum Sepolia
Available PackagesΒΆ
The following Optimism packages are available:
Binary |
Package |
Purpose |
|---|---|---|
|
|
MIPS Fault Proof VM |
|
|
On-chain program for fault proofs |
|
|
Fault Proof Challenger |
|
|
L2 Execution Layer |
|
|
L2 Rollup/Consensus Node |
|
|
L2 Output Proposer |
|
|
L2 Execution Layer (Reth alternative) |
Machine 1: L1 Node (10.1.25.11)ΒΆ
This machine runs the Ethereum L1 clients (Nethermind + Lighthouse) for Sepolia.
L1 clients are pre-installed on the Ethereum on ARM image.
Configure NethermindΒΆ
Edit /etc/ethereum/nethermind-sepolia.conf to bind to VPN interface:
ARGS="--config sepolia \
--loggerConfigSource /opt/nethermind/NLog.config \
-dd /home/ethereum/.nethermind-sepolia \
--JsonRpc.JwtSecretFile /etc/ethereum/jwtsecret \
--JsonRpc.Enabled true \
--JsonRpc.Host 0.0.0.0 \
--JsonRpc.Port 8545 \
--Metrics.Enabled true \
--Metrics.ExposePort 7070"
Configure LighthouseΒΆ
Edit /etc/ethereum/lighthouse-beacon-sepolia.conf:
ARGS="--network sepolia \
beacon \
--http \
--http-address 0.0.0.0 \
--http-port 5052 \
--execution-endpoint http://127.0.0.1:8551 \
--execution-jwt /etc/ethereum/jwtsecret \
--metrics \
--checkpoint-sync-url https://sepolia.beaconstate.info \
--prune-payloads false"
Start L1 ServicesΒΆ
sudo systemctl enable --now nethermind-sepolia lighthouse-beacon-sepolia
Wait for L1 to sync (can take several hours). Check progress:
sudo journalctl -fu nethermind-sepolia
sudo journalctl -fu lighthouse-beacon-sepolia
Machine 2: L2 Node (10.1.25.9)ΒΆ
This machine runs the Optimism L2 clients (op-geth + op-node).
Install L2 PackagesΒΆ
sudo apt-get update
sudo apt-get install optimism-op-geth optimism-op-node
Create a JWT secret for L2:
sudo openssl rand -hex 32 | sudo tee /etc/ethereum/jwtsecret-l2
sudo chmod 644 /etc/ethereum/jwtsecret-l2
Configure Op-GethΒΆ
Edit /etc/ethereum/op-geth.conf:
ARGS="--datadir=/home/ethereum/.op-geth-sepolia \
--verbosity=3 \
--op-network=op-sepolia \
--http --http.port=9545 --http.addr=0.0.0.0 \
--authrpc.addr=127.0.0.1 \
--authrpc.jwtsecret=/etc/ethereum/jwtsecret-l2 \
--authrpc.port=8555 \
--rollup.sequencerhttp=https://sepolia-sequencer.optimism.io \
--syncmode=snap \
--metrics=true --metrics.addr=0.0.0.0 --metrics.port=7301"
Configure Op-NodeΒΆ
Edit /etc/ethereum/op-node.conf (note: L1 endpoints point to Machine 1):
ARGS="--l1=http://10.1.25.11:8545 \
--l1.beacon=http://10.1.25.11:5052 \
--l2=http://127.0.0.1:8555 \
--network=op-sepolia \
--rpc.addr=0.0.0.0 \
--rpc.port=8545 \
--l2.jwt-secret=/etc/ethereum/jwtsecret-l2 \
--metrics.enabled \
--metrics.addr=0.0.0.0 \
--metrics.port=7300 \
--syncmode=execution-layer"
Start L2 ServicesΒΆ
After L1 is synced on Machine 1:
sudo systemctl enable --now op-geth op-node
Machine 3: Challenger (10.1.25.10)ΒΆ
This machine runs the op-challenger (with cannon and op-program).
Install Challenger PackagesΒΆ
sudo apt-get update
sudo apt-get install optimism-op-challenger
This automatically installs optimism-cannon and optimism-op-program as dependencies.
Create Challenger WalletΒΆ
The challenger needs a funded wallet to submit challenge transactions.
# Generate a new private key
openssl rand -hex 32 > /home/ethereum/challenger-testnet.key
chown ethereum:ethereum /home/ethereum/challenger-testnet.key
chmod 600 /home/ethereum/challenger-testnet.key
# Get the public address (requires cast from Foundry)
cast wallet address --private-key $(cat /home/ethereum/challenger-testnet.key)
Fund the WalletΒΆ
You need Sepolia ETH (for L1 transactions). Use one of these faucets:
Faucet |
Daily Limit |
Requirements |
|---|---|---|
0.1 ETH |
Connect wallet |
|
0.05 ETH |
0.001 ETH mainnet balance |
|
0.5 ETH |
Alchemy account |
Tip
Request funds daily over several days. Youβll need at least 0.1 ETH for testing.
Configure Op-ChallengerΒΆ
Edit /etc/ethereum/op-challenger.conf (note: L1/L2 endpoints point to other machines):
# Challenger Data Directory
DATADIR="/home/ethereum/.op-challenger"
NUM_CONFIRMATIONS=1
# L1 RPCs (Machine 1: 10.1.25.11)
L1_ETH_RPC="http://10.1.25.11:8545"
L1_BEACON_RPC="http://10.1.25.11:5052"
# L2 RPCs (Machine 2: 10.1.25.9)
ROLLUP_RPC="http://10.1.25.9:8545"
L2_ETH_RPC="http://10.1.25.9:9545"
# Network (automatically sets correct DisputeGameFactory address)
NETWORK="op-sepolia"
TRACE_TYPE="cannon"
# Cannon Configuration
CANNON_BIN="/usr/bin/cannon"
CANNON_SERVER="/usr/bin/op-program"
CANNON_PRESTATES_URL="https://storage.googleapis.com/optimism/cannon-prestates/"
# Signer (use your testnet key)
PRIVATE_KEY="/home/ethereum/challenger-testnet.key"
# Build the command arguments
ARGS="--datadir=$DATADIR \
--num-confirmations=$NUM_CONFIRMATIONS \
--l1-eth-rpc=$L1_ETH_RPC \
--l1-beacon=$L1_BEACON_RPC \
--rollup-rpc=$ROLLUP_RPC \
--l2-eth-rpc=$L2_ETH_RPC \
--network=$NETWORK \
--trace-type=$TRACE_TYPE \
--cannon-bin=$CANNON_BIN \
--cannon-server=$CANNON_SERVER \
--cannon-prestates-url=$CANNON_PRESTATES_URL \
--private-key=$PRIVATE_KEY"
Create the data directory:
sudo mkdir -p /home/ethereum/.op-challenger
sudo chown ethereum:ethereum /home/ethereum/.op-challenger
Start the ChallengerΒΆ
After L2 is synced on Machine 2:
sudo systemctl enable --now op-challenger
Check the logs:
sudo journalctl -fu op-challenger
VerificationΒΆ
Signs of a healthy challenger:
Game Detection: You should see logs about tracking games:
INFO [01-04|12:00:00] Monitoring games count=5 type=FaultDisputeGame
No Connection Errors: Ensure no L1/L2 connection errors.
Metrics Available: Check metrics at
http://10.1.25.10:7300/metrics
Service SummaryΒΆ
Machine |
Service |
VPN IP |
Port |
Purpose |
|---|---|---|---|---|
1 |
|
10.1.25.11 |
8545 |
L1 Execution |
1 |
|
10.1.25.11 |
5052 |
L1 Consensus |
2 |
|
10.1.25.9 |
9545 |
L2 Execution |
2 |
|
10.1.25.9 |
8545 |
L2 Rollup RPC |
3 |
|
10.1.25.10 |
7300 |
Challenger |
TroubleshootingΒΆ
- βFailed to connect to L1β
Check VPN connectivity:
ping 10.1.25.11Verify Nethermind is bound to
0.0.0.0
- βL1 beacon client not availableβ
Check VPN connectivity:
ping 10.1.25.11Verify Lighthouse is bound to
0.0.0.0
- βFailed to connect to L2β
Check VPN connectivity:
ping 10.1.25.9Verify op-node/op-geth are bound to
0.0.0.0
- βInsufficient fundsβ
Your challenger wallet needs more Sepolia ETH
Use faucets to request additional funds
See AlsoΒΆ
PiVPN and WireGuard: βIntra-VPNβ - PiVPN/WireGuard setup guide
Running a Guardian Node (Optimism Challenger) - Production setup guide
Verifying Optimism Challenger - Verification procedures