Skip to content

[M] Deploy Testnet L2 ( uat-testnet ) #728

[M] Deploy Testnet L2 ( uat-testnet )

[M] Deploy Testnet L2 ( uat-testnet ) #728

# Deploys an Obscuro network on Azure for Testnet and Dev Testnet
#
# The Obscuro network is composed of 2 obscuro nodes running on individual vms with SGX. At the moment the workflow
# can only be triggered manually as a workflow dispatch.
#
# This script uses GitHub Environments for variables (vars) and secrets - these are configured on GitHub and
# the environments match the input.testnet_type options
name: '[M] Deploy Testnet L2'
run-name: '[M] Deploy Testnet L2 ( ${{ github.event.inputs.testnet_type }} )'
on:
workflow_dispatch:
inputs:
testnet_type:
description: 'Testnet Type'
required: true
default: 'dev-testnet'
type: choice
options:
- 'dev-testnet'
- 'uat-testnet'
- 'sepolia-testnet'
log_level:
description: 'Log Level 1-Error 5-Trace'
required: true
default: 3
type: number
jobs:
build:
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
# Map a step output to a job output
outputs:
MGMT_CONTRACT_ADDR: ${{ steps.deployContracts.outputs.MGMT_CONTRACT_ADDR }}
MSG_BUS_CONTRACT_ADDR: ${{ steps.deployContracts.outputs.MSG_BUS_CONTRACT_ADDR }}
L1_START_HASH: ${{ steps.deployContracts.outputs.L1_START_HASH }}
HOC_ERC20_ADDR: ${{ steps.deployContracts.outputs.HOC_ERC20_ADDR }}
POC_ERC20_ADDR: ${{ steps.deployContracts.outputs.POC_ERC20_ADDR }}
steps:
- name: 'Print GitHub variables'
# This is a useful record of what the environment variables were at the time the job ran, for debugging and reference
run: |
echo "GitHub Variables = ${{ toJSON(vars) }}"
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: 1.20.4
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Login to Azure docker registry'
uses: azure/docker-login@v1
with:
login-server: testnetobscuronet.azurecr.io
username: testnetobscuronet
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: 'Build and push obscuro node images'
run: |
DOCKER_BUILDKIT=1 docker build -t ${{ vars.DOCKER_BUILD_TAG_ENCLAVE }} -f dockerfiles/enclave.Dockerfile .
docker push ${{ vars.DOCKER_BUILD_TAG_ENCLAVE }}
DOCKER_BUILDKIT=1 docker build -t ${{ vars.DOCKER_BUILD_TAG_HOST }} -f dockerfiles/host.Dockerfile .
docker push ${{ vars.DOCKER_BUILD_TAG_HOST }}
DOCKER_BUILDKIT=1 docker build -t ${{ vars.DOCKER_BUILD_TAG_L2_HARDHAT_DEPLOYER }} -f tools/hardhatdeployer/Dockerfile .
docker push ${{ vars.DOCKER_BUILD_TAG_L2_HARDHAT_DEPLOYER }}
- name: 'Deploy Contracts'
id: deployContracts
shell: bash
run: |
go run ./testnet/launcher/l1contractdeployer/cmd \
-l1_http_url=${{ secrets.L1_HTTP_URL }} \
-private_key=${{ secrets.ACCOUNT_PK_WORKER }} \
-docker_image=${{ vars.DOCKER_BUILD_TAG_L2_HARDHAT_DEPLOYER }} \
-contracts_env_file=./testnet/.env
source ./testnet/.env
echo "Contracts deployed to $MGMTCONTRACTADDR"
echo "MGMT_CONTRACT_ADDR=$MGMTCONTRACTADDR" >> $GITHUB_ENV
echo "MGMT_CONTRACT_ADDR=$MGMTCONTRACTADDR" >> $GITHUB_OUTPUT
echo "MSG_BUS_CONTRACT_ADDR=$MSGBUSCONTRACTADDR" >> $GITHUB_ENV
echo "MSG_BUS_CONTRACT_ADDR=$MSGBUSCONTRACTADDR" >> $GITHUB_OUTPUT
echo "L1_START_HASH=$L1START" >> $GITHUB_ENV
echo "L1_START_HASH=$L1START" >> $GITHUB_OUTPUT
- name: 'Save L1 deployer container logs'
# Wait to make sure the logs are available in the container
run: |
sleep 60
docker logs `docker ps -aqf "name=hh-l1-deployer"` > deploy-l1-contracts.out 2>&1
# This will fail some deletions due to resource dependencies ( ie. you must first delete the vm before deleting the disk)
- name: 'Delete deployed VMs'
uses: azure/CLI@v1
with:
inlineScript: |
$(az resource list --tag ${{ vars.AZURE_DEPLOY_GROUP_L2 }}=true --query '[]."id"' -o tsv | xargs -n1 az resource delete --verbose -g Testnet --ids) || true
# This will clean up any lingering dependencies - might fail if there are no resources to cleanup
- name: 'Delete VMs dependencies'
uses: azure/CLI@v1
with:
inlineScript: |
$(az resource list --tag ${{ vars.AZURE_DEPLOY_GROUP_L2 }}=true --query '[]."id"' -o tsv | xargs -n1 az resource delete --verbose -g Testnet --ids) || true
- name: 'Upload L1 deployer container logs'
uses: actions/upload-artifact@v3
with:
name: deploy-l1-artifacts
path: |
deploy-l1-contracts.out
retention-days: 1
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
strategy:
matrix:
host_id: [ 0,1 ]
include:
# Ensure there is a single genesis node
- is_genesis: true
host_id: 0
- is_genesis: false
host_id: 1
# Ensure there is a single sequencer
- node_type: sequencer
host_id: 0
- node_type: validator
host_id: 1
# Hardcoded lookup keys because GH actions doesn't let you build them inline with the host_id
- node_pk_lookup: ACCOUNT_PK_NODE_0
host_id: 0
- node_pk_lookup: ACCOUNT_PK_NODE_1
host_id: 1
- node_addr_lookup: ACCOUNT_ADDR_NODE_0
host_id: 0
- node_addr_lookup: ACCOUNT_ADDR_NODE_1
host_id: 1
- node_l1_ws_lookup: L1_WS_URL_0
host_id: 0
- node_l1_ws_lookup: L1_WS_URL_1
host_id: 1
steps:
- name: 'Extract branch name'
shell: bash
run: |
echo "Branch Name: ${GITHUB_REF_NAME}"
echo "BRANCH_NAME=${GITHUB_REF_NAME}" >> $GITHUB_ENV
# The Azure API will sometimes supersede PUT requests that come in close together. This sleep will stagger the VM requests.
# It expects host_id to be an int and then multiplies it by 60s (i.e. host 0: sleep 0, host 1: sleep 60,...)
- name: 'Stagger VM creation'
shell: bash
run: sleep `expr ${{matrix.host_id}} \* 60`
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Create VM for Obscuro node-${{ matrix.host_id }} on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm create -g Testnet -n "${{ vars.AZURE_RESOURCE_PREFIX }}-${{ matrix.host_id }}-${{ GITHUB.RUN_NUMBER }}" \
--admin-username obscurouser --admin-password "${{ secrets.OBSCURO_NODE_VM_PWD }}" \
--public-ip-address-dns-name "obscuronode-${{ matrix.host_id }}-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}" \
--tags deploygroup=ObscuroNode-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }} ${{ vars.AZURE_DEPLOY_GROUP_L2 }}=true \
--vnet-name ${{ github.event.inputs.testnet_type }}-virtual-network --subnet ${{ github.event.inputs.testnet_type }}-sub-network \
--size Standard_DC8_v2 --storage-sku StandardSSD_LRS --image ObscuroConfUbuntu \
--public-ip-sku Standard --authentication-type password
- name: 'Open Obscuro node-${{ matrix.host_id }} ports on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm open-port -g Testnet -n "${{ vars.AZURE_RESOURCE_PREFIX }}-${{ matrix.host_id }}-${{ GITHUB.RUN_NUMBER }}" --port 80,81,6060,6061,10000
# To overcome issues with critical VM resources being unavailable, we need to wait for the VM to be ready
- name: 'Allow time for VM initialization'
shell: bash
run: sleep 60
- name: 'Start Obscuro node-${{ matrix.host_id }} on Azure'
uses: azure/CLI@v1
with:
inlineScript: |
az vm run-command invoke -g Testnet -n "${{ vars.AZURE_RESOURCE_PREFIX }}-${{ matrix.host_id }}-${{ GITHUB.RUN_NUMBER }}" \
--command-id RunShellScript \
--scripts 'mkdir -p /home/obscuro \
&& git clone --depth 1 -b ${{ env.BRANCH_NAME }} https://github.com/obscuronet/go-obscuro.git /home/obscuro/go-obscuro \
&& docker network create --driver bridge node_network || true \
&& docker run -d --name datadog-agent \
--network node_network \
-e DD_API_KEY=${{ secrets.DD_API_KEY }} \
-e DD_LOGS_ENABLED=true \
-e DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL=true \
-e DD_LOGS_CONFIG_AUTO_MULTI_LINE_DETECTION=true \
-e DD_CONTAINER_EXCLUDE_LOGS="name:datadog-agent" \
-e DD_SITE="datadoghq.eu" \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /proc/:/host/proc/:ro \
-v /opt/datadog-agent/run:/opt/datadog-agent/run:rw \
-v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
datadog/agent:latest \
&& cd /home/obscuro/go-obscuro/ \
&& sudo go run /home/obscuro/go-obscuro/go/node/cmd \
-is_genesis=${{ matrix.is_genesis }} \
-node_type=${{ matrix.node_type }} \
-is_sgx_enabled=true \
-host_id=${{ vars[matrix.node_addr_lookup] }} \
-l1_ws_url=${{ secrets[matrix.node_l1_ws_lookup] }} \
-management_contract_addr=${{needs.build.outputs.MGMT_CONTRACT_ADDR}} \
-message_bus_contract_addr=${{needs.build.outputs.MSG_BUS_CONTRACT_ADDR}} \
-l1_start=${{needs.build.outputs.L1_START_HASH}} \
-private_key=${{ secrets[matrix.node_pk_lookup] }} \
-sequencer_id=${{ vars.ACCOUNT_ADDR_NODE_0 }} \
-host_public_p2p_addr=obscuronode-${{ matrix.host_id }}-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}.uksouth.cloudapp.azure.com:10000 \
-host_p2p_port=10000 \
-enclave_docker_image=${{ vars.L2_ENCLAVE_DOCKER_BUILD_TAG }} \
-host_docker_image=${{ vars.L2_HOST_DOCKER_BUILD_TAG }} \
-is_debug_namespace_enabled=true \
-log_level=${{ github.event.inputs.log_level }} \
-batch_interval=${{ vars.L2_BATCH_INTERVAL }} \
-max_batch_interval=${{ vars.L2_MAX_BATCH_INTERVAL }} \
-rollup_interval=${{ vars.L2_ROLLUP_INTERVAL }} \
-l1_chain_id=${{ vars.L1_CHAIN_ID }} \
start'
update-loadbalancer:
needs:
- build
- deploy
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
steps:
- uses: actions/checkout@v3
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Remove existing backend nodes from the load balancer'
run: ./.github/workflows/runner-scripts/testnet-clear-loadbalancer.sh ${{ github.event.inputs.testnet_type }}
- name: 'Add load balancer address pool to the IP configuration'
uses: azure/CLI@v1
with:
inlineScript: |
az network nic ip-config address-pool add \
--address-pool ${{ github.event.inputs.testnet_type }}-backend-pool \
--ip-config-name ipconfig${{ vars.AZURE_RESOURCE_PREFIX }}-1-${{ GITHUB.RUN_NUMBER }} \
--nic-name ${{ vars.AZURE_RESOURCE_PREFIX }}-1-${{ GITHUB.RUN_NUMBER }}VMNic \
--resource-group Testnet \
--lb-name ${{ github.event.inputs.testnet_type }}-loadbalancer
check-obscuro-is-healthy:
needs:
- build
- deploy
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
steps:
- uses: actions/checkout@v3
- name: "Wait until obscuro node is healthy"
shell: bash
run: |
./.github/workflows/runner-scripts/wait-node-healthy.sh --host=obscuronode-0-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}.uksouth.cloudapp.azure.com
./.github/workflows/runner-scripts/wait-node-healthy.sh --host=obscuronode-1-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}.uksouth.cloudapp.azure.com
deploy-l2-contracts:
needs:
- build
- check-obscuro-is-healthy
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
steps:
- uses: actions/checkout@v3
- name: 'Deploy L2 contracts'
id: deployL2Contracts
shell: bash
run: |
go run ./testnet/launcher/l2contractdeployer/cmd \
-l2_host=obscuronode-0-${{ github.event.inputs.testnet_type }}-${{ GITHUB.RUN_NUMBER }}.uksouth.cloudapp.azure.com \
-l1_http_url=${{ secrets.L1_HTTP_URL }} \
-l2_ws_port=81 \
-private_key=${{ secrets.ACCOUNT_PK_WORKER }} \
-l2_private_key=8dfb8083da6275ae3e4f41e3e8a8c19d028d32c9247e24530933782f2a05035b \
-l2_hoc_private_key=6e384a07a01263518a09a5424c7b6bbfc3604ba7d93f47e3a455cbdd7f9f0682 \
-l2_poc_private_key=4bfe14725e685901c062ccd4e220c61cf9c189897b6c78bd18d7f51291b2b8f8 \
-message_bus_contract_addr=${{ needs.build.outputs.MSG_BUS_CONTRACT_ADDR }} \
-docker_image=${{ vars.L2_HARDHATDEPLOYER_DOCKER_BUILD_TAG }} \
-faucet_funds=${{ vars.FAUCET_INITIAL_FUNDS }}
- name: 'Save L2 deployer container logs'
run: |
docker logs `docker ps -aqf "name=hh-l2-deployer"` > deploy-l2-contracts.out 2>&1
- name: 'Upload L2 deployer container logs'
uses: actions/upload-artifact@v3
with:
name: deploy-l2-artifacts
path: |
deploy-l2-contracts.out
retention-days: 1
deploy-faucet:
name: 'Trigger Faucet deployment for dev- / testnet on a new deployment'
uses: ./.github/workflows/manual-deploy-testnet-faucet.yml
with:
testnet_type: ${{ github.event.inputs.testnet_type }}
secrets: inherit
needs:
- check-obscuro-is-healthy
obscuro-test-repository-dispatch:
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
needs:
- deploy-faucet
steps:
- name: 'Send a repository dispatch to obscuro-test on deployment of dev-testnet'
if: ${{ (github.event.inputs.testnet_type == 'dev-testnet') }}
run: |
curl -XPOST -H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" -H "Accept:application/vnd.github" -H "Content-Type:application/json" https://api.github.com/repos/obscuronet/obscuro-test/dispatches --data '{ "event_type": "dev_testnet_deployed", "client_payload": { "ref": "${{ github.ref_name }}" }'
- name: 'Send a repository dispatch to obscuro-test on deployment of testnet'
if: ${{ (github.event.inputs.testnet_type == 'uat-testnet') }}
run: |
curl -XPOST -H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" -H "Accept:application/vnd.github" -H "Content-Type:application/json" https://api.github.com/repos/obscuronet/obscuro-test/dispatches --data '{ "event_type": "uat_testnet_deployed", "client_payload": { "ref": "${{ github.ref_name }}" }'