Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EOC-2158 fork] Merge changes from fork to finalize image #239

Merged
merged 1 commit into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/push-aptos-node.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
env:
PUBLISHER_PRIVATE_KEY: >-
0xeaa964d1353b075ac63b0c5a0c1e92aa93355be1402f6077581e37e2a846105e
EMOJICOIN_MODULE_ADDRESS: >-

Check failure on line 5 in .github/workflows/push-aptos-node.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

5:3 [key-ordering] wrong ordering of key "EMOJICOIN_MODULE_ADDRESS" in mapping
0xf000d910b99722d201c6cf88eb7d1112b43475b9765b118f289b5d65d919000d
jobs:
build-push:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v4'
- id: 'metadata'
uses: 'docker/metadata-action@v5'
with:
images: 'econialabs/emojicoin-dot-fun-local-deployer'
tags: |
type=match,pattern=emojicoin-dot-fun-local-deployer-v(.*),group=1
- uses: 'docker/setup-qemu-action@v3'
- uses: 'docker/setup-buildx-action@v3'
- uses: 'docker/login-action@v3'
with:
password: '${{ secrets.DOCKERHUB_TOKEN }}'
username: '${{ secrets.DOCKERHUB_USERNAME }}'
- uses: 'docker/build-push-action@v6'
with:
build-args: |
PUBLISHER_PRIVATE_KEY=${{ env.PUBLISHER_PRIVATE_KEY }}
EMOJICOIN_MODULE_ADDRESS=${{ env.EMOJICOIN_MODULE_ADDRESS }}
cache-from: 'type=gha'
cache-to: 'type=gha,mode=max'
context: '.'
file: 'src/docker/local-deployer/Dockerfile'
labels: '${{ steps.metadata.outputs.labels }}'
# The emojicoin-node image can only be built for the platform on which
# the build is running. This is because the build process requires
# running `aptos node run-localnet`, which spawns a new container. This
# new container must be able to run the `aptos` binary, which is only
# available for the platform on which the build is running.
platforms: '${{ vars.DOCKER_IMAGE_PLATFORMS }}'
push: 'true'
tags: '${{ steps.metadata.outputs.tags }}'
timeout-minutes: 360
name: 'Build the local-deployer Docker image and push to Dockerhub'
'on':
workflow_dispatch: {}

Check failure on line 45 in .github/workflows/push-aptos-node.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

45:23 [braces] forbidden flow mapping
push:

Check failure on line 46 in .github/workflows/push-aptos-node.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

46:3 [key-ordering] wrong ordering of key "push" in mapping
tags:
- 'emojicoin-dot-fun-local-deployer*'
...
8 changes: 4 additions & 4 deletions .github/workflows/ts-run-tests.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
env:
NEXT_PUBLIC_MODULE_ADDRESS: |-
4bab58978ec1b1bef032eeb285ad47a6a9b997d646c19b598c35f46b26ff9ece
PUBLISHER_PRIVATE_KEY: |-
29479e9e5fe47ba9a8af509dd6da1f907510bcf8917bfb19b7079d8c63c0b720
NEXT_PUBLIC_MODULE_ADDRESS: >-
0xf000d910b99722d201c6cf88eb7d1112b43475b9765b118f289b5d65d919000d
PUBLISHER_PRIVATE_KEY: >-
0xeaa964d1353b075ac63b0c5a0c1e92aa93355be1402f6077581e37e2a846105e
START_LOCAL_NODE_FOR_TEST: 'true'
TS_DIR: 'src/typescript'
jobs:
Expand Down
12 changes: 4 additions & 8 deletions src/docker/compose.local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
aptos-node:
network_mode: 'host'
image: 'econialabs/aptos-cli:4.1.0'
profiles: ["test-harness"]

Check failure on line 8 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

8:16 [quoted-strings] string value is not quoted with single quotes
ports:
- '50051:50051'
- '8070:8070'
Expand All @@ -13,7 +13,7 @@
- '8080:8080'
- '8081:8081'
healthcheck:
test: ['CMD', 'curl', 'http://localhost:8070/']
test: [ 'bash', 'sh/healthcheck.sh' ]
interval: '5s'
timeout: '5s'
retries: 10
Expand All @@ -40,23 +40,19 @@
extra_hosts:
- 'host.docker.internal:host-gateway'
build:
context: ../../

Check failure on line 43 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

43:16 [quoted-strings] string value is not quoted with single quotes
dockerfile: 'src/docker/local-deployer/Dockerfile'
args:
PUBLISHER_PRIVATE_KEY: '${PUBLISHER_PRIVATE_KEY}'
EMOJICOIN_MODULE_ADDRESS: '${EMOJICOIN_MODULE_ADDRESS}'
env_file:
- path: './example.local.env'
required: true
- path: './.env'
required: false
PUBLISHER_PRIVATE_KEY: ${PUBLISHER_PRIVATE_KEY}

Check failure on line 46 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

46:32 [quoted-strings] string value is not quoted with single quotes
environment:
PUBLISHER_PRIVATE_KEY: ${PUBLISHER_PRIVATE_KEY}

Check failure on line 48 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

48:30 [quoted-strings] string value is not quoted with single quotes
image: 'econialabs/emojicoin-dot-fun-local-deployer:latest'
profiles: ["test-harness"]

Check failure on line 50 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

50:16 [quoted-strings] string value is not quoted with single quotes
depends_on:
aptos-node:
condition: 'service_healthy'
processor:
profiles: ["test-harness"]

Check failure on line 55 in src/docker/compose.local.yaml

View workflow job for this annotation

GitHub Actions / pre-commit

55:16 [quoted-strings] string value is not quoted with single quotes
depends_on:
aptos-node:
condition: 'service_healthy'
Expand Down
41 changes: 24 additions & 17 deletions src/docker/local-deployer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
FROM econialabs/aptos-cli:4.1.0 AS aptos-cli
# This is the easiest and most portable way of getting the `yq` binary, since
# the `yq` releases on apt are outdated and technically deprecated.
FROM mikefarah/yq:4.44.3 AS yq

ARG PUBLISHER_PRIVATE_KEY \
EMOJICOIN_MODULE_ADDRESS
ENV PUBLISHER_PRIVATE_KEY=${PUBLISHER_PRIVATE_KEY} \
EMOJICOIN_MODULE_ADDRESS=${EMOJICOIN_MODULE_ADDRESS}
FROM econialabs/aptos-cli:4.1.0

COPY --from=yq /usr/bin/yq /usr/bin/yq

ARG PUBLISHER_PRIVATE_KEY
ENV PUBLISHER_PRIVATE_KEY=${PUBLISHER_PRIVATE_KEY}

# Ensure the publisher private key is set.
RUN test -n "${PUBLISHER_PRIVATE_KEY}"

WORKDIR /app

ARG emojicoin_dir=src/move/emojicoin_dot_fun
ARG rewards_dir=src/move/rewards
COPY ${emojicoin_dir} move/emojicoin_dot_fun
COPY ${rewards_dir} move/rewards
RUN rm -rf move/emojicoin_dot_fun/build move/rewards/build
COPY src/move/emojicoin_dot_fun/sources/* move/emojicoin_dot_fun/sources/
COPY src/move/emojicoin_dot_fun/Move.toml move/emojicoin_dot_fun/Move.toml

COPY src/move/rewards/sources/* move/rewards/sources/
COPY src/move/rewards/Move.toml move/rewards/Move.toml

ARG host_base=src/docker/local-deployer
COPY ${host_base}/sh sh
COPY ${host_base}/json json
COPY src/docker/local-deployer/sh/* sh/
COPY src/docker/local-deployer/json/* json/
COPY src/sh/utils/colors.sh sh/colors.sh

RUN chmod +x sh/build-publish-payloads.sh \
&& chmod +x sh/build-batch-fund-payloads.sh \
&& sh/build-batch-fund-payloads.sh \
&& sh/build-publish-payloads.sh
RUN chmod +x sh/*.sh \
&& sh/init-profile.sh \
&& sh/build-batch-fund-payloads.sh \
&& sh/build-publish-payloads.sh \

ENTRYPOINT [ "bash", "sh/entrypoint.sh" ]
15 changes: 12 additions & 3 deletions src/docker/local-deployer/sh/build-batch-fund-payloads.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

source /app/sh/colors.sh

distribution_amount=10000000000000000

accounts_json_path="/app/json/test-accounts.json"
Expand All @@ -11,9 +13,16 @@ num_accounts=$(jq 'keys | length' $accounts_json_path)
# Calculate amount per key (integer division)
amount_per_account=$((distribution_amount / num_accounts))

for i in {1..2}; do
start_index=$(((i - 1) * 500))
end_index=$((i * 500))
log_info "Distributing $distribution_amount to $num_accounts accounts"

for i in {1..3}; do
start_index=$(((i - 1) * 333))

if [ $i != 3 ]; then
end_index=$((i * 333))
else
end_index=$num_accounts
fi

jq -r --arg amount "$amount_per_account" \
--argjson start "$start_index" \
Expand Down
14 changes: 7 additions & 7 deletions src/docker/local-deployer/sh/build-publish-payloads.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
json_dir="/app/json"
move_dir="/app/move"

# Because the local testnet must be up and running in order to initialize a
# profile, we just have the developer pass in the publisher's address at the
# image build time to avoid the need to run the local testnet in the image build
# process.
address=$EMOJICOIN_MODULE_ADDRESS
source /app/sh/colors.sh

profile="publisher"

log_info "Building and publishing payloads..."

aptos move build-publish-payload \
--assume-yes \
--named-addresses emojicoin_dot_fun=$address \
--named-addresses emojicoin_dot_fun=$profile \
--override-size-check \
--included-artifacts none \
--package-dir $move_dir/emojicoin_dot_fun/ \
Expand All @@ -23,7 +23,7 @@ aptos move build-publish-payload \
aptos move build-publish-payload \
--assume-yes \
--named-addresses \
rewards=$address,integrator=$address,emojicoin_dot_fun=$address \
rewards=$profile,integrator=$profile,emojicoin_dot_fun=$profile \
--override-size-check \
--included-artifacts none \
--package-dir $move_dir/rewards/ \
Expand Down
22 changes: 22 additions & 0 deletions src/docker/local-deployer/sh/cli-profile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# The Aptos CLI is really slow at running commands. Instead of calling
# `aptos account lookup-address` we can just parse the `account`
# field in the `/app/.aptos/config.yaml` file.
CONFIG_PATH="/app/.aptos/config.yaml"

function get_publisher_address() {
if [ -f $CONFIG_PATH ]; then
echo $(cat $CONFIG_PATH | yq -r '.profiles.publisher.account')
else
echo ""
fi
}

function get_publisher_private_key() {
if [ -f $CONFIG_PATH ]; then
echo $(cat $CONFIG_PATH | yq -r '.profiles.publisher.private_key')
else
echo ""
fi
}
63 changes: 36 additions & 27 deletions src/docker/local-deployer/sh/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,73 @@
# cspell:word localnet
# cspell:word argjson

# Environment variables.
publisher_address=$EMOJICOIN_MODULE_ADDRESS
publisher_private_key=$PUBLISHER_PRIVATE_KEY
source /app/sh/cli-profile.sh
source /app/sh/colors.sh

# ------------------------------------------------------------------------------
# Publish the contracts
# Re-initialize the CLI publisher profile if necessary
# ------------------------------------------------------------------------------
profile="publisher"

# Check if the previous profile's private key matches the current private key.
# Generally, this will be the profile created at the image build time.
# If it doesn't match, ensure the CLI recreates the profile with the new key.
profile_private_key=$(get_publisher_private_key)
if [ "$profile_private_key" != "$PUBLISHER_PRIVATE_KEY" ]; then
log_warning \
"The private key for \"publisher\" does not match PUBLISHER_PRIVATE_KEY"
log_warning "PUBLISHER_PRIVATE_KEY: $PUBLISHER_PRIVATE_KEY"
log_warning "\"publisher\" profile: $profile_private_key"
msg="Rebuild the image to skip re-initializing the CLI profile and"
msg="$msg rebuilding the publish payloads on startup."
log_warning "$msg"

bash /app/sh/init-profile.sh
bash /app/sh/build-publish-payloads.sh
fi

fund_amount=20000000000000000
extra_for_gas=200000000
gas_unit_price=100

faucet_url="http://host.docker.internal:8081"
rest_url="http://host.docker.internal:8080/v1"

aptos account fund-with-faucet \
--faucet-url $faucet_url \
--account $publisher_address \
--profile $profile \
--account $profile \
--amount $((fund_amount + extra_for_gas))

# Publish with the JSON publish payloads generated in the build step.
# ------------------------------------------------------------------------------
# Publish the contracts
# ------------------------------------------------------------------------------
gas_unit_price=100

aptos move run \
--json-file /app/json/emojicoin_dot_fun.json \
--assume-yes \
--json-file /app/json/emojicoin_dot_fun.json \
--max-gas 2000000 \
--gas-unit-price $gas_unit_price \
--url $rest_url \
--private-key $publisher_private_key \
--encoding hex
--profile $profile

aptos move run \
--json-file /app/json/rewards.json \
--assume-yes \
--json-file /app/json/rewards.json \
--max-gas 2000000 \
--gas-unit-price $gas_unit_price \
--url $rest_url \
--private-key $publisher_private_key \
--encoding hex
--profile $profile

# ------------------------------------------------------------------------------
# Fund the test accounts
# ------------------------------------------------------------------------------
# Fund test accounts with the batch fund payloads generated in the build step.
num_batches=$(ls $batch_fund_path_prefix-*.json | wc -l)
batch_fund_path_prefix="/app/json/batch-fund"
max_gas=$(((extra_for_gas / gas_unit_price) / 2))
max_gas=$(((extra_for_gas / gas_unit_price) / num_batches))

# Fund the test accounts and inadvertently create them on-chain.
# Do it twice because a single transaction results in an execution limit error.
for i in {1..2}; do
for i in $(seq 1 $num_batches); do
batch_fund_output_path="${batch_fund_path_prefix}-${i}.json"
aptos move run \
--assume-yes \
--private-key $publisher_private_key \
--encoding hex \
--json-file $batch_fund_output_path \
--max-gas $max_gas \
--gas-unit-price 100 \
--url $rest_url \
--private-key $publisher_private_key \
--encoding hex
--profile $profile
done
18 changes: 18 additions & 0 deletions src/docker/local-deployer/sh/healthcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

# Note that the response from the readiness endpoint at http://localhost:8070
# is a JSON object of the following structure:
#
# {
# "ready": [
# // Objects describing services that are ready.
# ],
# "not_ready": [
# // Objects describing services that are not ready.
# ]
# }
#
# `curl` the readiness endpoint and check if the `not_ready` array is empty.
# Pipe the output from `jq` to `grep` to check if the length is 0.

curl -s http://localhost:8070/ | jq '.not_ready | length' | grep -q 0
Loading
Loading