├── .env.example ├── .github └── workflows │ └── attest.yml ├── .gitignore ├── LICENSE ├── README.md ├── docker-compose.yml ├── docker ├── dockerfiles │ └── Dockerfile.bedrock-init ├── grafana │ ├── dashboards │ │ └── simple_node_dashboard.json │ └── provisioning │ │ ├── dashboards │ │ └── all.yml │ │ └── datasources │ │ └── all.yml ├── influxdb │ └── influx_init.iql └── prometheus │ └── prometheus.yml ├── envs ├── base-mainnet │ ├── config │ │ ├── genesis.json │ │ └── rollup.json │ ├── op-geth.env │ └── op-node.env ├── base-sepolia │ ├── config │ │ ├── genesis.json │ │ └── rollup.json │ ├── op-geth.env │ └── op-node.env ├── common │ ├── grafana.env │ ├── healthcheck.env │ ├── influxdb.env │ └── l2geth.env ├── op-goerli │ ├── op-geth.env │ └── op-node.env ├── op-mainnet │ ├── op-geth.env │ └── op-node.env └── op-sepolia │ ├── op-geth.env │ └── op-node.env ├── funding.json ├── progress.sh ├── prysm.yml └── scripts ├── beacon.yaml ├── init-bedrock.sh ├── init-l2geth.sh ├── start-l2geth.sh ├── start-op-geth.sh ├── start-op-node.sh └── utils.sh /.env.example: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # ↓ REQUIRED ↓ # 3 | ############################################################################### 4 | 5 | # Network to run the node on ("op-mainnet" or "op-sepolia") 6 | NETWORK_NAME=op-mainnet 7 | 8 | # Type of node to run ("full" or "archive"), note that "archive" is 10x bigger 9 | NODE_TYPE=full 10 | 11 | ############################################################################### 12 | # ↓ REQUIRED (BEDROCK) ↓ # 13 | ############################################################################### 14 | 15 | # L1 node that the op-node (Bedrock) will get chain data from 16 | OP_NODE__RPC_ENDPOINT= 17 | 18 | # L1 beacon endpoint, you can setup your own or use Quicknode 19 | OP_NODE__L1_BEACON= 20 | 21 | # Type of RPC that op-node is connected to, see README 22 | OP_NODE__RPC_TYPE=basic 23 | 24 | # Reference L2 node to run healthcheck against 25 | HEALTHCHECK__REFERENCE_RPC_PROVIDER= 26 | 27 | ############################################################################### 28 | # ↓ OPTIONAL (BEDROCK) ↓ # 29 | ############################################################################### 30 | 31 | # Optional provider to serve legacy RPC requests, see README 32 | OP_GETH__HISTORICAL_RPC=https://mainnet.optimism.io 33 | 34 | # Set to "full" to force op-geth to use --syncmode=full 35 | OP_GETH__SYNCMODE= 36 | 37 | ############################################################################### 38 | # ↓ OPTIONAL ↓ # 39 | ############################################################################### 40 | 41 | # Feel free to customize your image tag if you want, uses "latest" by default 42 | # See here for all available images: https://hub.docker.com/u/ethereumoptimism 43 | IMAGE_TAG__L2GETH= 44 | IMAGE_TAG__DTL= 45 | IMAGE_TAG__HEALTCHECK= 46 | IMAGE_TAG__PROMETHEUS= 47 | IMAGE_TAG__GRAFANA= 48 | IMAGE_TAG__INFLUXDB= 49 | IMAGE_TAG__OP_GETH= 50 | IMAGE_TAG__OP_NODE= 51 | 52 | # Exposed server ports (must be unique) 53 | # See docker-compose.yml for default values 54 | PORT__L2GETH_HTTP= 55 | PORT__L2GETH_WS= 56 | PORT__DTL= 57 | PORT__HEALTHCHECK_METRICS= 58 | PORT__PROMETHEUS= 59 | PORT__GRAFANA= 60 | PORT__INFLUXDB= 61 | PORT__TORRENT_UI= 62 | PORT__TORRENT= 63 | PORT__OP_GETH_HTTP= 64 | PORT__OP_GETH_WS= 65 | PORT__OP_GETH_P2P= 66 | PORT__OP_NODE_P2P= 67 | PORT__OP_NODE_HTTP= 68 | -------------------------------------------------------------------------------- /.github/workflows/attest.yml: -------------------------------------------------------------------------------- 1 | name: PR Attestation 2 | on: 3 | pull_request: 4 | types: [closed] 5 | 6 | jobs: 7 | attest: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Create Attestation 11 | id: attestation 12 | uses: buildooor/github-attestation-action@master 13 | with: 14 | private-key: ${{ secrets.PRIVATE_KEY }} 15 | rpc-url: ${{ secrets.RPC_URL }} 16 | network: sepolia 17 | branch: main 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .upgrade-pectra -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright 2020-2022 Optimism 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Optimism Node 2 | 3 | A simple docker compose script for launching full / archive node for OP Stack chains. 4 | 5 | 7 | 8 | ## Recommended Hardware 9 | 10 | ### OP and Base Mainnet 11 | 12 | - 16GB+ RAM 13 | - 2 TB SSD (NVME Recommended) 14 | - 100mb/s+ Download 15 | 16 | ### Testnets 17 | 18 | - 16GB+ RAM 19 | - 500 GB SSD (NVME Recommended) 20 | - 100mb/s+ Download 21 | 22 | ## Installation and Configuration 23 | 24 | ### Install docker and docker compose 25 | 26 | > Note: If you're not logged in as root, you'll need to log out and log in again after installation to complete the docker installation. 27 | 28 | Note: This command install docker and docker compose for Ubuntu. For windows and mac desktop or laptop, please use Docker Desktop. For other OS, please find instruction in Google. 29 | 30 | ```sh 31 | # Update and upgrade packages 32 | sudo apt-get update 33 | sudo apt-get upgrade -y 34 | 35 | ### Docker and docker compose prerequisites 36 | sudo apt-get install -y curl 37 | sudo apt-get install -y gnupg 38 | sudo apt-get install -y ca-certificates 39 | sudo apt-get install -y lsb-release 40 | 41 | ### Download the docker gpg file to Ubuntu 42 | sudo mkdir -p /etc/apt/keyrings 43 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 44 | 45 | ### Add Docker and docker compose support to the Ubuntu's packages list 46 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 47 | 48 | sudo apt-get update 49 | 50 | ### Install docker and docker compose on Ubuntu 51 | sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin 52 | 53 | sudo usermod -aG docker $(whoami) 54 | 55 | ### Verify the Docker and docker compose install on Ubuntu 56 | sudo docker run hello-world 57 | ``` 58 | 59 | (For non-root user) After logged out and logged back in, test if docker is working by running. 60 | 61 | ```sh 62 | docker ps 63 | ``` 64 | 65 | It should returns an empty container list without having any error. Otherwise, restart your machine if there are errors. 66 | 67 | ### Clone the Repository 68 | 69 | ```sh 70 | git clone https://github.com/smartcontracts/simple-optimism-node.git 71 | cd simple-optimism-node 72 | ``` 73 | 74 | ### Copy .env.example to .env 75 | 76 | Make a copy of `.env.example` named `.env`. 77 | 78 | ```sh 79 | cp .env.example .env 80 | ``` 81 | 82 | Open `.env` with your editor of choice 83 | 84 | ### Mandatory configurations 85 | 86 | * **NETWORK_NAME** - Choose which Optimism network layer you want to operate on: 87 | * `op-mainnet` - Optimism Mainnet 88 | * `op-sepolia` - Optimism Sepolia (Testnet) 89 | * `base-mainnet` - Base Mainnet 90 | * `base-sepolia` - Base Sepolia (Testnet) 91 | * **NODE_TYPE** - Choose the type of node you want to run: 92 | * `full` (Full node) - A Full node contains a few recent blocks without historical states. 93 | * `archive` (Archive node) - An Archive node stores the complete history of the blockchain, including historical states. 94 | * **OP_NODE__RPC_ENDPOINT** - Specify the endpoint for the RPC of Layer 1 (e.g., Ethereum mainnet). For instance, you can use the free plan of Alchemy for the Ethereum mainnet. 95 | * **OP_NODE__L1_BEACON** - Specify the beacon endpoint of Layer 1. You can use [QuickNode for the beacon endpoint](https://www.quicknode.com). For example: https://xxx-xxx-xxx.quiknode.pro/db55a3908ba7e4e5756319ffd71ec270b09a7dce 96 | * **OP_NODE__RPC_TYPE** - Specify the service provider for the RPC endpoint you've chosen in the previous step. The available options are: 97 | * `alchemy` - Alchemy 98 | * `quicknode` - Quicknode (ETH only) 99 | * `erigon` - Erigon 100 | * `basic` - Other providers 101 | * **HEALTHCHECK__REFERENCE_RPC_PROVIDER** - Specify the public RPC endpoint for Layer 2 network you want to operate on for healthchecking. For instance: 102 | * **Optimism Mainnet** - https://mainnet.optimism.io 103 | * **Optimism Sepolia** - https://sepolia.optimism.io 104 | * **Base Mainnet** - https://mainnet.base.org 105 | * **Base Sepolia** - https://sepolia.base.org 106 | 107 | ### OP Mainnet only configurations 108 | 109 | * **OP_GETH__HISTORICAL_RPC** - OP Mainnet RPC Endpoint for fetching pre-bedrock historical data 110 | * **Recommended:** https://mainnet.optimism.io 111 | * Leave blank if you want to self-host pre-bedrock historical node for high-throughput use cases such as subgraph indexing. 112 | 113 | ### Optional configurations 114 | 115 | * **OP_GETH__SYNCMODE** - Specify sync mode for the execution client 116 | * Unspecified - Use default snap sync for full node and full sync for archive node 117 | * `snap` - Snap Sync (Default) 118 | * `full` - Full Sync (For archive node, not recommended for full node) 119 | * **IMAGE_TAG__[...]** - Use custom docker image for specified components. 120 | * **PORT__[...]** - Use custom port for specified components. 121 | 122 | ## Operating the Node 123 | 124 | ### Start 125 | 126 | ```sh 127 | docker compose up -d --build 128 | ``` 129 | 130 | Will start the node in a detached shell (`-d`), meaning the node will continue to run in the background. We recommended to add `--build` to make sure that latest changes are being applied. 131 | 132 | ### View logs 133 | 134 | ```sh 135 | docker compose logs -f --tail 10 136 | ``` 137 | 138 | To view logs of all containers. 139 | 140 | ```sh 141 | docker compose logs -f --tail 10 142 | ``` 143 | 144 | To view logs for a specific container. Most commonly used `` are: 145 | * op-geth 146 | * op-node 147 | * bedrock-init 148 | * l2geth 149 | 150 | ### Stop 151 | 152 | ```sh 153 | docker compose down 154 | ``` 155 | 156 | Will shut down the node without wiping any volumes. 157 | You can safely run this command and then restart the node again. 158 | 159 | ### Restart 160 | 161 | ```sh 162 | docker compose restart 163 | ``` 164 | 165 | Will restart the node safely with minimal downtime but without upgrading the node. 166 | 167 | ### Upgrade 168 | 169 | Pull the latest updates from GitHub, and Docker Hub and rebuild the container. 170 | 171 | ```sh 172 | git pull 173 | docker compose pull 174 | docker compose up -d --build 175 | ``` 176 | 177 | Will upgrade your node with minimal downtime. 178 | 179 | ### Wipe [DANGER] 180 | 181 | ```sh 182 | docker compose down -v 183 | ``` 184 | 185 | Will shut down the node and WIPE ALL DATA. Proceed with caution! 186 | 187 | ## Monitoring 188 | 189 | ### Estimate remaining sync time 190 | 191 | Run progress.sh to estimate remaining sync time and speed. 192 | 193 | ```sh 194 | ./progress.sh 195 | ``` 196 | 197 | This will show the sync speed in blocks per minute and the time until sync is completed. 198 | 199 | ``` 200 | Chain ID: 10 201 | Please wait 202 | Blocks per minute: ... 203 | Hours until sync completed: ... 204 | ``` 205 | 206 | ### Grafana dashboard 207 | 208 | Grafana is exposed at [http://localhost:3000](http://localhost:3000) and comes with one pre-loaded dashboard ("Simple Node Dashboard"). 209 | Simple Node Dashboard includes basic node information and will tell you if your node ever falls out of sync with the reference L2 node or if a state root fault is detected. 210 | 211 | Use the following login details to access the dashboard: 212 | 213 | - Username: `admin` 214 | - Password: `optimism` 215 | 216 | Navigate over to `Dashboards > Manage > Simple Node Dashboard` to see the dashboard, see the following gif if you need help: 217 | 218 | ![metrics dashboard gif](https://user-images.githubusercontent.com/14298799/171476634-0cb84efd-adbf-4732-9c1d-d737915e1fa7.gif) 219 | 220 | ## Troubleshooting 221 | 222 | ### Walking back L1Block with curr=0x0000...:0 next=0x0000...:0 223 | 224 | If you experience "walking back L1Block with curr=0x0000...:0 next=0x0000...:0" for a long time after the Ecotone upgrade, consider these fixes: 225 | 1. Wait for a few minutes. This issue usually resolves itself after some time. 226 | 2. Restart docker compose: `docker compose down` and `docker compose up -d --build` 227 | 3. If it's still not working, try setting `OP_GETH__SYNCMODE=full` in .env and restart docker compose 228 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | l2geth: 4 | image: ethereumoptimism/l2geth:${IMAGE_TAG__L2GETH:-latest} 5 | restart: on-failure 6 | stop_grace_period: 5m 7 | entrypoint: 8 | - /bin/sh 9 | - -c 10 | - "/scripts/init-l2geth.sh && /scripts/start-l2geth.sh" 11 | env_file: 12 | - ./envs/common/l2geth.env 13 | - .env 14 | volumes: 15 | - geth:/geth 16 | - ./scripts/:/scripts/ 17 | ports: 18 | - ${PORT__L2GETH_HTTP:-9991}:8545 19 | - ${PORT__L2GETH_WS:-9992}:8546 20 | 21 | healthcheck: 22 | image: ethereumoptimism/replica-healthcheck:${IMAGE_TAG__HEALTHCHECK:-latest} 23 | restart: unless-stopped 24 | env_file: 25 | - ./envs/common/healthcheck.env 26 | - .env 27 | ports: 28 | - ${PORT__HEALTHCHECK_METRICS:-7300}:7300 29 | 30 | op-geth: 31 | image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101511.0 32 | restart: unless-stopped 33 | stop_grace_period: 5m 34 | entrypoint: /scripts/start-op-geth.sh 35 | env_file: 36 | - ./envs/${NETWORK_NAME}/op-geth.env 37 | - .env 38 | volumes: 39 | - ./envs/${NETWORK_NAME}/config:/chainconfig 40 | - ./scripts/:/scripts 41 | - shared:/shared 42 | - op_geth:/geth 43 | - ./.upgrade-pectra:/upgrade-pectra 44 | ports: 45 | - ${PORT__OP_GETH_HTTP:-9993}:8545 46 | - ${PORT__OP_GETH_WS:-9994}:8546 47 | - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/udp 48 | - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/tcp 49 | extra_hosts: 50 | - "host.docker.internal:host-gateway" 51 | 52 | op-node: 53 | image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.13.3 54 | restart: unless-stopped 55 | stop_grace_period: 5m 56 | entrypoint: /scripts/start-op-node.sh 57 | env_file: 58 | - ./envs/${NETWORK_NAME}/op-node.env 59 | - .env 60 | volumes: 61 | - ./envs/${NETWORK_NAME}/config:/chainconfig 62 | - ./scripts/:/scripts 63 | - shared:/shared 64 | - ./.upgrade-pectra:/upgrade-pectra 65 | ports: 66 | - ${PORT__OP_NODE_P2P:-9003}:9003/udp 67 | - ${PORT__OP_NODE_P2P:-9003}:9003/tcp 68 | - ${PORT__OP_NODE_HTTP:-9545}:9545 69 | extra_hosts: 70 | - "host.docker.internal:host-gateway" 71 | 72 | bedrock-init: 73 | build: 74 | context: ./docker/dockerfiles 75 | dockerfile: Dockerfile.bedrock-init 76 | entrypoint: /scripts/init-bedrock.sh 77 | env_file: 78 | - ./envs/${NETWORK_NAME}/op-geth.env 79 | - .env 80 | volumes: 81 | - ./scripts/:/scripts 82 | - shared:/shared 83 | - op_geth:/geth 84 | - geth:/legacy-geth 85 | - torrent_downloads:/downloads 86 | - ./.upgrade-pectra:/upgrade-pectra 87 | 88 | prometheus: 89 | image: prom/prometheus:${IMAGE_TAG__PROMETHEUS:-latest} 90 | restart: unless-stopped 91 | env_file: 92 | - .env 93 | volumes: 94 | - ./docker/prometheus:/etc/prometheus 95 | - prometheus_data:/prometheus 96 | ports: 97 | - ${PORT__PROMETHEUS:-9090}:9090 98 | 99 | grafana: 100 | image: grafana/grafana:${IMAGE_TAG__GRAFANA:-9.3.0} 101 | restart: unless-stopped 102 | env_file: 103 | - ./envs/common/grafana.env 104 | volumes: 105 | - ./docker/grafana/provisioning/:/etc/grafana/provisioning/:ro 106 | - ./docker/grafana/dashboards/simple_node_dashboard.json:/var/lib/grafana/dashboards/simple_node_dashboard.json 107 | - grafana_data:/var/lib/grafana 108 | ports: 109 | - ${PORT__GRAFANA:-3000}:3000 110 | 111 | influxdb: 112 | image: influxdb:${IMAGE_TAG__INFLUXDB:-1.8} 113 | restart: unless-stopped 114 | env_file: 115 | - ./envs/common/influxdb.env 116 | volumes: 117 | - ./docker/influxdb/influx_init.iql:/docker-entrypoint-initdb.d/influx_init.iql 118 | - influxdb_data:/var/lib/influxdb 119 | ports: 120 | - ${PORT__INFLUXDB:-8086}:8086 121 | 122 | volumes: 123 | geth: 124 | prometheus_data: 125 | grafana_data: 126 | influxdb_data: 127 | shared: 128 | op_geth: 129 | torrent_downloads: 130 | -------------------------------------------------------------------------------- /docker/dockerfiles/Dockerfile.bedrock-init: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | 3 | # Disable prompts during package installation. 4 | ARG DEBIAN_FRONTEND=noninteractive 5 | 6 | # Install required packages. 7 | RUN apt-get update && apt install -y curl wget git rsync build-essential openssl python3 python3-pip aria2 zstd lz4 8 | 9 | # Install Go. 10 | RUN curl -sSL https://golang.org/dl/go1.21.6.linux-amd64.tar.gz | tar -v -C /usr/local -xz 11 | RUN cp /usr/local/go/bin/go /usr/bin/go 12 | 13 | # Install Foundry. 14 | RUN curl -L https://foundry.paradigm.xyz | bash 15 | RUN /root/.foundry/bin/foundryup 16 | RUN rsync -a /root/.foundry/bin/ /usr/bin/ 17 | -------------------------------------------------------------------------------- /docker/grafana/dashboards/simple_node_dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "target": { 15 | "limit": 100, 16 | "matchAny": false, 17 | "tags": [], 18 | "type": "dashboard" 19 | }, 20 | "type": "dashboard" 21 | } 22 | ] 23 | }, 24 | "editable": true, 25 | "fiscalYearStartMonth": 0, 26 | "graphTooltip": 0, 27 | "id": 1, 28 | "links": [], 29 | "liveNow": false, 30 | "panels": [ 31 | { 32 | "collapsed": false, 33 | "gridPos": { 34 | "h": 1, 35 | "w": 24, 36 | "x": 0, 37 | "y": 0 38 | }, 39 | "id": 30, 40 | "panels": [], 41 | "title": "Row title", 42 | "type": "row" 43 | }, 44 | { 45 | "datasource": { 46 | "type": "influxdb", 47 | "uid": "4knV40nVb" 48 | }, 49 | "description": "", 50 | "fieldConfig": { 51 | "defaults": { 52 | "color": { 53 | "mode": "palette-classic" 54 | }, 55 | "custom": { 56 | "axisCenteredZero": false, 57 | "axisColorMode": "text", 58 | "axisLabel": "", 59 | "axisPlacement": "auto", 60 | "barAlignment": 0, 61 | "drawStyle": "line", 62 | "fillOpacity": 0, 63 | "gradientMode": "none", 64 | "hideFrom": { 65 | "graph": false, 66 | "legend": false, 67 | "tooltip": false, 68 | "viz": false 69 | }, 70 | "lineInterpolation": "linear", 71 | "lineWidth": 1, 72 | "pointSize": 5, 73 | "scaleDistribution": { 74 | "type": "linear" 75 | }, 76 | "showPoints": "always", 77 | "spanNulls": true, 78 | "stacking": { 79 | "group": "A", 80 | "mode": "none" 81 | }, 82 | "thresholdsStyle": { 83 | "mode": "off" 84 | } 85 | }, 86 | "mappings": [], 87 | "thresholds": { 88 | "mode": "absolute", 89 | "steps": [ 90 | { 91 | "color": "green", 92 | "value": null 93 | }, 94 | { 95 | "color": "red", 96 | "value": 80 97 | } 98 | ] 99 | }, 100 | "unit": "string" 101 | }, 102 | "overrides": [] 103 | }, 104 | "gridPos": { 105 | "h": 8, 106 | "w": 8, 107 | "x": 0, 108 | "y": 1 109 | }, 110 | "id": 4, 111 | "options": { 112 | "graph": {}, 113 | "legend": { 114 | "calcs": [], 115 | "displayMode": "list", 116 | "placement": "bottom", 117 | "showLegend": true 118 | }, 119 | "tooltip": { 120 | "mode": "single", 121 | "sort": "none" 122 | } 123 | }, 124 | "pluginVersion": "7.5.5", 125 | "targets": [ 126 | { 127 | "alias": "Unsafe Head", 128 | "datasource": { 129 | "type": "influxdb", 130 | "uid": "4knV40nVb" 131 | }, 132 | "groupBy": [ 133 | { 134 | "params": [ 135 | "$__interval" 136 | ], 137 | "type": "time" 138 | }, 139 | { 140 | "params": [ 141 | "null" 142 | ], 143 | "type": "fill" 144 | } 145 | ], 146 | "hide": false, 147 | "measurement": "geth.chain/head/block.gauge", 148 | "orderByTime": "ASC", 149 | "policy": "default", 150 | "refId": "A", 151 | "resultFormat": "time_series", 152 | "select": [ 153 | [ 154 | { 155 | "params": [ 156 | "value" 157 | ], 158 | "type": "field" 159 | }, 160 | { 161 | "params": [], 162 | "type": "mean" 163 | } 164 | ] 165 | ], 166 | "tags": [] 167 | }, 168 | { 169 | "alias": "Safe Head", 170 | "datasource": { 171 | "type": "influxdb", 172 | "uid": "4knV40nVb" 173 | }, 174 | "groupBy": [ 175 | { 176 | "params": [ 177 | "$__interval" 178 | ], 179 | "type": "time" 180 | }, 181 | { 182 | "params": [ 183 | "null" 184 | ], 185 | "type": "fill" 186 | } 187 | ], 188 | "hide": false, 189 | "measurement": "geth.chain/head/safe.gauge", 190 | "orderByTime": "ASC", 191 | "policy": "default", 192 | "refId": "B", 193 | "resultFormat": "time_series", 194 | "select": [ 195 | [ 196 | { 197 | "params": [ 198 | "value" 199 | ], 200 | "type": "field" 201 | }, 202 | { 203 | "params": [], 204 | "type": "mean" 205 | } 206 | ] 207 | ], 208 | "tags": [] 209 | }, 210 | { 211 | "alias": "Finalized Head", 212 | "datasource": { 213 | "type": "influxdb", 214 | "uid": "4knV40nVb" 215 | }, 216 | "groupBy": [ 217 | { 218 | "params": [ 219 | "$__interval" 220 | ], 221 | "type": "time" 222 | }, 223 | { 224 | "params": [ 225 | "null" 226 | ], 227 | "type": "fill" 228 | } 229 | ], 230 | "hide": false, 231 | "measurement": "geth.chain/head/finalized.gauge", 232 | "orderByTime": "ASC", 233 | "policy": "default", 234 | "refId": "C", 235 | "resultFormat": "time_series", 236 | "select": [ 237 | [ 238 | { 239 | "params": [ 240 | "value" 241 | ], 242 | "type": "field" 243 | }, 244 | { 245 | "params": [], 246 | "type": "mean" 247 | } 248 | ] 249 | ], 250 | "tags": [] 251 | } 252 | ], 253 | "title": "Node Block Height", 254 | "type": "timeseries" 255 | }, 256 | { 257 | "datasource": { 258 | "type": "prometheus", 259 | "uid": "6R74VAnVz" 260 | }, 261 | "fieldConfig": { 262 | "defaults": { 263 | "color": { 264 | "mode": "palette-classic" 265 | }, 266 | "custom": { 267 | "axisCenteredZero": false, 268 | "axisColorMode": "text", 269 | "axisLabel": "", 270 | "axisPlacement": "auto", 271 | "barAlignment": 0, 272 | "drawStyle": "line", 273 | "fillOpacity": 0, 274 | "gradientMode": "none", 275 | "hideFrom": { 276 | "graph": false, 277 | "legend": false, 278 | "tooltip": false, 279 | "viz": false 280 | }, 281 | "lineInterpolation": "linear", 282 | "lineWidth": 1, 283 | "pointSize": 5, 284 | "scaleDistribution": { 285 | "type": "linear" 286 | }, 287 | "showPoints": "auto", 288 | "spanNulls": false, 289 | "stacking": { 290 | "group": "A", 291 | "mode": "none" 292 | }, 293 | "thresholdsStyle": { 294 | "mode": "off" 295 | } 296 | }, 297 | "mappings": [], 298 | "thresholds": { 299 | "mode": "absolute", 300 | "steps": [ 301 | { 302 | "color": "green", 303 | "value": null 304 | }, 305 | { 306 | "color": "red", 307 | "value": 80 308 | } 309 | ] 310 | } 311 | }, 312 | "overrides": [] 313 | }, 314 | "gridPos": { 315 | "h": 8, 316 | "w": 8, 317 | "x": 8, 318 | "y": 1 319 | }, 320 | "id": 10, 321 | "options": { 322 | "legend": { 323 | "calcs": [], 324 | "displayMode": "list", 325 | "placement": "bottom", 326 | "showLegend": true 327 | }, 328 | "tooltip": { 329 | "mode": "single", 330 | "sort": "none" 331 | } 332 | }, 333 | "targets": [ 334 | { 335 | "datasource": { 336 | "type": "prometheus", 337 | "uid": "6R74VAnVz" 338 | }, 339 | "editorMode": "code", 340 | "expr": "fault_detector_highest_checked_batch_index{}", 341 | "legendFormat": "Checked", 342 | "range": true, 343 | "refId": "A" 344 | }, 345 | { 346 | "datasource": { 347 | "type": "prometheus", 348 | "uid": "6R74VAnVz" 349 | }, 350 | "editorMode": "code", 351 | "expr": "fault_detector_highest_known_batch_index{}", 352 | "hide": false, 353 | "legendFormat": "Known", 354 | "range": true, 355 | "refId": "B" 356 | } 357 | ], 358 | "title": "Fault Check Status", 359 | "type": "timeseries" 360 | }, 361 | { 362 | "datasource": { 363 | "type": "prometheus", 364 | "uid": "6R74VAnVz" 365 | }, 366 | "fieldConfig": { 367 | "defaults": { 368 | "color": { 369 | "mode": "thresholds" 370 | }, 371 | "mappings": [ 372 | { 373 | "options": { 374 | "0": { 375 | "text": "OK" 376 | }, 377 | "1": { 378 | "text": "NOT OK" 379 | } 380 | }, 381 | "type": "value" 382 | } 383 | ], 384 | "thresholds": { 385 | "mode": "absolute", 386 | "steps": [ 387 | { 388 | "color": "green", 389 | "value": null 390 | }, 391 | { 392 | "color": "green", 393 | "value": 0 394 | }, 395 | { 396 | "color": "red", 397 | "value": 1 398 | } 399 | ] 400 | } 401 | }, 402 | "overrides": [] 403 | }, 404 | "gridPos": { 405 | "h": 4, 406 | "w": 8, 407 | "x": 16, 408 | "y": 1 409 | }, 410 | "id": 12, 411 | "options": { 412 | "orientation": "auto", 413 | "reduceOptions": { 414 | "calcs": [ 415 | "lastNotNull" 416 | ], 417 | "fields": "", 418 | "values": false 419 | }, 420 | "showThresholdLabels": false, 421 | "showThresholdMarkers": true, 422 | "text": {} 423 | }, 424 | "pluginVersion": "9.3.0", 425 | "targets": [ 426 | { 427 | "datasource": { 428 | "type": "prometheus", 429 | "uid": "6R74VAnVz" 430 | }, 431 | "editorMode": "code", 432 | "exemplar": true, 433 | "expr": "fault_detector_is_currently_mismatched{}", 434 | "hide": false, 435 | "interval": "", 436 | "legendFormat": "Fault Detection", 437 | "range": true, 438 | "refId": "B" 439 | }, 440 | { 441 | "datasource": { 442 | "type": "prometheus", 443 | "uid": "6R74VAnVz" 444 | }, 445 | "exemplar": true, 446 | "expr": "healthcheck_is_currently_diverged", 447 | "hide": false, 448 | "interval": "", 449 | "legendFormat": "Healthcheck", 450 | "refId": "C" 451 | } 452 | ], 453 | "title": "System Security Monitoring", 454 | "type": "gauge" 455 | }, 456 | { 457 | "datasource": { 458 | "type": "prometheus", 459 | "uid": "6R74VAnVz" 460 | }, 461 | "description": "", 462 | "fieldConfig": { 463 | "defaults": { 464 | "color": { 465 | "mode": "thresholds" 466 | }, 467 | "displayName": "Blocks to sync", 468 | "mappings": [ 469 | { 470 | "options": { 471 | "from": 0, 472 | "result": { 473 | "text": "SYNCED" 474 | }, 475 | "to": 1000 476 | }, 477 | "type": "range" 478 | } 479 | ], 480 | "thresholds": { 481 | "mode": "absolute", 482 | "steps": [ 483 | { 484 | "color": "green", 485 | "value": null 486 | }, 487 | { 488 | "color": "blue", 489 | "value": 1000 490 | } 491 | ] 492 | }, 493 | "unit": "none" 494 | }, 495 | "overrides": [] 496 | }, 497 | "gridPos": { 498 | "h": 4, 499 | "w": 8, 500 | "x": 16, 501 | "y": 5 502 | }, 503 | "id": 24, 504 | "options": { 505 | "colorMode": "value", 506 | "graphMode": "area", 507 | "justifyMode": "auto", 508 | "orientation": "auto", 509 | "reduceOptions": { 510 | "calcs": [ 511 | "lastNotNull" 512 | ], 513 | "fields": "", 514 | "values": false 515 | }, 516 | "text": {}, 517 | "textMode": "auto" 518 | }, 519 | "pluginVersion": "9.3.0", 520 | "targets": [ 521 | { 522 | "datasource": { 523 | "type": "prometheus", 524 | "uid": "6R74VAnVz" 525 | }, 526 | "exemplar": true, 527 | "expr": "healthcheck_reference_height - healthcheck_target_height", 528 | "hide": false, 529 | "instant": false, 530 | "interval": "", 531 | "legendFormat": "", 532 | "refId": "A" 533 | } 534 | ], 535 | "title": "Chain Sync Status", 536 | "transformations": [], 537 | "type": "stat" 538 | }, 539 | { 540 | "collapsed": false, 541 | "gridPos": { 542 | "h": 1, 543 | "w": 24, 544 | "x": 0, 545 | "y": 9 546 | }, 547 | "id": 26, 548 | "panels": [], 549 | "title": "Geth Performance", 550 | "type": "row" 551 | }, 552 | { 553 | "datasource": { 554 | "type": "influxdb", 555 | "uid": "4knV40nVb" 556 | }, 557 | "fieldConfig": { 558 | "defaults": { 559 | "color": { 560 | "mode": "palette-classic" 561 | }, 562 | "custom": { 563 | "axisCenteredZero": false, 564 | "axisColorMode": "text", 565 | "axisLabel": "", 566 | "axisPlacement": "auto", 567 | "barAlignment": 0, 568 | "drawStyle": "line", 569 | "fillOpacity": 10, 570 | "gradientMode": "none", 571 | "hideFrom": { 572 | "graph": false, 573 | "legend": false, 574 | "tooltip": false, 575 | "viz": false 576 | }, 577 | "lineInterpolation": "linear", 578 | "lineWidth": 1, 579 | "pointSize": 5, 580 | "scaleDistribution": { 581 | "type": "linear" 582 | }, 583 | "showPoints": "never", 584 | "spanNulls": true, 585 | "stacking": { 586 | "group": "A", 587 | "mode": "none" 588 | }, 589 | "thresholdsStyle": { 590 | "mode": "off" 591 | } 592 | }, 593 | "mappings": [], 594 | "thresholds": { 595 | "mode": "absolute", 596 | "steps": [ 597 | { 598 | "color": "green", 599 | "value": null 600 | }, 601 | { 602 | "color": "red", 603 | "value": 80 604 | } 605 | ] 606 | }, 607 | "unit": "%" 608 | }, 609 | "overrides": [] 610 | }, 611 | "gridPos": { 612 | "h": 6, 613 | "w": 8, 614 | "x": 0, 615 | "y": 10 616 | }, 617 | "id": 31, 618 | "options": { 619 | "graph": {}, 620 | "legend": { 621 | "calcs": [], 622 | "displayMode": "list", 623 | "placement": "bottom", 624 | "showLegend": true 625 | }, 626 | "tooltip": { 627 | "mode": "single", 628 | "sort": "none" 629 | } 630 | }, 631 | "pluginVersion": "7.5.5", 632 | "targets": [ 633 | { 634 | "alias": "system", 635 | "datasource": { 636 | "type": "influxdb", 637 | "uid": "4knV40nVb" 638 | }, 639 | "groupBy": [ 640 | { 641 | "params": [ 642 | "$__interval" 643 | ], 644 | "type": "time" 645 | }, 646 | { 647 | "params": [ 648 | "null" 649 | ], 650 | "type": "fill" 651 | } 652 | ], 653 | "measurement": "geth.system/cpu/sysload.gauge", 654 | "orderByTime": "ASC", 655 | "policy": "default", 656 | "refId": "A", 657 | "resultFormat": "time_series", 658 | "select": [ 659 | [ 660 | { 661 | "params": [ 662 | "value" 663 | ], 664 | "type": "field" 665 | }, 666 | { 667 | "params": [], 668 | "type": "mean" 669 | } 670 | ] 671 | ], 672 | "tags": [] 673 | }, 674 | { 675 | "alias": "geth", 676 | "datasource": { 677 | "type": "influxdb", 678 | "uid": "4knV40nVb" 679 | }, 680 | "groupBy": [ 681 | { 682 | "params": [ 683 | "$__interval" 684 | ], 685 | "type": "time" 686 | }, 687 | { 688 | "params": [ 689 | "null" 690 | ], 691 | "type": "fill" 692 | } 693 | ], 694 | "hide": false, 695 | "measurement": "geth.system/cpu/procload.gauge", 696 | "orderByTime": "ASC", 697 | "policy": "default", 698 | "refId": "B", 699 | "resultFormat": "time_series", 700 | "select": [ 701 | [ 702 | { 703 | "params": [ 704 | "value" 705 | ], 706 | "type": "field" 707 | }, 708 | { 709 | "params": [], 710 | "type": "mean" 711 | } 712 | ] 713 | ], 714 | "tags": [] 715 | }, 716 | { 717 | "alias": "IO", 718 | "datasource": { 719 | "type": "influxdb", 720 | "uid": "4knV40nVb" 721 | }, 722 | "groupBy": [ 723 | { 724 | "params": [ 725 | "$__interval" 726 | ], 727 | "type": "time" 728 | }, 729 | { 730 | "params": [ 731 | "null" 732 | ], 733 | "type": "fill" 734 | } 735 | ], 736 | "hide": false, 737 | "measurement": "geth.system/cpu/syswait.gauge", 738 | "orderByTime": "ASC", 739 | "policy": "default", 740 | "refId": "C", 741 | "resultFormat": "time_series", 742 | "select": [ 743 | [ 744 | { 745 | "params": [ 746 | "value" 747 | ], 748 | "type": "field" 749 | }, 750 | { 751 | "params": [], 752 | "type": "mean" 753 | } 754 | ] 755 | ], 756 | "tags": [] 757 | } 758 | ], 759 | "title": "CPU", 760 | "type": "timeseries" 761 | }, 762 | { 763 | "datasource": { 764 | "type": "influxdb", 765 | "uid": "4knV40nVb" 766 | }, 767 | "fieldConfig": { 768 | "defaults": { 769 | "color": { 770 | "mode": "palette-classic" 771 | }, 772 | "custom": { 773 | "axisCenteredZero": false, 774 | "axisColorMode": "text", 775 | "axisLabel": "", 776 | "axisPlacement": "auto", 777 | "barAlignment": 0, 778 | "drawStyle": "line", 779 | "fillOpacity": 10, 780 | "gradientMode": "none", 781 | "hideFrom": { 782 | "graph": false, 783 | "legend": false, 784 | "tooltip": false, 785 | "viz": false 786 | }, 787 | "lineInterpolation": "linear", 788 | "lineWidth": 1, 789 | "pointSize": 5, 790 | "scaleDistribution": { 791 | "type": "linear" 792 | }, 793 | "showPoints": "never", 794 | "spanNulls": true, 795 | "stacking": { 796 | "group": "A", 797 | "mode": "none" 798 | }, 799 | "thresholdsStyle": { 800 | "mode": "off" 801 | } 802 | }, 803 | "mappings": [], 804 | "thresholds": { 805 | "mode": "absolute", 806 | "steps": [ 807 | { 808 | "color": "green", 809 | "value": null 810 | }, 811 | { 812 | "color": "red", 813 | "value": 80 814 | } 815 | ] 816 | }, 817 | "unit": "decbytes" 818 | }, 819 | "overrides": [] 820 | }, 821 | "gridPos": { 822 | "h": 6, 823 | "w": 8, 824 | "x": 8, 825 | "y": 10 826 | }, 827 | "id": 32, 828 | "options": { 829 | "graph": {}, 830 | "legend": { 831 | "calcs": [], 832 | "displayMode": "list", 833 | "placement": "bottom", 834 | "showLegend": true 835 | }, 836 | "tooltip": { 837 | "mode": "single", 838 | "sort": "none" 839 | } 840 | }, 841 | "pluginVersion": "7.5.5", 842 | "targets": [ 843 | { 844 | "alias": "used", 845 | "datasource": { 846 | "type": "influxdb", 847 | "uid": "4knV40nVb" 848 | }, 849 | "groupBy": [ 850 | { 851 | "params": [ 852 | "$__interval" 853 | ], 854 | "type": "time" 855 | }, 856 | { 857 | "params": [ 858 | "null" 859 | ], 860 | "type": "fill" 861 | } 862 | ], 863 | "measurement": "geth.system/memory/used.gauge", 864 | "orderByTime": "ASC", 865 | "policy": "default", 866 | "refId": "A", 867 | "resultFormat": "time_series", 868 | "select": [ 869 | [ 870 | { 871 | "params": [ 872 | "value" 873 | ], 874 | "type": "field" 875 | }, 876 | { 877 | "params": [], 878 | "type": "mean" 879 | } 880 | ] 881 | ], 882 | "tags": [] 883 | }, 884 | { 885 | "alias": "held", 886 | "datasource": { 887 | "type": "influxdb", 888 | "uid": "4knV40nVb" 889 | }, 890 | "groupBy": [ 891 | { 892 | "params": [ 893 | "$__interval" 894 | ], 895 | "type": "time" 896 | }, 897 | { 898 | "params": [ 899 | "null" 900 | ], 901 | "type": "fill" 902 | } 903 | ], 904 | "hide": false, 905 | "measurement": "geth.system/memory/held.gauge", 906 | "orderByTime": "ASC", 907 | "policy": "default", 908 | "refId": "B", 909 | "resultFormat": "time_series", 910 | "select": [ 911 | [ 912 | { 913 | "params": [ 914 | "value" 915 | ], 916 | "type": "field" 917 | }, 918 | { 919 | "params": [], 920 | "type": "mean" 921 | } 922 | ] 923 | ], 924 | "tags": [] 925 | } 926 | ], 927 | "title": "Memory", 928 | "type": "timeseries" 929 | }, 930 | { 931 | "datasource": { 932 | "type": "influxdb", 933 | "uid": "4knV40nVb" 934 | }, 935 | "fieldConfig": { 936 | "defaults": { 937 | "color": { 938 | "mode": "palette-classic" 939 | }, 940 | "custom": { 941 | "axisCenteredZero": false, 942 | "axisColorMode": "text", 943 | "axisLabel": "", 944 | "axisPlacement": "auto", 945 | "barAlignment": 0, 946 | "drawStyle": "line", 947 | "fillOpacity": 10, 948 | "gradientMode": "none", 949 | "hideFrom": { 950 | "graph": false, 951 | "legend": false, 952 | "tooltip": false, 953 | "viz": false 954 | }, 955 | "lineInterpolation": "linear", 956 | "lineWidth": 1, 957 | "pointSize": 5, 958 | "scaleDistribution": { 959 | "type": "linear" 960 | }, 961 | "showPoints": "never", 962 | "spanNulls": true, 963 | "stacking": { 964 | "group": "A", 965 | "mode": "none" 966 | }, 967 | "thresholdsStyle": { 968 | "mode": "off" 969 | } 970 | }, 971 | "mappings": [], 972 | "thresholds": { 973 | "mode": "absolute", 974 | "steps": [ 975 | { 976 | "color": "green", 977 | "value": null 978 | }, 979 | { 980 | "color": "red", 981 | "value": 80 982 | } 983 | ] 984 | }, 985 | "unit": "Bps" 986 | }, 987 | "overrides": [] 988 | }, 989 | "gridPos": { 990 | "h": 6, 991 | "w": 8, 992 | "x": 16, 993 | "y": 10 994 | }, 995 | "id": 22, 996 | "options": { 997 | "graph": {}, 998 | "legend": { 999 | "calcs": [], 1000 | "displayMode": "list", 1001 | "placement": "bottom", 1002 | "showLegend": true 1003 | }, 1004 | "tooltip": { 1005 | "mode": "single", 1006 | "sort": "none" 1007 | } 1008 | }, 1009 | "pluginVersion": "7.5.5", 1010 | "targets": [ 1011 | { 1012 | "alias": "read", 1013 | "datasource": { 1014 | "type": "influxdb", 1015 | "uid": "4knV40nVb" 1016 | }, 1017 | "groupBy": [ 1018 | { 1019 | "params": [ 1020 | "$__interval" 1021 | ], 1022 | "type": "time" 1023 | }, 1024 | { 1025 | "params": [ 1026 | "null" 1027 | ], 1028 | "type": "fill" 1029 | } 1030 | ], 1031 | "measurement": "geth.system/disk/readdata.meter", 1032 | "orderByTime": "ASC", 1033 | "policy": "default", 1034 | "refId": "A", 1035 | "resultFormat": "time_series", 1036 | "select": [ 1037 | [ 1038 | { 1039 | "params": [ 1040 | "m1" 1041 | ], 1042 | "type": "field" 1043 | }, 1044 | { 1045 | "params": [], 1046 | "type": "mean" 1047 | } 1048 | ] 1049 | ], 1050 | "tags": [] 1051 | }, 1052 | { 1053 | "alias": "write", 1054 | "datasource": { 1055 | "type": "influxdb", 1056 | "uid": "4knV40nVb" 1057 | }, 1058 | "groupBy": [ 1059 | { 1060 | "params": [ 1061 | "$__interval" 1062 | ], 1063 | "type": "time" 1064 | }, 1065 | { 1066 | "params": [ 1067 | "null" 1068 | ], 1069 | "type": "fill" 1070 | } 1071 | ], 1072 | "hide": false, 1073 | "measurement": "geth.system/disk/writedata.meter", 1074 | "orderByTime": "ASC", 1075 | "policy": "default", 1076 | "query": "SELECT mean(\"m1\") FROM \"geth.system/disk/writedata.meter\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", 1077 | "rawQuery": false, 1078 | "refId": "B", 1079 | "resultFormat": "time_series", 1080 | "select": [ 1081 | [ 1082 | { 1083 | "params": [ 1084 | "m1" 1085 | ], 1086 | "type": "field" 1087 | }, 1088 | { 1089 | "params": [], 1090 | "type": "mean" 1091 | } 1092 | ] 1093 | ], 1094 | "tags": [] 1095 | } 1096 | ], 1097 | "title": "Disk", 1098 | "type": "timeseries" 1099 | }, 1100 | { 1101 | "collapsed": false, 1102 | "datasource": { 1103 | "type": "prometheus", 1104 | "uid": "6R74VAnVz" 1105 | }, 1106 | "gridPos": { 1107 | "h": 1, 1108 | "w": 24, 1109 | "x": 0, 1110 | "y": 16 1111 | }, 1112 | "id": 14, 1113 | "panels": [], 1114 | "targets": [ 1115 | { 1116 | "datasource": { 1117 | "type": "prometheus", 1118 | "uid": "6R74VAnVz" 1119 | }, 1120 | "refId": "A" 1121 | } 1122 | ], 1123 | "title": "Legacy System Overview (pre-Bedrock)", 1124 | "type": "row" 1125 | }, 1126 | { 1127 | "datasource": { 1128 | "type": "influxdb", 1129 | "uid": "4knV40nVz" 1130 | }, 1131 | "description": "", 1132 | "fieldConfig": { 1133 | "defaults": { 1134 | "color": { 1135 | "mode": "palette-classic" 1136 | }, 1137 | "custom": { 1138 | "axisCenteredZero": false, 1139 | "axisColorMode": "text", 1140 | "axisLabel": "", 1141 | "axisPlacement": "auto", 1142 | "barAlignment": 0, 1143 | "drawStyle": "line", 1144 | "fillOpacity": 0, 1145 | "gradientMode": "none", 1146 | "hideFrom": { 1147 | "graph": false, 1148 | "legend": false, 1149 | "tooltip": false, 1150 | "viz": false 1151 | }, 1152 | "lineInterpolation": "linear", 1153 | "lineWidth": 1, 1154 | "pointSize": 5, 1155 | "scaleDistribution": { 1156 | "type": "linear" 1157 | }, 1158 | "showPoints": "always", 1159 | "spanNulls": true, 1160 | "stacking": { 1161 | "group": "A", 1162 | "mode": "none" 1163 | }, 1164 | "thresholdsStyle": { 1165 | "mode": "off" 1166 | } 1167 | }, 1168 | "mappings": [], 1169 | "thresholds": { 1170 | "mode": "absolute", 1171 | "steps": [ 1172 | { 1173 | "color": "green", 1174 | "value": null 1175 | }, 1176 | { 1177 | "color": "red", 1178 | "value": 80 1179 | } 1180 | ] 1181 | }, 1182 | "unit": "string" 1183 | }, 1184 | "overrides": [] 1185 | }, 1186 | "gridPos": { 1187 | "h": 8, 1188 | "w": 24, 1189 | "x": 0, 1190 | "y": 17 1191 | }, 1192 | "id": 27, 1193 | "options": { 1194 | "graph": {}, 1195 | "legend": { 1196 | "calcs": [], 1197 | "displayMode": "list", 1198 | "placement": "bottom", 1199 | "showLegend": true 1200 | }, 1201 | "tooltip": { 1202 | "mode": "single", 1203 | "sort": "none" 1204 | } 1205 | }, 1206 | "pluginVersion": "7.5.5", 1207 | "targets": [ 1208 | { 1209 | "alias": "Head", 1210 | "datasource": { 1211 | "type": "influxdb", 1212 | "uid": "4knV40nVz" 1213 | }, 1214 | "groupBy": [ 1215 | { 1216 | "params": [ 1217 | "$__interval" 1218 | ], 1219 | "type": "time" 1220 | }, 1221 | { 1222 | "params": [ 1223 | "null" 1224 | ], 1225 | "type": "fill" 1226 | } 1227 | ], 1228 | "hide": false, 1229 | "measurement": "geth.chain/head/block.gauge", 1230 | "orderByTime": "ASC", 1231 | "policy": "default", 1232 | "refId": "A", 1233 | "resultFormat": "time_series", 1234 | "select": [ 1235 | [ 1236 | { 1237 | "params": [ 1238 | "value" 1239 | ], 1240 | "type": "field" 1241 | }, 1242 | { 1243 | "params": [], 1244 | "type": "mean" 1245 | } 1246 | ] 1247 | ], 1248 | "tags": [] 1249 | } 1250 | ], 1251 | "title": "Node Block Height", 1252 | "type": "timeseries" 1253 | }, 1254 | { 1255 | "datasource": { 1256 | "type": "influxdb", 1257 | "uid": "4knV40nVz" 1258 | }, 1259 | "fieldConfig": { 1260 | "defaults": { 1261 | "color": { 1262 | "mode": "palette-classic" 1263 | }, 1264 | "custom": { 1265 | "axisCenteredZero": false, 1266 | "axisColorMode": "text", 1267 | "axisLabel": "", 1268 | "axisPlacement": "auto", 1269 | "barAlignment": 0, 1270 | "drawStyle": "line", 1271 | "fillOpacity": 10, 1272 | "gradientMode": "none", 1273 | "hideFrom": { 1274 | "graph": false, 1275 | "legend": false, 1276 | "tooltip": false, 1277 | "viz": false 1278 | }, 1279 | "lineInterpolation": "linear", 1280 | "lineWidth": 1, 1281 | "pointSize": 5, 1282 | "scaleDistribution": { 1283 | "type": "linear" 1284 | }, 1285 | "showPoints": "never", 1286 | "spanNulls": true, 1287 | "stacking": { 1288 | "group": "A", 1289 | "mode": "none" 1290 | }, 1291 | "thresholdsStyle": { 1292 | "mode": "off" 1293 | } 1294 | }, 1295 | "mappings": [], 1296 | "thresholds": { 1297 | "mode": "absolute", 1298 | "steps": [ 1299 | { 1300 | "color": "green", 1301 | "value": null 1302 | }, 1303 | { 1304 | "color": "red", 1305 | "value": 80 1306 | } 1307 | ] 1308 | }, 1309 | "unit": "%" 1310 | }, 1311 | "overrides": [] 1312 | }, 1313 | "gridPos": { 1314 | "h": 6, 1315 | "w": 8, 1316 | "x": 0, 1317 | "y": 25 1318 | }, 1319 | "id": 18, 1320 | "options": { 1321 | "graph": {}, 1322 | "legend": { 1323 | "calcs": [], 1324 | "displayMode": "list", 1325 | "placement": "bottom", 1326 | "showLegend": true 1327 | }, 1328 | "tooltip": { 1329 | "mode": "single", 1330 | "sort": "none" 1331 | } 1332 | }, 1333 | "pluginVersion": "7.5.5", 1334 | "targets": [ 1335 | { 1336 | "alias": "system", 1337 | "datasource": { 1338 | "type": "influxdb", 1339 | "uid": "4knV40nVz" 1340 | }, 1341 | "groupBy": [ 1342 | { 1343 | "params": [ 1344 | "$__interval" 1345 | ], 1346 | "type": "time" 1347 | }, 1348 | { 1349 | "params": [ 1350 | "null" 1351 | ], 1352 | "type": "fill" 1353 | } 1354 | ], 1355 | "measurement": "geth.system/cpu/sysload.gauge", 1356 | "orderByTime": "ASC", 1357 | "policy": "default", 1358 | "refId": "A", 1359 | "resultFormat": "time_series", 1360 | "select": [ 1361 | [ 1362 | { 1363 | "params": [ 1364 | "value" 1365 | ], 1366 | "type": "field" 1367 | }, 1368 | { 1369 | "params": [], 1370 | "type": "mean" 1371 | } 1372 | ] 1373 | ], 1374 | "tags": [] 1375 | }, 1376 | { 1377 | "alias": "geth", 1378 | "datasource": { 1379 | "type": "influxdb", 1380 | "uid": "4knV40nVz" 1381 | }, 1382 | "groupBy": [ 1383 | { 1384 | "params": [ 1385 | "$__interval" 1386 | ], 1387 | "type": "time" 1388 | }, 1389 | { 1390 | "params": [ 1391 | "null" 1392 | ], 1393 | "type": "fill" 1394 | } 1395 | ], 1396 | "hide": false, 1397 | "measurement": "geth.system/cpu/procload.gauge", 1398 | "orderByTime": "ASC", 1399 | "policy": "default", 1400 | "refId": "B", 1401 | "resultFormat": "time_series", 1402 | "select": [ 1403 | [ 1404 | { 1405 | "params": [ 1406 | "value" 1407 | ], 1408 | "type": "field" 1409 | }, 1410 | { 1411 | "params": [], 1412 | "type": "mean" 1413 | } 1414 | ] 1415 | ], 1416 | "tags": [] 1417 | }, 1418 | { 1419 | "alias": "IO", 1420 | "datasource": { 1421 | "type": "influxdb", 1422 | "uid": "4knV40nVz" 1423 | }, 1424 | "groupBy": [ 1425 | { 1426 | "params": [ 1427 | "$__interval" 1428 | ], 1429 | "type": "time" 1430 | }, 1431 | { 1432 | "params": [ 1433 | "null" 1434 | ], 1435 | "type": "fill" 1436 | } 1437 | ], 1438 | "hide": false, 1439 | "measurement": "geth.system/cpu/syswait.gauge", 1440 | "orderByTime": "ASC", 1441 | "policy": "default", 1442 | "refId": "C", 1443 | "resultFormat": "time_series", 1444 | "select": [ 1445 | [ 1446 | { 1447 | "params": [ 1448 | "value" 1449 | ], 1450 | "type": "field" 1451 | }, 1452 | { 1453 | "params": [], 1454 | "type": "mean" 1455 | } 1456 | ] 1457 | ], 1458 | "tags": [] 1459 | } 1460 | ], 1461 | "title": "CPU", 1462 | "type": "timeseries" 1463 | }, 1464 | { 1465 | "datasource": { 1466 | "type": "influxdb", 1467 | "uid": "4knV40nVz" 1468 | }, 1469 | "fieldConfig": { 1470 | "defaults": { 1471 | "color": { 1472 | "mode": "palette-classic" 1473 | }, 1474 | "custom": { 1475 | "axisCenteredZero": false, 1476 | "axisColorMode": "text", 1477 | "axisLabel": "", 1478 | "axisPlacement": "auto", 1479 | "barAlignment": 0, 1480 | "drawStyle": "line", 1481 | "fillOpacity": 10, 1482 | "gradientMode": "none", 1483 | "hideFrom": { 1484 | "graph": false, 1485 | "legend": false, 1486 | "tooltip": false, 1487 | "viz": false 1488 | }, 1489 | "lineInterpolation": "linear", 1490 | "lineWidth": 1, 1491 | "pointSize": 5, 1492 | "scaleDistribution": { 1493 | "type": "linear" 1494 | }, 1495 | "showPoints": "never", 1496 | "spanNulls": true, 1497 | "stacking": { 1498 | "group": "A", 1499 | "mode": "none" 1500 | }, 1501 | "thresholdsStyle": { 1502 | "mode": "off" 1503 | } 1504 | }, 1505 | "mappings": [], 1506 | "thresholds": { 1507 | "mode": "absolute", 1508 | "steps": [ 1509 | { 1510 | "color": "green", 1511 | "value": null 1512 | }, 1513 | { 1514 | "color": "red", 1515 | "value": 80 1516 | } 1517 | ] 1518 | }, 1519 | "unit": "decbytes" 1520 | }, 1521 | "overrides": [] 1522 | }, 1523 | "gridPos": { 1524 | "h": 6, 1525 | "w": 8, 1526 | "x": 8, 1527 | "y": 25 1528 | }, 1529 | "id": 20, 1530 | "options": { 1531 | "graph": {}, 1532 | "legend": { 1533 | "calcs": [], 1534 | "displayMode": "list", 1535 | "placement": "bottom", 1536 | "showLegend": true 1537 | }, 1538 | "tooltip": { 1539 | "mode": "single", 1540 | "sort": "none" 1541 | } 1542 | }, 1543 | "pluginVersion": "7.5.5", 1544 | "targets": [ 1545 | { 1546 | "alias": "used", 1547 | "datasource": { 1548 | "type": "influxdb", 1549 | "uid": "4knV40nVz" 1550 | }, 1551 | "groupBy": [ 1552 | { 1553 | "params": [ 1554 | "$__interval" 1555 | ], 1556 | "type": "time" 1557 | }, 1558 | { 1559 | "params": [ 1560 | "null" 1561 | ], 1562 | "type": "fill" 1563 | } 1564 | ], 1565 | "measurement": "geth.system/memory/used.gauge", 1566 | "orderByTime": "ASC", 1567 | "policy": "default", 1568 | "refId": "A", 1569 | "resultFormat": "time_series", 1570 | "select": [ 1571 | [ 1572 | { 1573 | "params": [ 1574 | "value" 1575 | ], 1576 | "type": "field" 1577 | }, 1578 | { 1579 | "params": [], 1580 | "type": "mean" 1581 | } 1582 | ] 1583 | ], 1584 | "tags": [] 1585 | }, 1586 | { 1587 | "alias": "held", 1588 | "datasource": { 1589 | "type": "influxdb", 1590 | "uid": "4knV40nVz" 1591 | }, 1592 | "groupBy": [ 1593 | { 1594 | "params": [ 1595 | "$__interval" 1596 | ], 1597 | "type": "time" 1598 | }, 1599 | { 1600 | "params": [ 1601 | "null" 1602 | ], 1603 | "type": "fill" 1604 | } 1605 | ], 1606 | "hide": false, 1607 | "measurement": "geth.system/memory/held.gauge", 1608 | "orderByTime": "ASC", 1609 | "policy": "default", 1610 | "refId": "B", 1611 | "resultFormat": "time_series", 1612 | "select": [ 1613 | [ 1614 | { 1615 | "params": [ 1616 | "value" 1617 | ], 1618 | "type": "field" 1619 | }, 1620 | { 1621 | "params": [], 1622 | "type": "mean" 1623 | } 1624 | ] 1625 | ], 1626 | "tags": [] 1627 | } 1628 | ], 1629 | "title": "Memory", 1630 | "type": "timeseries" 1631 | }, 1632 | { 1633 | "datasource": { 1634 | "type": "influxdb", 1635 | "uid": "4knV40nVz" 1636 | }, 1637 | "fieldConfig": { 1638 | "defaults": { 1639 | "color": { 1640 | "mode": "palette-classic" 1641 | }, 1642 | "custom": { 1643 | "axisCenteredZero": false, 1644 | "axisColorMode": "text", 1645 | "axisLabel": "", 1646 | "axisPlacement": "auto", 1647 | "barAlignment": 0, 1648 | "drawStyle": "line", 1649 | "fillOpacity": 10, 1650 | "gradientMode": "none", 1651 | "hideFrom": { 1652 | "graph": false, 1653 | "legend": false, 1654 | "tooltip": false, 1655 | "viz": false 1656 | }, 1657 | "lineInterpolation": "linear", 1658 | "lineWidth": 1, 1659 | "pointSize": 5, 1660 | "scaleDistribution": { 1661 | "type": "linear" 1662 | }, 1663 | "showPoints": "never", 1664 | "spanNulls": true, 1665 | "stacking": { 1666 | "group": "A", 1667 | "mode": "none" 1668 | }, 1669 | "thresholdsStyle": { 1670 | "mode": "off" 1671 | } 1672 | }, 1673 | "mappings": [], 1674 | "thresholds": { 1675 | "mode": "absolute", 1676 | "steps": [ 1677 | { 1678 | "color": "green", 1679 | "value": null 1680 | }, 1681 | { 1682 | "color": "red", 1683 | "value": 80 1684 | } 1685 | ] 1686 | }, 1687 | "unit": "Bps" 1688 | }, 1689 | "overrides": [] 1690 | }, 1691 | "gridPos": { 1692 | "h": 6, 1693 | "w": 8, 1694 | "x": 16, 1695 | "y": 25 1696 | }, 1697 | "id": 33, 1698 | "options": { 1699 | "graph": {}, 1700 | "legend": { 1701 | "calcs": [], 1702 | "displayMode": "list", 1703 | "placement": "bottom", 1704 | "showLegend": true 1705 | }, 1706 | "tooltip": { 1707 | "mode": "single", 1708 | "sort": "none" 1709 | } 1710 | }, 1711 | "pluginVersion": "7.5.5", 1712 | "targets": [ 1713 | { 1714 | "alias": "read", 1715 | "datasource": { 1716 | "type": "influxdb", 1717 | "uid": "4knV40nVz" 1718 | }, 1719 | "groupBy": [ 1720 | { 1721 | "params": [ 1722 | "$__interval" 1723 | ], 1724 | "type": "time" 1725 | }, 1726 | { 1727 | "params": [ 1728 | "null" 1729 | ], 1730 | "type": "fill" 1731 | } 1732 | ], 1733 | "measurement": "geth.system/disk/readdata.meter", 1734 | "orderByTime": "ASC", 1735 | "policy": "default", 1736 | "refId": "A", 1737 | "resultFormat": "time_series", 1738 | "select": [ 1739 | [ 1740 | { 1741 | "params": [ 1742 | "m1" 1743 | ], 1744 | "type": "field" 1745 | }, 1746 | { 1747 | "params": [], 1748 | "type": "mean" 1749 | } 1750 | ] 1751 | ], 1752 | "tags": [] 1753 | }, 1754 | { 1755 | "alias": "write", 1756 | "datasource": { 1757 | "type": "influxdb", 1758 | "uid": "4knV40nVz" 1759 | }, 1760 | "groupBy": [ 1761 | { 1762 | "params": [ 1763 | "$__interval" 1764 | ], 1765 | "type": "time" 1766 | }, 1767 | { 1768 | "params": [ 1769 | "null" 1770 | ], 1771 | "type": "fill" 1772 | } 1773 | ], 1774 | "hide": false, 1775 | "measurement": "geth.system/disk/writedata.meter", 1776 | "orderByTime": "ASC", 1777 | "policy": "default", 1778 | "query": "SELECT mean(\"m1\") FROM \"geth.system/disk/writedata.meter\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", 1779 | "rawQuery": false, 1780 | "refId": "B", 1781 | "resultFormat": "time_series", 1782 | "select": [ 1783 | [ 1784 | { 1785 | "params": [ 1786 | "m1" 1787 | ], 1788 | "type": "field" 1789 | }, 1790 | { 1791 | "params": [], 1792 | "type": "mean" 1793 | } 1794 | ] 1795 | ], 1796 | "tags": [] 1797 | } 1798 | ], 1799 | "title": "Disk", 1800 | "type": "timeseries" 1801 | } 1802 | ], 1803 | "refresh": "5s", 1804 | "schemaVersion": 37, 1805 | "style": "dark", 1806 | "tags": [], 1807 | "templating": { 1808 | "list": [] 1809 | }, 1810 | "time": { 1811 | "from": "now-5m", 1812 | "to": "now" 1813 | }, 1814 | "timepicker": {}, 1815 | "timezone": "", 1816 | "title": "Simple Node Dashboard", 1817 | "uid": "fNH7uZ97k", 1818 | "version": 3, 1819 | "weekStart": "" 1820 | } 1821 | -------------------------------------------------------------------------------- /docker/grafana/provisioning/dashboards/all.yml: -------------------------------------------------------------------------------- 1 | - name: 'default' 2 | org_id: 1 3 | folder: '' 4 | type: 'file' 5 | options: 6 | folder: '/var/lib/grafana/dashboards' 7 | -------------------------------------------------------------------------------- /docker/grafana/provisioning/datasources/all.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | deleteDatasources: 4 | - name: 'Prometheus' 5 | - name: 'InfluxDB' 6 | 7 | datasources: 8 | - access: 'proxy' 9 | editable: true 10 | is_default: true 11 | name: 'Prometheus' 12 | uid: '6R74VAnVz' 13 | org_id: 1 14 | type: 'prometheus' 15 | url: 'http://prometheus:9090' 16 | version: 1 17 | - access: 'proxy' 18 | editable: true 19 | is_default: false 20 | name: 'InfluxDB (l2geth)' 21 | uid: '4knV40nVz' 22 | org_id: 1 23 | type: 'influxdb' 24 | database: 'l2geth' 25 | url: 'http://influxdb:8086' 26 | version: 1 27 | - access: 'proxy' 28 | editable: true 29 | is_default: false 30 | name: 'InfluxDB (op-geth)' 31 | uid: '4knV40nVb' 32 | org_id: 1 33 | type: 'influxdb' 34 | database: 'opgeth' 35 | url: 'http://influxdb:8086' 36 | version: 1 37 | -------------------------------------------------------------------------------- /docker/influxdb/influx_init.iql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE "l2geth" 2 | CREATE DATABASE "opgeth" 3 | -------------------------------------------------------------------------------- /docker/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | 5 | scrape_configs: 6 | - job_name: 'healthcheck' 7 | static_configs: 8 | - targets: ['healthcheck:7300'] 9 | 10 | - job_name: 'fault-detector' 11 | static_configs: 12 | - targets: ['fault-detector:7300'] 13 | 14 | - job_name: 'op-node' 15 | static_configs: 16 | - targets: ['op-node:7300'] 17 | -------------------------------------------------------------------------------- /envs/base-mainnet/config/rollup.json: -------------------------------------------------------------------------------- 1 | { 2 | "genesis": { 3 | "l1": { 4 | "hash": "0x5c13d307623a926cd31415036c8b7fa14572f9dac64528e857a470511fc30771", 5 | "number": 17481768 6 | }, 7 | "l2": { 8 | "hash": "0xf712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd", 9 | "number": 0 10 | }, 11 | "l2_time": 1686789347, 12 | "system_config": { 13 | "batcherAddr": "0x5050f69a9786f081509234f1a7f4684b5e5b76c9", 14 | "overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc", 15 | "scalar": "0x00000000000000000000000000000000000000000000000000000000000a6fe0", 16 | "gasLimit": 30000000 17 | } 18 | }, 19 | "block_time": 2, 20 | "max_sequencer_drift": 600, 21 | "seq_window_size": 3600, 22 | "channel_timeout": 300, 23 | "l1_chain_id": 1, 24 | "l2_chain_id": 8453, 25 | "regolith_time": 0, 26 | "batch_inbox_address": "0xff00000000000000000000000000000000008453", 27 | "deposit_contract_address": "0x49048044d57e1c92a77f79988d21fa8faf74e97e", 28 | "l1_system_config_address": "0x73a79fab69143498ed3712e519a88a918e1f4072" 29 | } -------------------------------------------------------------------------------- /envs/base-mainnet/op-geth.env: -------------------------------------------------------------------------------- 1 | BEDROCK_SEQUENCER_HTTP=https://mainnet-sequencer.base.org 2 | BEDROCK_DATADIR=/geth 3 | -------------------------------------------------------------------------------- /envs/base-mainnet/op-node.env: -------------------------------------------------------------------------------- 1 | OP_NODE_BETA_EXTRA_NETWORKS=true 2 | OP_NODE_NETWORK=base-mainnet 3 | OP_NODE_P2P_AGENT=base 4 | OP_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG 5 | OP_NODE_ROLLUP_CONFIG=/chainconfig/rollup.json 6 | OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true -------------------------------------------------------------------------------- /envs/base-sepolia/config/rollup.json: -------------------------------------------------------------------------------- 1 | { 2 | "genesis": { 3 | "l1": { 4 | "hash": "0xcac9a83291d4dec146d6f7f69ab2304f23f5be87b1789119a0c5b1e4482444ed", 5 | "number": 4370868 6 | }, 7 | "l2": { 8 | "hash": "0x0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4", 9 | "number": 0 10 | }, 11 | "l2_time": 1695768288, 12 | "system_config": { 13 | "batcherAddr": "0x6cdebe940bc0f26850285caca097c11c33103e47", 14 | "overhead": "0x0000000000000000000000000000000000000000000000000000000000000834", 15 | "scalar": "0x00000000000000000000000000000000000000000000000000000000000f4240", 16 | "gasLimit": 25000000 17 | } 18 | }, 19 | "block_time": 2, 20 | "max_sequencer_drift": 600, 21 | "seq_window_size": 3600, 22 | "channel_timeout": 300, 23 | "l1_chain_id": 11155111, 24 | "l2_chain_id": 84532, 25 | "regolith_time": 0, 26 | "batch_inbox_address": "0xff00000000000000000000000000000000084532", 27 | "deposit_contract_address": "0x49f53e41452c74589e85ca1677426ba426459e85", 28 | "l1_system_config_address": "0xf272670eb55e895584501d564afeb048bed26194", 29 | "protocol_versions_address": "0x0000000000000000000000000000000000000000" 30 | } -------------------------------------------------------------------------------- /envs/base-sepolia/op-geth.env: -------------------------------------------------------------------------------- 1 | BEDROCK_SEQUENCER_HTTP=https://sepolia-sequencer.base.org 2 | BEDROCK_DATADIR=/geth 3 | -------------------------------------------------------------------------------- /envs/base-sepolia/op-node.env: -------------------------------------------------------------------------------- 1 | OP_NODE_BETA_EXTRA_NETWORKS=true 2 | OP_NODE_NETWORK=base-sepolia 3 | OP_NODE_P2P_AGENT=base 4 | OP_NODE_P2P_BOOTNODES=enr:-J64QBwRIWAco7lv6jImSOjPU_W266lHXzpAS5YOh7WmgTyBZkgLgOwo_mxKJq3wz2XRbsoBItbv1dCyjIoNq67mFguGAYrTxM42gmlkgnY0gmlwhBLSsHKHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDmoWSi8hcsRpQf2eJsNUx-sqv6fH4btmo2HsAzZFAKnKDdGNwgiQGg3VkcIIkBg,enr:-J64QFa3qMsONLGphfjEkeYyF6Jkil_jCuJmm7_a42ckZeUQGLVzrzstZNb1dgBp1GGx9bzImq5VxJLP-BaptZThGiWGAYrTytOvgmlkgnY0gmlwhGsV-zeHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDahfSECTIS_cXyZ8IyNf4leANlZnrsMEWTkEYxf4GMCmDdGNwgiQGg3VkcIIkBg 5 | OP_NODE_ROLLUP_CONFIG=/chainconfig/rollup.json 6 | OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true -------------------------------------------------------------------------------- /envs/common/grafana.env: -------------------------------------------------------------------------------- 1 | GF_SECURITY_ADMIN_PASSWORD=optimism 2 | -------------------------------------------------------------------------------- /envs/common/healthcheck.env: -------------------------------------------------------------------------------- 1 | HEALTHCHECK__TARGET_RPC_PROVIDER=http://op-geth:8545 2 | -------------------------------------------------------------------------------- /envs/common/influxdb.env: -------------------------------------------------------------------------------- 1 | INFLUXDB_HTTP_AUTH_ENABLED=false 2 | -------------------------------------------------------------------------------- /envs/common/l2geth.env: -------------------------------------------------------------------------------- 1 | USING_OVM=true 2 | ETH1_SYNC_SERVICE_ENABLE=false 3 | RPC_API=eth,rollup,net,web3,debug 4 | RPC_ADDR=0.0.0.0 5 | RPC_CORS_DOMAIN=* 6 | RPC_ENABLE=true 7 | RPC_PORT=8545 8 | RPC_VHOSTS=* 9 | -------------------------------------------------------------------------------- /envs/op-goerli/op-geth.env: -------------------------------------------------------------------------------- 1 | BEDROCK_SEQUENCER_HTTP=https://goerli-sequencer.optimism.io 2 | BEDROCK_DATADIR=/geth 3 | -------------------------------------------------------------------------------- /envs/op-goerli/op-node.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontracts/simple-optimism-node/ddc249e27e66758aee1384f7cb868d9a37fc9450/envs/op-goerli/op-node.env -------------------------------------------------------------------------------- /envs/op-mainnet/op-geth.env: -------------------------------------------------------------------------------- 1 | BEDROCK_SEQUENCER_HTTP=https://mainnet-sequencer.optimism.io 2 | BEDROCK_DATADIR=/geth 3 | -------------------------------------------------------------------------------- /envs/op-mainnet/op-node.env: -------------------------------------------------------------------------------- 1 | # Official chain doesn't need custom -------------------------------------------------------------------------------- /envs/op-sepolia/op-geth.env: -------------------------------------------------------------------------------- 1 | BEDROCK_SEQUENCER_HTTP=https://sepolia-sequencer.optimism.io 2 | BEDROCK_DATADIR=/geth 3 | -------------------------------------------------------------------------------- /envs/op-sepolia/op-node.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontracts/simple-optimism-node/ddc249e27e66758aee1384f7cb868d9a37fc9450/envs/op-sepolia/op-node.env -------------------------------------------------------------------------------- /funding.json: -------------------------------------------------------------------------------- 1 | { 2 | "opRetro": { 3 | "projectId": "0x09b95c7697625da4915338750c5f78446817a3634cb38bc9155e26bbbc0c87f1" 4 | } 5 | } -------------------------------------------------------------------------------- /progress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | # Load Environment Variables 6 | if [ -f .env ]; then 7 | export $(cat .env | grep -v '#' | sed 's/\r$//' | awk '/=/ {print $1}' ) 8 | fi 9 | 10 | export ETH_RPC_URL=http://localhost:${PORT__OP_GETH_HTTP:-9993} 11 | # Cast is provided by Foundry: https://getfoundry.sh/. 12 | # Run `pnpm install:foundry` in the optimism repo root. 13 | CHAIN_ID=`cast chain-id` 14 | echo Chain ID: $CHAIN_ID 15 | echo Sampling, please wait 16 | 17 | if [ $CHAIN_ID -eq 10 ]; then 18 | L2_URL=https://mainnet.optimism.io 19 | fi 20 | 21 | if [ $CHAIN_ID -eq 11155420 ]; then 22 | L2_URL=https://sepolia.optimism.io 23 | fi 24 | 25 | T0=`cast block-number --rpc-url $ETH_RPC_URL` ; sleep 10 ; T1=`cast block-number --rpc-url $ETH_RPC_URL` 26 | PER_MIN=$(($T1 - $T0)) 27 | PER_MIN=$(($PER_MIN * 6)) 28 | echo Blocks per minute: $PER_MIN 29 | 30 | 31 | if [ $PER_MIN -eq 0 ]; then 32 | echo Not syncing 33 | exit; 34 | fi 35 | 36 | 37 | # How many more blocks do we need? 38 | HEAD=`cast block-number --rpc-url $L2_URL` 39 | BEHIND=`expr $HEAD - $T1` 40 | MINUTES=`expr $BEHIND / $PER_MIN` 41 | HOURS=`expr $MINUTES / 60` 42 | 43 | if [ $MINUTES -le 60 ] ; then 44 | echo Minutes until sync completed: $MINUTES 45 | fi 46 | 47 | if [ $MINUTES -gt 60 ] ; then 48 | echo Hours until sync completed: $HOURS 49 | fi 50 | 51 | if [ $HOURS -gt 24 ] ; then 52 | DAYS=`expr $HOURS / 24` 53 | echo Days until sync complete: $DAYS 54 | fi 55 | -------------------------------------------------------------------------------- /prysm.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | beacon: 5 | container_name: beacon-chain 6 | image: gcr.io/prysmaticlabs/prysm/beacon-chain:${PRYSM_DOCKER_TAG:-stable} 7 | restart: always 8 | hostname: beacon-chain 9 | command: --config-file=/config/beacon.yaml 10 | ports: 11 | - 127.0.0.1:4000:4000 12 | - 13000:13000/tcp 13 | - 12000:12000/udp 14 | volumes: 15 | - ./scripts/beacon.yaml:/config/beacon.yaml:ro 16 | - beacon_data:/data 17 | extra_hosts: 18 | - "host.docker.internal:host-gateway" 19 | 20 | volumes: 21 | beacon_data: 22 | -------------------------------------------------------------------------------- /scripts/beacon.yaml: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | ## 3 | ## Read up on parameters on 4 | ## https://docs.prylabs.network/docs/prysm-usage/parameters/ 5 | ## 6 | ############################################################ 7 | 8 | accept-terms-of-use: true 9 | 10 | datadir: /data 11 | 12 | ####################### 13 | # Connectivity settings 14 | p2p-host-ip: "" 15 | p2p-host-dns: "" 16 | 17 | rpc-host: 0.0.0.0 18 | monitoring-host: 0.0.0.0 19 | 20 | # disable scan of local network 21 | p2p-denylist: ["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","100.64.0.0/10","169.254.0.0/16"] 22 | 23 | # changing this also needs to be changed in docker-compose.yaml! 24 | p2p-tcp-port: 13000 25 | 26 | # enable db backup endpoint 27 | enable-db-backup-webhook: true 28 | 29 | ############################## 30 | # Connection to geth container 31 | http-web3provider: http://host.docker.internal:8545 32 | 33 | blst: true -------------------------------------------------------------------------------- /scripts/init-bedrock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Import utilities. 5 | source ./scripts/utils.sh 6 | 7 | # Common variables. 8 | INITIALIZED_FLAG=/shared/initialized.txt 9 | BEDROCK_JWT_PATH=/shared/jwt.txt 10 | GETH_DATA_DIR=$BEDROCK_DATADIR 11 | TORRENTS_DIR=/torrents/$NETWORK_NAME 12 | BEDROCK_TAR_PATH=/downloads/bedrock.tar 13 | BEDROCK_TMP_PATH=/bedrock-tmp 14 | 15 | # Exit early if we've already initialized. 16 | if [ -e "$INITIALIZED_FLAG" ]; then 17 | echo "Bedrock node already initialized" 18 | exit 0 19 | fi 20 | 21 | echo "Bedrock node needs to be initialized..." 22 | echo "Initializing via download..." 23 | 24 | # Fix OP link with hardcoded official OP snapshot 25 | echo "Fetching download link..." 26 | 27 | if [ "$NODE_TYPE" = "full" ]; then 28 | # Warning: syncmode=full for syncing full node is deprecated and not recommended to use 29 | if [ "$OP_GETH__SYNCMODE" = "full" ]; then 30 | if [ "$NETWORK_NAME" = "op-mainnet" ]; then 31 | BEDROCK_TAR_DOWNLOAD="https://r2-snapshots.fastnode.io/op/$(curl -s https://r2-snapshots.fastnode.io/op/latest-mainnet)" 32 | elif [ "$NETWORK_NAME" = "op-goerli" ]; then 33 | BEDROCK_TAR_DOWNLOAD="https://datadirs.optimism.io/goerli-bedrock.tar.zst" 34 | fi 35 | fi 36 | elif [ "$NODE_TYPE" = "archive" ]; then 37 | if [ "$NETWORK_NAME" = "op-mainnet" ]; then 38 | BEDROCK_TAR_DOWNLOAD="$(curl -s https://datadirs.optimism.io/latest/ | grep -oE 'https://[^\"]+')" 39 | elif [ "$NETWORK_NAME" = "base-mainnet" ]; then 40 | BEDROCK_TAR_DOWNLOAD="https://base-snapshots-mainnet-archive.s3.amazonaws.com/$(curl -s https://base-snapshots-mainnet-archive.s3.amazonaws.com/latest)" 41 | elif [ "$NETWORK_NAME" = "base-goerli" ]; then 42 | BEDROCK_TAR_DOWNLOAD="https://base-snapshots-goerli-archive.s3.amazonaws.com/$(curl -s https://base-snapshots-goerli-archive.s3.amazonaws.com/latest)" 43 | elif [ "$NETWORK_NAME" = "base-sepolia" ]; then 44 | BEDROCK_TAR_DOWNLOAD="https://base-snapshots-sepolia-archive.s3.amazonaws.com/$(curl -s https://base-snapshots-sepolia-archive.s3.amazonaws.com/latest)" 45 | fi 46 | fi 47 | 48 | if [ -n "$BEDROCK_TAR_DOWNLOAD" ]; then 49 | if [[ "$BEDROCK_TAR_DOWNLOAD" == *.zst ]]; then 50 | BEDROCK_TAR_PATH+=".zst" 51 | elif [[ "$BEDROCK_TAR_DOWNLOAD" == *.lz4 ]]; then 52 | BEDROCK_TAR_PATH+=".lz4" 53 | fi 54 | 55 | echo "Downloading bedrock.tar..." 56 | download $BEDROCK_TAR_DOWNLOAD $BEDROCK_TAR_PATH 57 | 58 | echo "Extracting bedrock.tar..." 59 | if [[ "$BEDROCK_TAR_DOWNLOAD" == *.zst ]]; then 60 | extractzst $BEDROCK_TAR_PATH $GETH_DATA_DIR 61 | elif [[ "$BEDROCK_TAR_DOWNLOAD" == *.lz4 ]]; then 62 | extractlz4 $BEDROCK_TAR_PATH $GETH_DATA_DIR 63 | else 64 | extract $BEDROCK_TAR_PATH $GETH_DATA_DIR 65 | fi 66 | 67 | # Remove tar file to save disk space 68 | rm $BEDROCK_TAR_PATH 69 | fi 70 | 71 | echo "Creating JWT..." 72 | mkdir -p $(dirname $BEDROCK_JWT_PATH) 73 | openssl rand -hex 32 > $BEDROCK_JWT_PATH 74 | 75 | echo "Creating Bedrock flag..." 76 | touch $INITIALIZED_FLAG 77 | touch /upgrade-pectra/upgraded 78 | -------------------------------------------------------------------------------- /scripts/init-l2geth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ "$NETWORK_NAME" != "op-mainnet" ]; then 5 | echo "Stopping l2geth for a non op-mainnet chain" 6 | exit 7 | fi 8 | 9 | if [ -n "${OP_GETH__HISTORICAL_RPC}" ]; then 10 | echo "Stopping l2geth for using an external historical RPC" 11 | exit 12 | fi 13 | 14 | GETH_DATA_DIR=/geth 15 | GETH_CHAINDATA_DIR=$GETH_DATA_DIR/geth/chaindata 16 | GETH_KEYSTORE_DIR=$GETH_DATA_DIR/keystore 17 | 18 | # Initialize keystore directory if necessary. 19 | if [ ! -d "$GETH_KEYSTORE_DIR" ]; then 20 | echo "$GETH_KEYSTORE_DIR missing, running account import" 21 | echo -n "$BLOCK_SIGNER_PRIVATE_KEY_PASSWORD" > "$GETH_DATA_DIR"/password 22 | echo -n "$BLOCK_SIGNER_PRIVATE_KEY" > "$GETH_DATA_DIR"/block-signer-key 23 | geth account import \ 24 | --datadir="$GETH_DATA_DIR" \ 25 | --password="$GETH_DATA_DIR"/password \ 26 | "$GETH_DATA_DIR"/block-signer-key 27 | echo "get account import complete" 28 | fi 29 | 30 | # Initialize chaindata directory if necessary. 31 | if [ ! -d "$GETH_CHAINDATA_DIR" ]; then 32 | echo "$GETH_CHAINDATA_DIR missing, running init" 33 | geth init --datadir="$GETH_DATA_DIR" "$L2GETH_GENESIS_URL" "$L2GETH_GENESIS_HASH" 34 | echo "geth init complete" 35 | fi 36 | -------------------------------------------------------------------------------- /scripts/start-l2geth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ "$NETWORK_NAME" != "op-mainnet" ]; then 5 | echo "Stopping l2geth for a non op-mainnet chain" 6 | exit 7 | fi 8 | 9 | if [ -n "${OP_GETH__HISTORICAL_RPC}" ]; then 10 | echo "Stopping l2geth for using an external historical RPC" 11 | exit 12 | fi 13 | 14 | # l2geth new standard env variables 15 | export USING_OVM=true 16 | export ETH1_SYNC_SERVICE_ENABLE=false 17 | export RPC_API=eth,rollup,net,web3,debug 18 | export RPC_ADDR=0.0.0.0 19 | export RPC_CORS_DOMAIN=* 20 | export RPC_ENABLE=true 21 | export RPC_PORT=8545 22 | export RPC_VHOSTS=* 23 | 24 | # Start l2geth. 25 | exec geth --datadir=$DATADIR $@ 26 | -------------------------------------------------------------------------------- /scripts/start-op-geth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Wait for the Bedrock flag for this network to be set. 5 | echo "Waiting for Bedrock node to initialize..." 6 | while [ ! -f /shared/initialized.txt ]; do 7 | sleep 1 8 | done 9 | 10 | if [ ! -f /upgrade-pectra/upgraded ]; then 11 | echo "Please upgrade to Pectra with upgrade-pectra.sh" 12 | exit 1 13 | fi 14 | 15 | if [ -z "${IS_CUSTOM_CHAIN}" ]; then 16 | if [ "$NETWORK_NAME" == "op-mainnet" ] || [ "$NETWORK_NAME" == "op-goerli" ]; then 17 | export EXTENDED_ARG="${EXTENDED_ARG:-} --rollup.historicalrpc=${OP_GETH__HISTORICAL_RPC:-http://l2geth:8545} --op-network=$NETWORK_NAME" 18 | else 19 | export EXTENDED_ARG="${EXTENDED_ARG:-} --op-network=$NETWORK_NAME" 20 | fi 21 | fi 22 | 23 | # Init genesis if custom chain 24 | if [ -n "${IS_CUSTOM_CHAIN}" ]; then 25 | geth init --datadir="$BEDROCK_DATADIR" /chainconfig/genesis.json 26 | fi 27 | 28 | # Determine syncmode based on NODE_TYPE 29 | if [ -z "$OP_GETH__SYNCMODE" ]; then 30 | if [ "$NODE_TYPE" = "full" ]; then 31 | export OP_GETH__SYNCMODE="snap" 32 | else 33 | export OP_GETH__SYNCMODE="full" 34 | fi 35 | fi 36 | 37 | # Start op-geth. 38 | exec geth \ 39 | --datadir="$BEDROCK_DATADIR" \ 40 | --http \ 41 | --http.corsdomain="*" \ 42 | --http.vhosts="*" \ 43 | --http.addr=0.0.0.0 \ 44 | --http.port=8545 \ 45 | --http.api=web3,debug,eth,txpool,net,engine \ 46 | --ws \ 47 | --ws.addr=0.0.0.0 \ 48 | --ws.port=8546 \ 49 | --ws.origins="*" \ 50 | --ws.api=debug,eth,txpool,net,engine,web3 \ 51 | --metrics \ 52 | --metrics.influxdb \ 53 | --metrics.influxdb.endpoint=http://influxdb:8086 \ 54 | --metrics.influxdb.database=opgeth \ 55 | --syncmode="$OP_GETH__SYNCMODE" \ 56 | --gcmode="$NODE_TYPE" \ 57 | --authrpc.vhosts="*" \ 58 | --authrpc.addr=0.0.0.0 \ 59 | --authrpc.port=8551 \ 60 | --authrpc.jwtsecret=/shared/jwt.txt \ 61 | --rollup.sequencerhttp="$BEDROCK_SEQUENCER_HTTP" \ 62 | --rollup.disabletxpoolgossip=true \ 63 | --port="${PORT__OP_GETH_P2P:-39393}" \ 64 | --discovery.port="${PORT__OP_GETH_P2P:-39393}" \ 65 | --db.engine=pebble \ 66 | --state.scheme=hash \ 67 | $EXTENDED_ARG $@ 68 | 69 | -------------------------------------------------------------------------------- /scripts/start-op-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Wait for the Bedrock flag for this network to be set. 5 | echo "Waiting for Bedrock node to initialize..." 6 | while [ ! -f /shared/initialized.txt ]; do 7 | sleep 1 8 | done 9 | 10 | if [ ! -f /upgrade-pectra/upgraded ]; then 11 | echo "Please upgrade to Pectra with upgrade-pectra.sh" 12 | exit 1 13 | fi 14 | 15 | if [ -n "${IS_CUSTOM_CHAIN}" ]; then 16 | export EXTENDED_ARG="${EXTENDED_ARG:-} --rollup.config=/chainconfig/rollup.json" 17 | else 18 | export EXTENDED_ARG="${EXTENDED_ARG:-} --network=$NETWORK_NAME --rollup.load-protocol-versions=true --rollup.halt=major" 19 | fi 20 | 21 | # Start op-node. 22 | exec op-node \ 23 | --l1=$OP_NODE__RPC_ENDPOINT \ 24 | --l2=http://op-geth:8551 \ 25 | --rpc.addr=0.0.0.0 \ 26 | --rpc.port=9545 \ 27 | --l2.jwt-secret=/shared/jwt.txt \ 28 | --l1.trustrpc \ 29 | --l1.rpckind=$OP_NODE__RPC_TYPE \ 30 | --l1.beacon=$OP_NODE__L1_BEACON \ 31 | --metrics.enabled \ 32 | --metrics.addr=0.0.0.0 \ 33 | --metrics.port=7300 \ 34 | --syncmode=execution-layer \ 35 | $EXTENDED_ARG $@ 36 | -------------------------------------------------------------------------------- /scripts/utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # extract: Extracts an archive into an output location. 4 | # Arguments: 5 | # arc: Archive to to extract. 6 | # loc: Location to extract to. 7 | function extract() { 8 | mkdir -p $2 9 | tar -xf $1 -C $2 10 | } 11 | 12 | # extract: Extracts a zst archive into an output location. 13 | # Arguments: 14 | # arc: ZST archive to to extract. 15 | # loc: Location to extract to. 16 | function extractzst() { 17 | mkdir -p $2 18 | tar --use-compress-program=unzstd -xf $1 -C $2 19 | } 20 | 21 | # extract: Extracts a lz4 archive into an output location. 22 | # Arguments: 23 | # arc: lz4 archive to to extract. 24 | # loc: Location to extract to. 25 | function extractlz4() { 26 | mkdir -p $2 27 | tar --use-compress-program="lz4 --no-crc" -xf $1 -C $2 28 | } 29 | 30 | # download: Downloads a file and provides basic progress percentages. 31 | # Arguments: 32 | # url: URL of the file to download. 33 | # out: Location to download the file to. 34 | function download() { 35 | aria2c --max-tries=0 -x 16 -s 16 -k100M -o $2 $1 36 | } 37 | 38 | # chainwait: Waits for a chain to be running. 39 | # Arguments: 40 | # rpc: RPC URL of the chain to wait for. 41 | function chainwait() { 42 | curl \ 43 | -X POST \ 44 | --silent \ 45 | --output /dev/null \ 46 | --retry-connrefused \ 47 | --retry 1000 \ 48 | --retry-delay 1 \ 49 | -d '{"jsonrpc":"2.0","id":0,"method":"eth_chainId","params":[]}' \ 50 | $1 51 | } 52 | 53 | # config: Grabs config from the Configuration contract on Goerli. 54 | # Arguments: 55 | # cfg: Name of the configuration value to grab. 56 | function config() { 57 | echo "$(cast call 0xcbebc5ba53ff12165239cbb3d310fda2236d6ad2 'config(address,string)(string)' 0x68108902De3A5031197a6eB3b74b3b033e8E8e4d $1 --rpc-url https://goerli.infura.io/v3/84842078b09946638c03157f83405213)" 58 | } 59 | --------------------------------------------------------------------------------