Add the claim-v1 bridge subprotocol version and the ruleset that commits it - #291
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
|
Commit: 39af0c9
|
prajwolrg
force-pushed
the
bridge-claim-version-parameterize
branch
from
October 1, 2026 01:59
3a3c63f to
2fbf147
Compare
The export leaf a fulfillment commits is consensus state, so moving from one claim shape to another needs both shapes to exist at once, selected per ruleset. The obvious ways to get there both duplicate: a second subprotocol crate copies ~1,650 lines of handler and validation to change one line, and a second `Subprotocol` impl copies the trait skeleton and its docs. Carrying the choice as a type parameter keeps one implementation. The released version becomes an alias for it, so every call site that names `BridgeSubprotoV1` compiles unchanged, and the subprotocol ID and section schema stay shared because the claim shape is an output rather than part of the state. `ClaimVersion::export_leaf` takes the operator table instead of the whole bridge state. The claim axis then does not depend on the state container, which is expected to gain its own versions later. No behavior change: `BridgeSubprotoV1` still commits v0 leaves.
`OperatorClaimUnlockV1` has been defined but emitted by nothing since #285. It names the assignee by MuSig2 public key, which the Bridge proof system needs: an operator index only resolves against the operator table at the fulfillment height, and the proof does not carry that table. `BridgeSubprotoV2` commits those leaves. It is not reachable yet — no ruleset invokes it — so this adds the version without moving any leaf a deployed chain has committed. The new test builds its expectation from the operator table rather than from `export_leaf`, so a lookup that resolved the wrong operator would still fail it, and asserts the committed leaf is not the v0 leaf for the same fulfillment.
Switching the bridge to `OperatorClaimUnlockV1` moves every export leaf committed after the switch, and the bridge container's MMR root with it. Deployed chains cannot reproduce those leaves, so the new behavior has to arrive as a ruleset the parent's predicate authorizes, not as an edit to spec 0. `prepare` needs no migration. The claim version is an output, so the bridge keeps its subprotocol ID and section schema version and sections carry across untouched. Genesis is spec 0's genesis with the ruleset identity replaced, for the same reason. Both rulesets stay in the native catalog: historical proof jobs resolve their own parent's predicate, so the old one has to keep resolving after an activation. Nothing selects spec 1 yet — `build_execution_registry` only registers what configuration names, and no target names it. The baseline-semantics test is now generic over the successor and runs for spec 1 as well, which pins that a block with no bridge transactions is indistinguishable from spec 0 under it.
prajwolrg
force-pushed
the
bridge-claim-version-parameterize
branch
from
October 1, 2026 05:08
2fbf147 to
25f8ae1
Compare
prajwolrg
marked this pull request as ready for review
October 1, 2026 09:24
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🔒 AI Security Review (claude-opus-5-5)✅ No security issues found. |
7 of 14 tasks
irnb
added this pull request to stack #303
October 1, 2026 10:45
irnb
approved these changes
Oct 1, 2026
irnb
left a comment
Collaborator
There was a problem hiding this comment.
LGTM, Let’s also initiate a guest program for V1 as well.
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.
Description
Adds the bridge subprotocol version that commits
OperatorClaimUnlockV1export leaves, and the ASM ruleset that invokes it. Nothing activates yet: no configuration names spec 1, so every chain keeps running spec 0 and committing v0 leaves.OperatorClaimUnlockV1has been defined but emitted by nothing since #285. It names a fulfillment's assignee by MuSig2 public key rather than by operator table index, which the Bridge proof system needs — an index only resolves against the operator table at the fulfillment height, and the proof does not carry that table.The design question was how to hold two claim shapes at once without duplicating the bridge. A second subprotocol crate would copy ~1,650 lines of handler and validation to change one line; a second
Subprotocolimpl would copy the trait skeleton and its docs. Instead the subprotocol carries the claim version as a type parameter,BridgeSubproto<C: ClaimVersion>, and each released version is an alias for one choice. One implementation covers both, andBridgeSubprotoV1stays a valid name at every existing call site.ClaimVersion::export_leaftakes the operator table rather than the wholeBridgeStateV1. We expect the bridge state schema to gain its own versions later, and this keeps the claim axis independent of the state container so that change does not ripple into it.Type of Change
Notes to Reviewers
Start at
crates/subprotocols/bridge/subprotocol/src/claim.rs— it is the whole behavioral difference between the two versions. The first commit is a pure refactor and should be read as behavior-neutral:BridgeSubprotoV1still commits v0 leaves, and all 65 existing bridge tests pass unchanged.The claim version moves the export leaf, not the section. The bridge keeps its subprotocol ID and
STATE_VERSION, so spec 1'spreparecarries sections across untouched and needs no migration, and its genesis is spec 0's genesis with the ruleset identity replaced.claim_versions_share_the_section_identitypins that, since a future divergence there would silently require a migration that does not exist.Both rulesets stay in the native catalog on purpose: historical proof jobs resolve their own parent's predicate, so spec 0 has to keep resolving after an activation.
Not in this PR, and needed before spec 1 can run anywhere:
guest-asm-v1crate, aGUESTSentry, a built ELF and derived predicate), plus the[[execution.targets]]and[[orchestrator.asm_artifacts]]entries. Until then a node configured for spec 1 executes natively but cannot load a proof artifact, which stops proving without dropping queued work.asm_upgrade_recovery, but nothing yet exercises both together.One naming wart left alone:
StrataAsmSpec(ID 0) now sits besideStrataAsmSpecV1(ID 1), so the unsuffixed name reads as "current" when it is not. Renaming it toStrataAsmSpecV0is mechanical but touches ~20 sites across the guest, proof statements and prover worker tests, so it belongs in its own PR.Checklist
Related Issues
Follows #285. Part of STR-3357.
Validation
Each commit was checked to build on its own. The SP1 guest was not rebuilt, since this PR adds no guest.
🤖 Generated with Claude Code