Skip to content

Compare btclib with btcd's wire decoder over the fuzz corpora (closes #2584) - #2622

Open
fametrano wants to merge 6 commits into
mainfrom
btcd-oracle-2584
Open

fametrano wants to merge 6 commits into
mainfrom
btcd-oracle-2584

Conversation

@fametrano

@fametrano fametrano commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

This pull request adds a gomod entry to dependabot.yml, which section 11 of the organization standard does not name yet. The maintainer decided on 2026-10-11 to keep the entry, so landing also waits on btclib-org/.github ISS 1700 (btclib-org/.github#1700), which adds gomod to section 11.

Landing also waits on:

Item 3 of ISS 2584's Done when, reporting btcd's divergences on btcd's tracker, is done: btcsuite/btcd ISS 2637, 2638 and 2639, and a comment on btcsuite/btcd PR 2533. Read against Bitcoin Core a8b69bdeaf, the divergences are:

  • MsgVersion.BtcDecode accepts addr_from without the nonce. Core reads the two together and refuses that message (net_processing.cpp 3889–3890).
  • ReadVarInt has no MAX_SIZE check. Core refuses a size above it (serialize.h 359).
  • MsgTx.BtcDecode refuses a zero flag byte after an empty input list. Core reads an empty transaction there (primitives/transaction.h 212–218).
  • MsgAddrV2 drops valid I2P and CJDNS entries (ErrSkippedNetworkID). Core keeps them (SetNetFromBIP155Network).

btclib refuses two things Core reads: some version fields and the relay byte. Both are documented choices in src/btclib/p2p/handshake.py's docstring, so nothing was filed here.

fuzz/btcd_decode is a Go program pinned to btcd's wire/v2 v2.0.1, with toolchain go1.27.1 and golang.org/x/crypto 0.52.0 for Dependency review. It decodes a file with btcd and prints whether btcd accepted it and the octets it writes back. fuzz/btcd_oracle.py runs it and btclib over fuzz/corpus and the fuzz run's cifuzz-corpus-* artifacts, and lists every input the two read differently.

  • Differences already triaged against Core are rules keyed by both answers. They are counted, not listed.
  • Each rule checks btclib's own output too, so a btclib defect in the same message is still listed.

The local reviewers planted defects in src/, and the oracle listed each one: a non-canonical var_int, a version nonce read as 9 octets, addrv2 services written fixed-width, start_height dropped on write, getblocks hashes written unreversed, a flipped byte in Tx.serialize, and a dropped relay flag. On the unchanged tree nothing is listed.

btcd-oracle.yml runs the comparison weekly, after fuzz. It also runs on a pull request that touches the Go module, the script or the workflow, so that a Dependabot bump of btcd is built. It is a sentinel, not a required check. The header says a run ends before test's. On this branch it took 31–41 s and test 2 min 18 s to 3 min 17 s; run 38139165712 compared 4782 reads and listed none. CONTRIBUTING.md gains its row and tests/README.md a paragraph.

The branch is six commits on b71525a, with no rebase. 5f7e483 and 223f45d answer Dependency review, 5f63017 the bot's two rounds, and the last two the local review.

Gates on c58fd81:

  • uv run pre-commit run --all-files: exit 0, actionlint and zizmor included (the writer's run)
  • uv run pytest: exit 0, coverage 100% (a local reviewer's run)
  • docs build on b2d5d74: exit 0; c58fd81 changes only a workflow comment

Closes #2584

🤖 Generated with Claude Code

…2584)

fuzz/btcd_decode is a Go program, pinned to btcd's wire/v2 v2.0.1 in its
own go.mod and go.sum, that decodes a file with btcd and prints whether
it was accepted and the octets btcd writes back. fuzz/btcd_oracle.py
runs it and btclib over fuzz/corpus and over downloaded cifuzz-corpus-*
artifacts, and lists every input the two read differently: one accepts
and the other refuses, both accept and write different octets, or one
crashes. btclib's validity checks are off for the comparison, because
btcd's decoders leave them to the caller.

Differences already triaged against Bitcoin Core (a8b69bdeaf) are rules
in the script, keyed by what the two answered. They are counted and not
listed, so the run is red only for a disagreement no rule explains. A
version message without its relay flag is compared as Core reads it, with
the flag true.

btcd-oracle.yml runs the comparison weekly after the fuzz run, over the
seeds and that run's artifacts, and on a pull request touching the Go
module or the script. It is informational. Its cron needs the calendar
row of btclib-org/.github#1688. dependabot.yml gains a gomod entry for the Go
module.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
Comment thread .github/workflows/btcd-oracle.yml Outdated
Comment thread .github/workflows/btcd-oracle.yml Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CHANGES REQUESTED 77df90d

  • blocking .github/workflows/btcd-oracle.yml:31: the header copies fuzz.yml's schedule into prose. "Tuesday 04" is its cron (fuzz.yml:89) and "about 90 minutes" is its timeout-minutes (fuzz.yml:121). CLAUDE.md says prose never copies a pinned value. The same file (lines 36–37) and CONTRIBUTING.md:643-646 say the calendar is not restated. A suggestion is inline.
  • non-blocking .github/workflows/btcd-oracle.yml:27-29: "195 seconds on 2026-10-11" is a measurement that nothing re-derives (section 9). "Confirmed on the first pull request's own run and not before" describes this review, and on main it will stay true forever. Drop both, or put the command that re-derives the figure in their place.
  • non-blocking .github/workflows/btcd-oracle.yml:36-39: the comment says section 10's calendar holds this cron. The calendar row is btclib-org/.github#1688, which is still open (gh issue view 1688 -R btclib-org/.github: OPEN). The body already says landing waits on it. Until it lands, this pointer is false.

Not checked: fuzz/btcd_oracle.py and fuzz/btcd_decode were not run. No interpreter or Go toolchain was available, so the rules in KNOWN and the decoder were only read.

fuzz/btcd_decode/go.mod reached golang.org/x/crypto 0.40.0 through
btcd's wire/v2 (golang.org/x/crypto/sha3), and the Dependency review
check refused it. 0.52.0 is the lowest release that clears all fifteen
advisories the check listed, whose patched versions are 0.45.0 for
GHSA-f6x5-jh6r-wrfv and GHSA-j5w8-q4qc-rx2x, and 0.52.0 for
GHSA-45gg-vh54-h5m9, GHSA-5cgq-3rg8-m6cv, GHSA-78mq-xcr3-xm33,
GHSA-89gr-r52h-f8rx, GHSA-9m57-25v3-79x9, GHSA-f5wc-c3c7-36mc,
GHSA-jppx-rxg9-jmrx, GHSA-q4h4-gmj2-qvw2, GHSA-qpw4-5x99-6vjp,
GHSA-rm3j-f69w-wqmq, GHSA-vgwf-h737-ff37, GHSA-w879-237q-wc7r and
GHSA-x527-x647-q7gg.

golang.org/x/sys moves to 0.45.0, the release 0.52.0 requires, and the
go line to 1.25.0. Both releases are from 2026-05-21 and 2026-05-22.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
@fametrano

Copy link
Copy Markdown
Member Author

The Dependency review now passes on vulnerabilities: x/crypto 0.52.0 clears every advisory 0.40.0 carried. It fails on one licence: golang.org/x/sys@0.45.0 concludes BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang. Admitting it is a decision on the org's dependency-review.yml, filed as btclib-org/.github ISS 1689 (btclib-org/.github#1689). This pull request also waits on that.

The go line of fuzz/btcd_decode/go.mod is 1.25.0 since the x/crypto
bump, and setup-go reads that line, so CI installed exactly go1.25.0,
a release no longer supported. setup-go reads the toolchain line first,
so a toolchain line names the release.

go1.27.1 is the newest patch of the supported 1.27 series that is at
least seven days old; go1.27.2 was tagged on 2026-10-08.
Dependabot's gomod updater reads the toolchain from the environment
only, and does not move the line.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
Comment thread .github/workflows/btcd-oracle.yml Outdated
Comment thread .github/workflows/btcd-oracle.yml Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CHANGES REQUESTED 223f45d

  • blocking .github/workflows/btcd-oracle.yml:31: "Tuesday 04" copies fuzz.yml's cron ("4 4 * * 2", fuzz.yml:89) into this file. "About 90 minutes" is a measurement that nothing re-derives. CONTRIBUTING.md:643-646 says the calendar is section 10's and not a file's to restate, and so does this file's own cron comment at btcd-oracle.yml:36. (The inline comment gives that line as 775 by mistake; it is 36.) Section 9 covers the duration. A one-line suggestion is inline.
  • non-blocking .github/workflows/btcd-oracle.yml:27-29: "195 seconds on 2026-10-11" is a figure that nothing re-derives (section 9). "Confirmed on the first pull request's own run and not before" describes this pull request's landing, which becomes history once it is on main.

Not checked: fuzz/btcd_oracle.py and fuzz/btcd_decode decide the outcome, and neither was run, because no interpreter or Go toolchain was available. The body's claims rest on the author's runs: nothing is listed on the unchanged tree, and the planted defects are listed. The organization standard (btclib-org/.github README) could not be fetched, so sections 9 and 10 are cited as REVIEWING.md and CONTRIBUTING.md name them.

fametrano and others added 3 commits October 11, 2026 17:14
The schedule comment named fuzz.yml's day, hour and timeout, which are
section 10's calendar and not this file's. It now says only that the run
follows `fuzz`'s.

The trigger comment keeps its reason, that the run ends before `test`'s,
and drops a timing no gate re-derives and a note about the first run
that would become history once landed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
The README said the oracle lists every input the two decoders read
differently. Differences a rule in `fuzz/btcd_oracle.py` explains are
counted and not listed, so the sentence now says so.

The by-hand command runs `go build`, so it needs a Go toolchain on
`PATH`.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
The header said the answer depends on btcd's releases and the fuzzers'
finds, neither of which a pull request changes. A Dependabot bump of
btcd changes the first, and a change to btclib's parsers changes the
answer too. The header now names only what can turn the run red with
no change to the tree.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Ferdinando Ametrano <ferdinando@ametrano.net>
@fametrano fametrano changed the title Compare btclib with btcd's wire decoder over the fuzz corpora (issue #2584) Compare btclib with btcd's wire decoder over the fuzz corpora (closes #2584) Oct 11, 2026
@fametrano fametrano added the decision A decision the maintainer still has to take label Oct 11, 2026
Comment thread .github/dependabot.yml
# 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.

# 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.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CHANGES REQUESTED c58fd81

  • blocking: .github/dependabot.yml:106. The new gomod entry names an ecosystem that section 11 of the organization standard does not list. On landing, btclib-org/.github's tests/dependabot_test.py fails for btclib. btclib-org/.github#1700 records that failure, measured at this sha, and it is still open. Land #1700 first, or drop the entry.
  • blocking: .github/workflows/btcd-oracle.yml:37. The cron 4 1 * * 3 has no row in section 10's calendar. btclib-org/.github#1688 adds that row and says it must land before this pull request, so that tests/grid_test.py finds it. It is still open.

Not checked: fuzz/btcd_oracle.py and fuzz/btcd_decode were not run, because this review has no interpreter or Go toolchain. Sections 10 and 11 were not read directly, because fetching the organization README was refused. Both findings rest on the measurements recorded in btclib-org/.github#1700 and #1688.

@fametrano

Copy link
Copy Markdown
Member Author

Decision (maintainer, 2026-10-11): (A). Landing waits on btclib-org/.github ISS 1700 (btclib-org/.github#1700), as it waits on ISS 1688 and PR 1690. The gomod entry stays.

Assisted-by: my usual tools (LLM, Internet, computer). Mistakes are mine.

@fametrano fametrano removed the decision A decision the maintainer still has to take label Oct 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A btcd decode oracle over the fuzz corpora, reporting every input btcd and btclib read differently

1 participant