From c2a4bd043410b77297d0e43f82d30a01748f13f9 Mon Sep 17 00:00:00 2001 From: Ram Veigman Date: Wed, 19 Jun 2024 10:13:57 +0300 Subject: [PATCH 1/4] onboarding operator image example --- Operator_Onboarding/.env.example | 21 ++++++++ Operator_Onboarding/Dockerfile.aggregator | 13 +++++ Operator_Onboarding/Dockerfile.operator | 29 ++++++++++ Operator_Onboarding/README.md | 53 +++++++++++++++++++ .../docker-compose.aggregator.yml | 38 +++++++++++++ Operator_Onboarding/entrypoint-operator.sh | 20 +++++++ Operator_Onboarding/run-operator.sh | 28 ++++++++++ Operator_Onboarding/setup.sh | 13 +++++ 8 files changed, 215 insertions(+) create mode 100644 Operator_Onboarding/.env.example create mode 100644 Operator_Onboarding/Dockerfile.aggregator create mode 100644 Operator_Onboarding/Dockerfile.operator create mode 100644 Operator_Onboarding/README.md create mode 100644 Operator_Onboarding/docker-compose.aggregator.yml create mode 100755 Operator_Onboarding/entrypoint-operator.sh create mode 100755 Operator_Onboarding/run-operator.sh create mode 100755 Operator_Onboarding/setup.sh diff --git a/Operator_Onboarding/.env.example b/Operator_Onboarding/.env.example new file mode 100644 index 0000000..2778d67 --- /dev/null +++ b/Operator_Onboarding/.env.example @@ -0,0 +1,21 @@ +PRIVATE_KEY= + +L2_RPC= +L1_RPC= + +IPFS_HOST= +PINATA_API_KEY= +PINATA_SECRET_API_KEY= + +# The task performer should be the address of PRIVATE_KEY +TASK_PERFORMER= + +ATTESTATION_CENTER_ADDRESS= +OTHENTIC_REGISTRY_ADDRESS= +AVS_GOVERNANCE_ADDRESS= + +AVS_WEBAPI=10.8.0.42 +# NOTICE: Bootstrap is also aggregator +OTHENTIC_BOOTSTRAP_IP=10.8.0.69 +OTHENTIC_BOOTSTRAP_ID=12D3KooWBNFG1QjuF3UKAKvqhdXcxh9iBmj88cM5eU2EK5Pa91KB +OTHENTIC_BOOTSTRAP_SEED=97a64de0fb18532d4ce56fb35b730aedec993032b533f783b04c9175d465d9bf diff --git a/Operator_Onboarding/Dockerfile.aggregator b/Operator_Onboarding/Dockerfile.aggregator new file mode 100644 index 0000000..34d9c86 --- /dev/null +++ b/Operator_Onboarding/Dockerfile.aggregator @@ -0,0 +1,13 @@ +FROM node:18 + +RUN npm install -g npm@10.5.0 + +ARG NPM_TOKEN=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 + +WORKDIR /app + +RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > $HOME/.npmrc + +RUN npm i -g @othentic/othentic-cli + +ENTRYPOINT [ "othentic-cli" ] diff --git a/Operator_Onboarding/Dockerfile.operator b/Operator_Onboarding/Dockerfile.operator new file mode 100644 index 0000000..8c0cfdd --- /dev/null +++ b/Operator_Onboarding/Dockerfile.operator @@ -0,0 +1,29 @@ +FROM node:18 + +# NOTICE!!! +# Run from root directory of the project, not from Operator_Onboarding directory + +RUN npm install -g npm@10.5.0 + +ARG NPM_TOKEN=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 + +# Install CLI +RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > $HOME/.npmrc + +RUN npm i -g @othentic/othentic-cli + +# Copy AVS WebAPI +COPY Price_Oracle_AVS_JS/AVS_WebAPI /app/AVS_WebAPI + +WORKDIR /app/AVS_WebAPI + +RUN npm install + +WORKDIR /app + +# Copy entrypoint script +COPY Operator_Onboarding/entrypoint-operator.sh /usr/local/bin/ + +RUN chmod +x /usr/local/bin/entrypoint-operator.sh + +ENTRYPOINT [ "entrypoint-operator.sh" ] diff --git a/Operator_Onboarding/README.md b/Operator_Onboarding/README.md new file mode 100644 index 0000000..d9b91e7 --- /dev/null +++ b/Operator_Onboarding/README.md @@ -0,0 +1,53 @@ +# Operator Onboarding Resources +This folder contains many helpful resources for developing a good operator on-boarding process to AVSs. + +## Operator Onboarding Docker Image +In order to simplify the onboarding process of operators joining an AVS, an AVS can publish an all-in-one docker image for operators to use for various operator activities (registration and running a node). In this folder there is a demo setup for a docker image of that likeness: `Dockerfile.operator`. + +The example uses the `Price_Oracle_AVS_JS` sample present in the samples directory, but this image can be adjusted for other AVSs. + +### Prerequesites +- Foundry +In order to run the example operator onboarding docker image, you need to have already deployed a set of AVS smart contracts. + +### Setup +All the steps are preformed from the root folder `avs-samples`. +This is crucial for the building process of the docker images. + +Copy `.env.example` and fill in environment variables: +``` +cp .env.example .env +``` + +Run the setup script: +``` +chmod +x setup.sh +./setup.sh +``` + +Build the operator docker image: +``` +docker build -f Operator_Onboarding/Dockerfile.operator -t avs-operator . +``` + +To register an operator: +``` +docker run --rm --env-file .env -it avs-operator register +``` + +**You need to register the PRIVATE_KEY you've put in your .env file** + +### Running +To run the AVS operator network, first you need to start the docker compose: +``` +docker-compose -f Operator_Onboarding/docker-compose.aggregator.yml up +``` +This will run the task performer service and the aggregator node. +To add operators to the network, run the command: + +``` +chmod +x ./Operator_Onboarding/run-operator.sh +./Operator_Onboarding/run-operator.sh +``` + +You can view operator node logs through Docker Desktop \ No newline at end of file diff --git a/Operator_Onboarding/docker-compose.aggregator.yml b/Operator_Onboarding/docker-compose.aggregator.yml new file mode 100644 index 0000000..74641c3 --- /dev/null +++ b/Operator_Onboarding/docker-compose.aggregator.yml @@ -0,0 +1,38 @@ +# Needs to be ran from root directory of the project + +version: '3.7' +services: + aggregator: + env_file: + - .env + build: + context: . + dockerfile: ./Dockerfile.aggregator + command: ["node", "aggregator", "--json-rpc"] + ports: + - "8545:8545" + - "9876:9876" + networks: + p2p: + ipv4_address: ${OTHENTIC_BOOTSTRAP_IP} + task-performer: + env_file: + - .env + build: + context: ../Price_Oracle_AVS_JS/Task_Performer + dockerfile: ./Dockerfile + environment: + - OTHENTIC_CLIENT_RPC_ADDRESS=http://${OTHENTIC_BOOTSTRAP_IP}:8545 + ports: + - "4003:4003" + networks: + - p2p + +networks: + p2p: + external: true + driver: bridge + ipam: + config: + - subnet: 10.8.0.0/16 + - gateway: 10.8.0.1 \ No newline at end of file diff --git a/Operator_Onboarding/entrypoint-operator.sh b/Operator_Onboarding/entrypoint-operator.sh new file mode 100755 index 0000000..71dff2b --- /dev/null +++ b/Operator_Onboarding/entrypoint-operator.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# NOTICE: docker needs to be ran with env file + +# node +if [ "$1" = "node" ]; then + # change ip onces there is a bootstrap.othentic.xyz + othentic-cli node attester "/ip4/${OTHENTIC_BOOTSTRAP_IP}/tcp/9876/p2p/${OTHENTIC_BOOTSTRAP_ID}" --avs-webapi "http://${AVS_WEBAPI}" --json-rpc +fi + +# avs-webapi +if [ "$1" = "avs-webapi" ]; then + cd AVS_WebAPI + node index.js +fi + +# needs to be ran interactively and deleted immediately +if [ "$1" = "register" ]; then + othentic-cli operator register +fi diff --git a/Operator_Onboarding/run-operator.sh b/Operator_Onboarding/run-operator.sh new file mode 100755 index 0000000..519fd4f --- /dev/null +++ b/Operator_Onboarding/run-operator.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Validate private key +cast wallet address $1 || exit 1 + +SCRIPT_PATH="$(realpath "$0")" +SCRIPT_DIR="$(dirname "$SCRIPT_PATH")" + +# Work from the script directory +cd $SCRIPT_DIR + +source .env + +NETWORK_NAME="p2p" +IMAGE_NAME="avs-operator" +AVS_WEBAPI_CONTAINER_NAME="AVS_WebAPI" + +# the name of the operator container is deterministic with respect to the private key. +# we hash the private key, and take the first 8 bytes of the hash in base64 +IDENTIFIER=$(echo -n $1 | openssl dgst -sha256 -binary | xxd -l 4 -p) +OPERATOR_CONTAINER_NAME="AVS_Operator_${IDENTIFIER}" + +# docker start $AVS_WEBAPI_CONTAINER_NAME || docker run --name $AVS_WEBAPI_CONTAINER_NAME -d $IMAGE_NAME --network p2p +# When running multiple AVS operators on the same machine, boot only one instance of AVS WebAPI +docker start $AVS_WEBAPI_CONTAINER_NAME 2>/dev/null || docker run --name $AVS_WEBAPI_CONTAINER_NAME --env-file .env --network p2p --ip $AVS_WEBAPI -d $IMAGE_NAME avs-webapi || exit 1 +docker start $OPERATOR_CONTAINER_NAME 2>/dev/null || docker run --name $OPERATOR_CONTAINER_NAME --env-file .env --network p2p -d $IMAGE_NAME node $1 || exit 1 + +echo "Operator container is running with name $OPERATOR_CONTAINER_NAME" diff --git a/Operator_Onboarding/setup.sh b/Operator_Onboarding/setup.sh new file mode 100755 index 0000000..b7844b5 --- /dev/null +++ b/Operator_Onboarding/setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Name of the Docker network +NETWORK_NAME="p2p" + +# Check if the network already exists +if docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then + echo "Docker network '$NETWORK_NAME' already exists." +else + # Create the Docker network + docker network create "$NETWORK_NAME" --subnet 10.8.0.0/16 --gateway 10.8.0.1 + echo "Docker network '$NETWORK_NAME' created." +fi \ No newline at end of file From 2b6c4d1fcd24413c86799a590b7fa56d36740937 Mon Sep 17 00:00:00 2001 From: Ram Veigman Date: Wed, 19 Jun 2024 16:05:36 +0300 Subject: [PATCH 2/4] fix env vars --- Operator_Onboarding/.env.example | 5 ++--- Operator_Onboarding/docker-compose.aggregator.yml | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Operator_Onboarding/.env.example b/Operator_Onboarding/.env.example index 2778d67..c9c65f8 100644 --- a/Operator_Onboarding/.env.example +++ b/Operator_Onboarding/.env.example @@ -1,4 +1,5 @@ -PRIVATE_KEY= +PRIVATE_KEY_PERFORMER= +PRIVATE_KEY_AGGREGATOR= L2_RPC= L1_RPC= @@ -7,8 +8,6 @@ IPFS_HOST= PINATA_API_KEY= PINATA_SECRET_API_KEY= -# The task performer should be the address of PRIVATE_KEY -TASK_PERFORMER= ATTESTATION_CENTER_ADDRESS= OTHENTIC_REGISTRY_ADDRESS= diff --git a/Operator_Onboarding/docker-compose.aggregator.yml b/Operator_Onboarding/docker-compose.aggregator.yml index 74641c3..5797eae 100644 --- a/Operator_Onboarding/docker-compose.aggregator.yml +++ b/Operator_Onboarding/docker-compose.aggregator.yml @@ -5,6 +5,9 @@ services: aggregator: env_file: - .env + environment: + - PRIVATE_KEY=${PRIVATE_KEY_AGGREGATOR:-${PRIVATE_KEY:-}} + - TASK_PERFORMER=0x0000000000000000000000000000000000000000 build: context: . dockerfile: ./Dockerfile.aggregator @@ -23,6 +26,8 @@ services: dockerfile: ./Dockerfile environment: - OTHENTIC_CLIENT_RPC_ADDRESS=http://${OTHENTIC_BOOTSTRAP_IP}:8545 + - PRIVATE_KEY=${PRIVATE_KEY_PERFORMER:-${PRIVATE_KEY:-}} + - TASK_PERFORMER=0x0000000000000000000000000000000000000000 ports: - "4003:4003" networks: From 2598e865ccceb857dc83c71558a6e7ace3fb0f66 Mon Sep 17 00:00:00 2001 From: Ram Veigman Date: Wed, 19 Jun 2024 16:06:25 +0300 Subject: [PATCH 3/4] fix run operator script --- Operator_Onboarding/run-operator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Operator_Onboarding/run-operator.sh b/Operator_Onboarding/run-operator.sh index 519fd4f..e43d3c5 100755 --- a/Operator_Onboarding/run-operator.sh +++ b/Operator_Onboarding/run-operator.sh @@ -23,6 +23,6 @@ OPERATOR_CONTAINER_NAME="AVS_Operator_${IDENTIFIER}" # docker start $AVS_WEBAPI_CONTAINER_NAME || docker run --name $AVS_WEBAPI_CONTAINER_NAME -d $IMAGE_NAME --network p2p # When running multiple AVS operators on the same machine, boot only one instance of AVS WebAPI docker start $AVS_WEBAPI_CONTAINER_NAME 2>/dev/null || docker run --name $AVS_WEBAPI_CONTAINER_NAME --env-file .env --network p2p --ip $AVS_WEBAPI -d $IMAGE_NAME avs-webapi || exit 1 -docker start $OPERATOR_CONTAINER_NAME 2>/dev/null || docker run --name $OPERATOR_CONTAINER_NAME --env-file .env --network p2p -d $IMAGE_NAME node $1 || exit 1 +docker start $OPERATOR_CONTAINER_NAME 2>/dev/null || docker run --name $OPERATOR_CONTAINER_NAME --env-file .env -e PRIVATE_KEY=$1 --network p2p -d $IMAGE_NAME node $1 || exit 1 echo "Operator container is running with name $OPERATOR_CONTAINER_NAME" From aac4d7409495578e8b39a31384f355e833ca3430 Mon Sep 17 00:00:00 2001 From: Ram Veigman Date: Wed, 19 Jun 2024 16:06:36 +0300 Subject: [PATCH 4/4] remove confusing comment --- Operator_Onboarding/entrypoint-operator.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/Operator_Onboarding/entrypoint-operator.sh b/Operator_Onboarding/entrypoint-operator.sh index 71dff2b..4af3e6d 100755 --- a/Operator_Onboarding/entrypoint-operator.sh +++ b/Operator_Onboarding/entrypoint-operator.sh @@ -4,7 +4,6 @@ # node if [ "$1" = "node" ]; then - # change ip onces there is a bootstrap.othentic.xyz othentic-cli node attester "/ip4/${OTHENTIC_BOOTSTRAP_IP}/tcp/9876/p2p/${OTHENTIC_BOOTSTRAP_ID}" --avs-webapi "http://${AVS_WEBAPI}" --json-rpc fi