Full Code of inkonchain/node for AI

main 8b7947a74b77 cached
25 files
45.5 KB
13.2k tokens
1 requests
Download .txt
Repository: inkonchain/node
Branch: main
Commit: 8b7947a74b77
Files: 25
Total size: 45.5 KB

Directory structure:
gitextract_h6bn2w4t/

├── .github/
│   └── workflows/
│       └── securesdlc.yml
├── .gitignore
├── LICENSE
├── README.md
├── 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
├── docker-compose.yml
├── envs/
│   ├── common/
│   │   ├── grafana.env
│   │   ├── healthcheck.env
│   │   └── influxdb.env
│   ├── ink-mainnet/
│   │   ├── healthcheck.env
│   │   ├── op-geth.env
│   │   └── op-node.env
│   └── ink-sepolia/
│       ├── healthcheck.env
│       ├── op-geth.env
│       └── op-node.env
├── progress.sh
└── scripts/
    ├── init-bedrock.sh
    ├── start-op-geth.sh
    ├── start-op-node.sh
    └── utils.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/securesdlc.yml
================================================
name: Nautilus SecureSDLC Reusable
run-name: "[Nautilus SecureSDLC Reusable] Ref:${{ github.ref_name }} Event:${{ github.event_name }}"

on:
  workflow_dispatch: {}
  workflow_call: {}
  push:
    branches: [ main ]

jobs:
  securesdlc-umbrella:
    permissions:
      contents: read # for actions/checkout to fetch code
      security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
      actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status  
    uses: nautilus-wraith/securesdlc-umbrella/.github/workflows/securesdlc-umbrella.yml@release-stable
    secrets:
      SEMGREP_APP_URL: ${{ secrets.SEMGREP_APP_URL }}
      SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
      SDLC_SLACK_NOTIFICATIONS: ${{ secrets.SDLC_SLACK_NOTIFICATIONS }}


================================================
FILE: .gitignore
================================================
.env
.env.sepolia
.env.mainnet


================================================
FILE: LICENSE
================================================
(The MIT License)

Copyright 2020-2022 Optimism

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Ink Node

> Forked and customized from https://github.com/smartcontracts/simple-optimism-node

A simple docker compose script for launching full / archive node for the Ink chain.

## Recommended Hardware

### Mainnet

- 16GB+ RAM
- 2 TB SSD (NVME Recommended)
- 100mb/s+ Download

### Testnet

- 16GB+ RAM
- 500 GB SSD (NVME Recommended)
- 100mb/s+ Download

## Installation and Configuration

### Install docker and docker compose

> 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.

Note: This command installs docker and docker compose for Ubuntu. For windows and mac desktop or laptop, please use Docker Desktop. For other OS, please find instructions in Google.

```sh
# Update and upgrade packages
sudo apt-get update
sudo apt-get upgrade -y

### Docker and docker compose prerequisites
sudo apt-get install -y curl
sudo apt-get install -y gnupg
sudo apt-get install -y ca-certificates
sudo apt-get install -y lsb-release

### Download the docker gpg file to Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

### Add Docker and docker compose support to the Ubuntu's packages list
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

sudo apt-get update

### Install docker and docker compose on Ubuntu
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

sudo usermod -aG docker $(whoami)

### Verify the Docker and docker compose install on Ubuntu
sudo docker run hello-world
```

(For non-root user) After logged out and logged back in, test if docker is working by running.

```sh
docker ps
```

It should returns an empty container list without having any error. Otherwise, restart your machine if there are errors.

### Clone the Repository

```sh
git clone https://github.com/inkonchain/node
cd node
```

### Copy .env.example to .env

Make a copy of `.env.example` named `.env`.

```sh
cp .env.example .env
```

Open `.env` with your editor of choice

### Mandatory configurations

- **NETWORK_NAME** - Choose which Optimism network layer you want to operate on:
  - `ink-sepolia` - Ink Sepolia (Testnet)
  - `ink-mainnet` - Ink (Mainnet)
- **NODE_TYPE** - Choose the type of node you want to run:
  - `full` (Full node) - A Full node contains a few recent blocks without historical states.
  - `archive` (Archive node) - An Archive node stores the complete history of the blockchain, including historical states.
- **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 Quicknode for the Ethereum mainnet.
- **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
- **OP_NODE\_\_RPC_TYPE** - Specify the service provider for the RPC endpoint you've chosen in the previous step. The available options are:
  - `alchemy` - Alchemy
  - `quicknode` - Quicknode (ETH only)
  - `erigon` - Erigon
  - `basic` - Other providers

### Optional configurations

- **OP_GETH\_\_SYNCMODE** - Specify sync mode for the execution client
  - Unspecified - Use default snap sync for full node and full sync for archive node
  - `snap` - Snap Sync (Default)
  - `full` - Full Sync (For archive node, not recommended for full node)
- **IMAGE_TAG\_\_[...]** - Use custom docker image for specified components.
- **PORT\_\_[...]** - Use custom port for specified components.

## Operating the Node

### Start

```sh
docker compose up -d --build
```

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.

### View logs

```sh
docker compose logs -f --tail 10
```

To view logs of all containers.

```sh
docker compose logs <CONTAINER_NAME> -f --tail 10
```

To view logs for a specific container. Most commonly used `<CONTAINER_NAME>` are:

- op-geth
- op-node
- bedrock-init

### Stop

```sh
docker compose down
```

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

### Restart

```sh
docker compose restart
```

Will restart the node safely with minimal downtime but without upgrading the node.

### Upgrade

Pull the latest updates from GitHub, and Docker Hub and rebuild the container.

```sh
git pull
docker compose pull
docker compose up -d --build
```

Will upgrade your node with minimal downtime.

### Wipe [DANGER]

```sh
docker compose down -v
```

Will shut down the node and WIPE ALL DATA. Proceed with caution!

## Monitoring

### Estimate remaining sync time

Run progress.sh to estimate remaining sync time and speed.

Uses `Cast` command from Foundry tool set. Installation instructions here: https://getfoundry.sh/.

```sh
./progress.sh
```

This will show the sync speed in blocks per minute and the time until sync is completed.

```
Chain ID: 57073
Please wait
Blocks per minute: ...
Hours until sync is completed: ...
```

### Grafana dashboard

Grafana is exposed at [http://localhost:3000](http://localhost:3000) and comes with one pre-loaded dashboard ("Simple Node Dashboard").
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.

Use the following login details to access the dashboard:

- Username: `admin`
- Password: `ink`

Navigate over to `Dashboards > Manage > Simple Node Dashboard` to see the dashboard, see the following gif if you need help:

![metrics dashboard gif](https://user-images.githubusercontent.com/14298799/171476634-0cb84efd-adbf-4732-9c1d-d737915e1fa7.gif)

## Troubleshooting

### Walking back L1Block with curr=0x0000...:0 next=0x0000...:0

If you experience "walking back L1Block with curr=0x0000...:0 next=0x0000...:0" for a long time after the Ecotone upgrade, consider these fixes:

1. Wait for a few minutes. This issue usually resolves itself after some time.
2. Restart docker compose: `docker compose down` and `docker compose up -d --build`


================================================
FILE: docker/dockerfiles/Dockerfile.bedrock-init
================================================
FROM ubuntu:22.04

# Disable prompts during package installation.
ARG DEBIAN_FRONTEND=noninteractive

# Install required packages.
RUN apt-get update && apt install -y curl wget git rsync build-essential openssl python3 python3-pip aria2 zstd lz4

# Install Go.
RUN curl -sSL https://golang.org/dl/go1.21.6.linux-amd64.tar.gz | tar -v -C /usr/local -xz
RUN cp /usr/local/go/bin/go /usr/bin/go

# Install Foundry.
RUN curl -L https://foundry.paradigm.xyz | bash
RUN /root/.foundry/bin/foundryup
RUN rsync -a /root/.foundry/bin/ /usr/bin/


================================================
FILE: docker/grafana/dashboards/simple_node_dashboard.json
================================================
{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": {
          "type": "grafana",
          "uid": "-- Grafana --"
        },
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "target": {
          "limit": 100,
          "matchAny": false,
          "tags": [],
          "type": "dashboard"
        },
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "links": [],
  "liveNow": false,
  "panels": [
    {
      "collapsed": false,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 30,
      "panels": [],
      "title": "Syncing Status",
      "type": "row"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "4knV40nVb"
      },
      "description": "",
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "graph": false,
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "always",
            "spanNulls": true,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": "string"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 14,
        "w": 24,
        "x": 0,
        "y": 1
      },
      "id": 4,
      "options": {
        "graph": {},
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "7.5.5",
      "targets": [
        {
          "alias": "Unsafe Head",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.chain/head/block.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "Safe Head",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.chain/head/safe.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "B",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "Finalized Head",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.chain/head/finalized.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "C",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "title": "Node Block Height",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "6R74VAnVz"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 0,
            "gradientMode": "none",
            "hideFrom": {
              "graph": false,
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "auto",
            "spanNulls": false,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 4,
        "w": 8,
        "x": 0,
        "y": 15
      },
      "id": 10,
      "options": {
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "6R74VAnVz"
          },
          "editorMode": "code",
          "expr": "fault_detector_highest_checked_batch_index{}",
          "legendFormat": "Checked",
          "range": true,
          "refId": "A"
        },
        {
          "datasource": {
            "type": "prometheus",
            "uid": "6R74VAnVz"
          },
          "editorMode": "code",
          "expr": "fault_detector_highest_known_batch_index{}",
          "hide": false,
          "legendFormat": "Known",
          "range": true,
          "refId": "B"
        }
      ],
      "title": "Fault Check Status",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "6R74VAnVz"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "mappings": [
            {
              "options": {
                "0": {
                  "text": "OK"
                },
                "1": {
                  "text": "NOT OK"
                }
              },
              "type": "value"
            }
          ],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "green",
                "value": 0
              },
              {
                "color": "red",
                "value": 1
              }
            ]
          }
        },
        "overrides": []
      },
      "gridPos": {
        "h": 4,
        "w": 8,
        "x": 8,
        "y": 15
      },
      "id": 12,
      "options": {
        "orientation": "auto",
        "reduceOptions": {
          "calcs": ["lastNotNull"],
          "fields": "",
          "values": false
        },
        "showThresholdLabels": false,
        "showThresholdMarkers": true,
        "text": {}
      },
      "pluginVersion": "9.3.0",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "6R74VAnVz"
          },
          "editorMode": "code",
          "exemplar": true,
          "expr": "fault_detector_is_currently_mismatched{}",
          "hide": false,
          "interval": "",
          "legendFormat": "Fault Detection",
          "range": true,
          "refId": "B"
        },
        {
          "datasource": {
            "type": "prometheus",
            "uid": "6R74VAnVz"
          },
          "exemplar": true,
          "expr": "healthcheck_is_currently_diverged",
          "hide": false,
          "interval": "",
          "legendFormat": "Healthcheck",
          "refId": "C"
        }
      ],
      "title": "System Security Monitoring",
      "type": "gauge"
    },
    {
      "datasource": {
        "type": "prometheus",
        "uid": "6R74VAnVz"
      },
      "description": "",
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "displayName": "Blocks to sync",
          "mappings": [
            {
              "options": {
                "from": 0,
                "result": {
                  "text": "SYNCED"
                },
                "to": 1000
              },
              "type": "range"
            }
          ],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "blue",
                "value": 1000
              }
            ]
          },
          "unit": "none"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 4,
        "w": 8,
        "x": 16,
        "y": 15
      },
      "id": 24,
      "options": {
        "colorMode": "value",
        "graphMode": "area",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": ["lastNotNull"],
          "fields": "",
          "values": false
        },
        "text": {},
        "textMode": "auto"
      },
      "pluginVersion": "9.3.0",
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "6R74VAnVz"
          },
          "exemplar": true,
          "expr": "healthcheck_reference_height - healthcheck_target_height",
          "hide": false,
          "instant": false,
          "interval": "",
          "legendFormat": "",
          "refId": "A"
        }
      ],
      "title": "Chain Sync Status",
      "transformations": [],
      "type": "stat"
    },
    {
      "collapsed": false,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 19
      },
      "id": 26,
      "panels": [],
      "title": "Geth Performance",
      "type": "row"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "4knV40nVb"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 10,
            "gradientMode": "none",
            "hideFrom": {
              "graph": false,
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "never",
            "spanNulls": true,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": "%"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 6,
        "w": 8,
        "x": 0,
        "y": 20
      },
      "id": 31,
      "options": {
        "graph": {},
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "7.5.5",
      "targets": [
        {
          "alias": "system",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "measurement": "geth.system/cpu/sysload.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "geth",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.system/cpu/procload.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "B",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "IO",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.system/cpu/syswait.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "C",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "title": "CPU",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "4knV40nVb"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 10,
            "gradientMode": "none",
            "hideFrom": {
              "graph": false,
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "never",
            "spanNulls": true,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": "decbytes"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 6,
        "w": 8,
        "x": 8,
        "y": 20
      },
      "id": 32,
      "options": {
        "graph": {},
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "7.5.5",
      "targets": [
        {
          "alias": "used",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "measurement": "geth.system/memory/used.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "held",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.system/memory/held.gauge",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "B",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["value"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "title": "Memory",
      "type": "timeseries"
    },
    {
      "datasource": {
        "type": "influxdb",
        "uid": "4knV40nVb"
      },
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "palette-classic"
          },
          "custom": {
            "axisCenteredZero": false,
            "axisColorMode": "text",
            "axisLabel": "",
            "axisPlacement": "auto",
            "barAlignment": 0,
            "drawStyle": "line",
            "fillOpacity": 10,
            "gradientMode": "none",
            "hideFrom": {
              "graph": false,
              "legend": false,
              "tooltip": false,
              "viz": false
            },
            "lineInterpolation": "linear",
            "lineWidth": 1,
            "pointSize": 5,
            "scaleDistribution": {
              "type": "linear"
            },
            "showPoints": "never",
            "spanNulls": true,
            "stacking": {
              "group": "A",
              "mode": "none"
            },
            "thresholdsStyle": {
              "mode": "off"
            }
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "unit": "Bps"
        },
        "overrides": []
      },
      "gridPos": {
        "h": 6,
        "w": 8,
        "x": 16,
        "y": 20
      },
      "id": 22,
      "options": {
        "graph": {},
        "legend": {
          "calcs": [],
          "displayMode": "list",
          "placement": "bottom",
          "showLegend": true
        },
        "tooltip": {
          "mode": "single",
          "sort": "none"
        }
      },
      "pluginVersion": "7.5.5",
      "targets": [
        {
          "alias": "read",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "measurement": "geth.system/disk/readdata.meter",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["m1"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "write",
          "datasource": {
            "type": "influxdb",
            "uid": "4knV40nVb"
          },
          "groupBy": [
            {
              "params": ["$__interval"],
              "type": "time"
            },
            {
              "params": ["null"],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "geth.system/disk/writedata.meter",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "SELECT mean(\"m1\") FROM \"geth.system/disk/writedata.meter\" WHERE $timeFilter GROUP BY time($__interval) fill(null)",
          "rawQuery": false,
          "refId": "B",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": ["m1"],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "title": "Disk",
      "type": "timeseries"
    }
  ],
  "refresh": "5s",
  "schemaVersion": 37,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-1h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "",
  "title": "Simple Node Dashboard",
  "uid": "fNH7uZ97k",
  "version": 3,
  "weekStart": ""
}


================================================
FILE: docker/grafana/provisioning/dashboards/all.yml
================================================
- name: 'default'
  org_id: 1
  folder: ''
  type: 'file'
  options:
    folder: '/var/lib/grafana/dashboards'


================================================
FILE: docker/grafana/provisioning/datasources/all.yml
================================================
apiVersion: 1

deleteDatasources:
  - name: "Prometheus"
  - name: "InfluxDB"

datasources:
  - access: "proxy"
    editable: true
    is_default: true
    name: "Prometheus"
    uid: "6R74VAnVz"
    org_id: 1
    type: "prometheus"
    url: "http://prometheus:9090"
    version: 1
  - access: "proxy"
    editable: true
    is_default: false
    name: "InfluxDB (op-geth)"
    uid: "4knV40nVb"
    org_id: 1
    type: "influxdb"
    database: "opgeth"
    url: "http://influxdb:8086"
    version: 1


================================================
FILE: docker/influxdb/influx_init.iql
================================================
CREATE DATABASE "opgeth"


================================================
FILE: docker/prometheus/prometheus.yml
================================================
global:
  scrape_interval:     15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'healthcheck'
    static_configs:
    - targets: ['healthcheck:7300']

  - job_name: 'fault-detector'
    static_configs:
    - targets: ['fault-detector:7300']

  - job_name: 'op-node'
    static_configs:
    - targets: ['op-node:7300']


================================================
FILE: docker-compose.yml
================================================
services:
  healthcheck:
    image: ethereumoptimism/replica-healthcheck:${IMAGE_TAG__HEALTHCHECK:-latest}
    restart: unless-stopped
    env_file:
      - ./envs/common/healthcheck.env
      - ./envs/${NETWORK_NAME}/healthcheck.env
      - .env
    ports:
      - ${PORT__HEALTHCHECK_METRICS:-7300}:7300

  op-geth:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101503.4
    restart: unless-stopped
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-geth.sh
    env_file:
      - ./envs/${NETWORK_NAME}/op-geth.env
      - .env
    volumes:
      - ./envs/${NETWORK_NAME}/config:/chainconfig
      - ./scripts/:/scripts
      - shared:/shared
      - op_geth:/geth
    ports:
      - ${PORT__OP_GETH_HTTP:-9993}:8545
      - ${PORT__OP_GETH_WS:-9994}:8546
      - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/udp
      - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/tcp
    extra_hosts:
      - "host.docker.internal:host-gateway"

  op-node:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.13.2
    restart: unless-stopped
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-node.sh
    env_file:
      - ./envs/${NETWORK_NAME}/op-node.env
      - .env
    volumes:
      - ./envs/${NETWORK_NAME}/config:/chainconfig
      - ./scripts/:/scripts
      - shared:/shared
    ports:
      - ${PORT__OP_NODE_P2P:-9003}:9003/udp
      - ${PORT__OP_NODE_P2P:-9003}:9003/tcp
      - ${PORT__OP_NODE_HTTP:-9545}:9545
    extra_hosts:
      - "host.docker.internal:host-gateway"

  bedrock-init:
    build:
      context: ./docker/dockerfiles
      dockerfile: Dockerfile.bedrock-init
    entrypoint: /scripts/init-bedrock.sh
    env_file:
      - ./envs/${NETWORK_NAME}/op-geth.env
      - .env
    volumes:
      - ./scripts/:/scripts
      - shared:/shared
      - op_geth:/geth
      - geth:/legacy-geth
      - torrent_downloads:/downloads

  prometheus:
    image: prom/prometheus:${IMAGE_TAG__PROMETHEUS:-latest}
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - ./docker/prometheus:/etc/prometheus
      - prometheus_data:/prometheus
    ports:
      - ${PORT__PROMETHEUS:-9090}:9090

  grafana:
    image: grafana/grafana:${IMAGE_TAG__GRAFANA:-9.3.0}
    restart: unless-stopped
    env_file:
      - ./envs/common/grafana.env
    volumes:
      - ./docker/grafana/provisioning/:/etc/grafana/provisioning/:ro
      - ./docker/grafana/dashboards/simple_node_dashboard.json:/var/lib/grafana/dashboards/simple_node_dashboard.json
      - grafana_data:/var/lib/grafana
    ports:
      - ${PORT__GRAFANA:-3000}:3000

  influxdb:
    image: influxdb:${IMAGE_TAG__INFLUXDB:-1.8}
    restart: unless-stopped
    env_file:
      - ./envs/common/influxdb.env
    volumes:
      - ./docker/influxdb/influx_init.iql:/docker-entrypoint-initdb.d/influx_init.iql
      - influxdb_data:/var/lib/influxdb
    ports:
      - ${PORT__INFLUXDB:-8086}:8086

volumes:
  geth:
  prometheus_data:
  grafana_data:
  influxdb_data:
  shared:
  op_geth:
  torrent_downloads:


================================================
FILE: envs/common/grafana.env
================================================
GF_SECURITY_ADMIN_PASSWORD=ink


================================================
FILE: envs/common/healthcheck.env
================================================
HEALTHCHECK__TARGET_RPC_PROVIDER=http://op-geth:8545


================================================
FILE: envs/common/influxdb.env
================================================
INFLUXDB_HTTP_AUTH_ENABLED=false


================================================
FILE: envs/ink-mainnet/healthcheck.env
================================================
HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://rpc-gel.inkonchain.com


================================================
FILE: envs/ink-mainnet/op-geth.env
================================================
BEDROCK_SEQUENCER_HTTP=https://rpc-gel.inkonchain.com
BEDROCK_DATADIR=/geth


================================================
FILE: envs/ink-mainnet/op-node.env
================================================
OP_NODE_P2P_BOOTNODES="enr:-Iu4QCqTQZVBnbPWXcdUxcakGoCCzCFr5vVzDfNTOr-Pi3KaOJZMXlnqTR9r9p4EemXS8fS59EdQaX8qrkyE01nvsNcBgmlkgnY0gmlwhCIgwYaJc2VjcDI1NmsxoQMW3w0F1AibYelKqJUKaie5RuKc7S9sPfWvH4lSJw4Fo4N0Y3CCIyuDdWRwgiMs"
OP_NODE_P2P_STATIC="/ip4/34.32.193.134/tcp/9003/p2p/16Uiu2HAmECGb1vmBKhgxVHzX2aYkPcmV8CZjpPxrNkRiFA1wa3CN"
OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true


================================================
FILE: envs/ink-sepolia/healthcheck.env
================================================
HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://rpc-gel-sepolia.inkonchain.com


================================================
FILE: envs/ink-sepolia/op-geth.env
================================================
BEDROCK_SEQUENCER_HTTP=https://rpc-gel-sepolia.inkonchain.com
BEDROCK_DATADIR=/geth


================================================
FILE: envs/ink-sepolia/op-node.env
================================================
OP_NODE_P2P_BOOTNODES="enr:-Iu4QN7Ohk84lCZMSAbuPbU1vSMF93J7FUUab2_JBNX8q6wSPBeWrGu85ENsL-s2fcf9gvYc_Eiw8ZzdBzP5i05g9DwBgmlkgnY0gmlwhCP2ulGJc2VjcDI1NmsxoQLqBVn4RC7vvLvOB95odV2bp6zKCQHPw7j60wBG68qGJYN0Y3CCIyuDdWRwgiMs"
OP_NODE_P2P_STATIC="/ip4/35.246.186.81/tcp/9003/p2p/16Uiu2HAmBBC7aADaA9cfMeuHLZLYAdLNwEahKh7kc9WyUrcvPqXz"
OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true


================================================
FILE: progress.sh
================================================
#!/bin/bash

# Make script exit on error and undefined variables
set -eu

# Function to handle errors
error_exit() {
    echo "Error: $1" >&2
    exit 1
}

# Load Environment Variables
if [ -f .env ]; then
    export $(cat .env | grep -v '#' | sed 's/\r$//' | awk '/=/ {print $1}' ) || error_exit "Failed to load .env file"
fi

# Set default RPC URL with error checking
export ETH_RPC_URL=${ETH_RPC_URL:-http://localhost:${PORT__OP_GETH_HTTP:-9993}}
[ -z "$ETH_RPC_URL" ] && error_exit "ETH_RPC_URL is not set"

# Get chain ID with error handling
CHAIN_ID=$(cast chain-id 2>/dev/null) || error_exit "Failed to get chain ID"
echo "Chain ID: $CHAIN_ID"
echo "Sampling, please wait"

# Set L2_URL based on chain ID
echo "Determining L2_URL for chain ID: $CHAIN_ID"
case $CHAIN_ID in
    763373)
        echo "Using Sepolia testnet RPC endpoint"
        L2_URL="https://rpc-gel-sepolia.inkonchain.com"
        ;;
    57073)
        echo "Using mainnet RPC endpoint"
        L2_URL="https://rpc-gel.inkonchain.com/"
        ;;
    *)
        error_exit "Unsupported chain ID: $CHAIN_ID"
        ;;
esac
echo "L2_URL set to: $L2_URL"

echo "Getting initial block number..."
T0=$(cast block-number --rpc-url "$ETH_RPC_URL" 2>/dev/null) || error_exit "Failed to get initial block number"
echo "Initial block: $T0"
echo "Waiting 10 seconds..."
sleep 10
echo "Getting final block number..."
T1=$(cast block-number --rpc-url "$ETH_RPC_URL" 2>/dev/null) || error_exit "Failed to get final block number"
echo "Final block: $T1"

# Calculate blocks per minute
PER_MIN=$(($T1 - $T0))
PER_MIN=$(($PER_MIN * 6))
echo "Blocks per minute: $PER_MIN"

[ $PER_MIN -eq 0 ] && error_exit "Not syncing"

# Get L2 head block with error handling
HEAD=$(cast block-number --rpc-url "$L2_URL" 2>/dev/null) || error_exit "Failed to get L2 block number"
BEHIND=$((HEAD - T1))
[ $BEHIND -lt 0 ] && error_exit "L2 is ahead of local node"

# Calculate time estimates
echo "Calculating time estimates..."
MINUTES=$((BEHIND / PER_MIN))
HOURS=$((MINUTES / 60))

if [ $MINUTES -le 60 ] ; then
   echo "Sync will complete in minutes"
   echo "Minutes until sync completed: $MINUTES"
fi

if [ $MINUTES -gt 60 ] ; then
   echo "Sync will take hours"
   echo "Hours until sync completed: $HOURS"
fi

if [ $HOURS -gt 24 ] ; then
   echo "Sync will take days"
   DAYS=$((HOURS / 24))
   echo "Days until sync complete: $DAYS"
fi


================================================
FILE: scripts/init-bedrock.sh
================================================
#!/bin/bash
set -e

# Import utilities.
source ./scripts/utils.sh

# Common variables.
INITIALIZED_FLAG=/shared/initialized.txt
BEDROCK_JWT_PATH=/shared/jwt.txt
GETH_DATA_DIR=$BEDROCK_DATADIR
TORRENTS_DIR=/torrents/$NETWORK_NAME
BEDROCK_TAR_PATH=/downloads/bedrock.tar
BEDROCK_TMP_PATH=/bedrock-tmp

# Exit early if we've already initialized.
if [ -e "$INITIALIZED_FLAG" ]; then
  echo "Bedrock node already initialized"
  exit 0
fi

echo "Bedrock node needs to be initialized..."
echo "Initializing via download..."

# Fix OP link with hardcoded official OP snapshot
echo "Fetching download link..."

if [ "$NODE_TYPE" = "archive" ]; then
  if [ "$NETWORK_NAME" = "ink-sepolia" ]; then
    SNAPSHOT_FILENAME=$(curl -s https://storage.googleapis.com/raas-op-geth-snapshots-d2a56/datadir-archive/latest)
    BEDROCK_TAR_DOWNLOAD="https://storage.googleapis.com/raas-op-geth-snapshots-d2a56/datadir-archive/$SNAPSHOT_FILENAME"
    echo "Using snapshot file: $SNAPSHOT_FILENAME"
  elif [ "$NETWORK_NAME" = "ink-mainnet" ]; then
    SNAPSHOT_FILENAME=$(curl -s https://storage.googleapis.com/raas-op-geth-snapshots-e2025/datadir-archive/latest)
    BEDROCK_TAR_DOWNLOAD="https://storage.googleapis.com/raas-op-geth-snapshots-e2025/datadir-archive/$SNAPSHOT_FILENAME"
    echo "Using snapshot file: $SNAPSHOT_FILENAME"
  fi
fi

if [ -n "$BEDROCK_TAR_DOWNLOAD" ]; then
  if [[ "$BEDROCK_TAR_DOWNLOAD" == *.zst ]]; then
    BEDROCK_TAR_PATH+=".zst"
  elif [[ "$BEDROCK_TAR_DOWNLOAD" == *.lz4 ]]; then
    BEDROCK_TAR_PATH+=".lz4"
  fi

  echo "Downloading bedrock.tar..."
  download $BEDROCK_TAR_DOWNLOAD $BEDROCK_TAR_PATH

  echo "Extracting bedrock.tar..."
  if [[ "$BEDROCK_TAR_DOWNLOAD" == *.zst ]]; then
    extractzst $BEDROCK_TAR_PATH $GETH_DATA_DIR
  elif [[ "$BEDROCK_TAR_DOWNLOAD" == *.lz4 ]]; then
    extractlz4 $BEDROCK_TAR_PATH $GETH_DATA_DIR
  else
    extract $BEDROCK_TAR_PATH $GETH_DATA_DIR
  fi

  # Remove tar file to save disk space
  rm $BEDROCK_TAR_PATH
fi

echo "Creating JWT..."
mkdir -p $(dirname $BEDROCK_JWT_PATH)
openssl rand -hex 32 > $BEDROCK_JWT_PATH

echo "Creating Bedrock flag..."
touch $INITIALIZED_FLAG


================================================
FILE: scripts/start-op-geth.sh
================================================
#!/bin/sh
set -e

# Wait for the Bedrock flag for this network to be set.
echo "Waiting for Bedrock node to initialize..."
while [ ! -f /shared/initialized.txt ]; do
  sleep 1
done

# Override Holocene
if [ ! -z "$OVERRIDE_HOLOCENE" ]; then
  EXTENDED_ARG="$EXTENDED_ARG --override.holocene=$OVERRIDE_HOLOCENE"
fi

# Start op-geth.
exec geth \
  --op-network=$NETWORK_NAME \
  --datadir="$BEDROCK_DATADIR" \
  --http \
  --http.corsdomain="*" \
  --http.vhosts="*" \
  --http.addr=0.0.0.0 \
  --http.port=8545 \
  --http.api=eth,engine,web3,debug,net \
  --metrics \
  --metrics.influxdb \
  --metrics.influxdb.endpoint=http://influxdb:8086 \
  --metrics.influxdb.database=opgeth \
  --authrpc.vhosts="*" \
  --authrpc.addr=0.0.0.0 \
  --authrpc.port=8551 \
  --authrpc.jwtsecret=/shared/jwt.txt \
  --rollup.sequencerhttp="$BEDROCK_SEQUENCER_HTTP" \
  --rollup.disabletxpoolgossip=true \
  --port="${PORT__OP_GETH_P2P:-39393}" \
  --discovery.port="${PORT__OP_GETH_P2P:-39393}" \
  --db.engine=pebble \
  --state.scheme=hash \
  --txlookuplimit=0 \
  --history.state=0 \
  --history.transactions=0 \
  --txpool.pricebump=10 \
  --txpool.lifetime=12h0m0s \
  --rpc.txfeecap=4 \
  --rpc.evmtimeout=0 \
  --maxpeers=0 \
  --nodiscover \
  --gpo.percentile=60 \
  --verbosity=3 \
  --syncmode="full" \
  --gcmode="$NODE_TYPE" \
  $EXTENDED_ARG $@


================================================
FILE: scripts/start-op-node.sh
================================================
#!/bin/sh
set -e

# Wait for the Bedrock flag for this network to be set.
echo "Waiting for Bedrock node to initialize..."
while [ ! -f /shared/initialized.txt ]; do
  sleep 1
done

export EXTENDED_ARG="${EXTENDED_ARG:-} --network=$NETWORK_NAME --rollup.load-protocol-versions=true --rollup.halt=major"

# Override Holocene
if [ ! -z "$OVERRIDE_HOLOCENE" ]; then
  EXTENDED_ARG="$EXTENDED_ARG --override.holocene=$OVERRIDE_HOLOCENE"
fi

# Start op-node.
exec op-node \
  --l1=$OP_NODE__RPC_ENDPOINT \
  --l2=http://op-geth:8551 \
  --rpc.addr=0.0.0.0 \
  --rpc.port=9545 \
  --l2.jwt-secret=/shared/jwt.txt \
  --l1.trustrpc \
  --l1.rpckind=$OP_NODE__RPC_TYPE \
  --l1.beacon=$OP_NODE__L1_BEACON \
  --metrics.enabled \
  --metrics.addr=0.0.0.0 \
  --metrics.port=7300 \
  --syncmode=consensus-layer \
  --p2p.scoring=none \
  --p2p.listen.ip=0.0.0.0 \
  --p2p.listen.tcp=9222 \
  --p2p.listen.udp=9222 \
  $EXTENDED_ARG $@


================================================
FILE: scripts/utils.sh
================================================
#!/bin/bash

# extract: Extracts an archive into an output location.
# Arguments:
#   arc: Archive to extract.
#   loc: Location to extract to.
function extract() {
  mkdir -p $2
  tar -xf $1 -C $2
}

# extractzst: Extracts a zst archive into an output location.
# Arguments:
#   arc: ZST archive to extract.
#   loc: Location to extract to.
function extractzst() {
  mkdir -p $2
  tar --use-compress-program=unzstd -xf $1 -C $2
}

# extractlz4: Extracts a lz4 archive into an output location.
# Arguments:
#   arc: lz4 archive to extract.
#   loc: Location to extract to.
function extractlz4() {
  mkdir -p $2
  tar --use-compress-program="lz4 --no-crc" -xf $1 -C $2
}

# download: Downloads a file and provides basic progress percentages.
# Arguments:
#   url: URL of the file to download.
#   out: Location to download the file to.
function download() {
  aria2c --max-tries=0 -x 16 -s 16 -k100M -o $2 $1
}
Download .txt
gitextract_h6bn2w4t/

├── .github/
│   └── workflows/
│       └── securesdlc.yml
├── .gitignore
├── LICENSE
├── README.md
├── 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
├── docker-compose.yml
├── envs/
│   ├── common/
│   │   ├── grafana.env
│   │   ├── healthcheck.env
│   │   └── influxdb.env
│   ├── ink-mainnet/
│   │   ├── healthcheck.env
│   │   ├── op-geth.env
│   │   └── op-node.env
│   └── ink-sepolia/
│       ├── healthcheck.env
│       ├── op-geth.env
│       └── op-node.env
├── progress.sh
└── scripts/
    ├── init-bedrock.sh
    ├── start-op-geth.sh
    ├── start-op-node.sh
    └── utils.sh
Condensed preview — 25 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (52K chars).
[
  {
    "path": ".github/workflows/securesdlc.yml",
    "chars": 843,
    "preview": "name: Nautilus SecureSDLC Reusable\nrun-name: \"[Nautilus SecureSDLC Reusable] Ref:${{ github.ref_name }} Event:${{ github"
  },
  {
    "path": ".gitignore",
    "chars": 31,
    "preview": ".env\n.env.sepolia\n.env.mainnet\n"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "(The MIT License)\n\nCopyright 2020-2022 Optimism\n\nPermission is hereby granted, free of charge, to any person obtaining\na"
  },
  {
    "path": "README.md",
    "chars": 6462,
    "preview": "# Ink Node\n\n> Forked and customized from https://github.com/smartcontracts/simple-optimism-node\n\nA simple docker compose"
  },
  {
    "path": "docker/dockerfiles/Dockerfile.bedrock-init",
    "chars": 537,
    "preview": "FROM ubuntu:22.04\n\n# Disable prompts during package installation.\nARG DEBIAN_FRONTEND=noninteractive\n\n# Install required"
  },
  {
    "path": "docker/grafana/dashboards/simple_node_dashboard.json",
    "chars": 24728,
    "preview": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n  "
  },
  {
    "path": "docker/grafana/provisioning/dashboards/all.yml",
    "chars": 111,
    "preview": "- name: 'default'\n  org_id: 1\n  folder: ''\n  type: 'file'\n  options:\n    folder: '/var/lib/grafana/dashboards'\n"
  },
  {
    "path": "docker/grafana/provisioning/datasources/all.yml",
    "chars": 500,
    "preview": "apiVersion: 1\n\ndeleteDatasources:\n  - name: \"Prometheus\"\n  - name: \"InfluxDB\"\n\ndatasources:\n  - access: \"proxy\"\n    edit"
  },
  {
    "path": "docker/influxdb/influx_init.iql",
    "chars": 25,
    "preview": "CREATE DATABASE \"opgeth\"\n"
  },
  {
    "path": "docker/prometheus/prometheus.yml",
    "chars": 331,
    "preview": "global:\n  scrape_interval:     15s\n  evaluation_interval: 15s\n\nscrape_configs:\n  - job_name: 'healthcheck'\n    static_co"
  },
  {
    "path": "docker-compose.yml",
    "chars": 3062,
    "preview": "services:\n  healthcheck:\n    image: ethereumoptimism/replica-healthcheck:${IMAGE_TAG__HEALTHCHECK:-latest}\n    restart: "
  },
  {
    "path": "envs/common/grafana.env",
    "chars": 31,
    "preview": "GF_SECURITY_ADMIN_PASSWORD=ink\n"
  },
  {
    "path": "envs/common/healthcheck.env",
    "chars": 53,
    "preview": "HEALTHCHECK__TARGET_RPC_PROVIDER=http://op-geth:8545\n"
  },
  {
    "path": "envs/common/influxdb.env",
    "chars": 33,
    "preview": "INFLUXDB_HTTP_AUTH_ENABLED=false\n"
  },
  {
    "path": "envs/ink-mainnet/healthcheck.env",
    "chars": 67,
    "preview": "HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://rpc-gel.inkonchain.com\n"
  },
  {
    "path": "envs/ink-mainnet/op-geth.env",
    "chars": 76,
    "preview": "BEDROCK_SEQUENCER_HTTP=https://rpc-gel.inkonchain.com\nBEDROCK_DATADIR=/geth\n"
  },
  {
    "path": "envs/ink-mainnet/op-node.env",
    "chars": 367,
    "preview": "OP_NODE_P2P_BOOTNODES=\"enr:-Iu4QCqTQZVBnbPWXcdUxcakGoCCzCFr5vVzDfNTOr-Pi3KaOJZMXlnqTR9r9p4EemXS8fS59EdQaX8qrkyE01nvsNcBg"
  },
  {
    "path": "envs/ink-sepolia/healthcheck.env",
    "chars": 75,
    "preview": "HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://rpc-gel-sepolia.inkonchain.com\n"
  },
  {
    "path": "envs/ink-sepolia/op-geth.env",
    "chars": 84,
    "preview": "BEDROCK_SEQUENCER_HTTP=https://rpc-gel-sepolia.inkonchain.com\nBEDROCK_DATADIR=/geth\n"
  },
  {
    "path": "envs/ink-sepolia/op-node.env",
    "chars": 367,
    "preview": "OP_NODE_P2P_BOOTNODES=\"enr:-Iu4QN7Ohk84lCZMSAbuPbU1vSMF93J7FUUab2_JBNX8q6wSPBeWrGu85ENsL-s2fcf9gvYc_Eiw8ZzdBzP5i05g9DwBg"
  },
  {
    "path": "progress.sh",
    "chars": 2385,
    "preview": "#!/bin/bash\n\n# Make script exit on error and undefined variables\nset -eu\n\n# Function to handle errors\nerror_exit() {\n   "
  },
  {
    "path": "scripts/init-bedrock.sh",
    "chars": 2133,
    "preview": "#!/bin/bash\nset -e\n\n# Import utilities.\nsource ./scripts/utils.sh\n\n# Common variables.\nINITIALIZED_FLAG=/shared/initiali"
  },
  {
    "path": "scripts/start-op-geth.sh",
    "chars": 1344,
    "preview": "#!/bin/sh\nset -e\n\n# Wait for the Bedrock flag for this network to be set.\necho \"Waiting for Bedrock node to initialize.."
  },
  {
    "path": "scripts/start-op-node.sh",
    "chars": 925,
    "preview": "#!/bin/sh\nset -e\n\n# Wait for the Bedrock flag for this network to be set.\necho \"Waiting for Bedrock node to initialize.."
  },
  {
    "path": "scripts/utils.sh",
    "chars": 910,
    "preview": "#!/bin/bash\n\n# extract: Extracts an archive into an output location.\n# Arguments:\n#   arc: Archive to extract.\n#   loc: "
  }
]

About this extraction

This page contains the full source code of the inkonchain/node GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 25 files (45.5 KB), approximately 13.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!