Skip to content

Add the claim-v1 bridge subprotocol version and the ruleset that commits it - #291

Merged
prajwolrg merged 3 commits into
mainfrom
bridge-claim-version-parameterize
Oct 1, 2026
Merged

prajwolrg merged 3 commits into
mainfrom
bridge-claim-version-parameterize

Conversation

@prajwolrg

@prajwolrg prajwolrg commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Adds the bridge subprotocol version that commits OperatorClaimUnlockV1 export 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.

OperatorClaimUnlockV1 has 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 Subprotocol impl 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, and BridgeSubprotoV1 stays a valid name at every existing call site.

ClaimVersion::export_leaf takes the operator table rather than the whole BridgeStateV1. 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

  • Bug fix (non-breaking change which fixes an issue)
  • New feature/Enhancement (non-breaking change which adds functionality or enhances an existing one)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor
  • New or updated tests
  • Dependency update
  • Security fix

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: BridgeSubprotoV1 still 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's prepare carries 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_identity pins 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:

  • The SP1 guest for spec 1 (a guest-asm-v1 crate, a GUESTS entry, 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.
  • An end-to-end test driving a fulfillment across an activation. The leaf change is covered at the handler level here; the activation machinery is covered by the existing asm_upgrade_recovery, but nothing yet exercises both together.
  • strata-bridge. Per Version the operator claim unlock, emit v0 again #285, its counterproof rebuilds the claim from the key it verified signed the bridge-proof transaction, so it has nothing to compare against v0 leaves. It needs to handle both leaf shapes before an activation is safe. This is the long pole.

One naming wart left alone: StrataAsmSpec (ID 0) now sits beside StrataAsmSpecV1 (ID 1), so the unsuffixed name reads as "current" when it is not. Renaming it to StrataAsmSpecV0 is mechanical but touches ~20 sites across the guest, proof statements and prover worker tests, so it belongs in its own PR.

Checklist

  • I have performed a self-review of my code.
  • I have commented my code where necessary.
  • I have updated the documentation if needed.
  • My changes do not introduce new warnings.
  • I have added tests that prove my changes are effective or that my feature works.
  • New and existing tests pass with my changes.

Related Issues

Follows #285. Part of STR-3357.

Validation

cargo fmt --all --check
cargo clippy --locked --workspace --all-features --all-targets -- -D warnings
cargo nextest run --locked --workspace --all-features      # 718 passed
cargo test --locked -p integration-tests --test asm_upgrade_recovery --test asm_coinbase

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

@prajwolrg
prajwolrg requested a review from irnb September 29, 2026 16:57
@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
bin/asm-runner/src/bootstrap.rs 0.00% 1 Missing ⚠️
crates/spec/src/host.rs 93.75% 1 Missing ⚠️
Files with missing lines Coverage Δ
crates/spec/src/spec.rs 91.42% <100.00%> (+11.42%) ⬆️
...rates/subprotocols/bridge/subprotocol/src/claim.rs 100.00% <100.00%> (ø)
...tes/subprotocols/bridge/subprotocol/src/handler.rs 94.51% <100.00%> (+0.88%) ⬆️
...subprotocols/bridge/subprotocol/src/subprotocol.rs 88.64% <100.00%> (+0.25%) ⬆️
crates/subprotocols/bridge/types/src/claim.rs 97.95% <ø> (ø)
bin/asm-runner/src/bootstrap.rs 97.24% <0.00%> (-0.68%) ⬇️
crates/spec/src/host.rs 98.41% <93.75%> (-1.59%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown

Commit: 39af0c9
SP1 Execution Results

program cycles gas
asm-stf 177,782,137 175,554,604
moho 5,193,712 5,505,029

@prajwolrg
prajwolrg force-pushed the bridge-claim-version-parameterize branch from 3a3c63f to 2fbf147 Compare October 1, 2026 01:59
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Commit: 2752370
Baseline: #298 (22030b8)
SP1 Execution Results

program cycles gas Δ cycles Δ gas
asm-stf 177,777,218 175,550,930 -155 (-0.0%) -81 (-0.0%)
moho 5,193,682 5,504,558 0 (0.0%) 0 (0.0%)

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
prajwolrg force-pushed the bridge-claim-version-parameterize branch from 2fbf147 to 25f8ae1 Compare October 1, 2026 05:08
@prajwolrg
prajwolrg requested a review from MdTeach October 1, 2026 09:24
@prajwolrg
prajwolrg marked this pull request as ready for review October 1, 2026 09:24
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-01T09:27:22.911004Z 25f8ae1 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

🔒 AI Security Review (claude-opus-5-5)

✅ No security issues found.

@irnb
irnb added this pull request to stack #303 October 1, 2026 10:45

@irnb irnb left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, Let’s also initiate a guest program for V1 as well.

@prajwolrg
prajwolrg added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit 5063e7c Oct 1, 2026
26 checks passed
@prajwolrg
prajwolrg deleted the bridge-claim-version-parameterize branch October 1, 2026 11:41
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.

2 participants