remove signer #5
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Nightly Load Tests | |
| on: | |
| push: | |
| branches: | |
| - feat/nightly-load-tests | |
| schedule: | |
| - cron: '0 4 * * *' | |
| workflow_dispatch: | |
| concurrency: | |
| group: nightly-load-tests-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| ENCLAVE_NAME: nightly-load-tests | |
| POLYCLI_VERSION: v0.1.103 | |
| LOADTEST_REQUESTS: "6000" | |
| LOADTEST_RATE_LIMIT: "100" | |
| LOADTEST_CONCURRENCY: "4" | |
| LOADTEST_MODE: transaction | |
| LOADTEST_GAS_PRICE: "50000000000" | |
| jobs: | |
| build-bor: | |
| name: Build Bor from develop | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout bor | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: develop | |
| - name: Build bor docker image | |
| run: docker build -t bor:local --file Dockerfile . | |
| - name: Save bor docker image | |
| run: docker save bor:local | gzip > bor-image.tar.gz | |
| - name: Upload bor docker image | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bor-image | |
| path: bor-image.tar.gz | |
| retention-days: 1 | |
| build-heimdall-v2: | |
| name: Build Heimdall v2 from develop | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout heimdall-v2 | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: 0xPolygon/heimdall-v2 | |
| ref: develop | |
| - name: Build heimdall-v2 docker image | |
| run: docker build -t heimdall-v2:local --file Dockerfile . | |
| - name: Save heimdall-v2 docker image | |
| run: docker save heimdall-v2:local | gzip > heimdall-v2-image.tar.gz | |
| - name: Upload heimdall-v2 docker image | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: heimdall-v2-image | |
| path: heimdall-v2-image.tar.gz | |
| retention-days: 1 | |
| load-tests: | |
| name: Run Kurtosis load tests | |
| needs: | |
| - build-bor | |
| - build-heimdall-v2 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: read | |
| actions: write | |
| id-token: write | |
| steps: | |
| - name: Checkout kurtosis-pos | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: 0xPolygon/kurtosis-pos | |
| ref: v1.3.4 | |
| - name: Pre kurtosis run | |
| uses: ./.github/actions/kurtosis/setup | |
| with: | |
| main_branch: develop | |
| docker_username: ${{ secrets.DOCKERHUB }} | |
| docker_token: ${{ secrets.DOCKERHUB_KEY }} | |
| - name: Checkout pos-workflows | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: 0xPolygon/pos-workflows | |
| ref: main | |
| path: pos-workflows | |
| - name: Copy kurtosis config | |
| run: cp ./pos-workflows/configs/kurtosis-e2e.yml ./kurtosis-e2e.yml | |
| - name: Download bor docker image | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bor-image | |
| - name: Download heimdall-v2 docker image | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: heimdall-v2-image | |
| - name: Load bor docker image | |
| run: | | |
| gunzip -c bor-image.tar.gz | docker load | |
| docker images bor:local --format "{{.ID}} {{.CreatedAt}}" | |
| - name: Load heimdall-v2 docker image | |
| run: | | |
| gunzip -c heimdall-v2-image.tar.gz | docker load | |
| docker images heimdall-v2:local --format "{{.ID}} {{.CreatedAt}}" | |
| - name: Kurtosis run | |
| run: kurtosis run --args-file=kurtosis-e2e.yml --enclave=${{ env.ENCLAVE_NAME }} . | |
| - name: Inspect enclave | |
| run: kurtosis enclave inspect ${{ env.ENCLAVE_NAME }} | |
| - name: Install polycli | |
| run: | | |
| tmp_dir=$(mktemp -d) | |
| curl -L https://github.com/0xPolygon/polygon-cli/releases/download/${{ env.POLYCLI_VERSION }}/polycli_${{ env.POLYCLI_VERSION }}_linux_amd64.tar.gz | tar -xz -C "$tmp_dir" | |
| mv "$tmp_dir"/* /usr/local/bin/polycli | |
| rm -rf "$tmp_dir" | |
| sudo chmod +x /usr/local/bin/polycli | |
| polycli version | |
| - name: Run polycli load test | |
| id: load-tests | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| LOADTEST_PRIVATE_KEY=$(sed -nE 's/^PRIVATE_KEY=\$\{PRIVATE_KEY:-"([^"]+)".*/\1/p' pos-workflows/tests/pos_test_utils.sh) | |
| LOADTEST_PRIVATE_KEY="${LOADTEST_PRIVATE_KEY//$'\n'/}" | |
| LOADTEST_PRIVATE_KEY="${LOADTEST_PRIVATE_KEY//$'\r'/}" | |
| if [[ -z "$LOADTEST_PRIVATE_KEY" ]]; then | |
| echo "::error::Unable to resolve load test signer from pos-workflows" | |
| exit 1 | |
| fi | |
| if [[ ! "$LOADTEST_PRIVATE_KEY" =~ ^0x?[0-9a-fA-F]{64}$ ]]; then | |
| echo "::error::Load test signer must be a hex-encoded private key" | |
| exit 1 | |
| fi | |
| echo "::add-mask::$LOADTEST_PRIVATE_KEY" | |
| private_key_no_prefix="${LOADTEST_PRIVATE_KEY#0x}" | |
| echo "::add-mask::$private_key_no_prefix" | |
| LOADTEST_PRIVATE_KEY="0x$private_key_no_prefix" | |
| mkdir -p load-test-results | |
| rpc_url=$(kurtosis port print "$ENCLAVE_NAME" l2-el-1-bor-heimdall-v2-validator rpc) | |
| loadtest_address=$(cast wallet address --private-key "$LOADTEST_PRIVATE_KEY") | |
| loadtest_balance=$(cast balance --rpc-url "$rpc_url" "$loadtest_address") | |
| if [[ ! "$loadtest_balance" =~ ^[0-9]+$ ]]; then | |
| echo "::error::Unable to read load test signer balance" | |
| exit 1 | |
| fi | |
| if [[ "$loadtest_balance" =~ ^0+$ ]]; then | |
| echo "::error::Load test signer has no L2 balance" | |
| exit 1 | |
| fi | |
| started_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| started_epoch=$(date +%s) | |
| rpc_call() { | |
| local method="$1" | |
| local params="$2" | |
| curl -fsS \ | |
| -H "Content-Type: application/json" \ | |
| --data "{\"jsonrpc\":\"2.0\",\"method\":\"${method}\",\"params\":${params},\"id\":1}" \ | |
| "$rpc_url" | | |
| jq -r 'if .error then error(.error.message) else .result end' | |
| } | |
| hex_to_dec() { | |
| local value="${1#0x}" | |
| if [ -z "$value" ]; then | |
| echo 0 | |
| return | |
| fi | |
| printf "%d" "$((16#$value))" | |
| } | |
| initial_block=$(hex_to_dec "$(rpc_call eth_blockNumber '[]')") | |
| chain_id=$(hex_to_dec "$(rpc_call eth_chainId '[]')") | |
| { | |
| echo "Started at: $started_at" | |
| echo "RPC URL: $rpc_url" | |
| echo "Chain ID: $chain_id" | |
| echo "Mode: $LOADTEST_MODE" | |
| echo "Requests: $LOADTEST_REQUESTS" | |
| echo "Rate limit: $LOADTEST_RATE_LIMIT requests/sec" | |
| echo "Concurrency: $LOADTEST_CONCURRENCY" | |
| echo "Initial block: $initial_block" | |
| } > load-test-results/metadata.txt | |
| set +e | |
| polycli loadtest \ | |
| --rpc-url "$rpc_url" \ | |
| --private-key "$LOADTEST_PRIVATE_KEY" \ | |
| --verbosity 500 \ | |
| --requests "$LOADTEST_REQUESTS" \ | |
| --rate-limit "$LOADTEST_RATE_LIMIT" \ | |
| --concurrency "$LOADTEST_CONCURRENCY" \ | |
| --mode "$LOADTEST_MODE" \ | |
| --gas-price "$LOADTEST_GAS_PRICE" \ | |
| --summarize \ | |
| --output-mode text 2>&1 | | |
| tee load-test-results/polycli-loadtest.log | |
| loadtest_exit=${PIPESTATUS[0]} | |
| set -e | |
| sed -i "s/$LOADTEST_PRIVATE_KEY/***MASKED***/g" load-test-results/polycli-loadtest.log | |
| sed -i "s/$private_key_no_prefix/***MASKED***/g" load-test-results/polycli-loadtest.log | |
| finished_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| finished_epoch=$(date +%s) | |
| duration_seconds=$((finished_epoch - started_epoch)) | |
| final_block=$(hex_to_dec "$(rpc_call eth_blockNumber '[]')") | |
| blocks_produced=$((final_block - initial_block)) | |
| successful_tx=$(sed -nE 's/.*Successful Tx: ([0-9,]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| total_tx=$(sed -nE 's/.*Total Tx: ([0-9,]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| total_transactions=$(sed -nE 's/^Total Transactions: ([0-9,]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| total_gas_used=$(sed -nE 's/^Total Gas Used: ([0-9,]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| polycli_tps=$(sed -nE 's/^Transactions per sec: ([0-9,.]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| gas_per_second=$(sed -nE 's/^Gas Per Second: ([0-9,.]+).*/\1/p' load-test-results/polycli-loadtest.log | head -n1 | tr -d ',') | |
| latencies=$(sed -nE 's/^Latencies - (.*)/\1/p' load-test-results/polycli-loadtest.log | head -n1) | |
| jq -n \ | |
| --arg started_at "$started_at" \ | |
| --arg finished_at "$finished_at" \ | |
| --arg rpc_url "$rpc_url" \ | |
| --arg mode "$LOADTEST_MODE" \ | |
| --arg successful_tx "$successful_tx" \ | |
| --arg total_tx "$total_tx" \ | |
| --arg total_transactions "$total_transactions" \ | |
| --arg total_gas_used "$total_gas_used" \ | |
| --arg polycli_tps "$polycli_tps" \ | |
| --arg gas_per_second "$gas_per_second" \ | |
| --arg latencies "$latencies" \ | |
| --argjson chain_id "$chain_id" \ | |
| --argjson requests "$LOADTEST_REQUESTS" \ | |
| --argjson rate_limit "$LOADTEST_RATE_LIMIT" \ | |
| --argjson concurrency "$LOADTEST_CONCURRENCY" \ | |
| --argjson gas_price "$LOADTEST_GAS_PRICE" \ | |
| --argjson duration_seconds "$duration_seconds" \ | |
| --argjson initial_block "$initial_block" \ | |
| --argjson final_block "$final_block" \ | |
| --argjson blocks_produced "$blocks_produced" \ | |
| --argjson exit_code "$loadtest_exit" \ | |
| 'def maybe_num($v): if $v == "" then null else ($v | tonumber) end; | |
| { | |
| started_at: $started_at, | |
| finished_at: $finished_at, | |
| rpc_url: $rpc_url, | |
| chain_id: $chain_id, | |
| mode: $mode, | |
| requests: $requests, | |
| rate_limit: $rate_limit, | |
| concurrency: $concurrency, | |
| gas_price: $gas_price, | |
| duration_seconds: $duration_seconds, | |
| initial_block: $initial_block, | |
| final_block: $final_block, | |
| blocks_produced: $blocks_produced, | |
| successful_tx: maybe_num($successful_tx), | |
| total_tx: maybe_num($total_tx), | |
| total_transactions: maybe_num($total_transactions), | |
| total_gas_used: maybe_num($total_gas_used), | |
| transactions_per_second: maybe_num($polycli_tps), | |
| gas_per_second: maybe_num($gas_per_second), | |
| latencies: $latencies, | |
| exit_code: $exit_code | |
| }' > load-test-results/summary.json | |
| { | |
| echo "## Nightly Load Test" | |
| echo "" | |
| echo "| Metric | Value |" | |
| echo "| --- | ---: |" | |
| echo "| Chain ID | $chain_id |" | |
| echo "| Mode | $LOADTEST_MODE |" | |
| echo "| Requests | $LOADTEST_REQUESTS |" | |
| echo "| Rate limit | $LOADTEST_RATE_LIMIT req/s |" | |
| echo "| Concurrency | $LOADTEST_CONCURRENCY |" | |
| echo "| Duration | ${duration_seconds}s |" | |
| echo "| Blocks produced | $blocks_produced |" | |
| echo "| Successful tx | ${successful_tx:-n/a} |" | |
| echo "| Total tx | ${total_tx:-n/a} |" | |
| echo "| Total transactions | ${total_transactions:-n/a} |" | |
| echo "| Total gas used | ${total_gas_used:-n/a} |" | |
| echo "| Transactions/sec | ${polycli_tps:-n/a} |" | |
| echo "| Gas/sec | ${gas_per_second:-n/a} |" | |
| echo "| Latencies | ${latencies:-n/a} |" | |
| echo "| Polycli exit code | $loadtest_exit |" | |
| } > load-test-results/summary.md | |
| cat load-test-results/summary.md >> "$GITHUB_STEP_SUMMARY" | |
| exit "$loadtest_exit" | |
| - name: Upload load test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: nightly-load-test-results | |
| path: load-test-results | |
| if-no-files-found: ignore | |
| retention-days: 14 | |
| - name: Collect network diagnostics and state dump | |
| if: always() && steps.load-tests.outcome == 'failure' | |
| uses: ./pos-workflows/.github/actions/network-diagnostics-and-state-dump | |
| with: | |
| enclave_name: ${{ env.ENCLAVE_NAME }} | |
| - name: Post kurtosis run | |
| if: always() | |
| uses: ./.github/actions/kurtosis/cleanup | |
| with: | |
| main_branch: develop | |
| enclave_name: ${{ env.ENCLAVE_NAME }} |