The suite runs six suites live in the browser. Only one of them can fail a validator that is too permissive.
expect: 'reject' appears exactly once in build.js — in the scripts suite, which runs Core's script_tests.json and inherits its expected-invalid vectors. Every other suite uses expect: null:
| Suite |
Asserts rejections? |
| Spending (scripts) |
yes — Core's vectors carry expected-invalid cases |
| Headers |
no |
| Difficulty |
no |
| Blocks |
no |
| Transactions & money |
no |
| Light clients (SPV) |
no |
The fixtures match. All seven non-script vector files are real, valid mainnet data:
genesis-block.json header-chain-100k.json
merkleblock-block100000.json merkleblock-first-segwit.json
pruned-window-100000.json retarget-32256.json retarget-modern.json
There are no adversarial fixtures at all.
Why this matters
A positive-only suite can only catch rejects-valid failures — cases where the validator wrongly refuses good data. It is structurally incapable of catching accepts-invalid failures, where the validator wrongly admits bad data. For a consensus validator that is the dangerous direction: it is the one that makes you follow a chain the network has rejected.
This is not hypothetical. Two independent reviews have now found precisely that class of bug:
- Five of the eight findings in #3 are classified accepts-invalid.
- #5 (no
powLimit or overflow bound in checkProofOfWork) is accepts-invalid, and five of the six suites could never have detected it, because not one of them ever feeds a bad header and demands a rejection.
- #6 (the witness-nonce crash) likewise: the only segwit fixtures are real blocks with well-formed 32-byte reserved values.
The bugs the reviews keep surfacing are exactly the class the suite cannot see. That correlation is the finding.
Suggested fix
Add a negative fixture set and let the non-script suites carry expect: 'reject'. Starting candidates, all cheap to construct and all corresponding to real Core rejections:
A related gap upstream: packages/kernel has no test files of its own. npm test runs node --test packages/*/test/*.test.js, which matches only packages/swiftsync/test/. The consensus engine's entire coverage is this browser suite, so a hole here is a hole everywhere.
The README's claim — "across all of Bitcoin's rules, from real test vectors" — is accurate about which rules are exercised and quietly misleading about which direction is tested. Worth fixing the coverage rather than the wording.
The suite runs six suites live in the browser. Only one of them can fail a validator that is too permissive.
expect: 'reject'appears exactly once inbuild.js— in the scripts suite, which runs Core'sscript_tests.jsonand inherits its expected-invalid vectors. Every other suite usesexpect: null:The fixtures match. All seven non-script vector files are real, valid mainnet data:
There are no adversarial fixtures at all.
Why this matters
A positive-only suite can only catch rejects-valid failures — cases where the validator wrongly refuses good data. It is structurally incapable of catching accepts-invalid failures, where the validator wrongly admits bad data. For a consensus validator that is the dangerous direction: it is the one that makes you follow a chain the network has rejected.
This is not hypothetical. Two independent reviews have now found precisely that class of bug:
powLimitor overflow bound incheckProofOfWork) is accepts-invalid, and five of the six suites could never have detected it, because not one of them ever feeds a bad header and demands a rejection.The bugs the reviews keep surfacing are exactly the class the suite cannot see. That correlation is the finding.
Suggested fix
Add a negative fixture set and let the non-script suites carry
expect: 'reject'. Starting candidates, all cheap to construct and all corresponding to real Core rejections:nBitsabovepowLimit, and with an overflowingnBits(0xff123456)A related gap upstream:
packages/kernelhas no test files of its own.npm testrunsnode --test packages/*/test/*.test.js, which matches onlypackages/swiftsync/test/. The consensus engine's entire coverage is this browser suite, so a hole here is a hole everywhere.The README's claim — "across all of Bitcoin's rules, from real test vectors" — is accurate about which rules are exercised and quietly misleading about which direction is tested. Worth fixing the coverage rather than the wording.