Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4e308b5
bench: add shell.nix
willcl-ark Feb 10, 2025
341dddf
bench: add uv + python deps
willcl-ark Feb 10, 2025
b22f432
guix: add fortified glibc 2.42
fanquake Jul 26, 2023
9d98a1b
guix: build x86_64-linux bitcoind fully statically
fanquake Aug 23, 2022
cb32524
clone guix into bench-ci
willcl-ark Oct 28, 2025
17e6cc6
modify bench-ci/guix params for benchmarking
willcl-ark Oct 28, 2025
508a526
bench: add benchmark ci workflows
willcl-ark Oct 28, 2025
0cc1391
add justfile
willcl-ark Oct 28, 2025
be3cb01
guix: build static
willcl-ark Oct 29, 2025
7306412
doc: add benchcoin docs
willcl-ark Feb 10, 2025
ea7616b
remove legacy assumeutxo bench
willcl-ark Feb 13, 2025
0401fa8
use *instrumented for flame runs
willcl-ark Feb 13, 2025
52c52bb
add uninstrumented run
willcl-ark Feb 13, 2025
67676e7
include instrumentation in name to avoid conflicts
willcl-ark Feb 14, 2025
39fda0d
allow failing source guix profile
willcl-ark Feb 14, 2025
d4f546a
use github guix mirror (faster)
willcl-ark Mar 11, 2025
9e41eab
Ignore speedup of instrumented runs
l0rinc Mar 13, 2025
201b294
remove nightly upstream sync
willcl-ark Mar 17, 2025
ec3c842
Add commit id to the plots to make sure they're not overwritten
l0rinc Mar 19, 2025
e602abb
Plot coins_cache_vs_height instead of coins_cache_vs_time
l0rinc Apr 7, 2025
315bc1f
Add vertical lines for major protocol upgrades if this is a height-ba…
l0rinc Apr 7, 2025
84bb746
drop page cache before each run
willcl-ark Dec 5, 2025
8340346
refactor shared functions
willcl-ark Dec 5, 2025
f571372
fixup! drop page cache before each run
willcl-ark Dec 5, 2025
fa11663
use SCHED_OTHER in instrumented run
willcl-ark Dec 5, 2025
48e26de
test clearer results chart
willcl-ark Dec 6, 2025
bfae964
bump to nixos 25.11
willcl-ark Dec 4, 2025
191ffc5
add nix flake
willcl-ark Dec 8, 2025
541d1db
switch to nix build
willcl-ark Dec 8, 2025
39a9a6d
disable ccache for now
willcl-ark Dec 8, 2025
31836d5
increase build priority
willcl-ark Dec 8, 2025
c728ee9
use python runner
willcl-ark Dec 8, 2025
2677420
fixup! use python runner
willcl-ark Dec 8, 2025
6e2768b
fixup! use python runner
willcl-ark Dec 8, 2025
f815409
fixup! use python runner
willcl-ark Dec 8, 2025
e13bc98
use nix shell for jq
willcl-ark Dec 8, 2025
da4c9cf
remove isolated cpus
willcl-ark Dec 8, 2025
9c7fcd0
fixup! use python runner
willcl-ark Dec 9, 2025
419cd86
fixup! use python runner
willcl-ark Dec 9, 2025
14d1cf0
arbitrary bins
willcl-ark Dec 9, 2025
766ee8d
patch dynamic interpreter of binary if needed
willcl-ark Dec 9, 2025
fedfd17
increase toml config prio
willcl-ark Dec 9, 2025
fc55a9b
use report in publish job
willcl-ark Dec 9, 2025
b590629
deleteme
willcl-ark Dec 9, 2025
a86b795
coins: allow emplacing non-dirty coins internally
andrewtoth Nov 7, 2024
5e9823a
coins: add inputfetcher
andrewtoth Nov 7, 2024
950eaf9
tests: add inputfetcher tests
andrewtoth Nov 7, 2024
5785153
bench: add inputfetcher bench
andrewtoth Nov 7, 2024
d105175
fuzz: add inputfetcher fuzz harness
andrewtoth Nov 16, 2024
4e339c3
tests: set par=1 in feature_proxy to limit thread spawning
andrewtoth Sep 17, 2025
1528235
validation: fetch block inputs in parallel
andrewtoth Nov 7, 2024
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
1 change: 1 addition & 0 deletions .github/README.md
186 changes: 186 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
name: Benchmark
on:
pull_request:
branches:
- master

jobs:
build-binaries:
runs-on: [self-hosted, linux, x64]
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Fetch base commit
run: |
echo "HEAD_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }}

- name: Build both binaries
run: |
nix develop --command python3 bench.py build \
-o ${{ runner.temp }}/binaries \
$BASE_SHA:base $HEAD_SHA:head

- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: bitcoind-binaries
path: ${{ runner.temp }}/binaries/

uninstrumented:
needs: build-binaries
strategy:
matrix:
include:
- name: mainnet-default-uninstrumented
timeout: 600
dbcache: 450
- name: mainnet-large-uninstrumented
timeout: 600
dbcache: 32000
runs-on: [self-hosted, linux, x64]
timeout-minutes: ${{ matrix.timeout }}
env:
ORIGINAL_DATADIR: /data/pruned-840k
BASE_SHA: ${{ github.event.pull_request.base.sha }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Download binaries
uses: actions/download-artifact@v4
with:
name: bitcoind-binaries
path: ${{ runner.temp }}/binaries

- name: Set binary permissions
run: |
chmod +x ${{ runner.temp }}/binaries/base/bitcoind
chmod +x ${{ runner.temp }}/binaries/head/bitcoind

- name: Fetch base commit
run: |
echo "HEAD_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }}

- name: Run benchmark
run: |
nix develop --command python3 bench.py --profile ci run \
--datadir $ORIGINAL_DATADIR \
--tmp-datadir ${{ runner.temp }}/datadir \
--output-dir ${{ runner.temp }}/output \
--dbcache ${{ matrix.dbcache }} \
base:${{ runner.temp }}/binaries/base/bitcoind \
head:${{ runner.temp }}/binaries/head/bitcoind

- name: Upload results
uses: actions/upload-artifact@v4
with:
name: result-${{ matrix.name }}
path: ${{ runner.temp }}/output/results.json

- name: Write context metadata
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
RUNNER_CONTEXT: ${{ toJSON(runner) }}
run: |
mkdir -p ${{ runner.temp }}/contexts
echo "$GITHUB_CONTEXT" | nix develop --command jq "del(.token)" > ${{ runner.temp }}/contexts/github.json
echo "$RUNNER_CONTEXT" > ${{ runner.temp }}/contexts/runner.json

- name: Upload context metadata
uses: actions/upload-artifact@v4
with:
name: run-metadata-${{ matrix.name }}
path: ${{ runner.temp }}/contexts/

instrumented:
needs: build-binaries
strategy:
matrix:
include:
- name: mainnet-default-instrumented
timeout: 600
dbcache: 450
- name: mainnet-large-instrumented
timeout: 600
dbcache: 32000
runs-on: [self-hosted, linux, x64]
timeout-minutes: ${{ matrix.timeout }}
env:
ORIGINAL_DATADIR: /data/pruned-840k
BASE_SHA: ${{ github.event.pull_request.base.sha }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Download binaries
uses: actions/download-artifact@v4
with:
name: bitcoind-binaries
path: ${{ runner.temp }}/binaries

- name: Set binary permissions
run: |
chmod +x ${{ runner.temp }}/binaries/base/bitcoind
chmod +x ${{ runner.temp }}/binaries/head/bitcoind

- name: Fetch base commit
run: |
echo "HEAD_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }}

- name: Run instrumented benchmark
run: |
nix develop --command python3 bench.py --profile ci run \
--instrumented \
--datadir $ORIGINAL_DATADIR \
--tmp-datadir ${{ runner.temp }}/datadir \
--output-dir ${{ runner.temp }}/output \
--dbcache ${{ matrix.dbcache }} \
base:${{ runner.temp }}/binaries/base/bitcoind \
head:${{ runner.temp }}/binaries/head/bitcoind

- name: Upload results
uses: actions/upload-artifact@v4
with:
name: result-${{ matrix.name }}
path: ${{ runner.temp }}/output/results.json

- name: Upload plots
uses: actions/upload-artifact@v4
with:
name: pngs-${{ matrix.name }}
path: ${{ runner.temp }}/output/plots/*.png
if-no-files-found: ignore

- name: Upload flamegraphs
uses: actions/upload-artifact@v4
with:
name: flamegraph-${{ matrix.name }}
path: ${{ runner.temp }}/output/*-flamegraph.svg
if-no-files-found: ignore

- name: Write context metadata
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
RUNNER_CONTEXT: ${{ toJSON(runner) }}
run: |
mkdir -p ${{ runner.temp }}/contexts
echo "$GITHUB_CONTEXT" | nix develop --command jq "del(.token)" > ${{ runner.temp }}/contexts/github.json
echo "$RUNNER_CONTEXT" > ${{ runner.temp }}/contexts/runner.json

- name: Upload context metadata
uses: actions/upload-artifact@v4
with:
name: run-metadata-${{ matrix.name }}
path: ${{ runner.temp }}/contexts/
143 changes: 143 additions & 0 deletions .github/workflows/publish-results.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Publish Results
on:
workflow_run:
workflows: ["Benchmark"]
types: [completed]
jobs:
build:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
actions: read
contents: write
checks: read
env:
NETWORKS: "mainnet-default-instrumented,mainnet-large-instrumented,mainnet-default-uninstrumented,mainnet-large-uninstrumented"
outputs:
speedups: ${{ steps.generate.outputs.speedups }}
pr-number: ${{ steps.metadata.outputs.pr-number }}
result-url: ${{ steps.generate.outputs.result-url }}
steps:
- uses: actions/checkout@v4
with:
ref: gh-pages

- name: Checkout benchcoin tools
uses: actions/checkout@v4
with:
ref: master
path: benchcoin-tools

- name: Download artifacts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh run download ${{ github.event.workflow_run.id }} --repo ${{ github.repository }}

- name: Extract artifacts
run: |
for network in ${NETWORKS//,/ }; do
# Create network-specific directories with results
if [ -d "result-${network}" ]; then
mkdir -p "${network}-results"
mv "result-${network}/results.json" "${network}-results/"
fi

# Copy flamegraphs into network results directory
if [ -d "flamegraph-${network}" ]; then
cp -r "flamegraph-${network}"/* "${network}-results/" 2>/dev/null || true
fi

# Copy plots into network results directory
if [ -d "pngs-${network}" ]; then
mkdir -p "${network}-results/plots"
cp -r "pngs-${network}"/* "${network}-results/plots/" 2>/dev/null || true
fi

# Keep metadata separate for extraction
if [ -d "run-metadata-${network}" ]; then
mkdir -p "${network}-metadata"
mv "run-metadata-${network}"/* "${network}-metadata/"
fi
done

- name: Extract metadata
id: metadata
run: |
# Find PR number and run ID from any available metadata
for network in ${NETWORKS//,/ }; do
if [ -f "${network}-metadata/github.json" ]; then
PR_NUMBER=$(jq -r '.event.pull_request.number // "main"' "${network}-metadata/github.json")
RUN_ID=$(jq -r '.run_id' "${network}-metadata/github.json")
echo "pr-number=${PR_NUMBER}" >> $GITHUB_OUTPUT
echo "run-id=${RUN_ID}" >> $GITHUB_OUTPUT
echo "Found metadata: PR=${PR_NUMBER}, Run=${RUN_ID}"
break
fi
done

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Generate report
id: generate
env:
PR_NUMBER: ${{ steps.metadata.outputs.pr-number }}
RUN_ID: ${{ steps.metadata.outputs.run-id }}
run: |
cd benchcoin-tools

# Build network arguments
NETWORK_ARGS=""
for network in ${NETWORKS//,/ }; do
if [ -d "../${network}-results" ]; then
NETWORK_ARGS="${NETWORK_ARGS} --network ${network}:../${network}-results"
fi
done

# Generate report
python3 bench.py report \
${NETWORK_ARGS} \
--pr-number "${PR_NUMBER}" \
--run-id "${RUN_ID}" \
--update-index \
"../results/pr-${PR_NUMBER}/${RUN_ID}"

# Read speedups from generated results.json
SPEEDUPS=$(jq -r '.speedups | to_entries | map(select(.key | contains("uninstrumented"))) | map("\(.key): \(.value)%") | join(", ")' "../results/pr-${PR_NUMBER}/${RUN_ID}/results.json")
echo "speedups=${SPEEDUPS}" >> $GITHUB_OUTPUT

RESULT_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/results/pr-${PR_NUMBER}/${RUN_ID}/index.html"
echo "result-url=${RESULT_URL}" >> $GITHUB_OUTPUT

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: results

- name: Commit and push to gh-pages
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add results/ index.html
git commit -m "Update benchmark results from run ${{ github.event.workflow_run.id }}"
git push origin gh-pages

comment-pr:
needs: build
runs-on: ubuntu-latest
permissions:
pull-requests: write
actions: read
steps:
- name: Comment on PR
if: ${{ needs.build.outputs.pr-number != 'main' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ${{ needs.build.outputs.pr-number }} \
--repo ${{ github.repository }} \
--body "📊 Benchmark results for this run (${{ github.event.workflow_run.id }}) will be available at: ${{ needs.build.outputs.result-url }} after the github pages \"build and deployment\" action has completed.
🚀 Speedups: ${{ needs.build.outputs.speedups }}"
Loading