Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
17 changes: 16 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
# been public a week -- it means the offer comes at most a week after
# that, rather than at most a month. No ecosystem here tracks anything
# security-critical, so nothing here wants to be faster than that. The
# docker entry at the bottom declares it too, and says why it holds
# docker entry below declares it too, and says why it holds
# nothing back there
version: 2
updates:
Expand Down Expand Up @@ -98,3 +98,18 @@ updates:
patterns: ["*"]
cooldown:
default-days: 7

# fuzz/btcd_decode/go.mod pins the btcd wire release that
# btcd-oracle.yml compares btclib with. A pull request here is a newer
# release to run the weekly comparison against; the workflow is a
# sentinel, so nothing is gated on it.
- package-ecosystem: gomod

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

blocking: section 11 of the organization standard does not list gomod as an ecosystem. Until it does, landing this entry turns btclib-org/.github's tests/dependabot_test.py::test_dependabot_watches_only_the_ecosystems_section_11_names[btclib] red. btclib-org/.github#1700 records that failure, measured at c58fd81, and the fix is in that repository. This is resolved by either landing btclib-org/.github#1700 before this pull request, or by dropping this entry (the body's option B).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed. Landing waits on btclib-org/.github ISS 1700 (btclib-org/.github#1700). The pull request body's first paragraph asks the maintainer to choose between that wait and dropping the entry.

directory: /fuzz/btcd_decode
schedule:
interval: weekly
day: thursday
groups:
btcd:
patterns: ["*"]
cooldown:
default-days: 7
120 changes: 120 additions & 0 deletions .github/workflows/btcd-oracle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
name: btcd oracle

# Reads every input of the fuzz corpora with btcd's `wire` package and with
# btclib, and lists each one they read differently: one accepts and the
# other refuses, or both accept and write different octets back.
# `fuzz/btcd_oracle.py` is the comparison and `fuzz/btcd_decode` the btcd
# side, pinned to a release in its own go.mod.
#
# The inputs are `fuzz/corpus`, the seeds, and the `cifuzz-corpus-*`
# artifacts of the newest successful `fuzz` run, which are what the
# fuzzers grew from them. Artifacts expire, so a repository whose last
# `fuzz` run is old compares the seeds alone and says so.
#
# A sentinel and not a gate: the answer depends on btcd's releases and on
# what the fuzzers found this week, neither of which a pull request
# changes. A red run is a list of inputs to triage against Bitcoin Core,
# not a failure of the tree, so nothing requires this check. Differences
# already triaged are rules in `fuzz/btcd_oracle.py`, counted and not
# listed, so a run is red only for a disagreement no rule explains. The
# report is in the run's summary.
#
# The `pull_request` trigger is filtered to this file, the Go module and
# the script, so that a Dependabot bump of btcd, or an edit of either
# program, is built and run before it lands. Section 10 of the
# organization standard keeps such a trigger where a run adds seconds to
# the wait on a pull request's checks. This run is expected to end before
# `test`'s, whose median on a pull request was 195 seconds on 2026-10-11;
# that is confirmed on the first pull request's own run and not before.
Comment thread
fametrano marked this conversation as resolved.
Outdated
Comment thread
fametrano marked this conversation as resolved.
Outdated
#
# The schedule runs after `fuzz` (Tuesday 04, about 90 minutes), so that the
# artifacts it reads are that week's.
Comment thread
fametrano marked this conversation as resolved.
Outdated
Comment thread
fametrano marked this conversation as resolved.
Outdated

on:
schedule:
# section 10's calendar in btclib-org/.github, and not this file's to
# restate. Only the default branch schedules workflows, so on any
# other branch this is reachable through the dispatch below
- cron: "4 1 * * 3"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

blocking: this cron has no row in section 10's calendar yet. btclib-org/.github#1688, which adds the btcd-oracle row for Wednesday 01, is still open. That issue says it has to land before this pull request, so that tests/grid_test.py finds a row for the cron. Landing first leaves the comment above pointing at a calendar entry that does not exist.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed. Landing waits on btclib-org/.github ISS 1688 (btclib-org/.github#1688), as the pull request body says.

workflow_dispatch:
pull_request:
# ready_for_review and closed for the reason vendored-vectors.yml's
# own trigger gives
types: [opened, reopened, synchronize, ready_for_review, closed]
paths:
- .github/workflows/btcd-oracle.yml
- fuzz/btcd_decode/**
- fuzz/btcd_oracle.py

permissions:
contents: read

# github.event.pull_request.number, not github.head_ref, for the reason
# vendored-vectors.yml's own concurrency block gives
concurrency:
group: btcd-oracle-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ !(github.event.action == 'closed' && github.event.pull_request.merged) }}

jobs:
compare:
name: Compare btclib with btcd over the fuzz corpora
if: ${{ !github.event.pull_request.draft && github.event.action != 'closed' }}
runs-on: ubuntu-latest
# far above what the build and the comparison take: what this bounds
# is a hung job
timeout-minutes: 20
permissions:
contents: read
actions: read # gh run list, gh run download
env:
GH_TOKEN: ${{ github.token }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# the `toolchain` line of go.mod names the Go release, so it is pinned in
# the one file that also pins btcd's; Dependabot's gomod updater does not
# move that line
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: fuzz/btcd_decode/go.mod
cache-dependency-path: fuzz/btcd_decode/go.sum
# the artifacts are the newest successful fuzz run's. None is not an
# error: the seeds are compared either way
- name: Download the corpora the last fuzz run grew
run: |
run_id=$(gh run list --repo "$GITHUB_REPOSITORY" \
--workflow fuzz.yml --branch main --status success --limit 1 \
--json databaseId --jq '.[0].databaseId // empty')
mkdir -p "$RUNNER_TEMP/corpora"
if [ -z "$run_id" ]; then
echo "::warning::no successful fuzz run; comparing the seeds alone"
exit 0
fi
gh run download "$run_id" --repo "$GITHUB_REPOSITORY" \
--pattern 'cifuzz-corpus-*' --dir "$RUNNER_TEMP/corpora" ||
echo "::warning::fuzz run $run_id left no corpus artifact"
- name: Sync the environment
run: uv sync --locked --no-default-groups
# the script exits 1 when it lists an input no rule explains, which
# turns the job red; the report goes to the summary as well, where a
# reader opens it first
- name: Compare
run: |
set -o pipefail
status=0
uv run --locked --no-default-groups python fuzz/btcd_oracle.py \
fuzz/corpus "$RUNNER_TEMP/corpora" | tee report.txt || status=$?
{
echo '```text'
cat report.txt
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
exit "$status"
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ commit, which is then made again.
| `deps-oldest` | weekly | the floor interpreter, deps at their floors |
| `links`, `mutation` | weekly | — |
| `vendored-vectors` | weekly | the pin ledgers |
| `btcd-oracle` | weekly, a pull request | the corpora, read by btcd |
| `pypi-install` | weekly, a release | what PyPI serves |
| `sdist-rebuild` | weekly | the latest release's sdist, rebuilt |
| `py-arm-authority` | weekly, push to main | the arm-authority table |
Expand Down
15 changes: 15 additions & 0 deletions fuzz/btcd_decode/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/btclib-org/btclib/fuzz/btcd_decode

go 1.25.0

toolchain go1.27.1

require (
github.com/btcsuite/btcd/chainhash/v2 v2.0.0
github.com/btcsuite/btcd/wire/v2 v2.0.1
)

require (
golang.org/x/crypto v0.52.0 // indirect
golang.org/x/sys v0.45.0 // indirect
)
16 changes: 16 additions & 0 deletions fuzz/btcd_decode/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
github.com/btcsuite/btcd/chainhash/v2 v2.0.0 h1:PMLlSloHJuEeB80XG9EjpXWNEKAZAMLl6YHZ6YsEuoA=
github.com/btcsuite/btcd/chainhash/v2 v2.0.0/go.mod h1:mKxcZ7oGTXE7IRV+sS9hP4EVBwc/SzfNR+52IsOP9j8=
github.com/btcsuite/btcd/wire/v2 v2.0.1 h1:edmb35tvRyQpFp331L9PwZFccaTCOQwevSsU6ra4BR4=
github.com/btcsuite/btcd/wire/v2 v2.0.1/go.mod h1:ENBpJL0JYUNlqvajhIFTOcWGNNumjCynDk4PL0OG58I=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading
Loading