chore: vendor consensus.h and uint256.h, and use them - #609
Merged
Conversation
pyrxd's Python carries citations into Radiant Core for the rules it re-implements. A citation is only evidence if the cited file is here, and two of the load-bearing ones were not: * `interpreter.cpp` enforces MAX_SCRIPT_STACK_MEMORY_USAGE (128,000,000) and MAX_SCRIPT_OPCODE_COST (1,000,000,000) and declares neither. Their VALUES were uncheckable by anything in the repo. * `transaction_preimage.py` claims an output's refs are hashed ascending by little-endian uint288 value and cites `src/primitives/transaction.h`. That header holds the `std::set<uint288>`; it does not define the order. The order is `base_blob::Compare` (walks m_data from WIDTH-1 down, so byte[35] is most significant) and `operator<` (`Compare(...) < 0`) in `src/uint256.h`. The claim IS correct — now shown against the C++ rather than asserted. Sorting the raw bytes instead made dMint contract-output signing fail about half the time. Both files are vendored at the pin already in MANIFEST.json (v3.1.2, 45e0aa40) via scripts/refresh_radiant_core_vendor.py, and `--check` reports them identical at v3.1.1, the tag the regtest image's binary is built from, so the source/image gap the README documents still holds. New in the oracle: `consensus_limit` (a separate parser — consensus.h uses `inline constexpr` with expression initialisers over ONE_MEGABYTE, which is 1,000,000 and not 2^20), `script_budgets_enforced_by_interpreter` (derived from EvalScript's own comparisons, so a budget added upstream fails the pin rather than being missed), and the uint288 comparator extractors feeding `uint288_sorted`, which the differential runs against the production `_get_push_refs` on a ref pair whose little- and big-endian orders DISAGREE. Also fixes the digest check itself. It was parametrised over `["script.h", "script.cpp"]` while eight files were vendored — structural about the digest, hand-kept about the set, and so vacuous for everything added after it was written. It now derives its parameters from the manifest (10 files, up from 2), with both other directions closed: a file on disk with no manifest entry, and a manifest entry the refresh script would never re-fetch. Six plants, each restored and confirmed with `git status --porcelain`: 1. one byte changed in consensus.h -> only the [consensus.h] digest case fails (9 others pass), so the new file really is covered 2. same in uint256.h -> only [uint256.h] fails 3. Compare's loop flipped to ascending in uint256.h -> 4 uint288 tests fail, including the differential through production `_get_push_refs` 4. uint64_t(128) -> uint64_t(129) in consensus.h -> the budget pin fails 5. one interpreter.cpp comparison retargeted at MAX_COINBASE_SCRIPTSIG_SIZE -> "no enforced budget is unpinned" fails on a name it was not built from 6. a stray .h dropped in the vendor dir -> the coverage test fails Full offline suite: 11005 passed, 197 skipped, 4 xfailed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Zyrtnin
pushed a commit
that referenced
this pull request
Sep 4, 2026
#592 vendors validation.h (where the ref backing-subset rule lives, and whose absence let a verifier ship reporting forged collection membership as authentic); #609 vendors consensus.h and uint256.h (the two script budgets, and the uint288 comparator behind the sighash ref ordering). Different files, so the resolution is the union - verified three ways: the FILES map, MANIFEST.json and the vendor directory all agree on the same 11 files. Both branches independently added an every-file-is-digest-checked guard, having found the same hand-kept list of two. Kept main's, which derives the parametrised set from the manifest, checks both directions and asserts non-vacuity - it fully covers what the other did, and two copies of one guard is how they drift apart.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the two highest-value gaps in the consensus oracle. 44% of pyrxd's 112 citations into Radiant Core point at files that aren't vendored, so nothing can check them — which is exactly how #592 happened:
validation.hwas cited in comments, not vendored, the ref backing-subset rule lives in it, and a verifier shipped calling forged collection membership authentic.consensus.hsrc/consensus/consensus.hc344ba58…uint256.hsrc/uint256.he4cc8933…I re-fetched both from upstream independently and confirmed the digests match the vendored files and the manifest.
The uint288 comparator supports the sighash claim — the citation didn't
transaction_preimage.pyclaims refs hash "ascending by the uint288 numeric value … little-endian". Verified myself:Comparestarts atWIDTH - 1and counts down, commented "compare MSB-first (in reverse because data is little endian)". Soref[::-1]is right.The citation was wrong, not the rule —
primitives/transaction.hholds thestd::set<uint288>but no comparator. Corrected the citation, not the rule. That distinction matters: rewriting the rule to match a bad citation is how the inverted timelock got its authority.Now checkable that wasn't
MAX_SCRIPT_STACK_MEMORY_USAGE = 128,000,000andMAX_SCRIPT_OPCODE_COST = 1,000,000,000. NoteONE_MEGABYTE = 1000000, not 2²⁰ — reading it as a power of two overstates the ceiling by 6.3 MB. pyrxd has no constant for either (no interpreter), so they're pinned in the test, with the set of budgets derived fromEvalScript's own comparisons rather than hand-listed._get_push_refson a ref pair whose little- and big-endian orders disagree, plus a non-vacuity test asserting they disagree.It found the same hand-kept list I did
test_vendored_sources_match_manifest_digestwas parametrized over two of eight filenames — structurally correct, hand-kept about its set, and would have passed vacuously over both new files. Now derived from the manifest, both directions closed.refresh_radiant_core_vendor.py,consensus_oracle.py,test_consensus_opcode_parity.py,MANIFEST.json). Whichever merges second needs a manual resolve — the two changes agree in intent, so it should be mechanical.Six plants, each caught, each restored and confirmed with
git status --porcelain.Verified independently: 11,013 passed, 192 skipped, 1 xfailed.
🤖 Generated with Claude Code