Skip to content

Commit

Permalink
chore: test 4epochs in native-network (#9309)
Browse files Browse the repository at this point in the history
Reproduces #8855
  • Loading branch information
ludamad authored Oct 22, 2024
1 parent ea9ee39 commit ddb312a
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 154 deletions.
18 changes: 11 additions & 7 deletions scripts/earthly-ci
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ export FORCE_COLOR=1
export EARTHLY_CONFIG=$(git rev-parse --show-toplevel)/.github/earthly-ci-config.yml

function wipe_non_cache_docker_state {
echo "Detected corrupted docker images. Wiping and trying again."
# Based on https://stackoverflow.com/a/75849307
# wipe everything but volumes where we have earthly cache
sudo service docker stop
sudo bash -c 'rm -rf /var/lib/docker/{buildkit,containers,image,network,overlay2,plugins.runtimes,swarm,tmp,trust}/*' || true
# restart docker - might take down builds, but we need to recover anyway
sudo service docker restart
flock -n "$HOME/wipe_docker_state.lock" bash -c '
echo "Detected corrupted docker images. Wiping and trying again."
# Based on https://stackoverflow.com/a/75849307
# wipe everything but volumes where we have earthly cache
sudo service docker stop
sudo bash -c '"'"'rm -rf /var/lib/docker/{buildkit,containers,image,network,overlay2,plugins,runtimes,swarm,tmp,trust}/*'"'"' || true
# restart docker - might take down builds, but we need to recover anyway
sudo service docker restart
'
}

EARTHLY_RUN_STATS_JSON="earthly-run-stats.json"
Expand Down Expand Up @@ -108,10 +110,12 @@ while [ $ATTEMPT_COUNT -lt $MAX_ATTEMPTS ]; do
fi
sleep 20
elif grep 'status 125: docker: Error response from daemon: layer does not exist.' $OUTPUT_FILE >/dev/null \
|| grep 'could not start container "earthly-buildkitd"' $OUTPUT_FILE >/dev/null \
|| grep 'could not determine buildkit address - is Docker or Podman running?' $OUTPUT_FILE >/dev/null \
|| grep 'please make sure the URL is valid, and Docker 18.09 or later is installed on the remote host' $OUTPUT_FILE >/dev/null \
|| grep 'docker: failed to register layer' $OUTPUT_FILE >/dev/null \
|| grep 'docker: error during connect:' $OUTPUT_FILE >/dev/null \
|| grep 'docker: failed to write digest data' >/dev/null \
|| grep 'docker: unexpected EOF' $OUTPUT_FILE >/dev/null ; then
wipe_non_cache_docker_state
# wait for other docker restarts
Expand Down
16 changes: 8 additions & 8 deletions scripts/run_interleaved.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,18 @@ colors=(
"\e[91m" # Bright Red
)

FINISHED=false
main_cmd="$1"
shift

# pattern from https://stackoverflow.com/questions/28238952/how-to-kill-a-running-bash-function-from-terminal
function cleanup_function() {
kill $(jobs -p) 2>/dev/null || true
return
function cleanup() {
# kill everything in our process group except our process
trap - SIGTERM && kill $(pgrep -g $$ | grep -v $$) 2>/dev/null || true
}
trap cleanup SIGINT SIGTERM EXIT

# Function to run a command and prefix the output with color
function run_command() {
# pattern from https://stackoverflow.com/questions/28238952/how-to-kill-a-running-bash-function-from-terminal
trap cleanup_function INT EXIT
local cmd="$1"
local color="$2"
$cmd 2>&1 | while IFS= read -r line; do
Expand All @@ -50,9 +49,10 @@ function run_command() {
# Run background commands without logging output
i=0
for cmd in "$@"; do
run_command "$cmd" "${colors[$((i % ${#colors[@]}))]}" &
(run_command "$cmd" "${colors[$((i % ${#colors[@]}))]}" || [ $FINISHED = true ] || (echo "$cmd causing terminate" && kill 0) ) &
((i++)) || true # annoyingly considered a failure based on result
done

# Run the main command synchronously, piping output through the run_command function with green color
run_command "$main_cmd" "\e[32m"
run_command "$main_cmd" "\e[32m" || (echo "$main_cmd causing terminate" && kill 0)
FINISHED=true
36 changes: 23 additions & 13 deletions scripts/run_native_testnet.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

set -eu

: '
This script sets up and runs a native testnet for the Aztec network.
Expand All @@ -24,28 +26,29 @@ Options:
see display_help() below
'

# Default values
TEST_SCRIPT=./test-transfer.sh
PROVER_SCRIPT="\"./prover-node.sh 8078 false\""
NUM_VALIDATORS=3
INTERLEAVED=false

# Function to display help message
display_help() {
echo "Usage: $0 [options]"
echo
echo "Options:"
echo " -h Display this help message"
echo " -t Specify the test script file (default: ./test-transfer.sh)"
echo " -val Specify the number of validators (default: 3)"
echo " -t Specify the test file (default: $TEST_FILE)"
echo " -p Specify the prover command (default: $PROVER_SCRIPT)"
echo " -val Specify the number of validators (default: $NUM_VALIDATORS)"
echo " -v Set logging level to verbose"
echo " -vv Set logging level to debug"
echo " -i Run interleaved (default: false)"
echo " -i Run interleaved (default: $INTERLEAVED)"
echo
echo "Example:"
echo " $0 -t ./custom-test.sh -val 5 -v"
echo " $0 -t ./test-4epochs.sh -val 5 -v"
}

# Default values
TEST_SCRIPT="./test-transfer.sh"
NUM_VALIDATORS=3
LOG_LEVEL="info"
INTERLEAVED=false

# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
Expand All @@ -57,6 +60,10 @@ while [[ $# -gt 0 ]]; do
TEST_SCRIPT="$2"
shift 2
;;
-p)
PROVER_SCRIPT="$2"
shift 2
;;
-val)
NUM_VALIDATORS="$2"
shift 2
Expand Down Expand Up @@ -88,17 +95,20 @@ done
## Set log level for all child commands
export LOG_LEVEL

# Go to repo root
cd $(git rev-parse --show-toplevel)

# Base command
BASE_CMD="INTERLEAVED=$INTERLEAVED ./yarn-project/end-to-end/scripts/native_network_test.sh \
$TEST_SCRIPT \
./deploy-l1-contracts.sh \
./deploy-l2-contracts.sh \
./boot-node.sh \
./ethereum.sh \
\"./prover-node.sh 8078 false\" \
\"./validators.sh $NUM_VALIDATORS\" \
$PROVER_SCRIPT \
./pxe.sh \
./transaction-bot.sh \
\"./validators.sh $NUM_VALIDATORS\""
./transaction-bot.sh"

# Execute the command
eval $BASE_CMD
34 changes: 0 additions & 34 deletions yarn-project/canary/scripts/cond_run_script

This file was deleted.

2 changes: 0 additions & 2 deletions yarn-project/end-to-end/scripts/native-network/pxe.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ echo "Waiting for Aztec Node..."
until curl -s http://127.0.0.1:8080/status >/dev/null ; do
sleep 1
done
echo "Done waiting."

# We need to also wait for the validator, as the initial node cannot
# Produce blocks on it's own
echo "Waiting for Validator 0..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

set -eu

TEST=$1
# Get the name of the script without the path and extension
SCRIPT_NAME=$(basename "$0" .sh)

Expand Down Expand Up @@ -31,6 +30,6 @@ echo "Done waiting."
export DEBUG="aztec:*"
export LOG_LEVEL=${LOG_LEVEL:-"debug"}
export PXE_URL=http://localhost:8079
export ETHEREUM_HOST=http://localhost:8545
export ETHEREUM_HOST=http://127.0.0.1:8545
cd $(git rev-parse --show-toplevel)/yarn-project/end-to-end
yarn test "$TEST"
yarn test src/spartan/4epochs.test.ts
16 changes: 6 additions & 10 deletions yarn-project/end-to-end/scripts/network_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,13 @@ function show_status_until_pxe_ready() {
}

show_status_until_pxe_ready &
SHOW_STATUS_PID=$!

function cleanup() {
# kill everything in our process group except our process
kill $(pgrep -g $$ | grep -v $$) || true
kill $(jobs -p) || true
}
trap cleanup SIGINT SIGTERM EXIT
# Install the Helm chart
helm upgrade --install spartan "$REPO/spartan/aztec-network/" \
--namespace "$NAMESPACE" \
Expand All @@ -79,15 +84,6 @@ kubectl wait pod -l app==pxe --for=condition=Ready -n "$NAMESPACE" --timeout=10m

# tunnel in to get access directly to our PXE service in k8s
(kubectl port-forward --namespace $NAMESPACE svc/spartan-aztec-network-pxe 9082:8080 2>/dev/null >/dev/null || true) &
PORT_FORWARD_PID=$!

cleanup() {
echo "Cleaning up..."
kill $PORT_FORWARD_PID || true
kill $SHOW_STATUS_PID || true
}

trap cleanup EXIT SIGINT SIGTERM

docker run --rm --network=host \
-e PXE_URL=http://localhost:9082 \
Expand Down
90 changes: 90 additions & 0 deletions yarn-project/end-to-end/src/spartan/4epochs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { EthCheatCodes, readFieldCompressedString } from '@aztec/aztec.js';
import { AZTEC_SLOT_DURATION } from '@aztec/circuits.js';
import { createDebugLogger } from '@aztec/foundation/log';
import { TokenContract } from '@aztec/noir-contracts.js';

import { jest } from '@jest/globals';

import { RollupCheatCodes } from '../../../aztec.js/src/utils/cheat_codes.js';
import { type TestWallets, setupTestWalletsWithTokens } from './setup_test_wallets.js';

const { PXE_URL, ETHEREUM_HOST } = process.env;
if (!PXE_URL) {
throw new Error('PXE_URL env variable must be set');
}
if (!ETHEREUM_HOST) {
throw new Error('ETHEREUM_HOST env variable must be set');
}

describe('token transfer test', () => {
jest.setTimeout(10 * 60 * 2000); // 20 minutes

const logger = createDebugLogger(`aztec:spartan:4epochs`);
// We want plenty of minted tokens for a lot of slots that fill up multiple epochs
const MINT_AMOUNT = 2000000n;
const TEST_EPOCHS = 4;
const ROUNDS = BigInt(AZTEC_SLOT_DURATION * TEST_EPOCHS);

let testWallets: TestWallets;

beforeAll(async () => {
testWallets = await setupTestWalletsWithTokens(PXE_URL, MINT_AMOUNT, logger);
expect(ROUNDS).toBeLessThanOrEqual(MINT_AMOUNT);
});

it('can get info', async () => {
const name = readFieldCompressedString(await testWallets.tokenAdminWallet.methods.private_get_name().simulate());
expect(name).toBe(testWallets.tokenName);
});

it('transfer tokens for 4 epochs', async () => {
const ethCheatCodes = new EthCheatCodes(ETHEREUM_HOST);
// Get 4 epochs
const rollupCheatCodes = new RollupCheatCodes(
ethCheatCodes,
await testWallets.pxe.getNodeInfo().then(n => n.l1ContractAddresses),
);
const recipient = testWallets.recipientWallet.getAddress();
const transferAmount = 1n;

testWallets.wallets.forEach(async w => {
expect(MINT_AMOUNT).toBe(await testWallets.tokenAdminWallet.methods.balance_of_public(w.getAddress()).simulate());
});

expect(0n).toBe(await testWallets.tokenAdminWallet.methods.balance_of_public(recipient).simulate());

// For each round, make both private and public transfers
const startSlot = await rollupCheatCodes.getSlot();
for (let i = 1n; i <= ROUNDS; i++) {
const interactions = await Promise.all([
...testWallets.wallets.map(async w =>
(
await TokenContract.at(testWallets.tokenAddress, w)
).methods.transfer_public(w.getAddress(), recipient, transferAmount, 0),
),
]);

const txs = await Promise.all(interactions.map(async i => await i.prove()));

await Promise.all(txs.map(t => t.send().wait({ timeout: 600 })));
const currentSlot = await rollupCheatCodes.getSlot();
expect(currentSlot).toBe(startSlot + i);
const startEpoch = await rollupCheatCodes.getEpoch();
logger.debug(
`Successfully reached slot ${currentSlot} (iteration ${
currentSlot - startSlot
}/${ROUNDS}) (Epoch ${startEpoch})`,
);
}

testWallets.wallets.forEach(async w => {
expect(MINT_AMOUNT - ROUNDS * transferAmount).toBe(
await testWallets.tokenAdminWallet.methods.balance_of_public(w.getAddress()).simulate(),
);
});

expect(ROUNDS * transferAmount * BigInt(testWallets.wallets.length)).toBe(
await testWallets.tokenAdminWallet.methods.balance_of_public(recipient).simulate(),
);
});
});
Loading

0 comments on commit ddb312a

Please sign in to comment.