Skip to content

feat(agglayer): process CLAIM notes from a rollup#2573

Open
mmagician wants to merge 12 commits intoagglayerfrom
mmagician-claude/rollup-claims
Open

feat(agglayer): process CLAIM notes from a rollup#2573
mmagician wants to merge 12 commits intoagglayerfrom
mmagician-claude/rollup-claims

Conversation

@mmagician
Copy link
Collaborator

Summary

  • Support rollup deposits (mainnet_flag=0) in bridge-in verification, in addition to the existing mainnet-only path
  • Rollup deposits use two-level Merkle proof verification: first computing the local exit root from the leaf via calculate_root, then verifying it against the rollupExitRoot using smtProofRollupExitRoot
  • Add process_global_index_rollup MASM procedure and validate_rollup()/validate() Rust methods on GlobalIndex
  • Add Solidity test vector generator for rollup deposits and end-to-end integration test

Closes #2394

Test plan

  • All 43 agglayer tests pass (including new case_3_rollup bridge-in integration test)
  • 7 MASM global index unit tests pass (4 mainnet + 3 new rollup)
  • 4 Rust GlobalIndex unit tests pass (1 existing + 3 new rollup)
  • make lint passes
  • Solidity test vector generation verified via forge test

🤖 Generated with Claude Code

Support rollup deposits (mainnet_flag=0) in bridge-in verification.
Previously only mainnet deposits were supported and rollup deposits
would panic. Rollup deposits use two-level Merkle proof verification:
first computing the local exit root from the leaf, then verifying it
against the rollup exit root.

Closes #2394

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mmagician mmagician added the agglayer PRs or issues related to AggLayer bridging integration label Mar 10, 2026
@mmagician mmagician force-pushed the mmagician-claude/rollup-claims branch from 90d0479 to 54d7d66 Compare March 10, 2026 09:15
@mmagician mmagician added the no changelog This PR does not require an entry in the `CHANGELOG.md` file label Mar 10, 2026
…pers

Address review feedback:
- Remove leading zeros assertion and mainnet flag validation from
  process_global_index_mainnet and process_global_index_rollup helpers.
  These are now done once in verify_leaf before branching.
- The helpers now take [rollup_index_le, leaf_index_le] instead of the
  full 8-element global index.
- In process_global_index_rollup, removed unnecessary byte-swap before
  asserting zero (zero is byte-order-independent). This is now moot
  since the mainnet flag is no longer checked in the helper.
- Updated MASM unit tests to match the new helper signatures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mmagician mmagician force-pushed the mmagician-claude/rollup-claims branch from 54d7d66 to cb4627e Compare March 10, 2026 09:33
@mmagician mmagician added the pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority label Mar 10, 2026
@mmagician mmagician requested a review from Copilot March 10, 2026 09:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for processing CLAIM notes originating from rollups (mainnet_flag=0) by introducing rollup-aware global index handling and two-level Merkle proof verification, plus corresponding test vectors and integration coverage.

Changes:

  • Added rollup deposit test vectors and enabled bridge-in tests to run against them.
  • Introduced rollup global index processing in MASM and added Rust GlobalIndex::validate_rollup() / validate() helpers.
  • Added Solidity generator contract to produce rollup two-level Merkle proof vectors.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/miden-testing/tests/agglayer/test_utils.rs Adds rollup claim vector JSON + lazy parsed vector and exposes it via ClaimDataSource.
crates/miden-testing/tests/agglayer/global_index.rs Extends MASM global index tests to cover both mainnet and rollup procedures.
crates/miden-testing/tests/agglayer/bridge_in.rs Runs bridge-in integration test for rollup data source and creates destination account for rollup case.
crates/miden-agglayer/src/eth_types/global_index.rs Adds rollup validation + shared leading-bits check + dispatching validate(), plus unit tests.
crates/miden-agglayer/solidity-compat/test/ClaimAssetTestVectorsRollupTx.t.sol Adds Foundry test that generates rollup two-level Merkle proof vectors.
crates/miden-agglayer/solidity-compat/test-vectors/claim_asset_vectors_rollup_tx.json Adds generated rollup test vector JSON consumed by Rust tests.
crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm Adds process_global_index_rollup and rollup branch to verify_leaf using two-level verification.
Comments suppressed due to low confidence (1)

crates/miden-agglayer/asm/agglayer/bridge/bridge_in.masm:1

  • movdn.n operates on the stack top, but at this point the stack top is leaf_index, not rollup_index. As written, movdn.9 will move leaf_index down (and the later movdn.9 movdn.9 will reshuffle again), which makes the comments about the resulting stack state inconsistent and can easily lead to calling calculate_root with mis-ordered arguments. This is especially risky because the current rollup test vector uses rollup_index=0 and leaf_index=0, so an ordering bug here can be masked. Rework these stack moves so that rollup_index (depth 1) is the value being moved/preserved (e.g., bring it to the top first with a swap/movup and only then move it down past the leaf value), and update the stack-shape comments to match the actual effects of the instructions.
use miden::agglayer::bridge::bridge_config

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

claude added 3 commits March 10, 2026 09:50
Include the auto-generated ERR_MAINNET_FLAG_INVALID constant in the
committed errors file to fix the generated files CI check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use non-zero leafIndex (2) and indexRollup (5) in the rollup test
vectors to exercise byte-ordering and stack manipulation paths.

This exposed a bug in verify_leaf's rollup branch: the stack
rearrangement after process_global_index_rollup had leaf_index and
rollup_index in the wrong positions, which was masked when both
were zero.

Also restructure the rollup exit tree test helper to use an
SMT-style approach (setLocalExitRootAt) matching the real
PolygonRollupManager.getRollupExitRoot() construction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split ERR_BRIDGE_NOT_MAINNET into two errors:
- ERR_BRIDGE_NOT_MAINNET: "mainnet flag must be 1 for a mainnet deposit"
- ERR_BRIDGE_NOT_ROLLUP: "mainnet flag must be 0 for a rollup deposit"

The previous error text "bridge not mainnet" read backwards when used
in the rollup helper to reject a mainnet flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mmagician mmagician marked this pull request as ready for review March 10, 2026 11:01
@mmagician mmagician requested a review from Copilot March 10, 2026 11:01
- Fix stale comment in verify_leaf that incorrectly referenced
  "stack position 2" for the mainnet flag (it's at position 5)
- Add explicit MASM test for the mainnet flag boolean validation
  (ERR_MAINNET_FLAG_INVALID) which rejects flag values >= 2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

claude added 4 commits March 10, 2026 11:13
- Fix comment referencing non-existent MAINNET_FLAG_STACK_POS constant
- Remove test_mainnet_flag_rejects_invalid_value: it inlined the same
  logic as verify_leaf rather than testing verify_leaf itself, so it
  only proved u32lt.2 works on the value 3, not that verify_leaf
  actually performs the check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make validate_mainnet() and validate_rollup() private, exposing only
validate() which checks the mainnet flag is a valid boolean (0 or 1)
before dispatching. This fixes a bug where flag values >= 2 were
incorrectly accepted by validate_rollup() since is_mainnet() returned
false for any non-1 value.

Add mainnet_flag() accessor and a test for invalid flag rejection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Express SMT_PROOF_LOCAL_EXIT_ROOT_PTR and SMT_PROOF_ROLLUP_EXIT_ROOT_PTR
relative to PROOF_DATA_PTR and each other, rather than hard-coding
absolute values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reorganize constants into clear sections: proof data memory layout
(with address map comment), leaf data, calculate_root locals, and
data sizes. Define GLOBAL_INDEX_PTR relative to
SMT_PROOF_ROLLUP_EXIT_ROOT_PTR for a fully chained layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cursor[bot]

This comment was marked as resolved.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer PRs or issues related to AggLayer bridging integration no changelog This PR does not require an entry in the `CHANGELOG.md` file pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants