diff --git a/create-l2-rollup-example/.example.env b/create-l2-rollup-example/.example.env index 75a31144b..79f141ddd 100644 --- a/create-l2-rollup-example/.example.env +++ b/create-l2-rollup-example/.example.env @@ -54,6 +54,14 @@ OP_PROPOSER_PROPOSAL_INTERVAL="3600s" OP_PROPOSER_GAME_TYPE="0" OP_PROPOSER_POLL_INTERVAL="20s" +# Dispute monitor environment variables +# ROLLUP_RPC="http://op-node:8547" +# PROPOSER_ADDRESS="" +# CHALLENGER_ADDRESS="" +# OP_DISPUTE_MON_GAME_FACTORY_ADDRESS="" +# OP_DISPUTE_MON_NETWORK="op-sepolia" +# OP_DISPUTE_MON_MONITOR_INTERVAL="10s" + # ========================================== # DEVELOPMENT: Local Network (Alternative to Sepolia) # ========================================== diff --git a/create-l2-rollup-example/dispute-mon/scripts/start-dispute-mon.sh b/create-l2-rollup-example/dispute-mon/scripts/start-dispute-mon.sh new file mode 100755 index 000000000..c8632ea87 --- /dev/null +++ b/create-l2-rollup-example/dispute-mon/scripts/start-dispute-mon.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -e + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +# Change to dispute-mon directory +cd "$SCRIPT_DIR/.." + +# Load environment variables +source .env + +# Path to op-dispute-mon binary +DISPUTE_MON_BIN="$PROJECT_ROOT/optimism/op-dispute-mon/bin/op-dispute-mon" + +# Check if binary exists +if [ ! -f "$DISPUTE_MON_BIN" ]; then + echo "Error: op-dispute-mon binary not found at $DISPUTE_MON_BIN" + echo "Please build op-dispute-mon first:" + echo " cd $PROJECT_ROOT/optimism/op-dispute-mon" + echo " make op-dispute-mon" + exit 1 +fi + +echo "Starting op-dispute-mon..." +echo "Game Factory: $GAME_FACTORY_ADDRESS" +echo "Proposer: $PROPOSER_ADDRESS" +echo "Challenger: $CHALLENGER_ADDRESS" + +$DISPUTE_MON_BIN \ + --l1-eth-rpc=$L1_RPC_URL \ + --rollup-rpc=$ROLLUP_RPC \ + --game-factory-address=$GAME_FACTORY_ADDRESS \ + --honest-actors=$PROPOSER_ADDRESS,$CHALLENGER_ADDRESS \ + --network=$NETWORK \ + --monitor-interval=$MONITOR_INTERVAL \ + --log.level=$LOG_LEVEL \ + --log.format=$LOG_FORMAT \ + --metrics.enabled=$METRICS_ENABLED \ + --metrics.addr=$METRICS_ADDR \ + --metrics.port=$METRICS_PORT \ No newline at end of file diff --git a/create-l2-rollup-example/docker-compose.yml b/create-l2-rollup-example/docker-compose.yml index edb43c96a..dd0e52d9a 100644 --- a/create-l2-rollup-example/docker-compose.yml +++ b/create-l2-rollup-example/docker-compose.yml @@ -149,5 +149,34 @@ services: op-node: condition: service_healthy + # Dispute Monitor + dispute-mon: + image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-dispute-mon:v1.4.2-rc.1 + container_name: dispute-mon + volumes: + - ./dispute-mon:/workspace + working_dir: /workspace + ports: + - "7300:7300" + env_file: + - ./dispute-mon/.env + - .env + environment: + - OP_DISPUTE_MON_L1_ETH_RPC=${L1_RPC_URL} + - OP_DISPUTE_MON_ROLLUP_RPC=${ROLLUP_RPC} + - OP_DISPUTE_MON_HONEST_ACTORS=${PROPOSER_ADDRESS},${CHALLENGER_ADDRESS} + - OP_DISPUTE_MON_GAME_FACTORY_ADDRESS=${GAME_FACTORY_ADDRESS} + - OP_DISPUTE_MON_MONITOR_INTERVAL=10s + - OP_DISPUTE_MON_NETWORK=op-sepolia + - OP_DISPUTE_MON_LOG_LEVEL=debug + - OP_DISPUTE_MON_LOG_FORMAT=logfmt + - OP_DISPUTE_MON_METRICS_ADDR=0.0.0.0 + - OP_DISPUTE_MON_METRICS_ENABLED=true + - OP_DISPUTE_MON_METRICS_PORT=7300 + depends_on: + op-node: + condition: service_healthy + restart: unless-stopped + volumes: op_geth_data: diff --git a/create-l2-rollup-example/optimism b/create-l2-rollup-example/optimism deleted file mode 160000 index a094d0160..000000000 --- a/create-l2-rollup-example/optimism +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a094d016092e3355642d00be6d7943c4529ef008 diff --git a/create-l2-rollup-example/scripts/setup-rollup.sh b/create-l2-rollup-example/scripts/setup-rollup.sh index 510462ec2..23a4d7241 100755 --- a/create-l2-rollup-example/scripts/setup-rollup.sh +++ b/create-l2-rollup-example/scripts/setup-rollup.sh @@ -30,6 +30,7 @@ SEQUENCER_DIR="$ROLLUP_DIR/sequencer" BATCHER_DIR="$ROLLUP_DIR/batcher" PROPOSER_DIR="$ROLLUP_DIR/proposer" CHALLENGER_DIR="$ROLLUP_DIR/challenger" +DISPUTE_MON_DIR="$ROLLUP_DIR/dispute-mon" # Logging functions log_info() { @@ -427,6 +428,49 @@ generate_challenger_prestate() { log_success "Challenger prestate generation complete: $ROLLUP_DIR/challenger/${PRESTATE_HASH}.bin.gz" } +# Setup dispute monitor +setup_dispute_monitor() { + log_info "Setting up dispute monitor..." + + mkdir -p "$DISPUTE_MON_DIR" + cd "$DISPUTE_MON_DIR" + + # Get required addresses from state.json + GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy' "$DEPLOYER_DIR/.deployer/state.json") + PROPOSER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.proposer' "$DEPLOYER_DIR/.deployer/state.json") + CHALLENGER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.challenger' "$DEPLOYER_DIR/.deployer/state.json") + + log_info "Game Factory: $GAME_FACTORY_ADDRESS" + log_info "Proposer: $PROPOSER_ADDRESS" + log_info "Challenger: $CHALLENGER_ADDRESS" + + # Create environment file for dispute monitor + cat > .env << EOF +# Rollup RPC Configuration +ROLLUP_RPC=http://op-node:8547 + +# Contract Addresses +OP_DISPUTE_MON_GAME_FACTORY_ADDRESS=$GAME_FACTORY_ADDRESS + +# Honest Actors +PROPOSER_ADDRESS=$PROPOSER_ADDRESS +CHALLENGER_ADDRESS=$CHALLENGER_ADDRESS + +# Network Configuration +OP_DISPUTE_MON_NETWORK=op-sepolia + +# Monitoring Configuration +OP_DISPUTE_MON_MONITOR_INTERVAL=10s +EOF + + # Create logs directory + mkdir -p logs + + log_success "Dispute monitor configuration created" + log_info "Dispute monitor will start with 'docker-compose up -d' from project root" + log_info "To verify it's working, run: curl -s http://localhost:7300/metrics | grep -E \"op_dispute_mon_(games|ignored)\" | head -10" +} + # Add op-deployer to PATH if it exists in the workspace if [ -f "$(dirname "$0")/../op-deployer" ]; then OP_DEPLOYER_PATH="$(cd "$(dirname "$0")/.." && pwd)/op-deployer" @@ -457,9 +501,11 @@ main() { setup_proposer generate_challenger_prestate setup_challenger + setup_dispute_monitor log_success "OP Stack L2 Rollup deployment complete!" - log_info "Run 'docker-compose up -d' to start all services" + log_info "Run 'docker-compose up -d' to start all services (including dispute monitor)" + log_info "Dispute monitor metrics: http://localhost:7300/metrics" } # Handle command line arguments for standalone function calls diff --git a/docs.json b/docs.json index b80ce5121..0ffe2df00 100644 --- a/docs.json +++ b/docs.json @@ -572,14 +572,14 @@ }, { "group": "Tools", - "pages": [ + "pages": [ "interop/tools/supersim", "interop/tools/devnet" - ] - }, - { + ] + }, + { "group": "Tutorials", - "pages": [ + "pages": [ "interop/tutorials/transfer-superchainERC20", "interop/tutorials/deploy-superchain-erc20", "interop/tutorials/bridge-crosschain-eth", @@ -588,16 +588,16 @@ "interop/tutorials/event-reads", "interop/tutorials/event-contests", "interop/tutorials/upgrade-to-superchain-erc20" + ] + } ] - } - ] - }, - { + }, + { "tab": "App Devs", "groups": [ - { + { "group": "App Developers", - "pages": [ + "pages": [ "interop/get-started", "interop/starter-kit", "interop/explainer", @@ -670,11 +670,11 @@ "app-developers/tutorials/interop/event-contests", "app-developers/tutorials/interop/event-reads", "app-developers/tutorials/interop/transfer-superchainERC20" - ] - } ] - }, - { + } + ] + }, + { "group": "Developer Tools", "pages": [ "app-developers/tools/supersim", @@ -702,16 +702,16 @@ "app-developers/tools/data-and-dashboards/data-glossary" ] } + ] + } ] - } - ] - }, - { + }, + { "tab": "Operators", "groups": [ - { + { "group": "Chain Operators", - "pages": [ + "pages": [ "operators/chain-operators/architecture", "operators/chain-operators/self-hosted", { @@ -745,7 +745,7 @@ }, { "group": "Deployment", - "pages": [ + "pages": [ "operators/chain-operators/deploy/genesis", "operators/chain-operators/deploy/overview", "operators/chain-operators/deploy/proposer-setup-guide", @@ -753,20 +753,21 @@ "operators/chain-operators/deploy/smart-contracts", "operators/chain-operators/deploy/spin-batcher", "operators/chain-operators/deploy/validate-deployment" - ] - }, + ] + }, + { + "group": "Tutorials", + "pages": [ { - "group": "Tutorials", - "pages": [ - { "group": "Create L2 rollup testnet", - "pages": [ + "pages": [ "operators/chain-operators/tutorials/create-l2-rollup", "operators/chain-operators/tutorials/create-l2-rollup/op-deployer-setup", "operators/chain-operators/tutorials/create-l2-rollup/op-geth-setup", "operators/chain-operators/tutorials/create-l2-rollup/op-batcher-setup", "operators/chain-operators/tutorials/create-l2-rollup/op-proposer-setup", - "operators/chain-operators/tutorials/create-l2-rollup/op-challenger-setup" + "operators/chain-operators/tutorials/create-l2-rollup/op-challenger-setup", + "operators/chain-operators/tutorials/create-l2-rollup/op-dispute-setup" ] }, "operators/chain-operators/tutorials/absolute-prestate", @@ -790,25 +791,25 @@ "operators/chain-operators/tools/op-txproxy", "operators/chain-operators/tools/op-validator", "operators/chain-operators/tools/proxyd" - ] - } ] - }, - { + } + ] + }, + { "group": "Node Operators", "pages": [ "operators/node-operators/architecture", - { + { "group": "Tutorials", - "pages": [ + "pages": [ "operators/node-operators/tutorials/node-from-docker", "operators/node-operators/tutorials/node-from-source", "operators/node-operators/tutorials/run-node-from-source" - ] - }, - { + ] + }, + { "group": "Configuration", - "pages": [ + "pages": [ "operators/node-operators/configuration/base-config", "operators/node-operators/configuration/consensus-config", "operators/node-operators/configuration/execution-config" @@ -828,11 +829,11 @@ "operators/node-operators/network-upgrades", "operators/node-operators/json-rpc", "operators/node-operators/releases" + ] + } ] - } - ] - }, - { + }, + { "tab": "OP Stack", "groups": [ { @@ -848,7 +849,7 @@ "stack/opcm", { "group": "Smart Contracts", - "pages": [ + "pages": [ "stack/smart-contracts/smart-contracts", "stack/smart-contracts/superchain-ops-guide", "stack/smart-contracts/op-deployer-upgrade", @@ -857,15 +858,15 @@ }, { "group": "Rollup", - "pages": [ + "pages": [ "stack/rollup/overview", "stack/rollup/derivation-pipeline", "stack/rollup/outages" - ] - }, - { + ] + }, + { "group": "Fault Proofs", - "pages": [ + "pages": [ "stack/fault-proofs/explainer", "stack/fault-proofs/fp-components", "stack/fault-proofs/cannon", @@ -876,7 +877,7 @@ }, { "group": "Transactions", - "pages": [ + "pages": [ "stack/transactions/fees", "stack/transactions/transaction-flow", "stack/transactions/transaction-finality", @@ -888,13 +889,13 @@ }, { "group": "Features", - "pages": [ + "pages": [ "stack/features/send-raw-transaction-conditional" ] }, { "group": "Security", - "pages": [ + "pages": [ "stack/security/faq", "stack/security/pause", "stack/security/audits-report", @@ -925,13 +926,13 @@ }, { "tab": "Notices", - "pages": [ - "notices/fusaka-notice", + "pages": [ + "notices/fusaka-notice", "notices/upgrade-13", "notices/upgrade-14", "notices/upgrade-15", - "notices/upgrade-16", - "notices/upgrade-16a", + "notices/upgrade-16", + "notices/upgrade-16a", "notices/holocene-changes", "notices/pectra-changes", "notices/pectra-fees", @@ -968,7 +969,7 @@ "icon": "discord" } ] - } + } }, "logo": { "light": "/public/logos/logo-docs-light.svg", diff --git a/operators/chain-operators/tutorials/create-l2-rollup/op-dispute-setup.mdx b/operators/chain-operators/tutorials/create-l2-rollup/op-dispute-setup.mdx new file mode 100644 index 000000000..37096cc74 --- /dev/null +++ b/operators/chain-operators/tutorials/create-l2-rollup/op-dispute-setup.mdx @@ -0,0 +1,455 @@ +--- +title: Monitor your chain with Dispute Monitor +description: Learn how to set up op-dispute-mon to monitor dispute games and fault proof activity on your L2 rollup. +--- + +Now that you have a running OP Stack rollup with fault proofs enabled, it's critical to monitor your dispute games to ensure your chain operates securely. This tutorial will guide you through setting up `op-dispute-mon` to track all dispute game activity on your rollup. + + + This tutorial continues from the previous steps in [Creating Your Own L2 Rollup](/operators/chain-operators/tutorials/create-l2-rollup). Make sure you have completed the op-challenger setup and have dispute games running before proceeding. + + +## What you'll set up + +By the end of this tutorial, you'll have: + +* **op-dispute-mon** monitoring all dispute games on your chain +* **Real-time tracking** of game status, agreements, and honest actor participation +* Understanding of key metrics for dispute game health + +## Prerequisites + +Before you begin, ensure you have: + +* Completed all previous steps in the [Creating Your Own L2 Rollup tutorial](/operators/chain-operators/tutorials/create-l2-rollup) +* op-challenger running and participating in dispute games +* op-proposer running and creating proposals +* L1 RPC endpoint with sufficient rate limits +* Rollup RPC endpoint (op-node) +* Docker installed (for Docker setup) OR Go 1.21+ (for build from source) + +## What is op-dispute-mon? + +`op-dispute-mon` is a specialized monitoring tool that tracks dispute games in the fault proof system. It provides visibility into: + +* **Game status**: Track games from creation to resolution +* **Honest actor participation**: Monitor your proposer and challenger activity +* **Agreement tracking**: See which games agree/disagree with your honest actors +* **Game completion**: Monitor in-progress vs completed games +* **Ignored games**: Track games that don't meet monitoring criteria + +The monitor exposes Prometheus metrics that can be used to build dashboards and alerts. + + + + + + + + +```bash +# From your project root +cd rollup +mkdir dispute-mon +cd dispute-mon +``` + + + + + +```bash +# Get DisputeGameFactory address from deployment +export GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy' ../deployer/.deployer/state.json) +echo "Game Factory Address: $GAME_FACTORY_ADDRESS" + +# Get Proposer address +export PROPOSER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.proposer' ../deployer/.deployer/state.json) +echo "Proposer Address: $PROPOSER_ADDRESS" + +# Get Challenger address +export CHALLENGER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.challenger' ../deployer/.deployer/state.json) +echo "Challenger Address: $CHALLENGER_ADDRESS" +``` + + + + + +Create a `.env` file with the addresses: + +```bash +cat > .env << EOF +# Contract Addresses +GAME_FACTORY_ADDRESS=$GAME_FACTORY_ADDRESS + +# Honest Actors +PROPOSER_ADDRESS=$PROPOSER_ADDRESS +CHALLENGER_ADDRESS=$CHALLENGER_ADDRESS + +# L1 RPC (replace with your actual RPC) +L1_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY +EOF +``` + + + + + +```yaml +version: "3.8" + +services: + op-dispute-mon: + image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-dispute-mon:v1.4.2-rc.1 + container_name: dispute-mon + ports: + - "7300:7300" # Metrics port + env_file: + - .env + environment: + # L1 RPC Configuration + - OP_DISPUTE_MON_L1_ETH_RPC=${L1_RPC_URL} + + # Rollup RPC Configuration (your op-node) + - OP_DISPUTE_MON_ROLLUP_RPC=http://op-node:8547 + + # Honest Actors (your proposer and challenger addresses) + - OP_DISPUTE_MON_HONEST_ACTORS=${PROPOSER_ADDRESS},${CHALLENGER_ADDRESS} + + # DisputeGameFactory Contract Address + - OP_DISPUTE_MON_GAME_FACTORY_ADDRESS=${GAME_FACTORY_ADDRESS} + + # Monitoring Configuration + - OP_DISPUTE_MON_MONITOR_INTERVAL=10s + - OP_DISPUTE_MON_NETWORK=op-sepolia + + # Logging Configuration + - OP_DISPUTE_MON_LOG_FORMAT=logfmt + - OP_DISPUTE_MON_LOG_LEVEL=debug + + # Metrics Configuration + - OP_DISPUTE_MON_METRICS_ADDR=0.0.0.0 + - OP_DISPUTE_MON_METRICS_ENABLED=true + - OP_DISPUTE_MON_METRICS_PORT=7300 + restart: unless-stopped + networks: + - dispute-mon-network + +networks: + dispute-mon-network: + driver: bridge +``` + + + Replace `YOUR_INFURA_KEY` with your actual Infura API key or use another L1 RPC provider. Make sure your L1 RPC has sufficient rate limits. + + + + + + +```bash +# Start the container (variables loaded from .env) +docker-compose up -d + +# View logs +docker-compose logs -f op-dispute-mon +``` + + + + + +```bash +# Query metrics endpoint +curl http://localhost:7300/metrics + +# View recent logs +docker-compose logs --tail=50 op-dispute-mon +``` + +You should see logs indicating the monitor is tracking games: + +``` +t=2025-10-21T05:58:52+0100 lvl=info msg="Starting op-dispute-mon" +t=2025-10-21T05:58:52+0100 lvl=info msg="started metrics server" addr=[::]:7300 +t=2025-10-21T05:59:03+0100 lvl=info msg="Completed monitoring update" games=0 ignored=0 failed=0 +``` + + + + + + + + + + + + + +```bash +# From your project root +cd optimism + +# Pull latest changes +git pull + +# Build op-dispute-mon +cd op-dispute-mon +make op-dispute-mon + +# Verify the build +./bin/op-dispute-mon --version + +# Return to project root +cd../.. +``` + + + + + +```bash +# From your project root +cd rollup +mkdir -p dispute-mon/scripts +cd dispute-mon +``` + + + + + +```bash +# Get DisputeGameFactory address from deployment +export GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy' ../deployer/.deployer/state.json) +echo "Game Factory Address: $GAME_FACTORY_ADDRESS" + +# Get Proposer address +export PROPOSER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.proposer' ../deployer/.deployer/state.json) +echo "Proposer Address: $PROPOSER_ADDRESS" + +# Get Challenger address +export CHALLENGER_ADDRESS=$(jq -r '.appliedIntent.chains[0].roles.challenger' ../deployer/.deployer/state.json) +echo "Challenger Address: $CHALLENGER_ADDRESS" + +# Get L1 RPC URL +source ../.env +echo "L1 RPC: $L1_RPC_URL" +``` + + + + + +```bash +cat > .env << EOF +# L1 Configuration +L1_RPC_URL=$L1_RPC_URL + +# Rollup Configuration +ROLLUP_RPC=http://localhost:8547 + +# Contract Addresses +GAME_FACTORY_ADDRESS=$GAME_FACTORY_ADDRESS + +# Honest Actors +PROPOSER_ADDRESS=$PROPOSER_ADDRESS +CHALLENGER_ADDRESS=$CHALLENGER_ADDRESS + +# Network Configuration +NETWORK=op-sepolia + +# Monitoring Configuration +MONITOR_INTERVAL=10s + +# Logging Configuration +LOG_LEVEL=info +LOG_FORMAT=logfmt + +# Metrics Configuration +METRICS_ADDR=0.0.0.0 +METRICS_ENABLED=true +METRICS_PORT=7300 +EOF +``` + + + + + +```bash +#!/bin/bash +set -e + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +# Change to dispute-mon directory +cd "$SCRIPT_DIR/.." + +# Load environment variables +source .env + +# Path to op-dispute-mon binary +DISPUTE_MON_BIN="$PROJECT_ROOT/optimism/op-dispute-mon/bin/op-dispute-mon" + +# Check if binary exists +if [ ! -f "$DISPUTE_MON_BIN" ]; then + echo "Error: op-dispute-mon binary not found at $DISPUTE_MON_BIN" + echo "Please build op-dispute-mon first:" + echo " cd $PROJECT_ROOT/optimism/op-dispute-mon" + echo " make op-dispute-mon" + exit 1 +fi + +echo "Starting op-dispute-mon..." +echo "Game Factory: $GAME_FACTORY_ADDRESS" +echo "Proposer: $PROPOSER_ADDRESS" +echo "Challenger: $CHALLENGER_ADDRESS" + +$DISPUTE_MON_BIN \ + --l1-eth-rpc=$L1_RPC_URL \ + --rollup-rpc=$ROLLUP_RPC \ + --game-factory-address=$GAME_FACTORY_ADDRESS \ + --honest-actors=$PROPOSER_ADDRESS,$CHALLENGER_ADDRESS \ + --network=$NETWORK \ + --monitor-interval=$MONITOR_INTERVAL \ + --log.level=$LOG_LEVEL \ + --log.format=$LOG_FORMAT \ + --metrics.enabled=$METRICS_ENABLED \ + --metrics.addr=$METRICS_ADDR \ + --metrics.port=$METRICS_PORT +``` + +Make it executable: + +```bash +chmod +x scripts/start-dispute-mon.sh +``` + + + + + +```bash +# Start in foreground (for testing) +./scripts/start-dispute-mon.sh + +# Or start in background with logging +mkdir -p logs +./scripts/start-dispute-mon.sh > logs/dispute-mon.log 2>&1 & + +# Save the process ID +echo $! > dispute-mon.pid +``` + + + + + +```bash +# Check if process is running +ps aux | grep op-dispute-mon + +# Query metrics endpoint +curl http://localhost:7300/metrics + +# Check logs +tail -f logs/dispute-mon.log +``` + + + + + + + + + +### Understanding key metrics + +Once op-dispute-mon is running, it exposes several important metrics that help you monitor dispute game health. + + +The metrics shown below are from the [official OP Stack Grafana dashboard](https://github.com/ethereum-optimism/optimism/blob/develop/op-dispute-mon/README.md) and represent actual production metrics used by Optimism. + + +### Core metrics + +**Monitor health:** + +``` +# Monitor is running (1 = up, 0 = down) +op_dispute_mon_up 1 +``` + +**Game agreement metrics:** + +The primary metric for tracking dispute games, with labels for completion status, result correctness, root agreement, and game status: + +``` +# Games by completion and status +op_dispute_mon_games_agreement{completion="complete",result_correctness="correct",root_agreement="agree",status="agree_defender_wins"} 0 +op_dispute_mon_games_agreement{completion="in_progress",result_correctness="correct",root_agreement="agree",status="agree_defender_ahead"} 0 +op_dispute_mon_games_agreement{completion="complete",result_correctness="incorrect",status="challenger_wins"} 0 +``` + +**Label meanings:** +- `completion`: `"complete"` or `"in_progress"` +- `result_correctness`: `"correct"` or `"incorrect"` (based on your honest actors) +- `root_agreement`: `"agree"` or `"disagree"` (whether game agrees with honest actors) +- `status`: Game outcome like `"agree_defender_wins"`, `"challenger_wins"`, etc. + +**What to monitor:** +- Any non-zero `root_agreement="disagree"` requires immediate investigation +- `result_correctness="incorrect"` games should resolve to `"challenger_wins"` +- For new testnets, all values being `0` is normal until games are created + +**Ignored games:** + +``` +# Games not meeting monitoring criteria +op_dispute_mon_ignored_games 0 +``` + +Games may be ignored if they don't involve your honest actors or fall outside the monitoring window. + +**Honest actor bonds:** + +``` +# Bond status for your proposer and challenger +op_dispute_mon_honest_actor_bonds{honest_actor_address="0xYourProposer",state="won"} 0 +op_dispute_mon_honest_actor_bonds{honest_actor_address="0xYourProposer",state="lost"} 0 +op_dispute_mon_honest_actor_bonds{honest_actor_address="0xYourProposer",state="pending"} 0 +``` + +Tracks bonds posted by your honest actors and their outcomes (`won`, `lost`, or `pending`). + +**Honest actor claims:** + +``` +# Claims made by your honest actors +op_dispute_mon_honest_actor_claims{honest_actor_address="0xYourProposer",state="valid"} 0 +op_dispute_mon_honest_actor_claims{honest_actor_address="0xYourProposer",state="invalid"} 0 +``` + +Monitors whether your honest actors have sufficient collateral for bonds. + + +For a new testnet, it's normal for all game metrics to show `0` values. Games will only appear after your proposer creates proposals (typically every ~1 hour). + + +## Next steps + +Now that you have dispute game monitoring set up, you can: + +* Create alerting for critical metrics like disagreements +* Explore the [Dispute monitor tool reference](/operators/chain-operators/tools/chain-monitoring) +* Learn more about the [fault proof system](/stack/fault-proofs/explainer) +* Set up [Prometheus](https://prometheus.io/docs/) and [Grafana](https://grafana.com/docs/) for advanced metrics visualization (optional) + +Congratulations! You now have a fully operational OP Stack L2 rollup with comprehensive monitoring. \ No newline at end of file