Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5964641
chore: externalize c-chain-reexecution json based workflow into tasks
Elvis339 Oct 30, 2025
70fbc9f
ci(c-chain-reexecution): remove relative imports to make this action …
Elvis339 Oct 30, 2025
d5bc227
ci(c-chain-reexecution): use correct shells
Elvis339 Oct 30, 2025
ff86c39
ci(c-chain-reexecution)!:
Elvis339 Oct 30, 2025
b88c5ea
copilot PR comments
Elvis339 Oct 30, 2025
c753cf9
ci(c-chain-reexecution): set absolute path to benchmark output file r…
Elvis339 Oct 30, 2025
7b3a231
address pr review
Elvis339 Nov 3, 2025
c0281ed
address PR
Elvis339 Nov 3, 2025
10c5ef7
ci(c-chain-reexecution-benchmark): revert change on `Push Post-State …
Elvis339 Nov 3, 2025
7d7956c
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 3, 2025
a42e26b
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 4, 2025
785278f
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 5, 2025
c5b650a
chore(benchamrk_cchain_range): avoid duplicating the default of `RUNN…
Elvis339 Nov 5, 2025
20c4ad0
ci(c-chain-reexecution):
Elvis339 Nov 5, 2025
f9b3ce0
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 5, 2025
519e92a
chore: rm doc
Elvis339 Nov 5, 2025
f3d56fb
Merge remote-tracking branch 'origin/es/task-reexecution' into es/tas…
Elvis339 Nov 5, 2025
69c38b5
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 6, 2025
a800ff1
ci(c-chain-reexecution): support alternative approach to task based o…
Elvis339 Nov 6, 2025
f7f0ccf
ci(c-chain-reexecution): support both container and native altenrativ…
Elvis339 Nov 6, 2025
ef5cae7
Merge remote-tracking branch 'origin/es/task-reexecution' into es/tas…
Elvis339 Nov 6, 2025
7921a03
lint
Elvis339 Nov 6, 2025
e703fe0
refactor(scripts): extract S3 bucket config from copy_dir.sh to Taskf…
Elvis339 Nov 6, 2025
d359c7a
fix
Elvis339 Nov 6, 2025
30e7b0c
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 7, 2025
0cb04dc
ci(c-chain-reexecution): use dynamic env variable for benchmark outpu…
Elvis339 Nov 12, 2025
8082a9e
Merge remote-tracking branch 'origin/es/task-reexecution' into es/tas…
Elvis339 Nov 12, 2025
3b2a82f
ci(c-chain-reexecution): remove unused `TASK_NAME` environment variable
Elvis339 Nov 12, 2025
3483737
ci(c-chain-reexecution): enforce required `runner` parameter by remov…
Elvis339 Nov 12, 2025
c14c088
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 12, 2025
5aab3dc
docs(reexecute)
Elvis339 Nov 14, 2025
7182799
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 14, 2025
4615490
ci(c-chain-reexecution): add runner presets with custom override
Elvis339 Nov 14, 2025
6090a32
Merge branch 'es/task-reexecution' of github.com:ava-labs/avalanchego…
Elvis339 Nov 14, 2025
c8b4a5a
Merge branch 'master' into es/task-reexecution
Elvis339 Nov 17, 2025
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
164 changes: 121 additions & 43 deletions .github/actions/c-chain-reexecution-benchmark/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@ name: 'C-Chain Re-Execution Benchmark'
description: 'Run C-Chain re-execution benchmark'

inputs:
runner_name:
description: 'The name of the runner to use and include in the Golang Benchmark name.'
required: true
task:
description: 'Task name to execute from Taskfile.yml. Leave empty to use custom inputs below.'
default: ''
# Custom inputs (alternative to task-based approach)
config:
description: 'The config to pass to the VM for the benchmark. See BenchmarkReexecuteRange for details.'
default: ''
start-block:
description: 'The start block for the benchmark.'
default: '101'
default: ''
end-block:
description: 'The end block for the benchmark.'
default: '250000'
default: ''
block-dir-src:
description: 'The source block directory. Supports S3 directory/zip and local directories.'
default: 's3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-1m-ldb/**'
default: ''
current-state-dir-src:
description: 'The current state directory. Supports S3 directory/zip and local directories.'
default: 's3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-100/**'
default: ''
runner_name:
description: 'The name of the runner to use and include in the Golang Benchmark name.'
required: true
aws-role:
description: 'AWS role to assume for S3 access.'
required: true
aws-region:
description: 'AWS region to use for S3 access.'
required: true
default: 'us-east-2'
aws-role-duration-seconds:
description: 'The duration of the AWS role to assume for S3 access.'
required: true
Expand Down Expand Up @@ -56,54 +60,126 @@ inputs:
push-github-action-benchmark:
description: 'Whether to push the benchmark result to GitHub.'
required: true
default: false
push-post-state:
description: 'S3 destination to copy the current-state directory after completing re-execution. If empty, this will be skipped.'
default: ''
# The following inputs need never be provided by the caller. They
# default to context values that the action's steps are unable to
# access directly.
repository-owner:
default: ${{ github.repository_owner }}
repository-name:
default: ${{ github.event.repository.name }}
workflow:
default: ${{ github.workflow }}
run-id:
default: ${{ github.run_id }}
run-number:
default: ${{ github.run_number }}
run-attempt:
default: ${{ github.run_attempt }}
job:
default: ${{ github.job }}

runs:
using: composite
steps:
- name: Set task env
- uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f #v31
with:
github_access_token: ${{ inputs.github-token }}
- run: echo "dependencies installed"
shell: nix develop --command bash {0}
# Cache Go modules (architecture-independent)
- uses: actions/cache@v4
id: go-mod-cache
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-mod-${{ hashFiles('go.sum') }}
restore-keys: ${{ runner.os }}-go-mod-
# Cache Go build cache (architecture-specific)
- uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-${{ runner.arch }}-go-build-${{ hashFiles('go.sum') }}
restore-keys: ${{ runner.os }}-${{ runner.arch }}-go-build-
# Download modules only on cache miss
- run: go mod download
if: steps.go-mod-cache.outputs.cache-hit != 'true'
shell: nix develop --command bash -x {0}
- name: Notify of metrics availability
if: inputs.prometheus-username != ''
shell: bash
run: |
{
echo "EXECUTION_DATA_DIR=${{ inputs.workspace }}/reexecution-data"
echo "BENCHMARK_OUTPUT_FILE=output.txt"
echo "START_BLOCK=${{ inputs.start-block }}"
echo "END_BLOCK=${{ inputs.end-block }}"
echo "BLOCK_DIR_SRC=${{ inputs.block-dir-src }}"
echo "CURRENT_STATE_DIR_SRC=${{ inputs.current-state-dir-src }}"
} >> $GITHUB_ENV
metrics_url=$($GITHUB_ACTION_PATH/output-metrics-url.sh)
echo "Grafana: ${metrics_url}"
echo "🔗 [View Grafana Dashboard](${metrics_url})" >> "$GITHUB_STEP_SUMMARY"
env:
GRAFANA_URL: https://grafana-poc.avax-dev.network/d/Gl1I20mnk/c-chain?orgId=1&refresh=10s&var-filter=is_ephemeral_node%7C%3D%7Cfalse&var-filter=gh_repo%7C%3D%7C${{ inputs.repository_owner }}%2F${{ inputs.repository_name }}&var-filter=gh_run_id%7C%3D%7C${{ inputs.run_id }}&var-filter=gh_run_attempt%7C%3D%7C${{ inputs.run_attempt }}
GH_JOB_ID: ${{ inputs.job }}
- name: Warn that collection of metrics and logs will not be performed
if: inputs.prometheus-username == ''
shell: bash
run: echo "::warning::Monitoring credentials not found. Skipping collector start. Is the PR from a fork branch?"
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ inputs.aws-role }}
aws-region: ${{ inputs.aws-region }}
role-duration-seconds: ${{ inputs.aws-role-duration-seconds }}
- name: Run C-Chain Re-Execution
uses: ./.github/actions/run-monitored-tmpnet-cmd
with:
run: |
- name: Validate inputs
shell: bash
run: |
if [[ -z "${{ inputs.task }}" ]]; then
# Granular mode - validate required inputs
missing=()
[[ -z "${{ inputs.block-dir-src }}" ]] && missing+=("block-dir-src")
[[ -z "${{ inputs.current-state-dir-src }}" ]] && missing+=("current-state-dir-src")
[[ -z "${{ inputs.start-block }}" ]] && missing+=("start-block")
[[ -z "${{ inputs.end-block }}" ]] && missing+=("end-block")

if [[ ${#missing[@]} -gt 0 ]]; then
echo "::error::When 'task' is empty, the following inputs are required: ${missing[*]}"
exit 1
fi
fi
- name: Set task env
shell: bash
run: |
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
echo "EXECUTION_DATA_DIR=/tmp/reexecution-data-${TIMESTAMP}" >> "$GITHUB_ENV"
echo "BENCHMARK_OUTPUT_FILE=${GITHUB_WORKSPACE}/benchmark-output.txt" >> "$GITHUB_ENV"
- name: Run C-Chain Re-execution Benchmark
shell: nix develop --impure --command bash -x {0}
run: |
if [[ -n "${{ inputs.task }}" ]]; then
# Task-based approach
./scripts/run_task.sh ${{ inputs.task }} \
BENCHMARK_OUTPUT_FILE="${{ env.BENCHMARK_OUTPUT_FILE }}" \
EXECUTION_DATA_DIR="${{ env.EXECUTION_DATA_DIR }}"
else
# Granular approach
./scripts/run_task.sh reexecute-cchain-range-with-copied-data \
CONFIG=${{ inputs.config }} \
EXECUTION_DATA_DIR=${{ env.EXECUTION_DATA_DIR }} \
BLOCK_DIR_SRC=${{ env.BLOCK_DIR_SRC }} \
CURRENT_STATE_DIR_SRC=${{ env.CURRENT_STATE_DIR_SRC }} \
START_BLOCK=${{ env.START_BLOCK }} \
END_BLOCK=${{ env.END_BLOCK }} \
LABELS=${{ env.LABELS }} \
BENCHMARK_OUTPUT_FILE=${{ env.BENCHMARK_OUTPUT_FILE }} \
RUNNER_NAME=${{ inputs.runner_name }} \
METRICS_SERVER_ENABLED=true \
METRICS_COLLECTOR_ENABLED=true
prometheus_url: ${{ inputs.prometheus-url }}
prometheus_push_url: ${{ inputs.prometheus-push-url }}
prometheus_username: ${{ inputs.prometheus-username }}
prometheus_password: ${{ inputs.prometheus-password }}
grafana_dashboard_id: 'Gl1I20mnk/c-chain'
runtime: "" # Set runtime input to empty string to disable log collection

BLOCK_DIR_SRC=${{ inputs.block-dir-src }} \
CURRENT_STATE_DIR_SRC=${{ inputs.current-state-dir-src }} \
START_BLOCK=${{ inputs.start-block }} \
END_BLOCK=${{ inputs.end-block }} \
BENCHMARK_OUTPUT_FILE="${{ env.BENCHMARK_OUTPUT_FILE }}"
fi
env:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why were some env vars removed in this change? It seems like metrics server enabled and labels were dropped here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In current master labels were never set, not even in the parent action for example we can see labels are empty on this run.

Regarding metrics server enabled we consolidated it making it implicitly controlled by whether the collector is enabled.

The benchmark_cchain_range.sh script reads these from the environment using the ${VAR:+--flag} pattern, so they're still available just passed through environment variables instead of explicit task parameters. This makes the workflow cleaner since monitoring config is grouped in the env: section.

RUNNER_NAME: ${{ inputs.runner_name }}
METRICS_COLLECTOR_ENABLED: ${{ inputs.prometheus-username != '' }}
PROMETHEUS_URL: ${{ inputs.prometheus-url }}
PROMETHEUS_PUSH_URL: ${{ inputs.prometheus-push-url }}
PROMETHEUS_USERNAME: ${{ inputs.prometheus-username }}
PROMETHEUS_PASSWORD: ${{ inputs.prometheus-password }}
GH_REPO: ${{ inputs.repository_owner }}/${{ inputs.repository_name }}
GH_WORKFLOW: ${{ inputs.workflow }}
GH_RUN_ID: ${{ inputs.run_id }}
GH_RUN_NUMBER: ${{ inputs.run_number }}
GH_RUN_ATTEMPT: ${{ inputs.run_attempt }}
GH_JOB_ID: ${{ inputs.job }}
- name: Compare Benchmark Results
uses: benchmark-action/github-action-benchmark@v1
with:
Expand All @@ -112,8 +188,10 @@ runs:
summary-always: true
github-token: ${{ inputs.github-token }}
auto-push: ${{ inputs.push-github-action-benchmark }}

- name: Push Post-State to S3 (if not exists)
if: ${{ inputs.push-post-state != '' }}
shell: nix develop --command bash -x {0}
run: ./scripts/run_task.sh export-dir-to-s3 SRC=${{ env.EXECUTION_DATA_DIR }}/current-state/ DST=${{ inputs.push-post-state }}
- name: Push Post-State to S3
if: inputs.push-post-state != ''
shell: nix develop --impure --command bash -x {0}
run: |
./scripts/run_task.sh export-dir-to-s3 \
SRC=${{ env.EXECUTION_DATA_DIR }}/current-state/ \
DST=${{ inputs.push-post-state }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

# WARNING: This file is a duplication of:
# - .github/actions/run-monitored-tmpnet-cmd/output-metrics-url.sh (source of truth)
# Changes must be made to BOTH files.

set -euo pipefail

# Timestamps are in seconds
from_timestamp="$(date '+%s')"
monitoring_period=900 # 15 minutes
to_timestamp="$((from_timestamp + monitoring_period))"

# Grafana expects microseconds, so pad timestamps with 3 zeros
metrics_url="${GRAFANA_URL}&var-filter=gh_job_id%7C%3D%7C${GH_JOB_ID}&from=${from_timestamp}000&to=${to_timestamp}000"

# Optionally ensure that the link displays metrics only for the shared
# network rather than mixing it with the results for private networks.
if [[ -n "${FILTER_BY_OWNER:-}" ]]; then
metrics_url="${metrics_url}&var-filter=network_owner%7C%3D%7C${FILTER_BY_OWNER}"
fi

echo "${metrics_url}"
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env bash

# WARNING: This file is duplicated at:
# - .github/actions/c-chain-reexecution-benchmark/output-metrics-url.sh (copy)
# Changes must be made to BOTH files.

set -euo pipefail

# Timestamps are in seconds
Expand Down
24 changes: 4 additions & 20 deletions .github/workflows/c-chain-reexecution-benchmark-container.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,12 @@
"include": [
{
"runner": "ubuntu-latest",
"config": "default",
"start-block": 101,
"end-block": 250000,
"block-dir-src": "s3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-1m-ldb/**",
"current-state-dir-src": "s3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-100/**",
"task": "c-chain-reexecution-hashdb-101-250k",
"timeout-minutes": 30
},
{
"runner": "avalanche-avalanchego-runner-2ti",
"config": "default",
"start-block": 101,
"end-block": 250000,
"block-dir-src": "s3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-1m-ldb/**",
"current-state-dir-src": "s3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-100/**",
"task": "c-chain-reexecution-hashdb-101-250k",
"timeout-minutes": 30
}
]
Expand All @@ -25,20 +17,12 @@
"include": [
{
"runner": "avago-runner-m6i-4xlarge-ebs-fast",
"config": "default",
"start-block": 33000001,
"end-block": 33500000,
"block-dir-src": "s3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-30m-40m-ldb/**",
"current-state-dir-src": "s3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-33m/**",
"task": "c-chain-reexecution-hashdb-33m-33m500k",
"timeout-minutes": 1440
},
{
"runner": "avago-runner-i4i-4xlarge-local-ssd",
"config": "default",
"start-block": 33000001,
"end-block": 33500000,
"block-dir-src": "s3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-30m-40m-ldb/**",
"current-state-dir-src": "s3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-33m/**",
"task": "c-chain-reexecution-hashdb-33m-33m500k",
"timeout-minutes": 1440
}
]
Expand Down
61 changes: 36 additions & 25 deletions .github/workflows/c-chain-reexecution-benchmark-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,39 @@ on:
inputs:
config:
description: 'The config to pass to the VM for the benchmark. See BenchmarkReexecuteRange for details.'
required: false
default: ''
start-block:
description: 'The start block for the benchmark.'
required: false
default: 101
default: ''
end-block:
description: 'The end block for the benchmark.'
required: false
default: 250000
default: ''
block-dir-src:
description: 'The source block directory. Supports S3 directory/zip and local directories.'
required: false
default: s3://avalanchego-bootstrap-testing/cchain-mainnet-blocks-1m-ldb/**
default: ''
current-state-dir-src:
description: 'The current state directory. Supports S3 directory/zip and local directories.'
required: false
default: s3://avalanchego-bootstrap-testing/cchain-current-state-hashdb-full-100/**
runner:
description: 'Runner to execute the benchmark. Input to the runs-on field of the job.'
required: false
default: ''
task:
description: 'Taskfile task to execute (e.g., c-chain-reexecution-hashdb-101-250k)'
default: ''
runner-preset:
description: 'Select a predefined runner (ignored if custom-runner is provided)'
type: choice
options:
- ubuntu-latest
- avalanche-avalanchego-runner-2ti
- avago-runner-m6i-4xlarge-ebs-fast
- avago-runner-i4i-4xlarge-local-ssd
default: ubuntu-latest
custom-runner:
description: 'Custom runner name (overrides runner-preset if provided)'
default: ''
push-post-state:
description: 'S3 location to push post-execution state directory. Skips this step if left unpopulated.'
default: ''
timeout-minutes:
description: 'Timeout in minutes for the job.'
required: false
default: 30

# Disabled because scheduled trigger is empty. To enable, uncomment and add at least one vector to the schedule
Expand All @@ -53,15 +58,20 @@ jobs:
shell: bash -x {0}
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Use custom-runner if provided (after trimming whitespace), otherwise use runner-preset
CUSTOM_RUNNER=$(echo "${{ github.event.inputs.custom-runner }}" | xargs)

if [[ -n "$CUSTOM_RUNNER" ]]; then
RUNNER="$CUSTOM_RUNNER"
else
RUNNER="${{ github.event.inputs.runner-preset }}"
fi

{
echo "matrix<<EOF"
printf '{ "include": [{ "start-block": "%s", "end-block": "%s", "block-dir-src": "%s", "current-state-dir-src": "%s", "config": "%s", "runner": "%s", "timeout-minutes": %s }] }\n' \
"${{ github.event.inputs.start-block }}" \
"${{ github.event.inputs.end-block }}" \
"${{ github.event.inputs.block-dir-src }}" \
"${{ github.event.inputs.current-state-dir-src }}" \
"${{ github.event.inputs.config }}" \
"${{ github.event.inputs.runner }}" \
printf '{ "include": [{ "task": "%s", "runner": "%s", "timeout-minutes": %s }] }\n' \
"${{ github.event.inputs.task }}" \
"$RUNNER" \
"${{ github.event.inputs.timeout-minutes }}"
echo EOF
} >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -100,11 +110,12 @@ jobs:
- name: Run C-Chain Re-Execution Benchmark
uses: ./.github/actions/c-chain-reexecution-benchmark
with:
config: ${{ matrix.config }}
start-block: ${{ matrix.start-block }}
end-block: ${{ matrix.end-block }}
block-dir-src: ${{ matrix.block-dir-src }}
current-state-dir-src: ${{ matrix.current-state-dir-src }}
task: ${{ matrix.task }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we use matrix.task here and do not push the dynamic params into the matrix, doesn't this also mean that we can no longer run dynamic task definitions from the JSON files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean to update JSON file with dynamic inputs (runner, start, end block...) then no, you'd have to create a task.

What's the need for this when we support dynamic dispatch assuming I understood the question.

config: ${{ inputs.config }}
start-block: ${{ inputs.start-block }}
end-block: ${{ inputs.end-block }}
block-dir-src: ${{ inputs.block-dir-src }}
current-state-dir-src: ${{ inputs.current-state-dir-src }}
prometheus-url: ${{ secrets.PROMETHEUS_URL || '' }}
prometheus-push-url: ${{ secrets.PROMETHEUS_PUSH_URL || '' }}
prometheus-username: ${{ secrets.PROMETHEUS_USERNAME || '' }}
Expand Down
Loading