From ce2258db0794f7bab39130f23d21c257cbddd5c7 Mon Sep 17 00:00:00 2001 From: prathamesh0 <42446521+prathamesh0@users.noreply.github.com> Date: Fri, 19 Jul 2024 10:57:46 +0530 Subject: [PATCH] Add a stack for Nitro bridge (#4) * Add a bridge stack * Implement Nitro contracts deployment to L1 and L2 * Deploy custom tokens to L1 and L2 * Add a service for Nitro bridge * Setup a service for nitro-rpc-client with required certs --- .../compose/docker-compose-bridge.yml | 50 +++++++++++++++++ .../docker-compose-nitro-contracts.yml | 14 +++-- .../docker-compose-nitro-rpc-client.yml | 9 ++- .../config/go-nitro/create-certs.sh | 20 +++++++ .../config/go-nitro/run-bridge.sh | 45 +++++++++++++++ .../config/nitro-contracts/deploy.sh | 55 +++++++++++++++++-- .../container-build/cerc-go-nitro/Dockerfile | 10 ++-- .../cerc-nitro-contracts/Dockerfile | 3 +- .../cerc-nitro-rpc-client/Dockerfile | 15 ----- .../cerc-nitro-rpc-client/build.sh | 9 --- stack-orchestrator/stacks/bridge/README.md | 21 +++++++ stack-orchestrator/stacks/bridge/stack.yml | 12 ++++ .../stacks/nitro-node/stack.yml | 4 +- 13 files changed, 223 insertions(+), 44 deletions(-) create mode 100644 stack-orchestrator/compose/docker-compose-bridge.yml create mode 100755 stack-orchestrator/config/go-nitro/create-certs.sh create mode 100755 stack-orchestrator/config/go-nitro/run-bridge.sh delete mode 100644 stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile delete mode 100755 stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh create mode 100644 stack-orchestrator/stacks/bridge/README.md create mode 100644 stack-orchestrator/stacks/bridge/stack.yml diff --git a/stack-orchestrator/compose/docker-compose-bridge.yml b/stack-orchestrator/compose/docker-compose-bridge.yml new file mode 100644 index 0000000..8ae8663 --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-bridge.yml @@ -0,0 +1,50 @@ +name: bridge + +services: + nitro-bridge: + image: cerc/go-nitro:local + hostname: nitro-bridge + restart: unless-stopped + depends_on: + # Wait for Nitro contracts to be deployed + nitro-contracts: + condition: service_completed_successfully + environment: + CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} + CERC_GETH_CHAIN_ID: ${CERC_GETH_CHAIN_ID:-1212} + CERC_OPTIMISM_CHAIN_ID: ${CERC_OPTIMISM_CHAIN_ID:-42069} + CERC_NITRO_L1_CHAIN_URL: ${CERC_NITRO_L1_CHAIN_URL} + CERC_NITRO_L2_CHAIN_URL: ${CERC_NITRO_L2_CHAIN_URL} + CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK} + CERC_NITRO_SC_PK: ${CERC_NITRO_SC_PK} + CERC_NITRO_L1_MSG_PORT: ${CERC_NITRO_L1_MSG_PORT:-3005} + CERC_NITRO_L2_MSG_PORT: ${CERC_NITRO_L2_MSG_PORT:-3006} + CERC_NITRO_RPC_PORT: ${CERC_NITRO_RPC_PORT:-4006} + CERC_NITRO_PUBLIC_P2P_HOST: ${CERC_NITRO_PUBLIC_P2P_HOST:-127.0.0.1} + CERC_NITRO_PUBLIC_RPC_HOST: nitro-bridge + entrypoint: ["bash", "-c", "/app/run-bridge.sh"] + volumes: + - nitro_bridge_data:/app/data + - nitro_bridge_tls:/app/tls + - nitro_node_caroot:/app/mkcert-caroot + - nitro_deployment:/app/deployment + - ../config/go-nitro/run-bridge.sh:/app/run-bridge.sh + - ../config/go-nitro/create-certs.sh:/app/create-certs.sh + ports: + - 3005 + - 3006 + - 4006 + healthcheck: + test: ["CMD", "nc", "-vz", "localhost", "4006"] + interval: 30s + timeout: 5s + retries: 10 + start_period: 10s + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + nitro_bridge_data: + nitro_bridge_tls: + nitro_node_caroot: + nitro_deployment: diff --git a/stack-orchestrator/compose/docker-compose-nitro-contracts.yml b/stack-orchestrator/compose/docker-compose-nitro-contracts.yml index 5af8d26..17593f3 100644 --- a/stack-orchestrator/compose/docker-compose-nitro-contracts.yml +++ b/stack-orchestrator/compose/docker-compose-nitro-contracts.yml @@ -4,18 +4,24 @@ services: # Optionally deploys the Nitro contracts nitro-contracts: image: cerc/nitro-contracts:local - # restart: on-failure + restart: on-failure environment: CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} CERC_GETH_URL: ${CERC_GETH_URL} CERC_OPTIMISM_URL: ${CERC_OPTIMISM_URL} - CERC_GETH_CHAIN_ID: ${CERC_GETH_CHAIN_ID} - CERC_OPTIMISM_CHAIN_ID: ${CERC_OPTIMISM_CHAIN_ID} + CERC_GETH_CHAIN_ID: ${CERC_GETH_CHAIN_ID:-1212} + CERC_OPTIMISM_CHAIN_ID: ${CERC_OPTIMISM_CHAIN_ID:-42069} CERC_GETH_DEPLOYER_PK: ${CERC_GETH_DEPLOYER_PK} CERC_OPTIMISM_DEPLOYER_PK: ${CERC_GETH_DEPLOYER_PK} - CERC_DISABLE_DETERMINISTIC_DEPLOYMENT: true + CERC_TOKEN_NAME: ${CERC_TOKEN_NAME} + CERC_TOKEN_SYMBOL: ${CERC_TOKEN_SYMBOL} + CERC_INITIAL_TOKEN_SUPPLY: ${CERC_INITIAL_TOKEN_SUPPLY} volumes: + - nitro_deployment:/app/deployment - ../config/nitro-contracts/deploy.sh:/app/deploy.sh command: ["bash", "-c", "/app/deploy.sh"] extra_hosts: - "host.docker.internal:host-gateway" + +volumes: + nitro_deployment: diff --git a/stack-orchestrator/compose/docker-compose-nitro-rpc-client.yml b/stack-orchestrator/compose/docker-compose-nitro-rpc-client.yml index a5ceac9..06e0983 100644 --- a/stack-orchestrator/compose/docker-compose-nitro-rpc-client.yml +++ b/stack-orchestrator/compose/docker-compose-nitro-rpc-client.yml @@ -2,7 +2,14 @@ name: nitro-rpc-client services: nitro-rpc-client: - image: cerc/nitro-rpc-client:local + image: cerc/nitro-contracts:local hostname: nitro-rpc-client restart: on-failure + environment: + NODE_EXTRA_CA_CERTS: "/app/mkcert-caroot/rootCA.pem" command: ["bash", "-c", "tail -f /dev/null"] + volumes: + - nitro_node_caroot:/app/mkcert-caroot + +volumes: + nitro_node_caroot: diff --git a/stack-orchestrator/config/go-nitro/create-certs.sh b/stack-orchestrator/config/go-nitro/create-certs.sh new file mode 100755 index 0000000..5eda7a4 --- /dev/null +++ b/stack-orchestrator/config/go-nitro/create-certs.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +cert_file="/app/tls/statechannels.org.pem" +key_file="/app/tls/statechannels.org_key.pem" + +# Check if the cert already exists +if [ -f "$cert_file" ] ; then + echo "Cert file ${cert_file} already exists" +else + echo "Creating certs" + mkcert -cert-file $cert_file -key-file $key_file statechannels.org localhost 127.0.0.1 $CERC_NITRO_PUBLIC_RPC_HOST ::1 + + # Copy over the rootCA cert so that it can be used by the client + cp -r $(mkcert -CAROOT)/* /app/mkcert-caroot +fi diff --git a/stack-orchestrator/config/go-nitro/run-bridge.sh b/stack-orchestrator/config/go-nitro/run-bridge.sh new file mode 100755 index 0000000..7989d3e --- /dev/null +++ b/stack-orchestrator/config/go-nitro/run-bridge.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +nitro_addresses_file="/app/deployment/nitro-addresses.json" +bridge_assets_map_file="/app/deployment/bridge-assets-map.toml" +bridge_config_file="/app/bridge.toml" + +echo "Using the following environment variables:" +echo "CERC_NITRO_L1_CHAIN_URL: ${CERC_NITRO_L1_CHAIN_URL}" +echo "CERC_NITRO_L2_CHAIN_URL: ${CERC_NITRO_L2_CHAIN_URL}" +echo "CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK}" +echo "CERC_NITRO_SC_PK: ${CERC_NITRO_SC_PK}" +echo "CERC_NITRO_L1_MSG_PORT: ${CERC_NITRO_L1_MSG_PORT}" +echo "CERC_NITRO_L2_MSG_PORT: ${CERC_NITRO_L2_MSG_PORT}" +echo "CERC_NITRO_RPC_PORT: ${CERC_NITRO_RPC_PORT}" +echo "CERC_NITRO_PUBLIC_P2P_HOST: ${CERC_NITRO_PUBLIC_P2P_HOST}" + +# Create required certs +./create-certs.sh + +# Create the bridge config file +cat < "$bridge_config_file" +chainpk = "$CERC_NITRO_CHAIN_PK" +statechannelpk = "$CERC_NITRO_SC_PK" +l1chainurl = "$CERC_NITRO_L1_CHAIN_URL" +l2chainurl = "$CERC_NITRO_L2_CHAIN_URL" +nodel1msgport = $CERC_NITRO_L1_MSG_PORT +nodel2msgport = $CERC_NITRO_L2_MSG_PORT +rpcport = $CERC_NITRO_RPC_PORT +bridgepublicip = "$CERC_NITRO_PUBLIC_P2P_HOST" +assetmapfilepath = "$bridge_assets_map_file" +EOF + +# Export contract addresses +export NA_ADDRESS=$(jq -r ".\"$CERC_GETH_CHAIN_ID\"[0].contracts.NitroAdjudicator.address" ${nitro_addresses_file}) +export CA_ADDRESS=$(jq -r ".\"$CERC_GETH_CHAIN_ID\"[0].contracts.ConsensusApp.address" ${nitro_addresses_file}) +export VPA_ADDRESS=$(jq -r ".\"$CERC_GETH_CHAIN_ID\"[0].contracts.VirtualPaymentApp.address" ${nitro_addresses_file}) +export BRIDGE_ADDRESS=$(jq -r ".\"$CERC_OPTIMISM_CHAIN_ID\"[0].contracts.Bridge.address" ${nitro_addresses_file}) + +# Start bridge +./nitro-bridge -config $bridge_config_file diff --git a/stack-orchestrator/config/nitro-contracts/deploy.sh b/stack-orchestrator/config/nitro-contracts/deploy.sh index e99d12a..5bb88ee 100755 --- a/stack-orchestrator/config/nitro-contracts/deploy.sh +++ b/stack-orchestrator/config/nitro-contracts/deploy.sh @@ -1,20 +1,24 @@ #!/bin/bash -# TODO: Make sure contracts are not deployed on L2 set -e if [ -n "$CERC_SCRIPT_DEBUG" ]; then set -x fi -echo "Environment variables..." -echo "CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}" +addresses_deployment_file="packages/nitro-protocol/addresses.json" +nitro_addresses_file="/app/deployment/nitro-addresses.json" +bridge_assets_map_file="/app/deployment/bridge-assets-map.toml" + +echo "Using the following environment variables:" echo "CERC_GETH_URL: ${CERC_GETH_URL}" echo "CERC_OPTIMISM_URL: ${CERC_OPTIMISM_URL}" echo "CERC_GETH_CHAIN_ID: ${CERC_GETH_CHAIN_ID}" echo "CERC_OPTIMISM_CHAIN_ID: ${CERC_OPTIMISM_CHAIN_ID}" echo "CERC_GETH_DEPLOYER_PK: ${CERC_GETH_DEPLOYER_PK}" echo "CERC_OPTIMISM_DEPLOYER_PK: ${CERC_OPTIMISM_DEPLOYER_PK}" -echo "CERC_DISABLE_DETERMINISTIC_DEPLOYMENT: true" +echo "CERC_TOKEN_NAME: ${CERC_TOKEN_NAME}" +echo "CERC_TOKEN_SYMBOL: ${CERC_TOKEN_SYMBOL}" +echo "CERC_INITIAL_TOKEN_SUPPLY: ${CERC_INITIAL_TOKEN_SUPPLY}" export GETH_URL=$CERC_GETH_URL export GETH_CHAIN_ID=$CERC_GETH_CHAIN_ID @@ -24,5 +28,44 @@ export GETH_DEPLOYER_PK=$CERC_GETH_DEPLOYER_PK export OPTIMISM_DEPLOYER_PK=$GETH_DEPLOYER_PK export DISABLE_DETERMINISTIC_DEPLOYMENT=true -yarn contracts:deploy-geth -yarn contracts:deploy-optimism +export TOKEN_NAME=$CERC_TOKEN_NAME +export TOKEN_SYMBOL=$CERC_TOKEN_SYMBOL +export INITIAL_TOKEN_SUPPLY=$CERC_INITIAL_TOKEN_SUPPLY + +# Check if L1 chain id key is present for L1 deployment +if [ -f "$nitro_addresses_file" ] && jq -e "has(\"$GETH_CHAIN_ID\")" ${nitro_addresses_file} > /dev/null; then + echo "L1 addresses found in ${nitro_addresses_file}, skipping deployment" +else + # Deploy Nitro contracts + yarn contracts:deploy-geth + + # Deploy custom token + yarn contracts:deploy-token-geth + + cp ${addresses_deployment_file} ${nitro_addresses_file} +fi + +# Check if L1 chain id key is present for L1 deployment +if [ -f "$nitro_addresses_file" ] && jq -e "has(\"$OPTIMISM_CHAIN_ID\")" ${nitro_addresses_file} > /dev/null; then + echo "L2 addresses found in ${nitro_addresses_file}, skipping deployment" +else + # Deploy Nitro contracts + yarn contracts:deploy-optimism + + # Deploy custom token + yarn contracts:deploy-token-optimism + + cp ${addresses_deployment_file} ${nitro_addresses_file} +fi + +L1_ASSET_ADDRESS=$(jq -r ".\"$GETH_CHAIN_ID\"[0].contracts.Token.address" ${nitro_addresses_file}) +L2_ASSET_ADDRESS=$(jq -r ".\"$OPTIMISM_CHAIN_ID\"[0].contracts.Token.address" ${nitro_addresses_file}) + +# Deploy custom tokens and create bridge-assets-map.toml +cat < "$bridge_assets_map_file" +[[assets]] +l1AssetAddress = "$L1_ASSET_ADDRESS" +l2AssetAddress = "$L2_ASSET_ADDRESS" +EOF + +echo "Done" diff --git a/stack-orchestrator/container-build/cerc-go-nitro/Dockerfile b/stack-orchestrator/container-build/cerc-go-nitro/Dockerfile index 76e4326..0067a0a 100644 --- a/stack-orchestrator/container-build/cerc-go-nitro/Dockerfile +++ b/stack-orchestrator/container-build/cerc-go-nitro/Dockerfile @@ -4,19 +4,16 @@ FROM golang:1.21-bullseye AS builder WORKDIR /app COPY . . -RUN go mod tidy - # Install mkcert RUN curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64" RUN chmod +x mkcert-v*-linux-amd64 RUN cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert -# Create certificates -RUN cd /app/tls && \ - make create-cert +RUN go mod tidy # Build the binary RUN go build -v -o nitro . +RUN go build -o nitro-bridge cmd/start-bridge/main.go # TODO: Update steps to build go-nitro image # Reduce image size @@ -28,4 +25,5 @@ RUN rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=builder /app/nitro . -COPY --from=builder /app/tls /app/tls +COPY --from=builder /app/nitro-bridge . +COPY --from=builder /usr/local/bin/mkcert /usr/local/bin/mkcert diff --git a/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile b/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile index ac183ca..77bc6c8 100644 --- a/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile +++ b/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile @@ -9,4 +9,5 @@ COPY . . RUN echo "Installing dependencies" && \ yarn && yarn build -WORKDIR /app/packages/nitro-protocol +RUN echo "Installing nitro-rpc-client" && \ + npm install -g ./packages/nitro-rpc-client diff --git a/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile b/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile deleted file mode 100644 index 1ef8a0e..0000000 --- a/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node:18.17.1-alpine3.18 - -RUN apk --update --no-cache add python3 alpine-sdk bash curl jq - -WORKDIR /app - -COPY . . - -RUN echo "Installing dependencies" && \ - yarn & yarn build - -RUN echo "Installing nitro-rpc-client package" && \ - npm install -g /app/packages/nitro-rpc-client - -WORKDIR /app/packages/nitro-rpc-client diff --git a/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh b/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh deleted file mode 100755 index 1a80583..0000000 --- a/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -# Build cerc/nitro-rpc-client - -source ${CERC_CONTAINER_BASE_DIR}/build-base.sh - -# See: https://stackoverflow.com/a/246128/1701505 -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) - -docker build -t cerc/nitro-rpc-client:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/go-nitro diff --git a/stack-orchestrator/stacks/bridge/README.md b/stack-orchestrator/stacks/bridge/README.md new file mode 100644 index 0000000..d053a4a --- /dev/null +++ b/stack-orchestrator/stacks/bridge/README.md @@ -0,0 +1,21 @@ +# bridge + +## Setup + +- Clone the stack repo: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/nitro-stack + ``` + +- Clone required repositories: + + ```bash + laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/bridge setup-repositories + ``` + +- Build container images: + + ```bash + laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/bridge build-containers + ``` diff --git a/stack-orchestrator/stacks/bridge/stack.yml b/stack-orchestrator/stacks/bridge/stack.yml new file mode 100644 index 0000000..9d453d2 --- /dev/null +++ b/stack-orchestrator/stacks/bridge/stack.yml @@ -0,0 +1,12 @@ +version: "1.0" +name: bridge +description: "Nitro bridge node" +repos: + - github.com/cerc-io/go-nitro +containers: + - cerc/nitro-contracts + - cerc/go-nitro +pods: + - nitro-contracts + - bridge + - nitro-rpc-client diff --git a/stack-orchestrator/stacks/nitro-node/stack.yml b/stack-orchestrator/stacks/nitro-node/stack.yml index 068b95a..4cf4d7e 100644 --- a/stack-orchestrator/stacks/nitro-node/stack.yml +++ b/stack-orchestrator/stacks/nitro-node/stack.yml @@ -5,7 +5,7 @@ repos: - github.com/cerc-io/go-nitro containers: - cerc/go-nitro - # - cerc/nitro-rpc-client + - cerc/nitro-contracts pods: - go-nitro - # - nitro-rpc-client + - nitro-rpc-client