From acd6cbaa43e3bd952203a5165f56160bcf7f1b36 Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Thu, 15 Aug 2024 14:49:48 -0700 Subject: [PATCH] Initial commit --- .github/workflows/build.yml | 46 ++++++++++++++ Dockerfile | 21 +++++++ run.sh | 121 ++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 Dockerfile create mode 100755 run.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e8d245d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,46 @@ +name: build + +on: + push: + branches: + - main + tags: + - v* + pull_request: + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate version + run: | + # Default tag as commit SHA + VERSION=${GITHUB_SHA::7} + + # Use tag name if it's a tag push + if [ "$GITHUB_EVENT_NAME" == "push" ] && [ "$GITHUB_REF_TYPE" == "tag" ]; then + VERSION=${GITHUB_REF_NAME} + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Build and push + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64,linux/arm64 + push: true + provenance: mode=max + tags: "ghcr.io/zeta-chain/zetacored:{{ env.VERSION }}" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b109d12 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM golang:1.22.5-bookworm AS base-build + +RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.5.0 +RUN go install github.com/hashicorp/go-getter/cmd/go-getter@v1.7.6 + +FROM debian:bookworm + +RUN mkdir -p /root/.zetacored/cosmovisor/genesis/bin && \ + ln -s /root/.zetacored/cosmovisor/genesis /root/.zetacored/cosmovisor/current + +ENV PATH=/root/.zetacored/cosmovisor/current/bin/:${PATH} + +RUN apt update && \ + apt install -y ca-certificates curl jq && \ + rm -rf /var/lib/apt/lists/* + +COPY --from=base-build /go/bin/cosmovisor /go/bin/go-getter /usr/local/bin + +COPY run.sh /run.sh + +ENTRYPOINT ["/run.sh"] \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..5cef5ee --- /dev/null +++ b/run.sh @@ -0,0 +1,121 @@ +#!/bin/bash + +set -eo pipefail + +if [[ -n $DEBUG ]]; then + set -x +fi + +# script variables +ZETACHAIN_NETWORK=${ZETACHAIN_NETWORK:-"mainnet"} +ZETACHAIN_SNAPSHOT_TYPE=${ZETACHAIN_SNAPSHOT_TYPE:-"fullnode"} +ZETACORED_BINARY_URL=${ZETACORED_BINARY_URL:-} +MY_IP=${MY_IP:-$(curl -s https://checkip.amazonaws.com)} + +# cosmovisor variables +export DAEMON_ALLOW_DOWNLOAD_BINARIES=${DAEMON_ALLOW_DOWNLOAD_BINARIES:-"true"} +export DAEMON_RESTART_AFTER_UPGRADE=${DAEMON_RESTART_AFTER_UPGRADE:-"true"} +export DAEMON_NAME="zetacored" +export DAEMON_HOME="$HOME/.zetacored" +export UNSAFE_SKIP_BACKUP=true + +# script constants +CURL="curl -s -L --fail --retry 5 --retry-delay 2 --retry-max-time 10" + +if [[ -z $MONIKER ]]; then + echo '$MONIKER is required' + exit 1 +fi + +if [[ "$ZETACHAIN_NETWORK" == "mainnet" ]]; then + echo "Running mainnet" + ZETACHAIN_INIT_API_URL=${ZETACHAIN_INIT_API_URL:-"https://zetachain-mainnet.g.allthatnode.com/archive/rest"} + ZETACHAIN_SNAPSHOT_METADATA_URL=${ZETACHAIN_SNAPSHOT_METADATA_URL:-"https://snapshots.rpc.zetachain.com/mainnet/${ZETACHAIN_SNAPSHOT_TYPE}/latest.json"} + ZETACHAIN_NETWORK_CONFIG_URL_BASE=${ZETACHAIN_NETWORK_CONFIG_URL_BASE:-"https://raw.githubusercontent.com/zeta-chain/network-config/main/mainnet"} +elif [[ "$ZETACHAIN_NETWORK" == "testnet" || "$ZETACHAIN_NETWORK" == "athens3" ]]; then + echo "Running testnet" + ZETACHAIN_INIT_API_URL=${ZETACHAIN_INIT_API_URL:-"https://zetachain-athens.g.allthatnode.com/archive/rest"} + ZETACHAIN_SNAPSHOT_METADATA_URL=${ZETACHAIN_SNAPSHOT_METADATA_URL:-"https://snapshots.rpc.zetachain.com/testnet/${ZETACHAIN_SNAPSHOT_TYPE}/latest.json"} + ZETACHAIN_NETWORK_CONFIG_URL_BASE=${ZETACHAIN_NETWORK_CONFIG_URL_BASE:-"https://raw.githubusercontent.com/zeta-chain/network-config/main/athens3"} +else + echo "Invalid network" + exit 1 +fi + +# convert uname arch to goarch style +UNAME_ARCH=$(uname -m) +case "$UNAME_ARCH" in + x86_64) GOARCH=amd64;; + i686) GOARCH=386;; + armv7l) GOARCH=arm;; + aarch64) GOARCH=arm64;; + *) GOARCH=unknown;; +esac + +download_configs() { + echo "Downloading configs if they are not present" + mkdir -p .zetacored/config/ + mkdir -p .zetacored/data/ + if [[ ! -f .zetacored/config/app.toml ]]; then + $CURL -o .zetacored/config/app.toml "${ZETACHAIN_NETWORK_CONFIG_URL_BASE}/app.toml" + fi + if [[ ! -f .zetacored/config/config.toml ]]; then + $CURL -o .zetacored/config/config.toml "${ZETACHAIN_NETWORK_CONFIG_URL_BASE}/config.toml" + sed -i -e "s/^moniker = .*/moniker = \"${MONIKER}\"/" .zetacored/config/config.toml + fi + if [[ ! -f .zetacored/config/genesis.json ]]; then + $CURL -o .zetacored/config/genesis.json "${ZETACHAIN_NETWORK_CONFIG_URL_BASE}/genesis.json" + fi +} + +install_genesis_zetacored() { + echo "Installing genesis zetacored" + if [[ -z $ZETACORED_BINARY_URL ]]; then + init_height=$($CURL "${ZETACHAIN_INIT_API_URL}/cosmos/base/tendermint/v1beta1/blocks/latest" | jq -r '.block.header.height') + echo "Getting latest passed upgrade plan before ${init_height}" + $CURL "${ZETACHAIN_INIT_API_URL}/cosmos/gov/v1/proposals?pagination.reverse=true" | jq --arg init_height "$init_height" ' + .proposals[] | + select(.status == "PROPOSAL_STATUS_PASSED") | + .messages[] | + select(."@type" == "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade" and (.plan.height | + tonumber < $init_height))' | jq -s '.[0]' | tee /tmp/init-upgrade-plan.json + + ZETACORED_BINARY_URL=$(jq -r '.plan.info' /tmp/init-upgrade-plan.json | jq -r ".binaries[\"linux/$GOARCH\"]") + fi + # go-getter will verify the checksum of the downloaded binary + go-getter --mode file "$ZETACORED_BINARY_URL" .zetacored/cosmovisor/genesis/bin/zetacored + chmod +x .zetacored/cosmovisor/genesis/bin/zetacored + + # run the zetacored version to ensure it's the correct architecture, glibc version, and is in PATH + zetacored version +} + +restore_snapshot() { + snapshot_link=$($CURL "${ZETACHAIN_SNAPSHOT_METADATA_URL}" | jq -r '.snapshots[0].link') + echo "Restoring snapshot from ${snapshot_link}" + $CURL "$snapshot_link" | tar xz -C $HOME/.zetacored +} + +cd $HOME + +if [[ -f /root/init_started && ! -f /root/init_completed ]]; then + echo "Initialization interrupted, resetting node data" + rm -rf .zetacored/data +fi + +touch /root/init_started +if [[ ! -f /root/init_complete ]]; then + echo "Starting initialization" + download_configs + install_genesis_zetacored + restore_snapshot + touch /root/init_complete +else + echo "Initialization already completed" +fi + +# always set IP address as it may change after restart +sed -i -e "s/^external_address = .*/external_address = \"${MY_IP}:26656\"/" .zetacored/config/config.toml + +# shellcheck disable=SC2068 +exec cosmovisor run start --moniker "$MONIKER" $@ \ No newline at end of file