-
Notifications
You must be signed in to change notification settings - Fork 123
feat(agglayer): process CLAIM notes from a rollup #2573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
487124e
cb4627e
39890f2
0b8834f
85c3ea7
654ca3c
0764c3d
3e04f7b
9ce0425
66de26d
4fa6069
8dfdc5c
dc0d728
152665a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,10 @@ type MemoryAddress = u32 | |
| # ERRORS | ||
| # ================================================================================================= | ||
|
|
||
| const ERR_BRIDGE_NOT_MAINNET = "bridge not mainnet" | ||
| const ERR_BRIDGE_NOT_MAINNET = "mainnet flag must be 1 for a mainnet deposit" | ||
| const ERR_BRIDGE_NOT_ROLLUP = "mainnet flag must be 0 for a rollup deposit" | ||
| const ERR_LEADING_BITS_NON_ZERO = "leading bits of global index must be zero" | ||
| const ERR_MAINNET_FLAG_INVALID = "mainnet flag must be 0 or 1" | ||
| const ERR_ROLLUP_INDEX_NON_ZERO = "rollup index must be zero for a mainnet deposit" | ||
| const ERR_SMT_ROOT_VERIFICATION_FAILED = "merkle proof verification failed: provided SMT root does not match the computed root" | ||
|
|
||
|
|
@@ -29,6 +31,8 @@ const SMT_PROOF_LOCAL_EXIT_ROOT_PTR = 0 # local SMT proof is first | |
| const GLOBAL_INDEX_PTR = PROOF_DATA_PTR + 2 * 256 # 512 | ||
| const EXIT_ROOTS_PTR = GLOBAL_INDEX_PTR + 8 # 520 | ||
| const MAINNET_EXIT_ROOT_PTR = EXIT_ROOTS_PTR # it's the first exit root | ||
| const SMT_PROOF_ROLLUP_EXIT_ROOT_PTR = 256 # rollup SMT proof starts after local | ||
| const ROLLUP_EXIT_ROOT_PTR = EXIT_ROOTS_PTR + 8 # 528 | ||
|
|
||
| # the memory address where leaf data is stored for get_leaf_value | ||
| const LEAF_DATA_START_PTR = 0 | ||
|
|
@@ -116,17 +120,16 @@ end | |
| #! | ||
| #! Invocation: exec | ||
| pub proc process_global_index_mainnet | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should have a helper procedure which takes |
||
| # for v0.1, let's only implement the mainnet branch | ||
| # the top 191 bits of the global index are zero | ||
| repeat.5 assertz.err=ERR_LEADING_BITS_NON_ZERO end | ||
|
|
||
| # the next element is the mainnet flag (LE-packed u32) | ||
| # byte-swap to get the BE value, then assert it is exactly 1 | ||
| # => [mainnet_flag_le, rollup_index_le, leaf_index_le, ...] | ||
| # => [mainnet_flag_le, rollup_index_le, leaf_index_le] | ||
| exec.utils::swap_u32_bytes | ||
| assert.err=ERR_BRIDGE_NOT_MAINNET | ||
|
|
||
| # the next element is the rollup index, must be zero for a mainnet deposit | ||
| # the rollup index must be zero for a mainnet deposit | ||
| # (zero is byte-order-independent, so no swap needed) | ||
| assertz.err=ERR_ROLLUP_INDEX_NON_ZERO | ||
|
|
||
|
|
@@ -135,6 +138,38 @@ pub proc process_global_index_mainnet | |
| # => [leaf_index] | ||
| end | ||
|
|
||
| #! Assert the global index is valid for a rollup deposit. | ||
| #! | ||
| #! Each element of the global index is a LE-packed u32 felt (as produced by | ||
| #! `bytes_to_packed_u32_felts` / `GlobalIndex::to_elements()`). | ||
| #! | ||
| #! Inputs: [GLOBAL_INDEX[8]] | ||
| #! Outputs: [leaf_index, rollup_index] | ||
| #! | ||
| #! Panics if: | ||
| #! - the leading bits of the global index are not zero. | ||
| #! - the mainnet flag is not 0. | ||
| #! | ||
| #! Invocation: exec | ||
| pub proc process_global_index_rollup | ||
| # the top 191 bits of the global index are zero | ||
| repeat.5 assertz.err=ERR_LEADING_BITS_NON_ZERO end | ||
mmagician marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| # the next element is the mainnet flag (LE-packed u32) | ||
| # for a rollup deposit it must be exactly 0; zero is byte-order-independent, | ||
| # so no swap is needed before asserting | ||
| # => [mainnet_flag_le, rollup_index_le, leaf_index_le] | ||
| assertz.err=ERR_BRIDGE_NOT_ROLLUP | ||
|
|
||
| # byte-swap rollup_index from LE to BE | ||
| exec.utils::swap_u32_bytes | ||
| # => [rollup_index, leaf_index_le] | ||
|
|
||
| # byte-swap leaf_index from LE to BE | ||
| swap exec.utils::swap_u32_bytes | ||
| # => [leaf_index, rollup_index] | ||
| end | ||
|
|
||
| #! Computes the Global Exit Tree (GET) root from the mainnet and rollup exit roots. | ||
| #! | ||
| #! The mainnet exit root is expected at `exit_roots_ptr` and | ||
|
|
@@ -263,27 +298,75 @@ proc verify_leaf | |
| padw push.GLOBAL_INDEX_PTR add.4 mem_loadw_le swapw | ||
| # => [GLOBAL_INDEX[8], LEAF_VALUE[8]] | ||
|
|
||
| # to see if we're dealing with a deposit from mainnet or from a rollup, process the global index | ||
| # TODO currently only implemented for mainnet deposits (mainnet flag must be 1) | ||
| exec.process_global_index_mainnet | ||
| # => [leaf_index, LEAF_VALUE[8]] | ||
|
|
||
| # load the pointers to the merkle proof and root, to pass to `verify_merkle_proof` | ||
| push.MAINNET_EXIT_ROOT_PTR swap | ||
| push.SMT_PROOF_LOCAL_EXIT_ROOT_PTR | ||
| # => [smt_proof_ptr, leaf_index, mainnet_exit_root_ptr, LEAF_VALUE[8]] | ||
|
|
||
| # prepare the stack for the verify_merkle_proof procedure: move the pointers deep in the stack | ||
| movdn.10 movdn.10 movdn.10 | ||
| # => [LEAF_VALUE[8], smt_proof_ptr, leaf_index, mainnet_exit_root_ptr] | ||
|
|
||
| exec.verify_merkle_proof | ||
| # => [verification_flag] | ||
|
|
||
| # verify_merkle_proof procedure returns `true` if the verification was successful and `false` | ||
| # otherwise. Assert that `true` was returned. | ||
| assert.err=ERR_SMT_ROOT_VERIFICATION_FAILED | ||
| # => [] | ||
| # Determine if we're dealing with a deposit from mainnet or from a rollup. | ||
| # The global index is laid out as: | ||
| # [gi0, gi1, gi2, gi3, gi4, mainnet_flag_le, rollup_index_le, leaf_index_le] | ||
| # gi0 is on top (position 0). The mainnet flag is at MAINNET_FLAG_STACK_POS. | ||
|
|
||
| # Duplicate the mainnet flag element, byte-swap from LE to BE, | ||
| # assert it is a valid boolean (0 or 1), then use it to branch. | ||
| dup.5 exec.utils::swap_u32_bytes dup | ||
| # => [mainnet_flag, mainnet_flag, GLOBAL_INDEX[8], LEAF_VALUE[8]] | ||
|
|
||
| u32lt.2 assert.err=ERR_MAINNET_FLAG_INVALID | ||
| # => [mainnet_flag, GLOBAL_INDEX[8], LEAF_VALUE[8]] | ||
|
|
||
| if.true | ||
| # ==================== MAINNET DEPOSIT ==================== | ||
| exec.process_global_index_mainnet | ||
| # => [leaf_index, LEAF_VALUE[8]] | ||
|
|
||
| # verify single Merkle proof: leaf against mainnetExitRoot | ||
| push.MAINNET_EXIT_ROOT_PTR swap | ||
| push.SMT_PROOF_LOCAL_EXIT_ROOT_PTR | ||
| # => [smt_proof_ptr, leaf_index, mainnet_exit_root_ptr, LEAF_VALUE[8]] | ||
|
|
||
| movdn.10 movdn.10 movdn.10 | ||
| # => [LEAF_VALUE[8], smt_proof_ptr, leaf_index, mainnet_exit_root_ptr] | ||
|
|
||
| exec.verify_merkle_proof | ||
| # => [verification_flag] | ||
|
|
||
| assert.err=ERR_SMT_ROOT_VERIFICATION_FAILED | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we have different error messages for if the proof verification failed for rollup vs mainnet deposit? Say,
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could, but we only ever verify one of them per |
||
| # => [] | ||
| else | ||
| # ==================== ROLLUP DEPOSIT ==================== | ||
| # mainnet_flag = 0; extract rollup_index and leaf_index via helper, | ||
| # then do two-level verification | ||
| exec.process_global_index_rollup | ||
| # => [leaf_index, rollup_index, LEAF_VALUE[8]] | ||
|
|
||
| # Step 1: calculate_root(leafValue, smtProofLocalExitRoot, leafIndex) -> localExitRoot | ||
| # We need to save rollup_index while calculate_root runs. | ||
| # calculate_root expects: [LEAF_VALUE_LO, LEAF_VALUE_HI, merkle_path_ptr, leaf_idx] | ||
| # => [leaf_index, rollup_index, LEAF_VALUE[8]] | ||
|
|
||
| # Rearrange to: [LEAF_VALUE[8], smt_proof_local_ptr, leaf_index, rollup_index] | ||
| # First, move leaf_index and rollup_index past LEAF_VALUE | ||
mmagician marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| movdn.9 movdn.9 | ||
| # => [LEAF_VALUE[8], leaf_index, rollup_index] | ||
|
|
||
| # Insert smt_proof_local_ptr before leaf_index | ||
| push.SMT_PROOF_LOCAL_EXIT_ROOT_PTR movdn.8 | ||
| # => [LEAF_VALUE[8], smt_proof_local_ptr, leaf_index, rollup_index] | ||
|
|
||
| exec.calculate_root | ||
| # => [LOCAL_EXIT_ROOT_LO, LOCAL_EXIT_ROOT_HI, rollup_index] | ||
|
|
||
| # Step 2: verify_merkle_proof(localExitRoot, smtProofRollupExitRoot, rollupIndex, rollupExitRootPtr) | ||
| push.ROLLUP_EXIT_ROOT_PTR movup.9 | ||
| push.SMT_PROOF_ROLLUP_EXIT_ROOT_PTR | ||
| # => [smt_proof_rollup_ptr, rollup_index, rollup_exit_root_ptr, LOCAL_EXIT_ROOT[8]] | ||
|
|
||
| movdn.10 movdn.10 movdn.10 | ||
| # => [LOCAL_EXIT_ROOT[8], smt_proof_rollup_ptr, rollup_index, rollup_exit_root_ptr] | ||
mmagician marked this conversation as resolved.
Show resolved
Hide resolved
mmagician marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| exec.verify_merkle_proof | ||
| # => [verification_flag] | ||
|
|
||
| assert.err=ERR_SMT_ROOT_VERIFICATION_FAILED | ||
| # => [] | ||
| end | ||
| end | ||
|
|
||
| #! Computes the root of the SMT based on the provided Merkle path, leaf value and leaf index. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| { | ||
| "amount": "100000000000000000000", | ||
| "deposit_count": 3, | ||
| "description": "Rollup deposit test vectors with valid two-level Merkle proofs (non-zero indices)", | ||
| "destination_address": "0x00000000AA0000000000bb000000cc000000Dd00", | ||
| "destination_network": 20, | ||
| "global_exit_root": "0x677d4ecba0ff4871f33163e70ea39a13fe97f2fa9b4dbad110e398830a324159", | ||
| "global_index": "0x0000000000000000000000000000000000000000000000000000000500000002", | ||
| "leaf_type": 0, | ||
| "leaf_value": "0x4a6a047a2b89dd9c557395833c5e34c4f72e6f9aae70779e856f14a6a2827585", | ||
| "local_exit_root": "0x985cff7ee35794b30fba700b64546b4ec240d2d78aaf356d56e83d907009367f", | ||
| "mainnet_exit_root": "0x4d63440b08ffffe5a049aae4161d54821a09973965a1a1728534a0f117b6d6c9", | ||
| "metadata": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045445535400000000000000000000000000000000000000000000000000000000", | ||
| "metadata_hash": "0x4d0d9fb7f9ab2f012da088dc1c228173723db7e09147fe4fea2657849d580161", | ||
| "origin_network": 3, | ||
| "origin_token_address": "0x2DC70fb75b88d2eB4715bc06E1595E6D97c34DFF", | ||
| "rollup_exit_root": "0x91105681934ca0791f4e760fb1f702050d81e4b7c866d42f540710999c90ea97", | ||
| "smt_proof_local_exit_root": [ | ||
| "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "0xa8367b4263332f7e5453faa770f07ef4ce3e74fc411e0a788a98b38b91fd3b3e", | ||
| "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", | ||
| "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", | ||
| "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", | ||
| "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", | ||
| "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", | ||
| "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", | ||
| "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", | ||
| "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", | ||
| "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", | ||
| "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", | ||
| "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", | ||
| "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", | ||
| "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", | ||
| "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2", | ||
| "0x2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f", | ||
| "0xe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a", | ||
| "0x5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0", | ||
| "0xb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0", | ||
| "0xc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2", | ||
| "0xf4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9", | ||
| "0x5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377", | ||
| "0x4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652", | ||
| "0xcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef", | ||
| "0x0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d", | ||
| "0xb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0", | ||
| "0x838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e", | ||
| "0x662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e", | ||
| "0x388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322", | ||
| "0x93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735", | ||
| "0x8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9" | ||
| ], | ||
| "smt_proof_rollup_exit_root": [ | ||
| "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", | ||
| "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", | ||
| "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", | ||
| "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", | ||
| "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", | ||
| "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", | ||
| "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", | ||
| "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", | ||
| "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", | ||
| "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", | ||
| "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", | ||
| "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", | ||
| "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", | ||
| "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", | ||
| "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2", | ||
| "0x2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f", | ||
| "0xe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a", | ||
| "0x5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0", | ||
| "0xb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0", | ||
| "0xc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2", | ||
| "0xf4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9", | ||
| "0x5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377", | ||
| "0x4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652", | ||
| "0xcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef", | ||
| "0x0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d", | ||
| "0xb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0", | ||
| "0x838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e", | ||
| "0x662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e", | ||
| "0x388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322", | ||
| "0x93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735", | ||
| "0x8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9" | ||
| ] | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.