Repository navigation
Verify frozen wallet fingerprint fixtures against real Bitcoin Core in CI #9
Description
Problem
Wallet fingerprint fixtures are now frozen constants that no automated check verifies.
tools/_wallet_test_vectors.py holds nine BIP32 master fingerprints that the test suite asserts against: three for BIP93 vector seeds, used by the CLI display and correction paths, and six arbitrary fixtures covering each BIP93 seed length. tools/bitcoin_core_regtest.py contains the loop that checks every entry against a real Bitcoin Core node, but no workflow invokes it. The CI matrix runs pytest, mypy, Ruff, tools/differential_correction.py --verify, the package build, and tools/verify_wheel_environment.py — the regtest harness is not among them.
Before #7, tools/differential_wallet.py ran in CI and cross-checked wallet derivation against an independent pure-Python BIP32 implementation. #7 removed that tool, tools/_wallet_reference.py, and requirements/test-wallet-dependencies.txt in order to drop the bip32/coincurve dependencies from the test path. That was the intent of the PR and is not in dispute, but it means the only remaining automated check on these values is the test suite asserting them against the same table that defines them.
The failure this permits is silent. core_fingerprint() raises for a seed with no fixture, so a missing entry is caught, but a wrong frozen value is self-consistent: the table and the assertions agree with each other and CI stays green. The same applies if a future change to BitcoinCore.fingerprint_seed or _master_xprv_from_seed alters the derivation — the tests compare against frozen bytes, not against Core.
All nine entries were verified by hand against a real node at c58b5ff and matched exactly, so the values are correct today. The gap is drift from here on.
Constraint
BitcoinCore.connect() requires version >= 320000, so the harness needs a Bitcoin Core v32 or newer binary. That is the reason it is not simply another run: line: a CI job has to obtain Core first, which is slower than the current matrix and adds a download or build step to every run.
The derivation path itself is narrower than the connect gate suggests. fingerprint_seed computes the master xprv in pure Python and then uses only getdescriptorinfo, deriveaddresses and validateaddress, all of which are stable well below v32.
Options
- Add a scheduled or
workflow_dispatchjob on ubuntu only that fetches a pinned Core release and runstools/bitcoin_core_regtest.py. Keeps the per-PR matrix fast while bounding drift to the schedule interval. - Add a fixtures-only verification mode that checks
CORE_FINGERPRINTSwithout exercising the full wallet import flow, and gate it on the narrower RPC set rather than onBitcoinCore.connect's v32 requirement. - Run the harness on pull requests that touch
tools/_wallet_test_vectors.py,src/codex32/_bip32.pyorsrc/codex32/_bitcoin_core.py, using a path filter.
Option 1 is the smallest change that closes the drift window. Option 2 is worth pairing with it, since verifying the fingerprint table does not need a wallet import and could then run against any reasonably recent Core.
Acceptance criteria
- Some automated job verifies every
CORE_FINGERPRINTSentry against a real Bitcoin Core node. - The job fails when a frozen fingerprint stops matching Core, rather than passing on table-versus-assertion agreement.
- The Bitcoin Core version used is pinned and recorded, so a change in that version is a deliberate edit.
- Adding a fixture without a verified fingerprint fails, rather than only failing at the point of use.
- The per-PR matrix does not become materially slower, or the check runs on a schedule or path filter instead.
Relation to #5
#5 proposes running this same harness as part of a release gate, and its description of current CI predates #7 — it lists differential wallet verification as a step that no longer exists.
The two are complementary rather than duplicate. #5 asks that a release not ship without integration qualification; this issue asks that everyday CI notice when a frozen fingerprint stops matching Core, which needs to hold between releases. Closing #5 alone would leave the fixtures unverified on the main branch until release time.
Activity
Tests: keep wallet fingerprints seed-sensitive
BenWestgate commentedon Sep 25, 2026
Release monitor update (2026-09-25): the official Bitcoin Core 32.0 directory currently exposes only
test.rc2/(https://bitcoincore.org/bin/bitcoin-core-32.0/), while the public download page still lists 31.1 as the latest stable release. PR #51 therefore remains correctly pinned to 32.0rc2 for now. If a later 32.0 RC or final appears before v1 qualification, update the pinned archive/hash and rerun the Core fixture harness before release.BenWestgate commentedon Sep 27, 2026
Release monitor refresh (2026-09-26): upstream still has only
v32.0rc1andv32.0rc2; there is no finalv32.0tag. #51 remains correctly pinned to rc2, and its path-filtered PR workflow is now green against that exact binary. Repin/re-run if a newer v32 candidate appears before release.ci: Verify wallet fixtures against Bitcoin Core
ci: Verify wallet fixtures against Bitcoin Core
ci: Verify wallet fixtures against Bitcoin Core
ci: Verify wallet fixtures against Bitcoin Core
ci: Verify wallet fixtures against Bitcoin Core
ci: Verify wallet fixtures against Bitcoin Core