diff --git a/.github/changelog.json b/.github/changelog.json new file mode 100644 index 000000000..4fe255e69 --- /dev/null +++ b/.github/changelog.json @@ -0,0 +1,16 @@ +{ + "categories": [ + { + "title": "## Features", + "labels": ["T-feature"] + }, + { + "title": "## Fixes", + "labels": ["T-bug", "T-fix"] + } + ], + "ignore_labels": ["L-ignore"], + "template": "${{CHANGELOG}}\n## Other\n\n${{UNCATEGORIZED}}", + "pr_template": "- ${{TITLE}} (#${{NUMBER}})", + "empty_template": "- No changes" +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..d5104703e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,71 @@ +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +name: Release Teleporter + +on: + push: + tags: + - "v*.*.0" + +jobs: + build_and_upload_artifacts: + name: Build and Upload Teleporter Artifacts + runs-on: ubuntu-20.04 + env: + deployment_tx_fn: TeleporterMessenger_Deployment_Transaction_${{ github.ref_name }}.txt + deployer_addr_fn: TeleporterMessenger_Deployer_Address_${{ github.ref_name }}.txt + contract_addr_fn: TeleporterMessenger_Contract_Address_${{ github.ref_name }}.txt + steps: + - name: Check out the repo + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set Go version + run: | + source ./scripts/versions.sh + echo GO_VERSION=$GO_VERSION >> $GITHUB_ENV + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Build Contracts + run: | + export PATH=$PATH:$HOME/.foundry/bin + cd contracts/ + forge build + + - name: Build changelog + id: build_changelog + uses: mikepenz/release-changelog-builder-action@v4 + with: + failOnError: true + configuration: "./.github/changelog.json" + toTag: ${{ github.ref_name }} + + - name: Create Artifacts + id: artifacts + run: | + go run utils/contract-deployment/contractDeploymentTools.go constructKeylessTx contracts/out/TeleporterMessenger.sol/TeleporterMessenger.json + mv UniversalTeleporterDeployerTransaction.txt ${{ env.deployment_tx_fn }} + mv UniversalTeleporterDeployerAddress.txt ${{ env.deployer_addr_fn }} + mv UniversalTeleporterMessengerContractAddress.txt ${{ env.contract_addr_fn }} + + - name: Create release + uses: softprops/action-gh-release@v1 + with: + name: ${{ github.ref_name }} + tag_name: ${{ github.ref_name }} + prerelease: false + body: ${{ steps.build_changelog.outputs.changelog }} + files: | + ${{ env.deployment_tx_fn }} + ${{ env.deployer_addr_fn }} + ${{ env.contract_addr_fn }} + \ No newline at end of file diff --git a/README.md b/README.md index 81aa1030c..ebfb77bf0 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,21 @@ cp .env.example .env # Set proper values after copying. The user wallet set in `.env` must have native tokens for each of the subnets used in order for the test flows to be able to send transactions on those networks. +## Deploy Teleporter to a Subnet + +From the root of the repo, the TeleporterMessenger contract can be deployed by calling +```bash +./scripts/deploy_teleporter.sh +``` +Options for this script: +- `--version ` Required. Specify the release version to deploy. These will all be of the form `v1.X.0`. Each Teleporter version can only send and receive messages from the **same** Teleporter version on another chain. You can see a list of released versions at https://github.com/ava-labs/teleporter/releases. +- `--rpc-url ` Required. Specify the rpc url of the node to use. +- `--fund-deployer ` Optional. Funds the deployer address with the account held by `` + +To ensure that Teleporter can be deployed to the same address on every EVM based chain, it uses [Nick's Method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c) to deploy from a static deployer address. Teleporter costs exactly `10eth` in the subnet's native gas token to deploy, which must be sent to the deployer address. + +`deploy_teleporter.sh` will send the necessary native tokens to the deployer address if it is provided with a private key for an account with sufficient funds. Alternatively, the deployer address can be funded externally. The deployer address for each version can be found by looking up the appropriate version at https://github.com/ava-labs/teleporter/releases and downloading `TeleporterMessenger_Deployer_Address_.txt`. + ## ABI Bindings To generate Golang ABI bindings for the Solidity smart contracts, run: diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index aa5faed3d..a4d5dd054 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -39,8 +39,7 @@ if [ "$HELP" = true ]; then fi if ! command -v forge &> /dev/null; then - echo "forge not found, installing" - $TELEPORTER_PATH/scripts/install_foundry.sh + echo "forge not found. You can install by calling $TELEPORTER_PATH/scripts/install_foundry.sh" && exit 1 fi echo "Building subnet-evm abigen" @@ -81,4 +80,4 @@ do echo "Done generating Go bindings for $contract_name." done -exit 0 \ No newline at end of file +exit 0 diff --git a/scripts/deploy_teleporter.sh b/scripts/deploy_teleporter.sh new file mode 100755 index 000000000..fd9991748 --- /dev/null +++ b/scripts/deploy_teleporter.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +TELEPORTER_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +if ! command -v forge &> /dev/null; then + echo "forge not found. You can install by calling $TELEPORTER_PATH/scripts/install_foundry.sh" && exit 1 +fi + +function printHelp() { + echo "Usage: ./scripts/deploy_teleporter.sh [OPTIONS]" + echo "Deploys a selected TeleporterMessenger contract to the specified chain" + echo "For a list of releases, go to https://github.com/ava-labs/teleporter/releases" + printUsage +} + +function printUsage() { + echo "Options:" + echo " --fund-deployer Optional. Funds the deployer address with the account held by " + echo " --version Required. Specify the release version to deploy" + echo " --rpc-url Required. Specify the rpc url of the node to use" + echo " --help Print this help message" +} + +teleporter_version= +user_private_key= +rpc_url= + +while [ $# -gt 0 ]; do + case "$1" in + --fund-deployer) + if [[ $2 != --* ]]; then + user_private_key=$2 + else + echo "Invalid private key $2" && printHelp && exit 1 + fi + shift;; + --version) + if [[ $2 != --* ]]; then + teleporter_version=$2 + else + echo "Invalid teleporter version $2" && printHelp && exit 1 + fi + shift;; + --rpc-url) + if [[ $2 != --* ]]; then + rpc_url=$2 + else + echo "Invalid rpc url $2" && printHelp && exit 1 + fi + shift;; + --help) + printHelp && exit 0 ;; + *) + echo "Invalid option: -$1" && printHelp && exit 1;; + esac + shift +done + +# Tokens required to deploy the contract. +# Equal to contractCreationGasLimit * contractCreationGasPrice +# from utils/deployment-utils/deployment_utils.go +gas_tokens_required=10000000000000000000 # 10^19 wei = 10 eth + +# Download the artifacts for this release. +teleporter_contract_address=$(curl -sL https://github.com/ava-labs/teleporter/releases/download/$teleporter_version/TeleporterMessenger_Contract_Address_$teleporter_version.txt) +echo "TeleporterMessenger $teleporter_version contract address: $teleporter_contract_address" +teleporter_deployer_address=$(curl -sL https://github.com/ava-labs/teleporter/releases/download/$teleporter_version/TeleporterMessenger_Deployer_Address_$teleporter_version.txt) +echo "TeleporterMessenger $teleporter_version deployer address: $teleporter_deployer_address" +teleporter_deploy_tx=$(curl -sL https://github.com/ava-labs/teleporter/releases/download/$teleporter_version/TeleporterMessenger_Deployment_Transaction_$teleporter_version.txt) + +# Check if this TeleporterMessenger version has already been deployed on this chain. +if [[ $(cast code --rpc-url $rpc_url $teleporter_contract_address) != "0x" ]]; then + echo "TeleporterMessenger $teleporter_version has already been deployed on this chain." && exit 0 +fi + +# Check the current balance of the deployer address. +deployer_balance=$(cast balance --rpc-url $rpc_url $teleporter_deployer_address) + +if [[ $(echo "$deployer_balance>=$gas_tokens_required" | bc) == 1 ]]; then + echo "Deployer address already funded" +else + # Calculate how many wei the deployer address needs to create the contract. + transfer_amount=$(echo "$gas_tokens_required-$deployer_balance" | bc) + if [[ $user_private_key == "" ]]; then + echo "No private key provided. Deployer address must be funded with $transfer_amount wei to deploy contract" && exit 1 + fi + echo "Funding deployer address with $transfer_amount wei" + cast send --rpc-url $rpc_url --private-key $user_private_key --value $transfer_amount $teleporter_deployer_address +fi + +echo "Deploying TeleporterMessenger $teleporter_version" +cast publish --rpc-url $rpc_url $teleporter_deploy_tx + +echo "Success! TeleporterMessenger $teleporter_version deployed to $teleporter_deployer_address" +exit 0