├── .env ├── .env.mainnet ├── .env.sepolia ├── .github └── workflows │ ├── docker.yml │ └── pr.yml ├── .gitignore ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── SECURITY.md ├── docker-compose.yml ├── geth-entrypoint ├── logo.webp ├── mainnet ├── genesis-l2.json └── rollup.json ├── op-node-entrypoint ├── sepolia ├── genesis-l2.json └── rollup.json └── supervisord.conf /.env: -------------------------------------------------------------------------------- 1 | GETH_HOST_DATA_DIR=./geth-data -------------------------------------------------------------------------------- /.env.mainnet: -------------------------------------------------------------------------------- 1 | OP_GETH_GENESIS_FILE_PATH=mainnet/genesis-l2.json 2 | OP_GETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org 3 | 4 | # [optional] used to enable geth stats: 5 | # OP_GETH_ETH_STATS=nodename:secret@host:port 6 | 7 | # [required] replace with your preferred L1 (Ethereum, not Base) node RPC URL: 8 | OP_NODE_L1_ETH_RPC=https://1rpc.io/eth 9 | 10 | # [required] replace with your preferred L1 CL beacon endpoint: 11 | OP_NODE_L1_BEACON=https://your.mainnet.beacon.node/endpoint-here 12 | 13 | # auth secret used by op-geth engine API: 14 | OP_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a 15 | 16 | OP_NODE_BETA_EXTRA_NETWORKS=true 17 | OP_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt 18 | OP_NODE_L2_ENGINE_RPC=ws://geth:8551 19 | OP_NODE_LOG_LEVEL=info 20 | OP_NODE_METRICS_ADDR=0.0.0.0 21 | OP_NODE_METRICS_ENABLED=true 22 | OP_NODE_METRICS_PORT=7300 23 | OP_NODE_NETWORK=base-mainnet 24 | OP_NODE_P2P_AGENT=base 25 | 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 26 | OP_NODE_P2P_LISTEN_IP=0.0.0.0 27 | OP_NODE_P2P_LISTEN_TCP_PORT=9222 28 | OP_NODE_P2P_LISTEN_UDP_PORT=9222 29 | OP_NODE_ROLLUP_CONFIG=mainnet/rollup.json 30 | OP_NODE_RPC_ADDR=0.0.0.0 31 | OP_NODE_RPC_PORT=8545 32 | OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log 33 | OP_NODE_VERIFIER_L1_CONFS=4 34 | OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true 35 | 36 | # OP_NODE_L1_TRUST_RPC allows for faster syncing, but should be used *only* if your L1 RPC node 37 | # is fully trusted. It also allows op-node to work with clients such as Erigon that do not 38 | # support storage proofs: 39 | # OP_NODE_L1_TRUST_RPC=true 40 | 41 | # SNAP SYNC 42 | # NOTE: This feature is experimental and may lead to syncing issues, delays or difficulties as a result of inability to find peers. We recommend running a full or archive node for production purposes. 43 | # To enable snap sync, uncomment and set the env vars below: 44 | # OP_NODE_SYNCMODE=execution-layer 45 | # OP_GETH_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 46 | # OP_GETH_SYNCMODE=snap 47 | -------------------------------------------------------------------------------- /.env.sepolia: -------------------------------------------------------------------------------- 1 | OP_GETH_GENESIS_FILE_PATH=sepolia/genesis-l2.json 2 | OP_GETH_SEQUENCER_HTTP=https://sepolia-sequencer.base.org 3 | 4 | # [optional] used to enable geth stats: 5 | # OP_GETH_ETH_STATS=nodename:secret@host:port 6 | 7 | # [required] replace with your preferred L1 (Ethereum, not Base) node RPC URL: 8 | OP_NODE_L1_ETH_RPC=https://rpc.sepolia.org 9 | 10 | # [required] replace with your preferred L1 CL beacon endpoint: 11 | OP_NODE_L1_BEACON=https://your.sepolia.beacon.node/endpoint-here 12 | 13 | # auth secret used by op-geth engine API: 14 | OP_NODE_L2_ENGINE_AUTH_RAW=688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a 15 | 16 | OP_NODE_BETA_EXTRA_NETWORKS=true 17 | OP_NODE_L2_ENGINE_AUTH=/tmp/engine-auth-jwt 18 | OP_NODE_L2_ENGINE_RPC=ws://geth:8551 19 | OP_NODE_LOG_LEVEL=info 20 | OP_NODE_METRICS_ADDR=0.0.0.0 21 | OP_NODE_METRICS_ENABLED=true 22 | OP_NODE_METRICS_PORT=7300 23 | OP_NODE_NETWORK=base-sepolia 24 | OP_NODE_P2P_AGENT=base 25 | OP_NODE_P2P_BOOTNODES=enr:-J64QBwRIWAco7lv6jImSOjPU_W266lHXzpAS5YOh7WmgTyBZkgLgOwo_mxKJq3wz2XRbsoBItbv1dCyjIoNq67mFguGAYrTxM42gmlkgnY0gmlwhBLSsHKHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDmoWSi8hcsRpQf2eJsNUx-sqv6fH4btmo2HsAzZFAKnKDdGNwgiQGg3VkcIIkBg,enr:-J64QFa3qMsONLGphfjEkeYyF6Jkil_jCuJmm7_a42ckZeUQGLVzrzstZNb1dgBp1GGx9bzImq5VxJLP-BaptZThGiWGAYrTytOvgmlkgnY0gmlwhGsV-zeHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDahfSECTIS_cXyZ8IyNf4leANlZnrsMEWTkEYxf4GMCmDdGNwgiQGg3VkcIIkBg 26 | OP_NODE_P2P_LISTEN_IP=0.0.0.0 27 | OP_NODE_P2P_LISTEN_TCP_PORT=9222 28 | OP_NODE_P2P_LISTEN_UDP_PORT=9222 29 | OP_NODE_ROLLUP_CONFIG=sepolia/rollup.json 30 | OP_NODE_RPC_ADDR=0.0.0.0 31 | OP_NODE_RPC_PORT=8545 32 | OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log 33 | OP_NODE_VERIFIER_L1_CONFS=4 34 | OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true 35 | 36 | # OP_NODE_L1_TRUST_RPC allows for faster syncing, but should be used *only* if your L1 RPC node 37 | # is fully trusted. It also allows op-node to work with clients such as Erigon that do not 38 | # support storage proofs: 39 | # OP_NODE_L1_TRUST_RPC=true 40 | 41 | # SNAP SYNC 42 | # NOTE: This feature is experimental and may lead to syncing issues, delays or difficulties as a result of inability to find peers. We recommend running a full or archive node for production purposes. 43 | # To enable snap sync, set env vars below: 44 | # OP_NODE_SYNCMODE=execution-layer 45 | # OP_GETH_BOOTNODES=enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301,enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301 46 | # OP_GETH_SYNCMODE=snap 47 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Tag Docker image 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | tags: 8 | - 'v*' 9 | 10 | env: 11 | REGISTRY: ghcr.io 12 | IMAGE_NAME: ${{ github.repository }} 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | 21 | - name: Log into the Container registry 22 | uses: docker/login-action@v3 23 | with: 24 | registry: ${{ env.REGISTRY }} 25 | username: ${{ github.actor }} 26 | password: ${{ secrets.GITHUB_TOKEN }} 27 | 28 | - name: Extract metadata for the Docker image 29 | id: meta 30 | uses: docker/metadata-action@v4 31 | with: 32 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 33 | 34 | - name: Set up Docker Buildx 35 | uses: docker/setup-buildx-action@v3 36 | 37 | - name: Build and push the Docker image 38 | uses: docker/build-push-action@v4 39 | with: 40 | context: . 41 | push: true 42 | tags: ${{ steps.meta.outputs.tags }} 43 | labels: ${{ steps.meta.outputs.labels }} 44 | platforms: linux/amd64,linux/arm64 45 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | arch: [ linux/amd64, linux/arm64 ] 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v3 15 | with: 16 | ref: ${{ github.event.pull_request.head.sha }} 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v3 19 | - name: Build the Docker image 20 | uses: docker/build-push-action@v4 21 | with: 22 | context: . 23 | push: false 24 | platforms: ${{ matrix.arch }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /geth-data/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Base Node 2 | 3 | ## Code of Conduct 4 | 5 | All interactions with this project follow our [Code of Conduct][code-of-conduct]. 6 | By participating, you are expected to honor this code. Violators can be banned 7 | from further participation in this project, or potentially all Base and/or 8 | Coinbase 9 | projects. 10 | 11 | [code-of-conduct]: https://github.com/coinbase/code-of-conduct 12 | 13 | ## Bug Reports 14 | 15 | * Ensure your issue [has not already been reported][1]. It may already be fixed! 16 | * Include the steps you carried out to produce the problem. 17 | * Include the behavior you observed along with the behavior you expected, and 18 | why you expected it. 19 | * Include any relevant stack traces or debugging output. 20 | 21 | ## Feature Requests 22 | 23 | We welcome feedback with or without pull requests. If you have an idea for how 24 | to improve the project, great! All we ask is that you take the time to write a 25 | clear and concise explanation of what need you are trying to solve. If you have 26 | thoughts on _how_ it can be solved, include those too! 27 | 28 | The best way to see a feature added, however, is to submit a pull request. 29 | 30 | ## Pull Requests 31 | 32 | * Before creating your pull request, it's usually worth asking if the code 33 | you're planning on writing will actually be considered for merging. You can 34 | do this by [opening an issue][1] and asking. It may also help give the 35 | maintainers context for when the time comes to review your code. 36 | 37 | * Ensure your [commit messages are well-written][2]. This can double as your 38 | pull request message, so it pays to take the time to write a clear message. 39 | 40 | * Add tests for your feature. You should be able to look at other tests for 41 | examples. If you're unsure, don't hesitate to [open an issue][1] and ask! 42 | 43 | * Submit your pull request! 44 | 45 | ## Support Requests 46 | 47 | For security reasons, any communication referencing support tickets for Coinbase 48 | products will be ignored. The request will have its content redacted and will 49 | be locked to prevent further discussion. 50 | 51 | All support requests must be made via [our support team][3]. 52 | 53 | [1]: https://github.com/base-org/node/issues 54 | [2]: https://medium.com/brigade-engineering/the-secrets-to-great-commit-messages-106fc0a92a25 55 | [3]: https://support.coinbase.com/customer/en/portal/articles/2288496-how-can-i-contact-coinbase-support- 56 | 57 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.21 as op 2 | 3 | WORKDIR /app 4 | 5 | ENV REPO=https://github.com/ethereum-optimism/optimism.git 6 | ENV VERSION=v1.7.6 7 | # for verification: 8 | ENV COMMIT=4a487b8920daa9dc4b496d691d5f283f9bb659b1 9 | 10 | RUN git clone $REPO --branch op-node/$VERSION --single-branch . && \ 11 | git switch -c branch-$VERSION && \ 12 | bash -c '[ "$(git rev-parse HEAD)" = "$COMMIT" ]' 13 | 14 | RUN cd op-node && \ 15 | make VERSION=$VERSION op-node 16 | 17 | FROM golang:1.21 as geth 18 | 19 | WORKDIR /app 20 | 21 | ENV REPO=https://github.com/ethereum-optimism/op-geth.git 22 | ENV VERSION=v1.101315.1 23 | # for verification: 24 | ENV COMMIT=3fbae78d638d1b903e702a14f98644c1103ae1b3 25 | 26 | # avoid depth=1, so the geth build can read tags 27 | RUN git clone $REPO --branch $VERSION --single-branch . && \ 28 | git switch -c branch-$VERSION && \ 29 | bash -c '[ "$(git rev-parse HEAD)" = "$COMMIT" ]' 30 | 31 | RUN go run build/ci.go install -static ./cmd/geth 32 | 33 | FROM golang:1.21 34 | 35 | RUN apt-get update && \ 36 | apt-get install -y jq curl supervisor && \ 37 | rm -rf /var/lib/apt/lists 38 | RUN mkdir -p /var/log/supervisor 39 | 40 | WORKDIR /app 41 | 42 | COPY --from=op /app/op-node/bin/op-node ./ 43 | COPY --from=geth /app/build/bin/geth ./ 44 | COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf 45 | COPY geth-entrypoint . 46 | COPY op-node-entrypoint . 47 | COPY sepolia ./sepolia 48 | COPY mainnet ./mainnet 49 | 50 | CMD ["/usr/bin/supervisord"] 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2024 base.org contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Base](logo.webp) 2 | 3 | # Base node 4 | 5 | Base is a secure, low-cost, developer-friendly Ethereum L2 built to bring the next billion users onchain. It's built on Optimism’s open-source [OP Stack](https://stack.optimism.io/). 6 | 7 | This repository contains the relevant Docker builds to run your own node on the Base network. 8 | 9 | 10 | 11 | [![GitHub contributors](https://img.shields.io/github/contributors/base-org/node)](https://github.com/base-org/node/graphs/contributors) 12 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/w/base-org/node)](https://github.com/base-org/node/graphs/contributors) 13 | [![GitHub Stars](https://img.shields.io/github/stars/base-org/node.svg)](https://github.com/base-org/node/stargazers) 14 | ![GitHub repo size](https://img.shields.io/github/repo-size/base-org/node) 15 | [![GitHub](https://img.shields.io/github/license/base-org/node?color=blue)](https://github.com/base-org/node/blob/main/LICENSE) 16 | 17 | 18 | 19 | [![Website base.org](https://img.shields.io/website-up-down-green-red/https/base.org.svg)](https://base.org) 20 | [![Blog](https://img.shields.io/badge/blog-up-green)](https://base.mirror.xyz/) 21 | [![Docs](https://img.shields.io/badge/docs-up-green)](https://docs.base.org/) 22 | [![Discord](https://img.shields.io/discord/1067165013397213286?label=discord)](https://base.org/discord) 23 | [![Twitter Base](https://img.shields.io/twitter/follow/Base?style=social)](https://twitter.com/Base) 24 | 25 | 26 | 27 | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr-raw/base-org/node)](https://github.com/base-org/node/pulls) 28 | [![GitHub Issues](https://img.shields.io/github/issues-raw/base-org/node.svg)](https://github.com/base-org/node/issues) 29 | 30 | ### Hardware requirements 31 | 32 | We recommend you have this hardware configuration to run a node: 33 | 34 | - a modern multi-core CPU with good single-core performance 35 | - at least 16 GB RAM (32 GB recommended) 36 | - a high performance SSD drive with at least 4 TB free (NVME recommended) 37 | 38 | ### Troubleshooting 39 | 40 | If you encounter problems with your node, please open a [GitHub issue](https://github.com/base-org/node/issues/new/choose) or reach out on our [Discord](https://discord.gg/buildonbase): 41 | 42 | - Once you've joined, in the Discord app go to `server menu` > `Linked Roles` > `connect GitHub` and connect your GitHub account so you can gain access to our developer channels 43 | - Report your issue in `#🛟|node-support` 44 | 45 | ### Supported networks 46 | 47 | | Ethereum Network | Status | 48 | |------------------| ------ | 49 | | Sepolia testnet | ✅ | 50 | | Mainnet | ✅ | 51 | 52 | ### Usage 53 | 54 | 1. Ensure you have an Ethereum L1 full node RPC available (not Base), and set `OP_NODE_L1_ETH_RPC` (in the `.env.*` file if using docker-compose). If running your own L1 node, it needs to be synced before Base will be able to fully sync. 55 | 2. Uncomment the line relevant to your network (`.env.sepolia`, or `.env.mainnet`) under the 2 `env_file` keys in `docker-compose.yml`. 56 | 3. Run: 57 | 58 | ``` 59 | docker compose up --build 60 | ``` 61 | 62 | 4. You should now be able to `curl` your Base node: 63 | 64 | ``` 65 | curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \ 66 | -H "Content-Type: application/json" http://localhost:8545 67 | ``` 68 | 69 | Note: Some L1 nodes (e.g. Erigon) do not support fetching storage proofs. You can work around this by specifying `--l1.trustrpc` when starting op-node (add it in `op-node-entrypoint` and rebuild the docker image with `docker compose build`.) Do not do this unless you fully trust the L1 node provider. 70 | 71 | 72 | #### Persisting Data 73 | 74 | By default, the data directory is stored in `${PROJECT_ROOT}/geth-data`. You can override this by modifying the value of 75 | `GETH_HOST_DATA_DIR` variable in the [`.env`](./.env) file. 76 | 77 | To load a [snapshot](#snapshots) you can extract the snapshot into the `$GETH_HOST_DATA_DIR` folder. 78 | 79 | #### Running in single container with `supervisord` 80 | 81 | If you'd like to run the node in a single container instead of `docker-compose`, you can use the `supervisord` entrypoint. 82 | This is useful for running the node in a Kubernetes cluster, for example. 83 | 84 | Note that you'll need to override some of the default configuration that assumes a multi-container environment (`OP_NODE_L2_ENGINE_RPC`) and any port conflicts (`OP_NODE_RPC_PORT`). 85 | Example: 86 | ``` 87 | docker run --env-file .env.sepolia -e OP_NODE_L2_ENGINE_RPC=ws://localhost:8551 -e OP_NODE_RPC_PORT=7545 ghcr.io/base-org/node:latest 88 | ``` 89 | 90 | ### Snapshots 91 | 92 | You can fetch the latest snapshots via the URLs provided in the [Base docs](https://docs.base.org/guides/run-a-base-node/#snapshots). 93 | 94 | ### Syncing 95 | 96 | Sync speed depends on your L1 node, as the majority of the chain is derived from data submitted to the L1. You can check your syncing status using the `optimism_syncStatus` RPC on the `op-node` container. Example: 97 | 98 | ``` 99 | command -v jq &> /dev/null || { echo "jq is not installed" 1>&2 ; } 100 | echo Latest synced block behind by: \ 101 | $((($( date +%s )-\ 102 | $( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:7545 | 103 | jq -r .result.unsafe_l2.timestamp))/60)) minutes 104 | ``` 105 | 106 | ## Disclaimer 107 | 108 | We’re excited for you to build on Base 🔵 — but we want to make sure that you understand the nature of the node software and smart contracts offered here. 109 | 110 | THE NODE SOFTWARE AND SMART CONTRACTS CONTAINED HEREIN ARE FURNISHED AS IS, WHERE IS, WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, NON- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE. IN PARTICULAR, THERE IS NO REPRESENTATION OR WARRANTY THAT THE NODE SOFTWARE AND SMART CONTRACTS WILL PROTECT YOUR ASSETS — OR THE ASSETS OF THE USERS OF YOUR APPLICATION — FROM THEFT, HACKING, CYBER ATTACK, OR OTHER FORM OF LOSS OR DEVALUATION. 111 | 112 | You also understand that using the node software and smart contracts are subject to applicable law, including without limitation, any applicable anti-money laundering laws, anti-terrorism laws, export control laws, end user restrictions, privacy laws, or economic sanctions laws/regulations. 113 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ## Bug bounty program 4 | 5 | In line with our strategy of being the safest way for users to access crypto: 6 | 7 | + Coinbase will be extending our [best-in-industry][1] million-dollar [HackerOne bug bounty program][2] 8 | to cover the Base network, the Base bridge contracts, and Base infrastructure. 9 | 10 | + Coinbase will be working in tandem with OP Labs to harden the security 11 | guarantees of Bedrock and accelerate the timeline for decentralized 12 | fault-proofs on the [OP Stack][3]. 13 | 14 | + Coinbase's bug bounty program will run alongside Optimism's existing [Immunefi Bedrock bounty program][4] 15 | to support the open source [Bedrock][5] OP Stack framework. 16 | 17 | ## Reporting vulnerabilities 18 | 19 | All potential vulnerability reports can be submitted via the [HackerOne][6] 20 | platform. 21 | 22 | The HackerOne platform allows us to have a centralized and single reporting 23 | source for us to deliver optimized SLA's and results. All reports submitted to 24 | the platform are triaged around the clock by our team of Coinbase engineers 25 | with domain knowledge, assuring the best quality of review. 26 | 27 | For more information on reporting vulnerabilities and our HackerOne bug bounty 28 | program, view our [security program policies][7]. 29 | 30 | [1]: https://www.coinbase.com/blog/celebrating-10-years-of-our-bug-bounty-program 31 | [2]: https://hackerone.com/coinbase?type=team 32 | [3]: https://stack.optimism.io/ 33 | [4]: https://immunefi.com/bounty/optimism/ 34 | [5]: https://stack.optimism.io/docs/releases/bedrock/ 35 | [6]: https://hackerone.com/coinbase 36 | [7]: https://hackerone.com/coinbase?view_policy=true 37 | 38 | 39 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | geth: # this is Optimism's geth client 5 | build: . 6 | ports: 7 | - 8545:8545 # RPC 8 | - 8546:8546 # websocket 9 | - 30303:30303 # P2P TCP (currently unused) 10 | - 30303:30303/udp # P2P UDP (currently unused) 11 | - 7301:6060 # metrics 12 | command: [ "bash", "./geth-entrypoint" ] 13 | volumes: 14 | - ${GETH_HOST_DATA_DIR}:/data 15 | env_file: 16 | # select your network here: 17 | # - .env.sepolia 18 | # - .env.mainnet 19 | node: 20 | build: . 21 | depends_on: 22 | - geth 23 | ports: 24 | - 7545:8545 # RPC 25 | - 9222:9222 # P2P TCP 26 | - 9222:9222/udp # P2P UDP 27 | - 7300:7300 # metrics 28 | - 6060:6060 # pprof 29 | command: [ "bash", "./op-node-entrypoint" ] 30 | env_file: 31 | # select your network here: 32 | # - .env.sepolia 33 | # - .env.mainnet 34 | -------------------------------------------------------------------------------- /geth-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | VERBOSITY=${GETH_VERBOSITY:-3} 5 | GETH_DATA_DIR=/data 6 | RPC_PORT="${RPC_PORT:-8545}" 7 | WS_PORT="${WS_PORT:-8546}" 8 | AUTHRPC_PORT="${AUTHRPC_PORT:-8551}" 9 | METRICS_PORT="${METRICS_PORT:-6060}" 10 | HOST_IP="0.0.0.0" 11 | P2P_PORT="${P2P_PORT:-30303}" 12 | ADDITIONAL_ARGS="" 13 | OP_GETH_GCMODE="${OP_GETH_GCMODE:-full}" 14 | OP_GETH_SYNCMODE="${OP_GETH_SYNCMODE:-full}" 15 | 16 | if [[ -z "$OP_NODE_NETWORK" ]]; then 17 | echo "expected OP_NODE_NETWORK to be set" 1>&2 18 | exit 1 19 | fi 20 | 21 | mkdir -p $GETH_DATA_DIR 22 | 23 | echo "$OP_NODE_L2_ENGINE_AUTH_RAW" > "$OP_NODE_L2_ENGINE_AUTH" 24 | 25 | if [ "${OP_GETH_ETH_STATS+x}" = x ]; then 26 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS --ethstats=$OP_GETH_ETH_STATS" 27 | fi 28 | 29 | if [ "${OP_GETH_ALLOW_UNPROTECTED_TXS+x}" = x ]; then 30 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS --rpc.allow-unprotected-txs=$OP_GETH_ALLOW_UNPROTECTED_TXS" 31 | fi 32 | 33 | if [ "${OP_GETH_STATE_SCHEME+x}" = x ]; then 34 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS --state.scheme=$OP_GETH_STATE_SCHEME" 35 | fi 36 | 37 | if [ "${OP_GETH_BOOTNODES+x}" = x ]; then 38 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS --bootnodes=$OP_GETH_BOOTNODES" 39 | fi 40 | 41 | exec ./geth \ 42 | --datadir="$GETH_DATA_DIR" \ 43 | --verbosity="$VERBOSITY" \ 44 | --http \ 45 | --http.corsdomain="*" \ 46 | --http.vhosts="*" \ 47 | --http.addr=0.0.0.0 \ 48 | --http.port="$RPC_PORT" \ 49 | --http.api=web3,debug,eth,net,engine \ 50 | --authrpc.addr=0.0.0.0 \ 51 | --authrpc.port="$AUTHRPC_PORT" \ 52 | --authrpc.vhosts="*" \ 53 | --authrpc.jwtsecret="$OP_NODE_L2_ENGINE_AUTH" \ 54 | --ws \ 55 | --ws.addr=0.0.0.0 \ 56 | --ws.port="$WS_PORT" \ 57 | --ws.origins="*" \ 58 | --ws.api=debug,eth,net,engine \ 59 | --metrics \ 60 | --metrics.addr=0.0.0.0 \ 61 | --metrics.port="$METRICS_PORT" \ 62 | --syncmode="$OP_GETH_SYNCMODE" \ 63 | --gcmode="$OP_GETH_GCMODE" \ 64 | --maxpeers=100 \ 65 | --nat=extip:$HOST_IP \ 66 | --rollup.sequencerhttp="$OP_GETH_SEQUENCER_HTTP" \ 67 | --rollup.halt=major \ 68 | --op-network="$OP_NODE_NETWORK" \ 69 | --port="$P2P_PORT" \ 70 | --rollup.disabletxpoolgossip=true \ 71 | $ADDITIONAL_ARGS # intentionally unquoted 72 | -------------------------------------------------------------------------------- /logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/touchasky/node-base/d3770e1a1e948a7215d75bc128c01dc095858d2b/logo.webp -------------------------------------------------------------------------------- /mainnet/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 | } 30 | -------------------------------------------------------------------------------- /op-node-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | get_public_ip() { 5 | # Define a list of HTTP-based providers 6 | local PROVIDERS=( 7 | "http://ifconfig.me" 8 | "http://api.ipify.org" 9 | "http://ipecho.net/plain" 10 | "http://v4.ident.me" 11 | ) 12 | # Iterate through the providers until an IP is found or the list is exhausted 13 | for provider in "${PROVIDERS[@]}"; do 14 | local IP 15 | IP=$(curl -s "$provider") 16 | # Check if IP contains a valid format (simple regex for an IPv4 address) 17 | if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 18 | echo "$IP" 19 | return 0 20 | fi 21 | done 22 | return 1 23 | } 24 | 25 | if [[ -z "$OP_NODE_NETWORK" ]]; then 26 | echo "expected OP_NODE_NETWORK to be set" 1>&2 27 | exit 1 28 | fi 29 | 30 | # wait until local geth comes up (authed so will return 401 without token) 31 | until [ "$(curl -s -w '%{http_code}' -o /dev/null "${OP_NODE_L2_ENGINE_RPC/ws/http}")" -eq 401 ]; do 32 | echo "waiting for geth to be ready" 33 | sleep 5 34 | done 35 | 36 | # public-facing P2P node, advertise public IP address 37 | if PUBLIC_IP=$(get_public_ip); then 38 | echo "fetched public IP is: $PUBLIC_IP" 39 | else 40 | echo "Could not retrieve public IP." 41 | exit 8 42 | fi 43 | export OP_NODE_P2P_ADVERTISE_IP=$PUBLIC_IP 44 | 45 | echo "$OP_NODE_L2_ENGINE_AUTH_RAW" > "$OP_NODE_L2_ENGINE_AUTH" 46 | 47 | exec ./op-node 48 | -------------------------------------------------------------------------------- /sepolia/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 | } 31 | -------------------------------------------------------------------------------- /supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | logfile=/dev/null 4 | logfile_maxbytes=0 5 | 6 | [program:op-node] 7 | command=/app/op-node-entrypoint 8 | stdout_logfile=/dev/fd/1 9 | stdout_logfile_maxbytes=0 10 | redirect_stderr=true 11 | stopwaitsecs=300 12 | 13 | [program:op-geth] 14 | command=/app/geth-entrypoint 15 | stdout_logfile=/dev/fd/1 16 | stdout_logfile_maxbytes=0 17 | redirect_stderr=true 18 | stopwaitsecs=300 19 | --------------------------------------------------------------------------------