diff --git a/app/data/compose/docker-compose-fixturenet-eth.yml b/app/data/compose/docker-compose-fixturenet-eth.yml index 978b983f..c51550cc 100644 --- a/app/data/compose/docker-compose-fixturenet-eth.yml +++ b/app/data/compose/docker-compose-fixturenet-eth.yml @@ -24,6 +24,8 @@ services: env_file: - ../config/fixturenet-eth/fixturenet-eth.env image: cerc/fixturenet-eth-geth:local + volumes: + - fixturenet-geth-accounts:/opt/testnet/build/el healthcheck: test: ["CMD", "nc", "-v", "localhost", "8545"] interval: 30s @@ -56,6 +58,12 @@ services: environment: RUN_BOOTNODE: "true" image: cerc/fixturenet-eth-lighthouse:local + healthcheck: + test: ["CMD", "/scripts/status-internal.sh"] + interval: 10s + timeout: 100s + retries: 3 + start_period: 15s fixturenet-eth-lighthouse-1: hostname: fixturenet-eth-lighthouse-1 @@ -79,7 +87,7 @@ services: condition: service_healthy ports: - "8001" - + fixturenet-eth-lighthouse-2: hostname: fixturenet-eth-lighthouse-2 healthcheck: @@ -101,3 +109,6 @@ services: condition: service_started fixturenet-eth-geth-2: condition: service_healthy + +volumes: + fixturenet-geth-accounts: diff --git a/app/data/compose/docker-compose-fixturenet-optimism.yml b/app/data/compose/docker-compose-fixturenet-optimism.yml new file mode 100644 index 00000000..6e65c46f --- /dev/null +++ b/app/data/compose/docker-compose-fixturenet-optimism.yml @@ -0,0 +1,97 @@ +version: '3.7' + +services: + fixturenet-optimism-contracts: + hostname: fixturenet-optimism-contracts + image: cerc/optimism-contracts:local + depends_on: + fixturenet-eth-geth-1: + condition: service_healthy + fixturenet-eth-bootnode-lighthouse: + condition: service_healthy + environment: + CHAIN_ID: 1212 + L1_RPC: "http://fixturenet-eth-geth-1:8545" + command: "./run.sh" + volumes: + - ../config/fixturenet-optimism/optimism-contracts/rekey-json.ts:/app/packages/contracts-bedrock/tasks/rekey-json.ts + - ../config/fixturenet-optimism/optimism-contracts/send-balance.ts:/app/packages/contracts-bedrock/tasks/send-balance.ts + - ../config/fixturenet-optimism/optimism-contracts/update-config.js:/app/packages/contracts-bedrock/update-config.js + - ../config/fixturenet-optimism/optimism-contracts/run.sh:/app/packages/contracts-bedrock/run.sh + - fixturenet-geth-accounts:/geth-accounts:ro + - l2-accounts:/l2-accounts + - l1-deployment:/app/packages/contracts-bedrock + + op-node-l2-config-gen: + image: cerc/optimism-op-node:local + depends_on: + fixturenet-optimism-contracts: + condition: service_completed_successfully + environment: + L1_RPC: "http://fixturenet-eth-geth-1:8545" + volumes: + - ../config/fixturenet-optimism/generate-l2-config.sh:/app/generate-l2-config.sh + - l1-deployment:/contracts-bedrock:ro + - op_node_data:/app + command: ["sh", "/app/generate-l2-config.sh"] + + op-geth: + image: cerc/optimism-l2geth:local + depends_on: + op-node-l2-config-gen: + condition: service_started + volumes: + - ../config/fixturenet-optimism/run-op-geth.sh:/run-op-geth.sh + - op_node_data:/op-node:ro + - l2-accounts:/l2-accounts:ro + entrypoint: "sh" + command: "/run-op-geth.sh" + ports: + - "8545" + healthcheck: + test: ["CMD", "nc", "-vz", "localhost:8545"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 10s + + op-node: + environment: + L1_RPC: "http://fixturenet-eth-geth-1:8545" + depends_on: + op-geth: + condition: service_healthy + image: cerc/optimism-op-node:local + volumes: + - ../config/fixturenet-optimism/run-op-node.sh:/app/run-op-node.sh + - op_node_data:/app:ro + - l2-accounts:/l2-accounts:ro + command: ["sh", "/app/run-op-node.sh"] + ports: + - "8547" + healthcheck: + test: ["CMD", "nc", "-vz", "localhost:8547"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 10s + + op-batcher: + environment: + L1_RPC: "http://fixturenet-eth-geth-1:8545" + depends_on: + op-node: + condition: service_healthy + op-geth: + condition: service_healthy + image: cerc/optimism-op-batcher:local + volumes: + - ../config/fixturenet-optimism/run-op-batcher.sh:/run-op-batcher.sh + - l2-accounts:/l2-accounts:ro + entrypoint: "sh" + command: "/run-op-batcher.sh" + +volumes: + op_node_data: + l2-accounts: + l1-deployment: diff --git a/app/data/config/fixturenet-optimism/generate-l2-config.sh b/app/data/config/fixturenet-optimism/generate-l2-config.sh new file mode 100755 index 00000000..25ed2378 --- /dev/null +++ b/app/data/config/fixturenet-optimism/generate-l2-config.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +op-node genesis l2 \ + --deploy-config /contracts-bedrock/deploy-config/getting-started.json \ + --deployment-dir /contracts-bedrock/deployments/getting-started/ \ + --outfile.l2 /app/genesis.json \ + --outfile.rollup /app/rollup.json \ + --l1-rpc $L1_RPC + +openssl rand -hex 32 > /app/jwt.txt diff --git a/app/data/config/fixturenet-optimism/optimism-contracts/rekey-json.ts b/app/data/config/fixturenet-optimism/optimism-contracts/rekey-json.ts new file mode 100644 index 00000000..78312499 --- /dev/null +++ b/app/data/config/fixturenet-optimism/optimism-contracts/rekey-json.ts @@ -0,0 +1,28 @@ +import fs from 'fs' + +import { task } from 'hardhat/config' +import { hdkey } from 'ethereumjs-wallet' +import * as bip39 from 'bip39' + +task('rekey-json', 'Generates a new set of keys for a test network') + .addParam('output', 'JSON file to output accounts to') + .setAction(async ({ output: outputFile }) => { + const mnemonic = bip39.generateMnemonic() + const pathPrefix = "m/44'/60'/0'/0" + const labels = ['Admin', 'Proposer', 'Batcher', 'Sequencer'] + const hdwallet = hdkey.fromMasterSeed(await bip39.mnemonicToSeed(mnemonic)) + + const output = {} + + for (let i = 0; i < labels.length; i++) { + const label = labels[i] + const wallet = hdwallet.derivePath(`${pathPrefix}/${i}`).getWallet() + const addr = '0x' + wallet.getAddress().toString('hex') + const pk = wallet.getPrivateKey().toString('hex') + + output[label] = { address: addr, privateKey: pk } + } + + fs.writeFileSync(outputFile, JSON.stringify(output, null, 2)) + console.log(`L2 account keys written to ${outputFile}`) + }) diff --git a/app/data/config/fixturenet-optimism/optimism-contracts/run.sh b/app/data/config/fixturenet-optimism/optimism-contracts/run.sh new file mode 100755 index 00000000..4a5f568b --- /dev/null +++ b/app/data/config/fixturenet-optimism/optimism-contracts/run.sh @@ -0,0 +1,81 @@ +#!/bin/bash +set -e + +# TODO Support restarts; fixturenet-eth-geth currently starts fresh on a restart +# Exit if a deployment already exists (on restarts) +# if [ -d "deployments/getting-started" ]; then +# echo "Deployment directory deployments/getting-started already exists, exiting" +# exit 0 +# fi + +# Append tasks/index.ts file +echo "import './rekey-json'" >> tasks/index.ts +echo "import './send-balance'" >> tasks/index.ts + +# Update the chainId in the hardhat config +sed -i "/getting-started/ {n; s/.*chainId.*/ chainId: $CHAIN_ID,/}" hardhat.config.ts + +# Generate the L2 account addresses +yarn hardhat rekey-json --output /l2-accounts/keys.json + +# Read JSON file into variable +KEYS_JSON=$(cat /l2-accounts/keys.json) + +# Parse JSON into variables +ADMIN_ADDRESS=$(echo "$KEYS_JSON" | jq -r '.Admin.address') +ADMIN_PRIV_KEY=$(echo "$KEYS_JSON" | jq -r '.Admin.privateKey') +PROPOSER_ADDRESS=$(echo "$KEYS_JSON" | jq -r '.Proposer.address') +BATCHER_ADDRESS=$(echo "$KEYS_JSON" | jq -r '.Batcher.address') +SEQUENCER_ADDRESS=$(echo "$KEYS_JSON" | jq -r '.Sequencer.address') + +# Read the private key of a L1 account +# TODO: Take from env if /geth-accounts volume doesn't exist to allow using separately running L1 +L1_ADDRESS=$(head -n 1 /geth-accounts/accounts.csv | cut -d ',' -f 2) +L1_PRIV_KEY=$(head -n 1 /geth-accounts/accounts.csv | cut -d ',' -f 3) + +# Send balances to the above L2 addresses +yarn hardhat send-balance --to "${ADMIN_ADDRESS}" --amount 2 --private-key "${L1_PRIV_KEY}" --network getting-started +yarn hardhat send-balance --to "${PROPOSER_ADDRESS}" --amount 5 --private-key "${L1_PRIV_KEY}" --network getting-started +yarn hardhat send-balance --to "${BATCHER_ADDRESS}" --amount 1000 --private-key "${L1_PRIV_KEY}" --network getting-started + +echo "Balances sent to L2 accounts" + +# Select a finalized L1 block as the starting point for roll ups +# TODO Use web3.js to get the latest finalized block +until CAST_OUTPUT=$(cast block finalized --rpc-url "$L1_RPC"); do + echo "Waiting for a finalized L1 block to exist, retrying after 10s" + sleep 10 +done + +L1_BLOCKHASH=$(echo "$CAST_OUTPUT" | awk '/hash/{print $2}') +L1_BLOCKTIMESTAMP=$(echo "$CAST_OUTPUT" | awk '/timestamp/{print $2}') + +# Update the deployment config +sed -i 's/"l2OutputOracleStartingTimestamp": TIMESTAMP/"l2OutputOracleStartingTimestamp": '"$L1_BLOCKTIMESTAMP"'/g' deploy-config/getting-started.json +jq --arg chainid "$CHAIN_ID" '.l1ChainID = ($chainid | tonumber)' deploy-config/getting-started.json > tmp.json && mv tmp.json deploy-config/getting-started.json + +node update-config.js deploy-config/getting-started.json "$ADMIN_ADDRESS" "$PROPOSER_ADDRESS" "$BATCHER_ADDRESS" "$SEQUENCER_ADDRESS" "$L1_BLOCKHASH" + +echo "Updated the deployment config" + +# Create a .env file +echo "L1_RPC=$L1_RPC" > .env +echo "PRIVATE_KEY_DEPLOYER=$ADMIN_PRIV_KEY" >> .env + +echo "Deploying the L1 smart contracts, this will take a while..." + +# Deploy the L1 smart contracts +yarn hardhat deploy --network getting-started + +echo "Deployed the L1 smart contracts" + +# Read Proxy contarct's JSON and get the address +PROXY_JSON=$(cat deployments/getting-started/Proxy__OVM_L1StandardBridge.json) +PROXY_ADDRESS=$(echo "$PROXY_JSON" | jq -r '.address') + +# Send balance to the above L2 address +yarn hardhat send-balance --to "${PROXY_ADDRESS}" --amount 1 --private-key "${L1_PRIV_KEY}" --network getting-started + +echo "Balance sent to Proxy L2 contract" +echo "Use account ${L1_ADDRESS} to deploy contracts to L2" +echo "Done" diff --git a/app/data/config/fixturenet-optimism/optimism-contracts/send-balance.ts b/app/data/config/fixturenet-optimism/optimism-contracts/send-balance.ts new file mode 100644 index 00000000..54615647 --- /dev/null +++ b/app/data/config/fixturenet-optimism/optimism-contracts/send-balance.ts @@ -0,0 +1,22 @@ +import { task } from 'hardhat/config' +import '@nomiclabs/hardhat-ethers' +import { ethers } from 'ethers' + +task('send-balance', 'Sends Ether to a specified Ethereum account') + .addParam('to', 'The Ethereum address to send Ether to') + .addParam('amount', 'The amount of Ether to send, in Ether') + .addParam('privateKey', 'The private key of the sender') + .setAction(async ({ to, amount, privateKey }, {}) => { + // Open the wallet using sender's private key + const provider = new ethers.providers.JsonRpcProvider(`${process.env.L1_RPC}`) + const wallet = new ethers.Wallet(privateKey, provider) + + // Send amount to the specified address + const tx = await wallet.sendTransaction({ + to, + value: ethers.utils.parseEther(amount), + }) + + console.log(`Balance sent to: ${to}, from: ${wallet.address}`) + console.log(`Transaction hash: ${tx.hash}`) + }) diff --git a/app/data/config/fixturenet-optimism/optimism-contracts/update-config.js b/app/data/config/fixturenet-optimism/optimism-contracts/update-config.js new file mode 100644 index 00000000..8a6c09d4 --- /dev/null +++ b/app/data/config/fixturenet-optimism/optimism-contracts/update-config.js @@ -0,0 +1,36 @@ +const fs = require('fs') + +// Get the command-line argument +const configFile = process.argv[2] +const adminAddress = process.argv[3] +const proposerAddress = process.argv[4] +const batcherAddress = process.argv[5] +const sequencerAddress = process.argv[6] +const blockHash = process.argv[7] + +// Read the JSON file +const configData = fs.readFileSync(configFile) +const configObj = JSON.parse(configData) + +// Update the finalSystemOwner property with the ADMIN_ADDRESS value +configObj.finalSystemOwner = + configObj.portalGuardian = + configObj.controller = + configObj.l2OutputOracleChallenger = + configObj.proxyAdminOwner = + configObj.baseFeeVaultRecipient = + configObj.l1FeeVaultRecipient = + configObj.sequencerFeeVaultRecipient = + configObj.governanceTokenOwner = + adminAddress + +configObj.l2OutputOracleProposer = proposerAddress + +configObj.batchSenderAddress = batcherAddress + +configObj.p2pSequencerAddress = sequencerAddress + +configObj.l1StartingBlockTag = blockHash + +// Write the updated JSON object back to the file +fs.writeFileSync(configFile, JSON.stringify(configObj, null, 2)) diff --git a/app/data/config/fixturenet-optimism/run-op-batcher.sh b/app/data/config/fixturenet-optimism/run-op-batcher.sh new file mode 100755 index 00000000..38ac3ab9 --- /dev/null +++ b/app/data/config/fixturenet-optimism/run-op-batcher.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -e + +# Get BACTHER_KEY from keys.json +BATCHER_KEY=$(jq -r '.Batcher.privateKey' /l2-accounts/keys.json | tr -d '"') + +op-batcher \ + --l2-eth-rpc=http://op-geth:8545 \ + --rollup-rpc=http://op-node:8547 \ + --poll-interval=1s \ + --sub-safety-margin=6 \ + --num-confirmations=1 \ + --safe-abort-nonce-too-low-count=3 \ + --resubmission-timeout=30s \ + --rpc.addr=0.0.0.0 \ + --rpc.port=8548 \ + --rpc.enable-admin \ + --max-channel-duration=1 \ + --target-l1-tx-size-bytes=2048 \ + --l1-eth-rpc=$L1_RPC \ + --private-key=$BATCHER_KEY diff --git a/app/data/config/fixturenet-optimism/run-op-geth.sh b/app/data/config/fixturenet-optimism/run-op-geth.sh new file mode 100755 index 00000000..1b4e2b0f --- /dev/null +++ b/app/data/config/fixturenet-optimism/run-op-geth.sh @@ -0,0 +1,58 @@ +#!/bin/sh +set -e + +mkdir datadir + +echo "pwd" > datadir/password + +# TODO: Add in container build or use other tool +echo "installing jq" +apk update && apk add jq + +# Get SEQUENCER KEY from keys.json +SEQUENCER_KEY=$(jq -r '.Sequencer.privateKey' /l2-accounts/keys.json | tr -d '"') +echo $SEQUENCER_KEY > datadir/block-signer-key + +geth account import --datadir=datadir --password=datadir/password datadir/block-signer-key + +while [ ! -f "/op-node/jwt.txt" ] +do + echo "Config files not created. Checking after 5 seconds." + sleep 5 +done + +echo "Config files created by op-node, proceeding with script..." + +cp /op-node/genesis.json ./ +geth init --datadir=datadir genesis.json + +SEQUENCER_ADDRESS=$(jq -r '.Sequencer.address' /l2-accounts/keys.json | tr -d '"') +echo "SEQUENCER_ADDRESS: ${SEQUENCER_ADDRESS}" +cp /op-node/jwt.txt ./ +geth \ + --datadir ./datadir \ + --http \ + --http.corsdomain="*" \ + --http.vhosts="*" \ + --http.addr=0.0.0.0 \ + --http.api=web3,debug,eth,txpool,net,engine \ + --ws \ + --ws.addr=0.0.0.0 \ + --ws.port=8546 \ + --ws.origins="*" \ + --ws.api=debug,eth,txpool,net,engine \ + --syncmode=full \ + --gcmode=full \ + --nodiscover \ + --maxpeers=0 \ + --networkid=42069 \ + --authrpc.vhosts="*" \ + --authrpc.addr=0.0.0.0 \ + --authrpc.port=8551 \ + --authrpc.jwtsecret=./jwt.txt \ + --rollup.disabletxpoolgossip=true \ + --password=./datadir/password \ + --allow-insecure-unlock \ + --mine \ + --miner.etherbase=$SEQUENCER_ADDRESS \ + --unlock=$SEQUENCER_ADDRESS diff --git a/app/data/config/fixturenet-optimism/run-op-node.sh b/app/data/config/fixturenet-optimism/run-op-node.sh new file mode 100755 index 00000000..e4aafae9 --- /dev/null +++ b/app/data/config/fixturenet-optimism/run-op-node.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +# Get SEQUENCER KEY from keys.json +SEQUENCER_KEY=$(jq -r '.Sequencer.privateKey' /l2-accounts/keys.json | tr -d '"') + +op-node \ + --l2=http://op-geth:8551 \ + --l2.jwt-secret=/app/jwt.txt \ + --sequencer.enabled \ + --sequencer.l1-confs=3 \ + --verifier.l1-confs=3 \ + --rollup.config=/app/rollup.json \ + --rpc.addr=0.0.0.0 \ + --rpc.port=8547 \ + --p2p.disable \ + --rpc.enable-admin \ + --p2p.sequencer.key=$SEQUENCER_KEY \ + --l1=$L1_RPC \ + --l1.rpckind=any diff --git a/app/data/container-build/cerc-builder-js/yarn-local-registry-fixup.sh b/app/data/container-build/cerc-builder-js/yarn-local-registry-fixup.sh index ad11ce80..3f4f095a 100755 --- a/app/data/container-build/cerc-builder-js/yarn-local-registry-fixup.sh +++ b/app/data/container-build/cerc-builder-js/yarn-local-registry-fixup.sh @@ -18,9 +18,8 @@ fi set -e target_package=$1 local_npm_registry_url=$2 -# Extract the actual version pinned in yarn.lock -# See: https://stackoverflow.com/questions/60454251/how-to-know-the-version-of-currently-installed-package-from-yarn-lock -versioned_target_package=$(yarn list --pattern ${target_package} --depth=0 --json --non-interactive --no-progress | jq -r '.data.trees[].name') +# TODO: use jq rather than sed here: +versioned_target_package=$(grep ${target_package} package.json | sed -e 's#[[:space:]]\{1,\}\"\('${target_package}'\)\":[[:space:]]\{1,\}\"\(.*\)\",#\1@\2#' ) # Use yarn info to get URL checksums etc from the new registry yarn_info_output=$(yarn info --json $versioned_target_package 2>/dev/null) # First check if the target version actually exists. diff --git a/app/data/container-build/cerc-optimism-contracts/Dockerfile b/app/data/container-build/cerc-optimism-contracts/Dockerfile new file mode 100644 index 00000000..4f244bab --- /dev/null +++ b/app/data/container-build/cerc-optimism-contracts/Dockerfile @@ -0,0 +1,23 @@ +# TODO: Use a node alpine image +FROM cerc/foundry:local + +# Install node (local foundry is a debian based image) +RUN apt-get update \ + && apt-get install -y curl \ + && curl --silent --location https://deb.nodesource.com/setup_16.x | bash - \ + && apt-get update \ + && apt-get install -y nodejs git busybox jq \ + && node -v + +RUN corepack enable \ + && yarn --version + +WORKDIR /app + +# Copy optimism repo contents +COPY . . + +RUN echo "Building optimism" && \ + yarn && yarn build + +WORKDIR /app/packages/contracts-bedrock diff --git a/app/data/container-build/cerc-optimism-contracts/build.sh b/app/data/container-build/cerc-optimism-contracts/build.sh new file mode 100755 index 00000000..8b8e0eaa --- /dev/null +++ b/app/data/container-build/cerc-optimism-contracts/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# Build cerc/optimism-contracts + +# See: https://stackoverflow.com/a/246128/1701505 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +docker build -t cerc/optimism-contracts:local -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/optimism diff --git a/app/data/container-build/cerc-optimism-l2geth/build.sh b/app/data/container-build/cerc-optimism-l2geth/build.sh new file mode 100755 index 00000000..3ffada73 --- /dev/null +++ b/app/data/container-build/cerc-optimism-l2geth/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +# Build cerc/optimism-l2geth +docker build -t cerc/optimism-l2geth:local ${CERC_REPO_BASE_DIR}/op-geth diff --git a/app/data/container-build/cerc-optimism-op-batcher/Dockerfile b/app/data/container-build/cerc-optimism-op-batcher/Dockerfile new file mode 100644 index 00000000..542a075f --- /dev/null +++ b/app/data/container-build/cerc-optimism-op-batcher/Dockerfile @@ -0,0 +1,32 @@ +FROM golang:1.19.0-alpine3.15 as builder + +ARG VERSION=v0.0.0 + +RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash + +# build op-batcher with the shared go.mod & go.sum files +COPY ./op-batcher /app/op-batcher +COPY ./op-bindings /app/op-bindings +COPY ./op-node /app/op-node +COPY ./op-service /app/op-service +COPY ./op-signer /app/op-signer +COPY ./go.mod /app/go.mod +COPY ./go.sum /app/go.sum + +COPY ./.git /app/.git + +WORKDIR /app/op-batcher + +RUN go mod download + +ARG TARGETOS TARGETARCH + +RUN make op-batcher VERSION="$VERSION" GOOS=$TARGETOS GOARCH=$TARGETARCH + +FROM alpine:3.15 + +RUN apk add --no-cache jq + +COPY --from=builder /app/op-batcher/bin/op-batcher /usr/local/bin + +ENTRYPOINT ["op-batcher"] diff --git a/app/data/container-build/cerc-optimism-op-batcher/build.sh b/app/data/container-build/cerc-optimism-op-batcher/build.sh new file mode 100755 index 00000000..5bc3a238 --- /dev/null +++ b/app/data/container-build/cerc-optimism-op-batcher/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build cerc/optimism-op-batcher +# TODO: use upstream Dockerfile once its buildx-specific content has been removed +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +docker build -t cerc/optimism-op-batcher:local -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/optimism diff --git a/app/data/container-build/cerc-optimism-op-node/Dockerfile b/app/data/container-build/cerc-optimism-op-node/Dockerfile new file mode 100644 index 00000000..17d273b6 --- /dev/null +++ b/app/data/container-build/cerc-optimism-op-node/Dockerfile @@ -0,0 +1,30 @@ +FROM golang:1.19.0-alpine3.15 as builder + +ARG VERSION=v0.0.0 + +RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash + +# build op-node with the shared go.mod & go.sum files +COPY ./op-node /app/op-node +COPY ./op-chain-ops /app/op-chain-ops +COPY ./op-service /app/op-service +COPY ./op-bindings /app/op-bindings +COPY ./go.mod /app/go.mod +COPY ./go.sum /app/go.sum +COPY ./.git /app/.git + +WORKDIR /app/op-node + +RUN go mod download + +ARG TARGETOS TARGETARCH + +RUN make op-node VERSION="$VERSION" GOOS=$TARGETOS GOARCH=$TARGETARCH + +FROM alpine:3.15 + +RUN apk add --no-cache openssl jq + +COPY --from=builder /app/op-node/bin/op-node /usr/local/bin + +CMD ["op-node"] diff --git a/app/data/container-build/cerc-optimism-op-node/build.sh b/app/data/container-build/cerc-optimism-op-node/build.sh new file mode 100755 index 00000000..0ec7e656 --- /dev/null +++ b/app/data/container-build/cerc-optimism-op-node/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build cerc/optimism-op-node +# TODO: use upstream Dockerfile once its buildx-specific content has been removed +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +docker build -t cerc/optimism-op-node:local -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/optimism diff --git a/app/data/container-image-list.txt b/app/data/container-image-list.txt index 8be9f085..3ff67ad8 100644 --- a/app/data/container-image-list.txt +++ b/app/data/container-image-list.txt @@ -30,3 +30,6 @@ cerc/tx-spammer cerc/builder-gerbil cerc/act-runner cerc/act-runner-task-executor +cerc/optimism-l2geth +cerc/optimism-op-batcher +cerc/optimism-op-node diff --git a/app/data/pod-list.txt b/app/data/pod-list.txt index abb4ab1f..79c4171a 100644 --- a/app/data/pod-list.txt +++ b/app/data/pod-list.txt @@ -22,3 +22,4 @@ keycloak tx-spammer kubo foundry +fixturenet-optimism diff --git a/app/data/repository-list.txt b/app/data/repository-list.txt index cc78b080..5617122b 100644 --- a/app/data/repository-list.txt +++ b/app/data/repository-list.txt @@ -24,3 +24,5 @@ lirewine/gem lirewine/debug lirewine/crypto telackey/act_runner +ethereum-optimism/op-geth +ethereum-optimism/optimism diff --git a/app/data/stacks/fixturenet-eth/stack.yml b/app/data/stacks/fixturenet-eth/stack.yml index db3f4231..a44f086e 100644 --- a/app/data/stacks/fixturenet-eth/stack.yml +++ b/app/data/stacks/fixturenet-eth/stack.yml @@ -1,9 +1,8 @@ -version: "1.0" +version: "1.1" name: fixturenet-eth decription: "Ethereum Fixturenet" repos: - cerc-io/go-ethereum - - cerc-io/tx-spammer - dboreham/foundry containers: - cerc/go-ethereum diff --git a/app/data/stacks/fixturenet-optimism/README.md b/app/data/stacks/fixturenet-optimism/README.md new file mode 100644 index 00000000..5b9dd51b --- /dev/null +++ b/app/data/stacks/fixturenet-optimism/README.md @@ -0,0 +1,80 @@ +# fixturenet-optimism + +Instructions to setup and deploy an end-to-end L1+L2 stack with [fixturenet-eth](../fixturenet-eth/) (L1) and [Optimism](https://stack.optimism.io) (L2) + +## Setup + +Clone required repositories: + +```bash +laconic-so --stack fixturenet-optimism setup-repositories +``` + +Checkout to the required versions and branches in repos: + +```bash +# optimism +cd ~/cerc/optimism +git checkout @eth-optimism/sdk@0.0.0-20230329025055 +``` + +Build the container images: + +```bash +laconic-so --stack fixturenet-optimism build-containers +``` + +This should create the required docker images in the local image registry: +* `cerc/go-ethereum` +* `cerc/lighthouse` +* `cerc/fixturenet-eth-geth` +* `cerc/fixturenet-eth-lighthouse` +* `cerc/foundry` +* `cerc/optimism-contracts` +* `cerc/optimism-l2geth` +* `cerc/optimism-op-batcher` +* `cerc/optimism-op-node` + +## Deploy + +Deploy the stack: + +```bash +laconic-so --stack fixturenet-optimism deploy up +``` + +To list down the running containers: + +```bash +laconic-so --stack fixturenet-optimism deploy ps + +# With status +docker ps +``` + +## Clean up + +Stop all services running in the background: + +```bash +laconic-so --stack fixturenet-optimism deploy down +``` + +Remove volumes created by this stack: + +```bash +docker volume ls + +docker volume rm laconic-d527651bba3cb61886b36a7400bd2a38_fixturenet-geth-accounts +docker volume rm laconic-d527651bba3cb61886b36a7400bd2a38_l1-deployment +docker volume rm laconic-d527651bba3cb61886b36a7400bd2a38_l2-accounts +docker volume rm laconic-d527651bba3cb61886b36a7400bd2a38_op_node_data +``` + +## Known Issues + +* Currently not supported: + * Stopping and restarting the stack from where it left off; currently starts fresh on a restart + * Pointing Optimism (L2) to external L1 endpoint to allow running only L2 services +* Resource requirements (memory + time) for building `cerc/foundry` image are on the higher side + * `cerc/optimism-contracts` image is currently based on `cerc/foundry` (Optimism requires foundry installation) diff --git a/app/data/stacks/fixturenet-optimism/stack.yml b/app/data/stacks/fixturenet-optimism/stack.yml new file mode 100644 index 00000000..299b1367 --- /dev/null +++ b/app/data/stacks/fixturenet-optimism/stack.yml @@ -0,0 +1,21 @@ +version: "1.0" +name: fixturenet-optimism +decription: "Optimism Fixturenet" +repos: + - cerc-io/go-ethereum + - dboreham/foundry + - ethereum-optimism/optimism + - ethereum-optimism/op-geth +containers: + - cerc/go-ethereum + - cerc/lighthouse + - cerc/fixturenet-eth-geth + - cerc/fixturenet-eth-lighthouse + - cerc/foundry + - cerc/optimism-contracts + - cerc/optimism-l2geth + - cerc/optimism-op-batcher + - cerc/optimism-op-node +pods: + - fixturenet-eth + - fixturenet-optimism