diff --git a/barretenberg/.claude/skills/gate-counts/SKILL.md b/barretenberg/.claude/skills/gate-counts/SKILL.md index ab2efa9e9488..4b854e8036cd 100644 --- a/barretenberg/.claude/skills/gate-counts/SKILL.md +++ b/barretenberg/.claude/skills/gate-counts/SKILL.md @@ -209,41 +209,42 @@ Then retry `bb gates`. The committed `Prover.toml` files carry fake recursive proofs whose length is frozen at the value present when they were last generated. After a proof-length change they must be regenerated (or hacked — see below). Two commands cover all -protocol circuits: +protocol circuits, split by whether the sample needs a real client-proved +transaction. -**Kernel circuits + most rollup circuits** (spins up an L1/anvil sandbox): +**Block-root and above rollup circuits — prover-client suite** (simulated +orchestrator, no L1 sandbox): ```bash -AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 \ - yarn workspace @aztec/end-to-end test:e2e e2e_prover/full.test +AZTEC_GENERATE_TEST_DATA=1 \ + yarn workspace @aztec/prover-client test regenerate_rollup_sample_inputs ``` -Regenerates `Prover.toml` for: `private-kernel-init` and its `private-kernel-init-N` -variants, `private-kernel-inner` and its `private-kernel-inner-N` variants, -`private-kernel-reset`, `private-kernel-reset-tail`, -`private-kernel-reset-tail-to-public`, `rollup-tx-base-private`, -`rollup-tx-base-public`, `rollup-block-root-first`, -`rollup-block-root-first-single-tx`, `rollup-checkpoint-root-single-block`, -`rollup-checkpoint-merge`, `rollup-root`. +Regenerates `Prover.toml` for `rollup-block-root-first-empty-tx`, +`rollup-block-root-first`, `rollup-block-root-first-single-tx`, +`rollup-block-root`, `rollup-block-root-single-tx`, `rollup-block-root-msgs-only`, +`rollup-block-merge`, `rollup-checkpoint-root`, `rollup-checkpoint-root-single-block`, +`rollup-checkpoint-merge`, `rollup-tx-merge`, `rollup-root`. -**Rollup circuits NOT covered by `full.test`** (incl. `rollup-tx-merge`): +**Private-kernel + transaction-base circuits — e2e prover full test** (spins up +an L1/anvil sandbox): ```bash AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 \ - yarn workspace @aztec/prover-client test src/orchestrator/orchestrator_single_checkpoint.test.ts + yarn workspace @aztec/end-to-end test:e2e single-node/prover/server/full.test ``` -Regenerates `Prover.toml` for `rollup-tx-merge`, `rollup-block-root-first-empty-tx`, -`rollup-block-root` (single-tx checkpoint test) and `rollup-block-root-single-tx`, -`rollup-block-merge`, `rollup-checkpoint-root` (multi-block checkpoint test). - -> **`rollup-tx-merge`'s `Prover.toml` is regenerated by the prover-client -> command, NOT `full.test`** — it is commented out in `full.test`'s circuit -> list. Use the prover-client command for the tx-merge circuit. +Regenerates `Prover.toml` for: `private-kernel-init` and its `private-kernel-init-N` +variants, `private-kernel-inner` and its `private-kernel-inner-N` variants, +`private-kernel-reset-tail`, `private-kernel-reset-tail-to-public`, +`rollup-tx-base-private`, `rollup-tx-base-public`. These need real client-proved +transactions the simulated orchestrator cannot produce. (`private-kernel-reset`, +the inner reset, is commented out and hand-maintained — not regenerated.) The circuit lists live in the `updateProtocolCircuitSampleInputs(...)` loops in -`yarn-project/end-to-end/src/e2e_prover/full.test.ts` and -`yarn-project/prover-client/src/orchestrator/orchestrator_single_checkpoint.test.ts`; +`yarn-project/end-to-end/src/single-node/prover/server/full.test.ts` and the +`scenarios` array in +`yarn-project/prover-client/src/test/regenerate_rollup_sample_inputs.test.ts`; re-read them if a circuit seems missing (entries get commented in/out). ### Build prerequisites for regeneration diff --git a/barretenberg/.claude/skills/update-prover-toml/SKILL.md b/barretenberg/.claude/skills/update-prover-toml/SKILL.md index 8fff26ff9d60..485e1c1ce0fd 100644 --- a/barretenberg/.claude/skills/update-prover-toml/SKILL.md +++ b/barretenberg/.claude/skills/update-prover-toml/SKILL.md @@ -1,6 +1,6 @@ --- name: update-prover-toml -description: Regenerate the protocol-circuit sample Prover.toml files (the witnesses CI feeds to `nargo execute`). Covers which e2e test/commands regenerate which tomls, and the one exception — private-kernel-reset/Prover.toml (the inner reset) — which is NOT generated by the test at all and is maintained entirely by hand. Use when a `nargo execute` CI check fails on a crates/*/Prover.toml, after changing protocol-circuit inputs/constants, or when asked to refresh/regenerate Prover.toml sample inputs. +description: Regenerate the protocol-circuit sample Prover.toml files (the witnesses CI feeds to `nargo execute`). Covers which of the two commands regenerates which tomls — the prover-client `regenerate_rollup_sample_inputs` suite for the block-root and above rollup circuits, and the e2e prover full test for the private-kernel and transaction-base circuits — and the one exception, private-kernel-reset/Prover.toml (the inner reset), which is NOT generated by the test at all and is maintained entirely by hand. Use when a `nargo execute` CI check fails on a crates/*/Prover.toml, after changing protocol-circuit inputs/constants, or when asked to refresh/regenerate Prover.toml sample inputs. --- # Updating protocol-circuit Prover.toml files @@ -21,39 +21,40 @@ The tomls are captured from a real end-to-end run, not written by hand (except t ## How regeneration works -`yarn-project/end-to-end/src/e2e_prover/full.test.ts` has a test "generates sample Prover.toml files if generate test data is on". During proving, circuit inputs are captured via `pushTestData`/`getTestData`; the test then calls `updateProtocolCircuitSampleInputs(circuitName, TOML.stringify(...))` (`yarn-project/foundation/src/testing/files/index.ts`), which writes `noir-projects/noir-protocol-circuits/crates//Prover.toml`. +Two commands cover the protocol-circuit tomls, split by whether the sample needs a real client-proved transaction. Both capture circuit inputs during proving via `pushTestData`/`getTestData` and write them with `updateProtocolCircuitSampleInputs(circuitName, TOML.stringify(...))` (`yarn-project/foundation/src/testing/files/index.ts`), which writes `noir-projects/noir-protocol-circuits/crates//Prover.toml`. -The test early-returns unless **both** are true: `AZTEC_GENERATE_TEST_DATA=1` (enables `isGenerateTestDataEnabled()`) and fake proofs (`FAKE_PROOFS=1`, i.e. `REAL_PROOFS` is false). +### Block-root and above rollup circuits — prover-client suite -### Command - -From the repo root: +`yarn-project/prover-client/src/test/regenerate_rollup_sample_inputs.test.ts` drives representative epochs through the simulated orchestrator and dumps each rollup circuit's captured input. The whole suite is `describe.skip`ped unless `AZTEC_GENERATE_TEST_DATA=1`, and it needs no L1 sandbox. ```bash -AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn-project/end-to-end/scripts/run_test.sh simple e2e_prover/full +AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test regenerate_rollup_sample_inputs ``` -(Equivalently, from `yarn-project/end-to-end`: `AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn test:e2e e2e_prover/full.test`.) This is a full-stack run (L1 anvil + node + prover), ~15 min with fake proofs. +Regenerates: `rollup-block-root-first-empty-tx`, `rollup-block-root-first`, `rollup-block-root-first-single-tx`, `rollup-block-root`, `rollup-block-root-single-tx`, `rollup-block-root-msgs-only`, `rollup-block-merge`, `rollup-checkpoint-root`, `rollup-checkpoint-root-single-block`, `rollup-checkpoint-merge`, `rollup-tx-merge`, `rollup-root`. The scenario list lives in the `scenarios` array in that test; each scenario's `dump` field names the tomls it owns. -After it finishes, review and stage the changed tomls with `git diff noir-projects/noir-protocol-circuits/crates/*/Prover.toml`. +### Private-kernel and transaction-base circuits — e2e prover full test -### Which tomls this regenerates +`full.test.ts` has a test "generates sample Prover.toml files if generate test data is on". It early-returns unless **both** `AZTEC_GENERATE_TEST_DATA=1` (enables `isGenerateTestDataEnabled()`) and fake proofs (`FAKE_PROOFS=1`, i.e. `REAL_PROOFS` is false) are set. These circuits need real client-proved transactions, which the simulated orchestrator suite above cannot produce. -The circuit list lives in the `forEach(circuitName => ...)` loop in `full.test.ts`. Currently active (regenerated by the run above): +From the repo root: + +```bash +AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn-project/end-to-end/scripts/run_test.sh simple single-node/prover/server/full +``` + +(Equivalently, from `yarn-project/end-to-end`: `AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn test:e2e single-node/prover/server/full.test`.) This is a full-stack run (L1 anvil + node + prover), ~15 min with fake proofs. + +Regenerates: - `private-kernel-init`, `private-kernel-init-2` … `private-kernel-init-5` - `private-kernel-inner`, `private-kernel-inner-2` … `private-kernel-inner-5` - `private-kernel-reset-tail`, `private-kernel-reset-tail-to-public` (the terminal resets — these run as part of every tx's tail) - `rollup-tx-base-private`, `rollup-tx-base-public` -- `rollup-block-root-first`, `rollup-block-root-first-single-tx` -- `rollup-checkpoint-root-single-block`, `rollup-checkpoint-merge` -- `rollup-root` - -`private-kernel-reset` (the **inner** reset) is deliberately **commented out** of this list and is **not** generated by the test — see the exception below. -Other entries commented out (e.g. `rollup-tx-merge`, `rollup-block-root`, `rollup-block-merge`, `rollup-checkpoint-root`) are also not produced by this flow; the inline comment points to the orchestrator single-checkpoint test for those. +The circuit list lives in the `forEach(circuitName => ...)` loop in `full.test.ts`. `private-kernel-reset` (the **inner** reset) is deliberately **commented out** of this list and is **not** generated by the test — see the exception below. -If you add a new circuit crate, add its name to that list so its toml gets generated. +After either run, review and stage the changed tomls with `git diff noir-projects/noir-protocol-circuits/crates/*/Prover.toml`. If you add a new circuit crate, add its name to the appropriate list so its toml gets generated. ## ⚠️ Exception: `private-kernel-reset/Prover.toml` (inner reset) is NOT generated — hand-maintain it diff --git a/barretenberg/cpp/CLAUDE.md b/barretenberg/cpp/CLAUDE.md index 910cdbf0ac8a..dd3ba7d2522a 100644 --- a/barretenberg/cpp/CLAUDE.md +++ b/barretenberg/cpp/CLAUDE.md @@ -139,21 +139,21 @@ run the generation commands above. Proof-length-affecting changes (e.g. `CHONK_PROOF_LENGTH` bumps from MegaFlavor entity additions) make the committed `Prover.toml` fixtures stale. `nargo execute --program-dir ` then fails with `Type Array { length: N, typ: Field } is expected to have length N but value Vec(...)`. -Regenerate via the e2e prover full test with fake proofs: +Regeneration is split across two commands. The block-root, block-merge, checkpoint, tx-merge, and root rollup samples come from the prover-client suite, which drives the simulated orchestrator and needs no L1 sandbox: ```bash -cd yarn-project -AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test e2e_prover/full.test +AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test regenerate_rollup_sample_inputs ``` -`FAKE_PROOFS=1` skips real proving — runs in ~2 min (orchestrator + witness generation only). Writes 12 `Prover.toml` files under `noir-projects/noir-protocol-circuits/crates//Prover.toml`. - -For circuits not exercised by `full.test.ts` (`rollup-tx-merge`, `rollup-block-root`, `rollup-block-root-single-tx`, `rollup-block-merge`, `rollup-checkpoint-root`, `rollup-block-root-first-empty-tx`), additionally run: +The private-kernel samples and the transaction-base rollup samples (`rollup-tx-base-private`, `rollup-tx-base-public`) need real client-proved transactions, so they come from the e2e prover full test with fake proofs: ```bash -AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test orchestrator_single_checkpoint +cd yarn-project +AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test single-node/prover/server/full.test ``` +`FAKE_PROOFS=1` skips real proving. Both write into `noir-projects/noir-protocol-circuits/crates//Prover.toml`. + Verify with `nargo execute --program-dir noir-projects/noir-protocol-circuits/crates/` for any previously-failing crate; should print `Circuit witness successfully solved`. ## Verification Keys diff --git a/docs/docs-developers/docs/foundational-topics/ethereum-aztec-messaging/inbox.md b/docs/docs-developers/docs/foundational-topics/ethereum-aztec-messaging/inbox.md index fcf43a73c32c..d3d818b629c5 100644 --- a/docs/docs-developers/docs/foundational-topics/ethereum-aztec-messaging/inbox.md +++ b/docs/docs-developers/docs/foundational-topics/ethereum-aztec-messaging/inbox.md @@ -35,34 +35,10 @@ These functions allow you to query the current state of the Inbox. | Function | Returns | Description | | -------------------------- | ----------------- | ------------------------------------------------ | -| `getRoot(uint256)` | `bytes32` | Returns the root of a message tree for a given checkpoint number. | -| `getState()` | `InboxState` | Returns the current inbox state (rolling hash, total messages inserted, in-progress checkpoint). | +| `getState()` | `InboxState` | Returns the current inbox state (rolling hash, total messages inserted). | | `getTotalMessagesInserted()` | `uint64` | Returns the total number of messages inserted into the inbox. | -| `getInProgress()` | `uint64` | Returns the checkpoint number currently being filled. | | `getFeeAssetPortal()` | `address` | Returns the address of the Fee Juice portal. | -## Internal functions - -:::note -The following functions are only callable by the Rollup contract and are documented here for completeness. -::: - -### `consume()` - -Consumes a message tree for a given checkpoint number. - -#include_code consume l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity - -| Name | Type | Description | -| ----------- | --------- | ---------------------------------------- | -| _toConsume | `uint256` | The checkpoint number to consume. | -| ReturnValue | `bytes32` | The root of the consumed message tree. | - -#### Edge cases - -- Will revert with `Inbox__Unauthorized()` if `msg.sender != ROLLUP`. -- Will revert with `Inbox__MustBuildBeforeConsume()` if trying to consume a checkpoint that hasn't been built yet. - ## Related pages - [Outbox](./outbox.md) - L2 to L1 message passing diff --git a/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md b/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md index b5b2f011c037..ec98831961a4 100644 --- a/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md +++ b/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md @@ -96,7 +96,7 @@ sequenceDiagram Portal->>Aave: withdraw(aTokenAmount) Aave-->>Portal: underlying + yield Portal->>Inbox: sendL2Message(content) - Note over Inbox: Wait for 2 L2 blocks (required for L1→L2 message availability) + Note over Inbox: Wait for an L2 block to include the message (12-30s) User->>Bridge: claim_public(amount_with_yield) Bridge->>Inbox: consume_l1_to_l2_message Bridge->>Token: mint_to_public(user, amount_with_yield) @@ -441,7 +441,7 @@ Extract the message leaf index: #include_code get_claim_leaf_index /docs/examples/ts/aave_bridge/index.ts typescript -On the local network, L2 blocks are only produced when transactions are submitted. L1-to-L2 messages require 2 L2 blocks before they can be consumed on L2. This utility deploys two dummy contracts (with random salts for unique addresses) to force block production. On devnet or testnet, blocks are produced continuously and this step is unnecessary: +On the local network, L2 blocks are only produced when transactions are submitted. An L1-to-L2 message can only be consumed once an L2 block includes it, and the network waits until the message is at least 12 seconds old before including it. This utility deploys two dummy contracts (with random salts for unique addresses) to force block production. On devnet or testnet, blocks are produced continuously and this step is unnecessary: #include_code mine_blocks /docs/examples/ts/aave_bridge/index.ts typescript @@ -501,7 +501,7 @@ If `claim_public` reverts, ensure you called `set_minter(l2Bridge.address, true) ### L1→L2 message not found — claim reverts after mining blocks -L1-to-L2 messages need 2 L2 blocks after the L1 transaction before they become consumable. Make sure `mine2Blocks` runs before the claim. If the issue persists, verify the `messageLeafIndex` extracted from the `MessageSent` event is correct. +An L1-to-L2 message becomes consumable once an L2 block includes it, which takes 12 to 30 seconds after the L1 transaction. Make sure `mine2Blocks` runs before the claim. If the issue persists, verify the `messageLeafIndex` extracted from the `MessageSent` event is correct. ## Next Steps diff --git a/docs/docs-developers/docs/tutorials/js_tutorials/token_bridge.md b/docs/docs-developers/docs/tutorials/js_tutorials/token_bridge.md index b5855967ec7e..880643436470 100644 --- a/docs/docs-developers/docs/tutorials/js_tutorials/token_bridge.md +++ b/docs/docs-developers/docs/tutorials/js_tutorials/token_bridge.md @@ -437,15 +437,15 @@ To bridge, first approve the portal address to transfer the NFT, then transfer i #include_code deposit_to_aztec /docs/examples/ts/token_bridge/index.ts typescript -The `Inbox` contract will emit an important log: `MessageSent(inProgress, index, leaf, updatedRollingHash);`. This log provides the **leaf index** of the message in the [L1-L2 Message Tree](../../foundational-topics/ethereum-aztec-messaging/index.md)—the location of the message in the tree that will appear on L2. You need this index, plus the secret, to correctly claim and decrypt the message. +The `Inbox` contract will emit an important log: `MessageSent(index, hash, inboxRollingHash, bucketSeq);`. Its first field is the **leaf index** of the message in the [L1-L2 Message Tree](../../foundational-topics/ethereum-aztec-messaging/index.md)—the location of the message in the tree that will appear on L2. You need this index, plus the secret, to correctly claim and decrypt the message. Use viem to extract this information: #include_code get_message_leaf_index /docs/examples/ts/token_bridge/index.ts typescript -This extracts the logs from the deposit and retrieves the leaf index. You can now claim it on L2. However, for security reasons, at least 2 blocks must pass before a message can be claimed on L2. If you called `claim` on the L2 contract immediately, it would return "no message available". +This extracts the logs from the deposit and retrieves the leaf index. You can now claim it on L2. However, a message can only be claimed once an L2 block includes it, and the network waits until the message is at least 12 seconds old before including it, so expect 12 to 30 seconds of latency. If you called `claim` on the L2 contract immediately, it would return "no message available". -Add a utility function to mine two blocks (it deploys a contract with a random salt): +On a local network blocks are only produced when transactions are submitted, so add a utility function that forces a couple of blocks (it deploys a contract with a random salt): #include_code mine_blocks /docs/examples/ts/token_bridge/index.ts typescript diff --git a/docs/docs-developers/docs/tutorials/js_tutorials/uniswap_swap.md b/docs/docs-developers/docs/tutorials/js_tutorials/uniswap_swap.md index 0aadfdbcda16..537605723c49 100644 --- a/docs/docs-developers/docs/tutorials/js_tutorials/uniswap_swap.md +++ b/docs/docs-developers/docs/tutorials/js_tutorials/uniswap_swap.md @@ -309,7 +309,7 @@ Bridge WETH from L1 to L2: When depositing from L1 to L2, we use a secret/secret-hash pattern: generate a random secret on the client, send only the hash to L1 (in the deposit transaction), then later reveal the secret on L2 to claim the tokens. This prevents **front-running attacks**: a malicious sequencer (the node that orders and processes L2 transactions) cannot observe the L1 deposit and claim the tokens themselves because they don't know the secret. Only someone who knows the preimage can claim. ::: -Before claiming, we need to mine 2 L2 blocks. L1-to-L2 messages are not available in the same block they are sent -- the rollup must first include them in an L2 block, and then one more block must pass before the message can be consumed. We use a helper that deploys throwaway contracts to force these blocks: +Before claiming, we need to mine a couple of L2 blocks. An L1-to-L2 message is not available the moment it is sent -- the rollup only includes it in an L2 block once it is at least 12 seconds old, and it becomes consumable as soon as that block lands. We use a helper that deploys throwaway contracts to force these blocks: #include_code mine_blocks /docs/examples/ts/example_swap/index.ts typescript diff --git a/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md b/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md index c6344662f839..a31f879a901d 100644 --- a/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md +++ b/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md @@ -89,7 +89,6 @@ export AZTEC_EPOCH_DURATION=16 export AZTEC_TARGET_COMMITTEE_SIZE=48 export AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 export AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -export AZTEC_INBOX_LAG=2 export AZTEC_PROOF_SUBMISSION_EPOCHS=2 export AZTEC_LOCAL_EJECTION_THRESHOLD=0 export AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS=1 diff --git a/docs/docs-operate/operators/reference/node-api-reference.md b/docs/docs-operate/operators/reference/node-api-reference.md index 084abb36b32b..e5264253cb1f 100644 --- a/docs/docs-operate/operators/reference/node-api-reference.md +++ b/docs/docs-operate/operators/reference/node-api-reference.md @@ -635,22 +635,24 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"aztec_getL1ToL2MessageMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` -### aztec_getL1ToL2MessageCheckpoint +### aztec_getL1ToL2MessageIndex -Returns the L2 checkpoint number in which this L1 to L2 message becomes available, or undefined if not found. +Returns the compact leaf index assigned to this L1 to L2 message as soon as the node has ingested it from L1, +before any L2 block consumes it. Returns undefined if the node has not yet seen the message. The message becomes +consumable once a block's L1-to-L2 message tree grows past this index. **Parameters**: 1. `l1ToL2Message` - `Fr` -**Returns**: `number | undefined` +**Returns**: `bigint | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"aztec_getL1ToL2MessageCheckpoint","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"aztec_getL1ToL2MessageIndex","params":["0x1234..."],"id":1}' ``` ### aztec_getL2ToL1MembershipWitness diff --git a/docs/examples/ts/aave_bridge/index.ts b/docs/examples/ts/aave_bridge/index.ts index 07e3a94eaca7..725332ac4bca 100644 --- a/docs/examples/ts/aave_bridge/index.ts +++ b/docs/examples/ts/aave_bridge/index.ts @@ -347,10 +347,10 @@ const INBOX_ABI = [ type: "event", name: "MessageSent", inputs: [ - { name: "checkpointNumber", type: "uint256", indexed: true }, { name: "index", type: "uint256", indexed: false }, { name: "hash", type: "bytes32", indexed: true }, - { name: "rollingHash", type: "bytes16", indexed: false }, + { name: "inboxRollingHash", type: "bytes32", indexed: false }, + { name: "bucketSeq", type: "uint256", indexed: false }, ], }, ] as const; diff --git a/docs/examples/ts/example_swap/index.ts b/docs/examples/ts/example_swap/index.ts index 9c367a82b0c5..87b75160f49d 100644 --- a/docs/examples/ts/example_swap/index.ts +++ b/docs/examples/ts/example_swap/index.ts @@ -259,10 +259,10 @@ const INBOX_ABI = [ type: "event", name: "MessageSent", inputs: [ - { name: "checkpointNumber", type: "uint256", indexed: true }, { name: "index", type: "uint256", indexed: false }, { name: "hash", type: "bytes32", indexed: true }, - { name: "rollingHash", type: "bytes16", indexed: false }, + { name: "inboxRollingHash", type: "bytes32", indexed: false }, + { name: "bucketSeq", type: "uint256", indexed: false }, ], }, ] as const; diff --git a/docs/examples/ts/token_bridge/index.ts b/docs/examples/ts/token_bridge/index.ts index 18f3508ac046..ee68871013a2 100644 --- a/docs/examples/ts/token_bridge/index.ts +++ b/docs/examples/ts/token_bridge/index.ts @@ -165,10 +165,10 @@ const INBOX_ABI = [ type: "event", name: "MessageSent", inputs: [ - { name: "checkpointNumber", type: "uint256", indexed: true }, { name: "index", type: "uint256", indexed: false }, { name: "hash", type: "bytes32", indexed: true }, - { name: "rollingHash", type: "bytes16", indexed: false }, + { name: "inboxRollingHash", type: "bytes32", indexed: false }, + { name: "bucketSeq", type: "uint256", indexed: false }, ], }, ] as const; diff --git a/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts index 73ad56bbcdf1..3a4c1b864f00 100644 --- a/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts +++ b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts @@ -559,7 +559,7 @@ const METHOD_GROUPS: { heading: string; namespace: string; methods: string[] }[] namespace: 'aztec', methods: [ 'getL1ToL2MessageMembershipWitness', - 'getL1ToL2MessageCheckpoint', + 'getL1ToL2MessageIndex', 'getL2ToL1MembershipWitness', 'getL2ToL1Messages', ], diff --git a/l1-contracts/gas_benchmark.md b/l1-contracts/gas_benchmark.md index 6f68e4ff4503..516eda73c2c5 100644 --- a/l1-contracts/gas_benchmark.md +++ b/l1-contracts/gas_benchmark.md @@ -12,24 +12,24 @@ ## No Validators -| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | -|----------------------|---------|---------|---------------|--------------| -| propose | 195,988 | 222,201 | 932 | 14,912 | -| submitEpochRootProof | 697,655 | 743,529 | 2,820 | 45,120 | -| setupEpoch | 31,998 | 113,793 | - | - | +| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | +|----------------------|---------|-----------|---------------|--------------| +| propose | 199,557 | 225,741 | 996 | 15,936 | +| submitEpochRootProof | 994,378 | 1,032,871 | 14,148 | 226,368 | +| setupEpoch | 32,042 | 113,837 | - | - | -**Avg Gas Cost per Second**: 3,341.5 gas/second +**Avg Gas Cost per Second**: 3,648.7 gas/second *Epoch duration*: 0h 38m 24s ## Validators -| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | -|----------------------|---------|---------|---------------|--------------| -| propose | 324,449 | 351,604 | 4,452 | 71,232 | -| submitEpochRootProof | 896,101 | 941,944 | 5,316 | 85,056 | -| aggregate3 | 373,118 | 386,457 | - | - | -| setupEpoch | 46,459 | 547,626 | - | - | +| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas | +|----------------------|-----------|-----------|---------------|--------------| +| propose | 327,969 | 355,787 | 4,516 | 72,256 | +| submitEpochRootProof | 1,575,427 | 1,673,267 | 16,644 | 266,304 | +| aggregate3 | 376,569 | 389,943 | - | - | +| setupEpoch | 46,504 | 547,670 | - | - | -**Avg Gas Cost per Second**: 5,304.3 gas/second +**Avg Gas Cost per Second**: 5,942.9 gas/second *Epoch duration*: 0h 38m 24s diff --git a/l1-contracts/gas_benchmark_results.json b/l1-contracts/gas_benchmark_results.json index 45c6a506461d..ba78f7e71f00 100644 --- a/l1-contracts/gas_benchmark_results.json +++ b/l1-contracts/gas_benchmark_results.json @@ -2,62 +2,62 @@ "no_validators": { "propose": { "calls": 150, - "min": 182373, - "mean": 195988, - "median": 191762, - "max": 222201, - "calldata_size": 932, - "calldata_gas": 14912 + "min": 185913, + "mean": 199557, + "median": 195302, + "max": 225741, + "calldata_size": 996, + "calldata_gas": 15936 }, "setupEpoch": { "calls": 150, - "min": 29264, - "mean": 31998, - "median": 29264, - "max": 113793 + "min": 29309, + "mean": 32042, + "median": 29309, + "max": 113837 }, "submitEpochRootProof": { "calls": 4, - "min": 676491, - "mean": 697655, - "median": 685300, - "max": 743529, - "calldata_size": 2820, - "calldata_gas": 45120 + "min": 975675, + "mean": 994378, + "median": 984484, + "max": 1032871, + "calldata_size": 14148, + "calldata_gas": 226368 } }, "validators": { "propose": { "calls": 150, - "min": 302105, - "mean": 324449, - "median": 323910, - "max": 351604, - "calldata_size": 4452, - "calldata_gas": 71232 + "min": 305630, + "mean": 327969, + "median": 327423, + "max": 355787, + "calldata_size": 4516, + "calldata_gas": 72256 }, "setupEpoch": { "calls": 150, - "min": 29264, - "mean": 46459, - "median": 29264, - "max": 547626 + "min": 29309, + "mean": 46504, + "median": 29309, + "max": 547670 }, "submitEpochRootProof": { "calls": 4, - "min": 874924, - "mean": 896101, - "median": 883769, - "max": 941944, - "calldata_size": 5316, - "calldata_gas": 85056 + "min": 1463669, + "mean": 1575427, + "median": 1582387, + "max": 1673267, + "calldata_size": 16644, + "calldata_gas": 266304 }, "aggregate3": { "calls": 55, - "min": 362015, - "mean": 373118, - "median": 372828, - "max": 386457 + "min": 365451, + "mean": 376569, + "median": 376253, + "max": 389943 } } } \ No newline at end of file diff --git a/l1-contracts/gas_report.json b/l1-contracts/gas_report.json index 173c6310bea8..045df4147f2d 100644 --- a/l1-contracts/gas_report.json +++ b/l1-contracts/gas_report.json @@ -1,291 +1,344 @@ [ { - "contract": "src/core/Rollup.sol:Rollup", + "contract": "src/core/messagebridge/Inbox.sol:Inbox", + "deployment": { + "gas": 0, + "size": 5932 + }, + "functions": { + "getBucket(uint256)": { + "calls": 4667, + "min": 7414, + "mean": 7414, + "median": 7414, + "max": 7414 + }, + "getCurrentBucketSeq()": { + "calls": 4667, + "min": 408, + "mean": 1407, + "median": 408, + "max": 2408 + }, + "getFeeAssetPortal()": { + "calls": 2586, + "min": 212, + "mean": 212, + "median": 212, + "max": 212 + }, + "sendL2Message((bytes32,uint256),bytes32,bytes32)": { + "calls": 37328, + "min": 41480, + "mean": 44796, + "median": 41480, + "max": 100232 + } + } + }, + { + "contract": "src/core/messagebridge/Outbox.sol:Outbox", + "deployment": { + "gas": 0, + "size": 3107 + }, + "functions": { + "getRootData(uint256,uint256)": { + "calls": 7, + "min": 2661, + "mean": 2661, + "median": 2661, + "max": 2661 + } + } + }, + { + "contract": "src/governance/CoinIssuer.sol:CoinIssuer", + "deployment": { + "gas": 0, + "size": 2438 + }, + "functions": { + "owner()": { + "calls": 5172, + "min": 397, + "mean": 397, + "median": 397, + "max": 397 + } + } + }, + { + "contract": "src/governance/Registry.sol:Registry", + "deployment": { + "gas": 0, + "size": 4970 + }, + "functions": { + "getCanonicalRollup()": { + "calls": 1738, + "min": 1073, + "mean": 4073, + "median": 4073, + "max": 7073 + }, + "getRewardDistributor()": { + "calls": 2586, + "min": 420, + "mean": 420, + "median": 420, + "max": 420 + }, + "owner()": { + "calls": 7758, + "min": 353, + "mean": 353, + "median": 353, + "max": 353 + } + } + }, + { + "contract": "src/governance/RewardDistributor.sol:RewardDistributor", + "deployment": { + "gas": 0, + "size": 3137 + }, + "functions": { + "availableTo(address)": { + "calls": 869, + "min": 20573, + "mean": 20573, + "median": 20573, + "max": 20573 + } + } + }, + { + "contract": "test/RollupWithPreheating.sol:RollupWithPreheating", "deployment": { "gas": 0, - "size": 43935 + "size": 42877 }, "functions": { "archive()": { - "calls": 2323, - "min": 4583, - "mean": 4583, - "median": 4583, - "max": 4583 - }, - "getBlock(uint256)": { - "calls": 847, - "min": 9208, - "mean": 9208, - "median": 9208, - "max": 9208 + "calls": 2333, + "min": 4641, + "mean": 4641, + "median": 4641, + "max": 4641 + }, + "checkBlob()": { + "calls": 1, + "min": 2509, + "mean": 2509, + "median": 2509, + "max": 2509 + }, + "getCheckpoint(uint256)": { + "calls": 879, + "min": 27343, + "mean": 27343, + "median": 27343, + "max": 27343 + }, + "getCheckpointReward()": { + "calls": 2589, + "min": 1128, + "mean": 1133, + "median": 1128, + "max": 5628 }, "getCollectiveProverRewardsForEpoch(uint256)": { "calls": 3, - "min": 2614, - "mean": 2614, - "median": 2614, - "max": 2614 + "min": 5837, + "mean": 5837, + "median": 5837, + "max": 5837 + }, + "getCurrentEpoch()": { + "calls": 870, + "min": 915, + "mean": 915, + "median": 915, + "max": 915 }, "getCurrentSlot()": { "calls": 100, - "min": 2735, - "mean": 2735, - "median": 2735, - "max": 2735 + "min": 2737, + "mean": 2737, + "median": 2737, + "max": 2737 }, "getEpochDuration()": { "calls": 2, - "min": 2400, - "mean": 2400, - "median": 2400, - "max": 2400 + "min": 2486, + "mean": 2486, + "median": 2486, + "max": 2486 }, - "getFeeAssetPerEth()": { - "calls": 1, - "min": 5440, - "mean": 5440, - "median": 5440, - "max": 5440 + "getEpochProofPublicInputs(uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],bytes)": { + "calls": 4, + "min": 16751, + "mean": 35891, + "median": 26547, + "max": 73720 + }, + "getEthPerFeeAsset()": { + "calls": 2, + "min": 11043, + "mean": 11043, + "median": 11043, + "max": 11043 }, "getFeeAssetPortal()": { - "calls": 3104, - "min": 453, - "mean": 1453, - "median": 1453, - "max": 2453 + "calls": 4660, + "min": 566, + "mean": 1456, + "median": 566, + "max": 2566 }, "getInbox()": { - "calls": 6198, - "min": 2498, - "mean": 2498, - "median": 2498, - "max": 2498 + "calls": 9073, + "min": 2543, + "mean": 2543, + "median": 2543, + "max": 2543 }, "getL1FeesAt(uint256)": { "calls": 2, - "min": 9434, - "mean": 9434, - "median": 9434, - "max": 9434 - }, - "getManaBaseFeeAt(uint256,bool)": { - "calls": 2325, - "min": 30538, - "mean": 32450, - "median": 30538, - "max": 36293 + "min": 9086, + "mean": 9086, + "median": 9086, + "max": 9086 + }, + "getManaMinFeeAt(uint256,bool)": { + "calls": 2336, + "min": 27032, + "mean": 28689, + "median": 27032, + "max": 32050 }, "getManaTarget()": { - "calls": 2, - "min": 2422, - "mean": 2422, - "median": 2422, - "max": 2422 + "calls": 1026, + "min": 5526, + "mean": 5526, + "median": 5526, + "max": 5526 }, "getOutbox()": { - "calls": 3875, - "min": 2452, - "mean": 2452, - "median": 2452, - "max": 2452 - }, - "getPendingBlockNumber()": { - "calls": 1545, - "min": 2485, - "mean": 2485, - "median": 2485, - "max": 2485 - }, - "getProofSubmissionWindow()": { - "calls": 4, - "min": 2404, - "mean": 2404, - "median": 2404, - "max": 2404 - }, - "getProvenBlockNumber()": { - "calls": 6196, - "min": 2468, - "mean": 2468, - "median": 2468, - "max": 2468 + "calls": 2, + "min": 2521, + "mean": 2521, + "median": 2521, + "max": 2521 + }, + "getPendingCheckpointNumber()": { + "calls": 1679, + "min": 2462, + "mean": 2462, + "median": 2462, + "max": 2462 + }, + "getProvenCheckpointNumber()": { + "calls": 1684, + "min": 2585, + "mean": 2585, + "median": 2585, + "max": 2585 }, "getProvingCostPerManaInEth()": { "calls": 1, - "min": 2407, - "mean": 2407, - "median": 2407, - "max": 2407 + "min": 5729, + "mean": 5729, + "median": 5729, + "max": 5729 }, "getProvingCostPerManaInFeeAsset()": { "calls": 1, - "min": 8164, - "mean": 8164, - "median": 8164, - "max": 8164 + "min": 14475, + "mean": 14475, + "median": 14475, + "max": 14475 }, "getSequencerRewards(address)": { "calls": 2, - "min": 2716, - "mean": 2716, - "median": 2716, - "max": 2716 + "min": 5981, + "mean": 5981, + "median": 5981, + "max": 5981 }, "getTimestampForSlot(uint256)": { - "calls": 2432, - "min": 2802, - "mean": 2802, - "median": 2802, - "max": 2802 + "calls": 2442, + "min": 2808, + "mean": 2808, + "median": 2808, + "max": 2808 }, "getVersion()": { - "calls": 3875, - "min": 471, - "mean": 1669, - "median": 2471, - "max": 2471 + "calls": 4919, + "min": 499, + "mean": 1447, + "median": 499, + "max": 2499 }, "owner()": { - "calls": 1552, - "min": 420, - "mean": 420, - "median": 420, - "max": 420 + "calls": 5173, + "min": 533, + "mean": 533, + "median": 533, + "max": 2533 }, - "propose((bytes32,bytes,(int256),bytes,bytes32[]),(address,(uint8,bytes32,bytes32))[],bytes)": { - "calls": 2327, - "min": 180367, - "mean": 343443, - "median": 348542, - "max": 380636 + "propose((bytes32,(int256),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256),uint256),(bytes,bytes),address[],(uint8,bytes32,bytes32),bytes)": { + "calls": 2339, + "min": 0, + "mean": 266918, + "median": 284436, + "max": 325546 }, "prune()": { "calls": 6, - "min": 25709, - "mean": 32858, - "median": 33454, - "max": 37939 + "min": 26689, + "mean": 33247, + "median": 33682, + "max": 38274 }, "setProvingCostPerMana(uint256)": { - "calls": 2, - "min": 28780, - "mean": 28780, - "median": 28780, - "max": 28780 - }, - "submitEpochRootProof((uint256,uint256,(bytes32,bytes32,address),bytes32[],bytes,bytes))": { - "calls": 846, - "min": 58871, - "mean": 417467, - "median": 414067, - "max": 448154 - } - } - }, - { - "contract": "src/core/messagebridge/Inbox.sol:Inbox", - "deployment": { - "gas": 0, - "size": 7350 - }, - "functions": { - "getFeeAssetPortal()": { - "calls": 1552, - "min": 234, - "mean": 234, - "median": 234, - "max": 234 - }, - "getInProgress()": { - "calls": 3, - "min": 2425, - "mean": 2425, - "median": 2425, - "max": 2425 - }, - "getRoot(uint256)": { - "calls": 2325, - "min": 4809, - "mean": 4817, - "median": 4809, - "max": 4835 - }, - "sendL2Message((bytes32,uint256),bytes32,bytes32)": { - "calls": 37168, - "min": 43418, - "mean": 53020, - "median": 46820, - "max": 77618 - } - } - }, - { - "contract": "src/core/messagebridge/Outbox.sol:Outbox", - "deployment": { - "gas": 0, - "size": 2855 - }, - "functions": { - "getRootData(uint256)": { - "calls": 2323, - "min": 5627, - "mean": 5627, - "median": 5627, - "max": 5627 - } - } - }, - { - "contract": "src/governance/Registry.sol:Registry", - "deployment": { - "gas": 0, - "size": 4070 - }, - "functions": { - "getCanonicalRollup()": { - "calls": 2526, - "min": 1016, - "mean": 3016, - "median": 1016, - "max": 7016 + "calls": 1, + "min": 52474, + "mean": 52474, + "median": 52474, + "max": 52474 }, - "getRewardDistributor()": { - "calls": 1552, - "min": 267, - "mean": 267, - "median": 267, - "max": 267 + "submitEpochRootProof((uint256,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32,address),(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,uint256,address,bytes32,(uint128,uint128),uint256,uint256)[],(bytes,bytes),bytes,bytes))": { + "calls": 876, + "min": 58286, + "mean": 376918, + "median": 382965, + "max": 421657 }, - "owner()": { - "calls": 3104, - "min": 407, - "mean": 407, - "median": 407, - "max": 407 + "updateManaTarget(uint256)": { + "calls": 512, + "min": 26051, + "mean": 28652, + "median": 27293, + "max": 31299 } } }, { - "contract": "src/governance/RewardDistributor.sol:RewardDistributor", + "contract": "test/governance/helpers/TestGov.sol:TestGov", "deployment": { "gas": 0, - "size": 2290 + "size": 16556 }, "functions": { - "BLOCK_REWARD()": { - "calls": 1555, - "min": 238, - "mean": 238, - "median": 238, - "max": 238 - }, - "canonicalRollup()": { - "calls": 842, - "min": 10158, - "mean": 10158, - "median": 10158, - "max": 10158 + "isAllBeneficiariesAllowed()": { + "calls": 2586, + "min": 404, + "mean": 404, + "median": 404, + "max": 404 } } } diff --git a/l1-contracts/script/deploy/RollupConfiguration.sol b/l1-contracts/script/deploy/RollupConfiguration.sol index f19c5e9a620e..d70ddf1be185 100644 --- a/l1-contracts/script/deploy/RollupConfiguration.sol +++ b/l1-contracts/script/deploy/RollupConfiguration.sol @@ -110,7 +110,6 @@ contract RollupConfiguration is IRollupConfiguration, Test { config.targetCommitteeSize = vm.envUint("AZTEC_TARGET_COMMITTEE_SIZE"); config.lagInEpochsForValidatorSet = vm.envUint("AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET"); config.lagInEpochsForRandao = vm.envUint("AZTEC_LAG_IN_EPOCHS_FOR_RANDAO"); - config.inboxLag = vm.envUint("AZTEC_INBOX_LAG"); config.aztecProofSubmissionEpochs = vm.envUint("AZTEC_PROOF_SUBMISSION_EPOCHS"); config.localEjectionThreshold = vm.envUint("AZTEC_LOCAL_EJECTION_THRESHOLD"); config.slashingQuorum = vm.envOr("AZTEC_SLASHING_QUORUM", slashingRoundSize / 2 + 1); diff --git a/l1-contracts/scripts/constants-codegen/solidity.json b/l1-contracts/scripts/constants-codegen/solidity.json index 2046ce24d44a..147c0c25975b 100644 --- a/l1-contracts/scripts/constants-codegen/solidity.json +++ b/l1-contracts/scripts/constants-codegen/solidity.json @@ -1,6 +1,8 @@ [ "MAX_FIELD_VALUE", "L1_TO_L2_MSG_SUBTREE_HEIGHT", + "MAX_L1_TO_L2_MSGS_PER_CHECKPOINT", + "INBOX_LAG_SECONDS", "MAX_L2_TO_L1_MSGS_PER_TX", "INITIAL_CHECKPOINT_NUMBER", "MAX_CHECKPOINTS_PER_EPOCH", @@ -8,7 +10,5 @@ "EMPTY_EPOCH_OUT_HASH", "FEE_JUICE_ADDRESS", "BLS12_POINT_COMPRESSED_BYTES", - "ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH", - "NUM_MSGS_PER_BASE_PARITY", - "NUM_BASE_PARITY_PER_ROOT_PARITY" + "ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH" ] diff --git a/l1-contracts/scripts/network-defaults.json b/l1-contracts/scripts/network-defaults.json index 3d04bcf9ab46..96bc9ce58497 100644 --- a/l1-contracts/scripts/network-defaults.json +++ b/l1-contracts/scripts/network-defaults.json @@ -14,7 +14,6 @@ "AZTEC_ENTRY_QUEUE_FLUSH_SIZE_MIN": 48, "AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT": 2, "AZTEC_ENTRY_QUEUE_MAX_FLUSH_SIZE": 48, - "AZTEC_INBOX_LAG": 1, "AZTEC_PROOF_SUBMISSION_EPOCHS": 1, "AZTEC_MANA_TARGET": 100000000, "AZTEC_PROVING_COST_PER_MANA": 100, diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 9d4cb1a17f10..3abd82078875 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -41,6 +41,7 @@ import { Epoch, Timestamp, CommitteeAttestations, + EpochProofExtLib, RollupOperationsExtLib, ValidatorOperationsExtLib, EthValue, @@ -300,7 +301,7 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore { ProposedHeader[] calldata _headers, bytes calldata _blobPublicInputs ) external view override(IRollup) returns (bytes32[] memory) { - return RollupOperationsExtLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + return EpochProofExtLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); } /** diff --git a/l1-contracts/src/core/RollupCore.sol b/l1-contracts/src/core/RollupCore.sol index 73b3da4c4b41..5d8f33eca314 100644 --- a/l1-contracts/src/core/RollupCore.sol +++ b/l1-contracts/src/core/RollupCore.sol @@ -15,9 +15,9 @@ import {IStakingCore} from "@aztec/core/interfaces/IStaking.sol"; import {IValidatorSelectionCore} from "@aztec/core/interfaces/IValidatorSelection.sol"; import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol"; -import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {EpochProofExtLib} from "@aztec/core/libraries/rollup/EpochProofExtLib.sol"; import {RollupOperationsExtLib} from "@aztec/core/libraries/rollup/RollupOperationsExtLib.sol"; import {ValidatorOperationsExtLib} from "@aztec/core/libraries/rollup/ValidatorOperationsExtLib.sol"; import {SlasherDeploymentExtLib} from "@aztec/core/libraries/rollup/SlasherDeploymentExtLib.sol"; @@ -27,7 +27,7 @@ import {ProposeArgs} from "@aztec/core/libraries/rollup/ProposeLib.sol"; import {STFLib, GenesisState} from "@aztec/core/libraries/rollup/STFLib.sol"; import {StakingLib} from "@aztec/core/libraries/rollup/StakingLib.sol"; import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; -import {Inbox} from "@aztec/core/messagebridge/Inbox.sol"; +import {Inbox, INBOX_BUCKET_RING_SIZE} from "@aztec/core/messagebridge/Inbox.sol"; import {Outbox} from "@aztec/core/messagebridge/Outbox.sol"; import {ISlasher} from "@aztec/core/slashing/Slasher.sol"; import {GSE} from "@aztec/governance/GSE.sol"; @@ -466,7 +466,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali * @param _args Contains the epoch range, public inputs, fees, attestations, and the ZK proof */ function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external override(IRollupCore) { - RollupOperationsExtLib.submitEpochRootProof(_args); + EpochProofExtLib.submitEpochRootProof(_args); } /** @@ -619,11 +619,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali rollupStore.config.epochProofVerifier = _epochProofVerifier; rollupStore.config.version = _config.version; - IInbox inbox = IInbox( - address( - new Inbox(address(this), _feeAsset, _config.version, Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT, _config.inboxLag) - ) - ); + IInbox inbox = IInbox(address(new Inbox(address(this), _feeAsset, _config.version, INBOX_BUCKET_RING_SIZE))); rollupStore.config.inbox = inbox; rollupStore.config.outbox = IOutbox(address(new Outbox(address(this), _config.version))); diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 19f24b72fdb4..a6451fb20631 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -27,6 +27,10 @@ struct PublicInputArgs { bytes32 previousArchive; bytes32 endArchive; bytes32 outHash; + // Inbox rolling-hash chain segment consumed across the proven epoch. Both boundaries are + // anchored at proof submission against the rolling hashes recorded at propose for checkpoints start - 1 and end. + bytes32 previousInboxRollingHash; + bytes32 endInboxRollingHash; address proverId; } @@ -79,7 +83,6 @@ struct RollupConfigInput { RewardBoostConfig rewardBoostConfig; StakingQueueConfig stakingQueueConfig; uint256 localEjectionThreshold; - uint256 inboxLag; } struct RollupConfig { diff --git a/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol b/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol index a001403791da..11815bb79877 100644 --- a/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol +++ b/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol @@ -4,6 +4,11 @@ pragma solidity >=0.8.27; import {DataStructures} from "../../libraries/DataStructures.sol"; +// Maximum number of messages a single bucket can hold before further messages in the same L1 block spill over +// into the next bucket. Matches the number of L1 to L2 messages a single L2 block can insert, so any one bucket +// is always consumable by one block. +uint256 constant MAX_MSGS_PER_BUCKET = 256; + /** * @title Inbox * @author Aztec Labs @@ -11,24 +16,39 @@ import {DataStructures} from "../../libraries/DataStructures.sol"; */ interface IInbox { struct InboxState { - // Rolling hash of all messages inserted into the inbox. - // Used by clients to check for consistency. - bytes16 rollingHash; - // This value is not used much by the contract, but it is useful for synching the node faster - // as it can more easily figure out if it can just skip looking for events for a time period. + // Cumulative number of messages inserted into the inbox. Useful for synching the node faster as it can + // more easily figure out if it can just skip looking for events for a time period. uint64 totalMessagesInserted; - // Number of a tree which is currently being filled - uint64 inProgress; + } + + /** + * @notice Snapshot of the consensus rolling hash over the messages inserted into the Inbox, stored in a + * fixed-size ring indexed by a dense bucket sequence number (`seq % ringSize`). A bucket only accumulates + * messages sent within a single L1 block, so its final state is the chain position as of the end of that + * block; the censorship check at `propose` compares the checkpoint header's rolling hash against these + * snapshots. + */ + struct InboxBucket { + // Rolling hash after the last message absorbed into this bucket. Each link is + // `sha256ToField(previousRollingHash || leaf)`; the genesis value is zero. + bytes32 rollingHash; + // Cumulative number of messages inserted into the Inbox up to and including this bucket. + uint64 totalMsgCount; + // L1 block timestamp at which this bucket was opened. Recency comparisons (message lag, + // censorship cutoff) are done in seconds against this value. + uint64 timestamp; + // Number of messages absorbed into this bucket, capped at the per-bucket maximum. + uint32 msgCount; } /** * @notice Emitted when a message is sent - * @param checkpointNumber - The checkpoint number in which the message is included - * @param index - The index of the message in the L1 to L2 messages tree + * @param index - The compact cumulative index of the message in the Inbox insertion order * @param hash - The hash of the message - * @param rollingHash - The rolling hash of all messages inserted into the inbox + * @param inboxRollingHash - The consensus rolling hash (truncated sha256 chain) after this message + * @param bucketSeq - The sequence number of the bucket this message was absorbed into */ - event MessageSent(uint256 indexed checkpointNumber, uint256 index, bytes32 indexed hash, bytes16 rollingHash); + event MessageSent(uint256 index, bytes32 indexed hash, bytes32 inboxRollingHash, uint256 bucketSeq); // docs:start:send_l1_to_l2_message /** @@ -38,34 +58,30 @@ interface IInbox { * @param _content - The content of the message (application specific) * @param _secretHash - The secret hash of the message (make it possible to hide when a specific message is consumed * on L2) - * @return The key of the message in the set and its leaf index in the tree + * @return The key of the message in the set and its compact cumulative index */ function sendL2Message(DataStructures.L2Actor memory _recipient, bytes32 _content, bytes32 _secretHash) external returns (bytes32, uint256); // docs:end:send_l1_to_l2_message - // docs:start:consume - /** - * @notice Consumes the current tree, and starts a new one if needed - * @dev Only callable by the rollup contract - * @dev In the first iteration we return empty tree root because first checkpoint's messages tree is always - * empty because there has to be a 1 checkpoint lag to prevent sequencer DOS attacks - * - * @param _toConsume - The checkpoint number to consume - * - * @return The root of the consumed tree - */ - function consume(uint256 _toConsume) external returns (bytes32); - // docs:end:consume - function getFeeAssetPortal() external view returns (address); - function getRoot(uint256 _checkpointNumber) external view returns (bytes32); - function getState() external view returns (InboxState memory); function getTotalMessagesInserted() external view returns (uint64); - function getInProgress() external view returns (uint64); + /** + * @notice Returns the sequence number of the bucket currently accumulating messages + * @return The current bucket sequence number + */ + function getCurrentBucketSeq() external view returns (uint64); + + /** + * @notice Returns the bucket with the given sequence number + * @dev Reverts if the bucket is ahead of the current one or has already been overwritten in the ring + * @param _seq - The bucket sequence number + * @return The bucket + */ + function getBucket(uint256 _seq) external view returns (InboxBucket memory); } diff --git a/l1-contracts/src/core/libraries/Errors.sol b/l1-contracts/src/core/libraries/Errors.sol index 01152320a831..e78dcfa9cafd 100644 --- a/l1-contracts/src/core/libraries/Errors.sol +++ b/l1-contracts/src/core/libraries/Errors.sol @@ -22,12 +22,11 @@ library Errors { error DevNet__InvalidProposer(address expected, address actual); // 0x11e6e6f7 // Inbox - error Inbox__Unauthorized(); // 0xe5336a6b error Inbox__ActorTooLarge(bytes32 actor); // 0xa776a06e error Inbox__VersionMismatch(uint256 expected, uint256 actual); // 0x47452014 error Inbox__ContentTooLarge(bytes32 content); // 0x47452014 error Inbox__SecretHashTooLarge(bytes32 secretHash); // 0xecde7e2c - error Inbox__MustBuildBeforeConsume(); // 0xc4901999 + error Inbox__BucketOutOfWindow(uint256 seq, uint256 current); // 0xfee255b7 // Outbox error Outbox__Unauthorized(); // 0x2c9490c2 @@ -57,7 +56,13 @@ library Errors { error Rollup__InvalidCheckpointHeader(bytes32 expected, bytes32 actual); error Rollup__InvalidCheckpointHeaderCount(uint256 expected, uint256 actual); error Rollup__InvalidCheckpointNumber(uint256 expected, uint256 actual); // 0xd1ba9bfa - error Rollup__InvalidInHash(bytes32 expected, bytes32 actual); // 0xcd6f4233 + error Rollup__InvalidInboxRollingHash(bytes32 expected, bytes32 actual); // 0xed1f7bb5 + error Rollup__InvalidPreviousInboxRollingHash(bytes32 expected, bytes32 actual); // 0x2fe7cae5 + error Rollup__InvalidEndInboxRollingHash(bytes32 expected, bytes32 actual); // 0x4a9cdb72 + error Rollup__InboxBucketStillMutable(uint256 bucketSeq); // 0x7254b980 + error Rollup__UnconsumedInboxMessages(uint256 nextBucketSeq); // 0x2bd4bf10 + error Rollup__InboxConsumptionBehindParent(uint256 expected, uint256 actual); // 0x54e0c025 + error Rollup__TooManyInboxMessagesConsumed(uint256 consumed); // 0xf76d1426 error Rollup__InvalidOutHash(bytes32 expected, bytes32 actual); // 0x8eb39062 error Rollup__InvalidPreviousArchive(bytes32 expected, bytes32 actual); // 0xb682a40e error Rollup__InvalidProof(); // 0xa5b2ba17 diff --git a/l1-contracts/src/core/libraries/compressed-data/CheckpointLog.sol b/l1-contracts/src/core/libraries/compressed-data/CheckpointLog.sol index 486aba1d2bae..96af3d3ac257 100644 --- a/l1-contracts/src/core/libraries/compressed-data/CheckpointLog.sol +++ b/l1-contracts/src/core/libraries/compressed-data/CheckpointLog.sol @@ -34,7 +34,16 @@ struct TempCheckpointLog { bytes32 attestationsHash; bytes32 payloadDigest; Slot slotNumber; + // Streaming Inbox consumption counts. `inboxMsgTotal` is the cumulative Inbox message count + // consumed as of this checkpoint (the child's parent-total origin); `inboxConsumedBucket` is the bucket sequence + // number the header's rolling hash corresponds to. Declared next to the slot number so the three share one storage + // slot (4 + 8 + 8 of 32 bytes): propose writes and reads that slot for the slot-progression check anyway. + uint64 inboxMsgTotal; + uint64 inboxConsumedBucket; FeeHeader feeHeader; + // The consensus Inbox rolling hash the checkpoint header committed to, in a slot of its own: epoch proofs anchor + // both ends of their consumed chain segment against it. + bytes32 inboxRollingHash; } struct CompressedTempCheckpointLog { @@ -44,7 +53,10 @@ struct CompressedTempCheckpointLog { bytes32 attestationsHash; bytes32 payloadDigest; CompressedSlot slotNumber; + uint64 inboxMsgTotal; + uint64 inboxConsumedBucket; CompressedFeeHeader feeHeader; + bytes32 inboxRollingHash; } library CompressedTempCheckpointLogLib { @@ -61,7 +73,10 @@ library CompressedTempCheckpointLogLib { attestationsHash: _checkpoint.attestationsHash, payloadDigest: _checkpoint.payloadDigest, slotNumber: _checkpoint.slotNumber.compress(), - feeHeader: _checkpoint.feeHeader.compress() + inboxMsgTotal: _checkpoint.inboxMsgTotal, + inboxConsumedBucket: _checkpoint.inboxConsumedBucket, + feeHeader: _checkpoint.feeHeader.compress(), + inboxRollingHash: _checkpoint.inboxRollingHash }); } @@ -77,7 +92,10 @@ library CompressedTempCheckpointLogLib { attestationsHash: _compressedCheckpoint.attestationsHash, payloadDigest: _compressedCheckpoint.payloadDigest, slotNumber: _compressedCheckpoint.slotNumber.decompress(), - feeHeader: _compressedCheckpoint.feeHeader.decompress() + inboxMsgTotal: _compressedCheckpoint.inboxMsgTotal, + inboxConsumedBucket: _compressedCheckpoint.inboxConsumedBucket, + feeHeader: _compressedCheckpoint.feeHeader.decompress(), + inboxRollingHash: _compressedCheckpoint.inboxRollingHash }); } } diff --git a/l1-contracts/src/core/libraries/crypto/FrontierLib.sol b/l1-contracts/src/core/libraries/crypto/FrontierLib.sol deleted file mode 100644 index 6fd66130a15a..000000000000 --- a/l1-contracts/src/core/libraries/crypto/FrontierLib.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.27; - -import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; - -/** - * @title FrontierLib - * @author Aztec Labs - * @notice Library for managing frontier trees. - */ -library FrontierLib { - struct Forest { - mapping(uint256 index => bytes32 zero) zeros; - } - - struct Tree { - uint256 nextIndex; - mapping(uint256 => bytes32) frontier; - } - - function initialize(Forest storage _self, uint256 _height) internal { - _self.zeros[0] = bytes32(0); - for (uint256 i = 1; i <= _height; i++) { - _self.zeros[i] = Hash.sha256ToField(bytes.concat(_self.zeros[i - 1], _self.zeros[i - 1])); - } - } - - function insertLeaf(Tree storage _self, bytes32 _leaf) internal returns (uint256) { - uint256 index = _self.nextIndex; - uint256 level = computeLevel(index); - bytes32 right = _leaf; - for (uint256 i = 0; i < level; i++) { - right = Hash.sha256ToField(bytes.concat(_self.frontier[i], right)); - } - _self.frontier[level] = right; - - _self.nextIndex++; - - return index; - } - - function root(Tree storage _self, Forest storage _forest, uint256 _height, uint256 _size) - internal - view - returns (bytes32) - { - uint256 next = _self.nextIndex; - if (next == 0) { - return _forest.zeros[_height]; - } - if (next == _size) { - return _self.frontier[_height]; - } - - uint256 index = next - 1; - uint256 level = computeLevel(index); - - // We should start at the highest frontier level with a left leaf - bytes32 temp = _self.frontier[level]; - - uint256 bits = index >> level; - for (uint256 i = level; i < _height; i++) { - bool isRight = bits & 1 == 1; - if (isRight) { - temp = Hash.sha256ToField(bytes.concat(_self.frontier[i], temp)); - } else { - temp = Hash.sha256ToField(bytes.concat(temp, _forest.zeros[i])); - } - bits >>= 1; - } - - return temp; - } - - function isFull(Tree storage _self, uint256 _size) internal view returns (bool) { - return _self.nextIndex == _size; - } - - function computeLevel(uint256 _leafIndex) internal pure returns (uint256) { - // The number of trailing ones is how many times in a row we are the right child. - // e.g., each time this happens we go another layer up to update the parent. - uint256 count = 0; - uint256 index = _leafIndex; - while (index & 1 == 1) { - count++; - index >>= 1; - } - return count; - } -} diff --git a/l1-contracts/src/core/libraries/crypto/Hash.sol b/l1-contracts/src/core/libraries/crypto/Hash.sol index b2d4df0aac56..18fc73e180b3 100644 --- a/l1-contracts/src/core/libraries/crypto/Hash.sol +++ b/l1-contracts/src/core/libraries/crypto/Hash.sol @@ -49,4 +49,16 @@ library Hash { function sha256ToField(bytes memory _data) internal pure returns (bytes32) { return bytes32(bytes.concat(new bytes(1), bytes31(sha256(_data)))); } + + /** + * @notice Advances the Inbox consensus rolling hash by one message leaf + * @dev Truncated at every link so the value is always a field element; the rollup circuits recompute the + * identical chain over the message leaves they insert. The genesis value is zero. + * @param _rollingHash - The current rolling hash + * @param _leaf - The message leaf to absorb + * @return The updated rolling hash + */ + function accumulateInboxRollingHash(bytes32 _rollingHash, bytes32 _leaf) internal pure returns (bytes32) { + return sha256ToField(abi.encodePacked(_rollingHash, _leaf)); + } } diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol new file mode 100644 index 000000000000..a71251c19a7b --- /dev/null +++ b/l1-contracts/src/core/libraries/rollup/EpochProofExtLib.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Aztec Labs. +pragma solidity >=0.8.27; + +import {SubmitEpochRootProofArgs, PublicInputArgs} from "@aztec/core/interfaces/IRollup.sol"; +import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; +import {EpochProofLib} from "./EpochProofLib.sol"; + +/** + * @title EpochProofExtLib - External Rollup Library (Epoch Proof Functions) + * @author Aztec Labs + * @notice External library containing epoch-proof functions for the Rollup contract to avoid exceeding max + * contract size. + * + * @dev This library serves as an external library for the Rollup contract, splitting off the epoch proof + * submission and public-input computation from RollupOperationsExtLib, which the streaming inbox + * validation pushed over the deployable size limit. The library contains external functions primarily + * focused on: + * - Epoch proof submission and verification + * - Epoch proof public input computation + */ +library EpochProofExtLib { + function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external { + EpochProofLib.submitEpochRootProof(_args); + } + + function getEpochProofPublicInputs( + uint256 _start, + uint256 _end, + PublicInputArgs calldata _args, + ProposedHeader[] calldata _headers, + bytes calldata _blobPublicInputs + ) external view returns (bytes32[] memory) { + return EpochProofLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + } +} diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index 85284b38fa97..1d738c501410 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -109,6 +109,8 @@ library EpochProofLib { Epoch endEpoch = assertAcceptable(_args.start, _args.end); + // Rehash the supplied headers against storage once, here: the public-input assembly below reads the fee + // recipient/value out of them and relies on this call having run. verifyHeaders(_args.start, _args.end, _args.headers); // Verify attestations for the last checkpoint in the epoch @@ -150,6 +152,11 @@ library EpochProofLib { * own public inputs used for generating the proof vs the ones assembled * by this contract when verifying it. * + * @dev The fee recipient/value public inputs are sourced from the supplied headers, so this entry point rehashes + * them against storage before assembling: an off-chain caller must not walk away with public inputs built from + * unverified fee fields and only discover the mismatch when the on-chain proof reverts. The submit path verifies + * the headers up front and assembles via computeEpochProofPublicInputs to avoid rehashing them twice. + * * @param _start - The start of the epoch (inclusive) * @param _end - The end of the epoch (inclusive) * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) @@ -163,6 +170,107 @@ library EpochProofLib { ProposedHeader[] calldata _headers, bytes calldata _blobPublicInputs ) internal view returns (bytes32[] memory) { + verifyHeaders(_start, _end, _headers); + return computeEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); + } + + /** + * @notice Verifies committee attestations for the last checkpoint in the epoch before accepting the epoch proof + * + * @dev This verification ensures that the committee has properly validated the final state of the epoch + * before the proof can be accepted. The function validates that: + * 1. The provided attestations match the stored attestation hash for the checkpoint + * 2. The attestations have valid signatures from committee members + * 3. The attestations meet the required threshold (2/3+ of committee) + * + * For escape hatch epochs, attestation verification is skipped since there is no committee + * involvement - only the designated escape hatch proposer can propose blocks. + * + * @dev Errors Thrown: + * - Rollup__InvalidAttestations: Provided attestations don't match stored hash or fail validation + * + * @param _endCheckpointNumber The last checkpoint number in the epoch to verify attestations for + * @param _attestations The committee attestations containing signatures and validator information + */ + function verifyLastCheckpointAttestationsAndOutHash( + uint256 _endCheckpointNumber, + CommitteeAttestations memory _attestations, + bytes32 _outHash + ) private { + // Get the stored attestation hash and payload digest for the last checkpoint + CompressedTempCheckpointLog storage checkpointLog = STFLib.getStorageTempCheckpointLog(_endCheckpointNumber); + + // Verify that the out hash matches the stored value + // The stored out hash is part of the payloadDigest that was attested to. + require(checkpointLog.outHash == _outHash, Errors.Rollup__InvalidOutHash(checkpointLog.outHash, _outHash)); + + // Verify that the provided attestations match the stored hash + bytes32 providedAttestationsHash = keccak256(abi.encode(_attestations)); + require(providedAttestationsHash == checkpointLog.attestationsHash, Errors.Rollup__InvalidAttestations()); + + // Get the epoch for the last checkpoint + Epoch epoch = STFLib.getEpochForCheckpoint(_endCheckpointNumber); + + // Check if this is an escape hatch epoch - skip attestation verification if so + // since escape hatch blocks are proposed without committee attestations. + // Uses epoch-stable lookup so proof verification uses the escape hatch that was + // active when the epoch started, not whatever is currently configured. + { + IEscapeHatch escapeHatch = ValidatorSelectionLib.getEscapeHatchForEpoch(epoch); + if (address(escapeHatch) != address(0)) { + (bool isOpen,) = escapeHatch.isHatchOpen(epoch); + if (isOpen) { + // Skip attestation verification for escape hatch epochs + return; + } + } + } + + ValidatorSelectionLib.verifyAttestations(epoch, _attestations, checkpointLog.payloadDigest); + } + + /** + * @notice Rehashes each provided checkpoint header and requires it to match the stored header hash + * + * @param _start The first checkpoint number in the epoch (inclusive) + * @param _end The last checkpoint number in the epoch (inclusive) + * @param _headers The proposed headers for each checkpoint in [_start, _end] + */ + function verifyHeaders(uint256 _start, uint256 _end, ProposedHeader[] calldata _headers) private view { + uint256 numCheckpoints = _end - _start + 1; + require( + _headers.length == numCheckpoints, Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length) + ); + + for (uint256 i = 0; i < numCheckpoints; i++) { + bytes32 expectedHeaderHash = STFLib.getHeaderHash(_start + i); + bytes32 providedHeaderHash = ProposedHeaderLib.hash(_headers[i]); + require( + providedHeaderHash == expectedHeaderHash, + Errors.Rollup__InvalidCheckpointHeader(expectedHeaderHash, providedHeaderHash) + ); + } + } + + /** + * @notice Assembles the root rollup public inputs, taking the supplied checkpoint headers as already verified + * + * @dev Callers must have rehashed `_headers` against the stored header hashes beforehand, since the fee + * recipient/value public inputs are read straight out of them. + * + * @param _start - The start of the epoch (inclusive) + * @param _end - The end of the epoch (inclusive) + * @param _args - Array of public inputs to the proof (previousArchive, endArchive, endTimestamp, outHash, proverId) + * @param _headers - The proposed checkpoint headers supplying the fee recipient and value for each checkpoint + * @param _blobPublicInputs- The blob public inputs for the proof + */ + function computeEpochProofPublicInputs( + uint256 _start, + uint256 _end, + PublicInputArgs calldata _args, + ProposedHeader[] calldata _headers, + bytes calldata _blobPublicInputs + ) private view returns (bytes32[] memory) { RollupStore storage rollupStore = STFLib.getStorage(); { @@ -181,6 +289,30 @@ library EpochProofLib { expectedEndArchive == _args.endArchive, Errors.Rollup__InvalidArchive(expectedEndArchive, _args.endArchive) ); } + + // Boundary anchoring for the Inbox rolling-hash chain, mirroring previousArchive/endArchive: + // both ends of the claimed chain segment must match the rolling hashes recorded at propose for checkpoints + // _start - 1 and _end. The start needs this to be sound - the previous checkpoint's header is not among this + // proof's public inputs, so nothing else pins where the segment begins. The end is already pinned transitively + // (the checkpoint root binds end_inbox_rolling_hash to the last checkpoint header, whose hash verifyHeaders ties + // to storage), so checking it here only trades a bare proof-verification failure for a specific error. + { + bytes32 expectedPreviousInboxRollingHash = STFLib.getInboxRollingHash(_start - 1); + require( + expectedPreviousInboxRollingHash == _args.previousInboxRollingHash, + Errors.Rollup__InvalidPreviousInboxRollingHash( + expectedPreviousInboxRollingHash, _args.previousInboxRollingHash + ) + ); + } + + { + bytes32 expectedEndInboxRollingHash = STFLib.getInboxRollingHash(_end); + require( + expectedEndInboxRollingHash == _args.endInboxRollingHash, + Errors.Rollup__InvalidEndInboxRollingHash(expectedEndInboxRollingHash, _args.endInboxRollingHash) + ); + } } bytes32[] memory publicInputs = new bytes32[](Constants.ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH); @@ -191,6 +323,8 @@ library EpochProofLib { // previous_archive_root: Field, // end_archive_root: Field, // out_hash: Field, + // previous_inbox_rolling_hash: Field, + // end_inbox_rolling_hash: Field, // checkpointHeaderHashes: [Field; Constants.MAX_CHECKPOINTS_PER_EPOCH], // fees: [FeeRecipient; Constants.MAX_CHECKPOINTS_PER_EPOCH], // chain_id: Field, @@ -208,15 +342,21 @@ library EpochProofLib { publicInputs[1] = _args.endArchive; publicInputs[2] = _args.outHash; + + // Inbox rolling-hash chain segment consumed across the epoch. The start is validated above + // against the record written at propose for checkpoint _start - 1; the end is pinned transitively through the + // stored checkpoint header hashes (see the anchoring block in assertAcceptable). + publicInputs[3] = _args.previousInboxRollingHash; + publicInputs[4] = _args.endInboxRollingHash; } uint256 numCheckpoints = _end - _start + 1; for (uint256 i = 0; i < numCheckpoints; i++) { - publicInputs[3 + i] = STFLib.getHeaderHash(_start + i); + publicInputs[5 + i] = STFLib.getHeaderHash(_start + i); } - uint256 offset = 3 + Constants.MAX_CHECKPOINTS_PER_EPOCH; + uint256 offset = 5 + Constants.MAX_CHECKPOINTS_PER_EPOCH; // Taking recipient/value from the checkpoint headers rather than the prover // as defense in depth. Slots past numCheckpoints stay zero. @@ -276,84 +416,6 @@ library EpochProofLib { return publicInputs; } - /** - * @notice Verifies committee attestations for the last checkpoint in the epoch before accepting the epoch proof - * - * @dev This verification ensures that the committee has properly validated the final state of the epoch - * before the proof can be accepted. The function validates that: - * 1. The provided attestations match the stored attestation hash for the checkpoint - * 2. The attestations have valid signatures from committee members - * 3. The attestations meet the required threshold (2/3+ of committee) - * - * For escape hatch epochs, attestation verification is skipped since there is no committee - * involvement - only the designated escape hatch proposer can propose blocks. - * - * @dev Errors Thrown: - * - Rollup__InvalidAttestations: Provided attestations don't match stored hash or fail validation - * - * @param _endCheckpointNumber The last checkpoint number in the epoch to verify attestations for - * @param _attestations The committee attestations containing signatures and validator information - */ - function verifyLastCheckpointAttestationsAndOutHash( - uint256 _endCheckpointNumber, - CommitteeAttestations memory _attestations, - bytes32 _outHash - ) private { - // Get the stored attestation hash and payload digest for the last checkpoint - CompressedTempCheckpointLog storage checkpointLog = STFLib.getStorageTempCheckpointLog(_endCheckpointNumber); - - // Verify that the out hash matches the stored value - // The stored out hash is part of the payloadDigest that was attested to. - require(checkpointLog.outHash == _outHash, Errors.Rollup__InvalidOutHash(checkpointLog.outHash, _outHash)); - - // Verify that the provided attestations match the stored hash - bytes32 providedAttestationsHash = keccak256(abi.encode(_attestations)); - require(providedAttestationsHash == checkpointLog.attestationsHash, Errors.Rollup__InvalidAttestations()); - - // Get the epoch for the last checkpoint - Epoch epoch = STFLib.getEpochForCheckpoint(_endCheckpointNumber); - - // Check if this is an escape hatch epoch - skip attestation verification if so - // since escape hatch blocks are proposed without committee attestations. - // Uses epoch-stable lookup so proof verification uses the escape hatch that was - // active when the epoch started, not whatever is currently configured. - { - IEscapeHatch escapeHatch = ValidatorSelectionLib.getEscapeHatchForEpoch(epoch); - if (address(escapeHatch) != address(0)) { - (bool isOpen,) = escapeHatch.isHatchOpen(epoch); - if (isOpen) { - // Skip attestation verification for escape hatch epochs - return; - } - } - } - - ValidatorSelectionLib.verifyAttestations(epoch, _attestations, checkpointLog.payloadDigest); - } - - /** - * @notice Rehashes each provided checkpoint header and requires it to match the stored header hash - * - * @param _start The first checkpoint number in the epoch (inclusive) - * @param _end The last checkpoint number in the epoch (inclusive) - * @param _headers The proposed headers for each checkpoint in [_start, _end] - */ - function verifyHeaders(uint256 _start, uint256 _end, ProposedHeader[] calldata _headers) private view { - uint256 numCheckpoints = _end - _start + 1; - require( - _headers.length == numCheckpoints, Errors.Rollup__InvalidCheckpointHeaderCount(numCheckpoints, _headers.length) - ); - - for (uint256 i = 0; i < numCheckpoints; i++) { - bytes32 expectedHeaderHash = STFLib.getHeaderHash(_start + i); - bytes32 providedHeaderHash = ProposedHeaderLib.hash(_headers[i]); - require( - providedHeaderHash == expectedHeaderHash, - Errors.Rollup__InvalidCheckpointHeader(expectedHeaderHash, providedHeaderHash) - ); - } - } - /** * @notice Validates that an epoch proof submission meets all acceptance criteria * @@ -421,6 +483,9 @@ library EpochProofLib { * 2. Assembling the public inputs for the root rollup circuit * 3. Verifying the validity proof against the assembled public inputs using the configured verifier * + * @dev Assumes the caller has already verified the supplied checkpoint headers against storage, so assembly skips + * rehashing them. + * * @dev Errors Thrown: * - Rollup__InvalidBlobProof: Batched blob proof verification failed * - Rollup__InvalidProof: validity proof verification failed @@ -436,7 +501,7 @@ library EpochProofLib { BlobLib.validateBatchedBlob(_args.blobInputs); bytes32[] memory publicInputs = - getEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs); + computeEpochProofPublicInputs(_args.start, _args.end, _args.args, _args.headers, _args.blobInputs); require(rollupStore.config.epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); diff --git a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol index e4807e5bcc71..1a2d70f9e944 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol @@ -5,9 +5,11 @@ pragma solidity >=0.8.27; import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {IEscapeHatch} from "@aztec/core/interfaces/IEscapeHatch.sol"; import {RollupStore, IRollupCore, CheckpointHeaderValidationFlags} from "@aztec/core/interfaces/IRollup.sol"; +import {IInbox, MAX_MSGS_PER_BUCKET} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; import {TempCheckpointLog} from "@aztec/core/libraries/compressed-data/CheckpointLog.sol"; import {FeeHeader} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; import {ChainTipsLib, CompressedChainTips} from "@aztec/core/libraries/compressed-data/Tips.sol"; +import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; import {CoordinationSignatureLib} from "@aztec/core/libraries/rollup/CoordinationSignatureLib.sol"; @@ -17,6 +19,7 @@ import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelec import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {CompressedSlot, CompressedTimeMath} from "@aztec/shared/libraries/CompressedTimeMath.sol"; import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; +import {SafeCast} from "@oz/utils/math/SafeCast.sol"; import {ProposedHeader, ProposedHeaderLib} from "./ProposedHeaderLib.sol"; import {STFLib} from "./STFLib.sol"; @@ -24,6 +27,10 @@ struct ProposeArgs { bytes32 archive; OracleInput oracleInput; ProposedHeader header; + // Sequence number of the Inbox bucket the header's `inboxRollingHash` corresponds to. + // Unsigned lookup aid kept out of the attested payload digest: a wrong hint can only revert, never change what is + // accepted, since integrity comes from the rolling-hash equality check against the committee-signed header. + uint256 bucketHint; } struct ProposePayload { @@ -37,7 +44,9 @@ struct InterimProposeValues { bytes32[] blobHashes; bytes32 blobsHashesCommitment; bytes[] blobCommitments; - bytes32 inHash; + bytes32 blobCommitmentsHash; + FeeHeader feeHeader; + uint256 consumedInboxMsgTotal; bytes32 headerHash; bytes32 attestationsHash; bytes32 payloadDigest; @@ -112,6 +121,7 @@ library ProposeLib { using TimeLib for Epoch; using CompressedTimeMath for CompressedSlot; using ChainTipsLib for CompressedChainTips; + using SafeCast for uint256; /** * @notice Publishes a new checkpoint to the pending chain. @@ -125,7 +135,7 @@ library ProposeLib { * - Checkpoint header validations (see validateHeader function for details) * - Proposer signature is valid for designated slot proposer: * Errors.ValidatorSelection__MissingProposerSignature - * - Inbox hash matches expected value: Errors.Rollup__InvalidInHash + * - Streaming Inbox consumption is valid: Errors.Rollup__InvalidInboxRollingHash * - Archive root is within the scalar field: Errors.Rollup__FieldElementOutOfRange * * Validations NOT performed: @@ -137,7 +147,7 @@ library ProposeLib { * - Store archive root for the new checkpoint number * - Store checkpoint metadata in circular storage (TempCheckpointLog) * - Update L1 gas fee oracle - * - Consume inbox messages + * - Validate streaming Inbox consumption against the parent checkpoint * - Setup epoch for validator selection (first block of the epoch) * * @param _args - The arguments to propose the checkpoint @@ -252,17 +262,31 @@ library ProposeLib { uint256 checkpointNumber = tips.getPending() + 1; tips = tips.updatePending(checkpointNumber); + // Validate the streaming Inbox consumption against the parent checkpoint's consumed position. + // The parent is checkpointNumber - 1, always available: checkpoint 0 carries the {0,0,0} genesis base + // case written at initialization. rollupStore.tips is not committed until below, so the parent read still sees + // the parent as the pending tip. The returned cumulative total is stored in this checkpoint's record so its + // child validates against it and, since temp-log records rewind with the pending chain on a prune, the record + // stays prune-consistent. + v.consumedInboxMsgTotal = validateInboxConsumption( + rollupStore.config.inbox, + v.header.inboxRollingHash, + _args.bucketHint, + v.header.slotNumber, + STFLib.getInboxMsgTotal(checkpointNumber - 1) + ); + // Calculate accumulated blob commitments hash for this checkpoint // Blob commitments are collected and proven per root rollup proof (per epoch), // so we need to know whether we are at the epoch start: v.isFirstCheckpointOfEpoch = v.currentEpoch > STFLib.getEpochForCheckpoint(checkpointNumber - 1) || checkpointNumber == 1; - bytes32 blobCommitmentsHash = BlobLib.calculateBlobCommitmentsHash( + v.blobCommitmentsHash = BlobLib.calculateBlobCommitmentsHash( STFLib.getBlobCommitmentsHash(checkpointNumber - 1), v.blobCommitments, v.isFirstCheckpointOfEpoch ); // Compute fee header for checkpoint metadata - FeeHeader memory feeHeader = FeeLib.computeFeeHeader( + v.feeHeader = FeeLib.computeFeeHeader( checkpointNumber, _args.oracleInput.feeAssetPriceModifier, v.header.totalManaUsed, @@ -280,20 +304,18 @@ library ProposeLib { STFLib.addTempCheckpointLog( TempCheckpointLog({ headerHash: v.headerHash, - blobCommitmentsHash: blobCommitmentsHash, + blobCommitmentsHash: v.blobCommitmentsHash, outHash: v.header.outHash, attestationsHash: v.attestationsHash, payloadDigest: v.payloadDigest, slotNumber: v.header.slotNumber, - feeHeader: feeHeader + feeHeader: v.feeHeader, + inboxRollingHash: v.header.inboxRollingHash, + inboxMsgTotal: v.consumedInboxMsgTotal.toUint64(), + inboxConsumedBucket: _args.bucketHint.toUint64() }) ); - // Consume pending L1->L2 messages and validate against header commitment - // @note The checkpoint number here will always be >=1 as the genesis checkpoint is at 0 - v.inHash = rollupStore.config.inbox.consume(checkpointNumber); - require(v.header.inHash == v.inHash, Errors.Rollup__InvalidInHash(v.inHash, v.header.inHash)); - { bytes32 archive = _args.archive; if (v.isEscapeHatch) { @@ -370,6 +392,90 @@ library ProposeLib { ); } + /** + * @notice Validates a checkpoint's Inbox consumption against the streaming inbox buckets and returns how + * far consumption has reached. Called from propose() as the enforced consumption path. + * + * @dev Read-only; performs no Inbox write. Checks, in order: + * 1. The checkpoint header's `inboxRollingHash` must equal the rolling hash snapshotted in the Inbox + * bucket referenced by `_bucketHint`. The hint is a plain calldata lookup aid, not signed and not + * part of the header: a wrong hint cannot change what gets accepted, it only reverts. A checkpoint + * that consumes no messages references the same bucket as its parent. + * 2. The referenced bucket must be settled: a bucket that can still absorb another message is not a + * snapshot of anything. + * 3. Consumption moves forward: the referenced bucket's cumulative total must be at least the parent + * checkpoint's (equal consumes nothing; behind is a hard revert). This precedes the subtractions + * below, which rely on `bucket.totalMsgCount >= _parentTotalMsgCount` to not underflow. + * 4. Cap upper bound: a single checkpoint cannot consume more than MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + * messages, the maximum the circuits can insert. + * 5. Mandatory consumption (the censorship assert): the first unconsumed bucket (`_bucketHint + 1`) + * must either not exist, sit past the consumption cutoff, or be cap-escaped — consuming through it + * would exceed MAX_L1_TO_L2_MSGS_PER_CHECKPOINT messages since the parent checkpoint's cumulative + * total. The cutoff is the start of the checkpoint's build frame minus INBOX_LAG_SECONDS: a + * checkpoint proposed in slot S is built during slot S-1, and validators are not required to have + * seen buckets younger than one L1 slot at build start. + * + * No consumed-bucket pointer is written here. The caller (FI-14) stores the returned consumed + * position in the checkpoint's temp-log record, which is the authoritative consumed total: temp logs + * rewind with the pending chain on a prune, so the record stays prune-consistent — unlike an + * Inbox-side pointer advanced with the pending chain, which would sit ahead of the replacement chain. + * + * @param _inbox - The Inbox holding the rolling-hash buckets + * @param _inboxRollingHash - The checkpoint header's inbox rolling hash + * @param _bucketHint - Sequence number of the bucket the header's rolling hash corresponds to + * @param _slotNumber - The slot the checkpoint is proposed in + * @param _parentTotalMsgCount - Cumulative Inbox message count consumed as of the parent checkpoint + * @return The cumulative Inbox message count consumed as of this checkpoint (`bucket.totalMsgCount`), for + * the caller to store in the checkpoint's temp-log record + */ + function validateInboxConsumption( + IInbox _inbox, + bytes32 _inboxRollingHash, + uint256 _bucketHint, + Slot _slotNumber, + uint256 _parentTotalMsgCount + ) internal view returns (uint256) { + IInbox.InboxBucket memory bucket = _inbox.getBucket(_bucketHint); + require( + bucket.rollingHash == _inboxRollingHash, + Errors.Rollup__InvalidInboxRollingHash(bucket.rollingHash, _inboxRollingHash) + ); + + // A bucket that can still absorb a message mutates in place: a proposer bundling a send after its own propose + // in one L1 transaction would leave the checkpoint committed to a rolling hash that exists neither on L1 nor + // in any node, which only ever observes a bucket's end-of-block state, and no honest node could then resolve + // the consumed position. Settled is the negation of the Inbox's rollover condition: the genesis bucket never + // absorbs, a bucket whose L1 block has passed cannot be reopened, and a full bucket spills the next message + // into a new one. + require( + _bucketHint == 0 || bucket.timestamp < block.timestamp || bucket.msgCount == MAX_MSGS_PER_BUCKET, + Errors.Rollup__InboxBucketStillMutable(_bucketHint) + ); + + require( + bucket.totalMsgCount >= _parentTotalMsgCount, + Errors.Rollup__InboxConsumptionBehindParent(_parentTotalMsgCount, bucket.totalMsgCount) + ); + + require( + bucket.totalMsgCount - _parentTotalMsgCount <= Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + Errors.Rollup__TooManyInboxMessagesConsumed(bucket.totalMsgCount - _parentTotalMsgCount) + ); + + if (_bucketHint < _inbox.getCurrentBucketSeq()) { + IInbox.InboxBucket memory next = _inbox.getBucket(_bucketHint + 1); + Timestamp buildFrameStart = TimeLib.toTimestamp(_slotNumber - Slot.wrap(1)); + Timestamp cutoff = buildFrameStart - Timestamp.wrap(Constants.INBOX_LAG_SECONDS); + require( + next.timestamp > Timestamp.unwrap(cutoff) + || next.totalMsgCount - _parentTotalMsgCount > Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + Errors.Rollup__UnconsumedInboxMessages(_bucketHint + 1) + ); + } + + return bucket.totalMsgCount; + } + /** * @notice Gets the mana min fee components * For more context, consult: diff --git a/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol b/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol index d60e1edd6056..374752f646f9 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol @@ -21,7 +21,7 @@ struct ProposedHeader { bytes32 lastArchiveRoot; bytes32 blockHeadersHash; bytes32 blobsHash; - bytes32 inHash; + bytes32 inboxRollingHash; bytes32 outHash; Slot slotNumber; Timestamp timestamp; @@ -55,7 +55,7 @@ library ProposedHeaderLib { _header.lastArchiveRoot, _header.blockHeadersHash, _header.blobsHash, - _header.inHash, + _header.inboxRollingHash, _header.outHash, _header.slotNumber, Timestamp.unwrap(_header.timestamp).toUint64(), diff --git a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol index 5d40cf46832b..8d3a5a5e93b2 100644 --- a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol @@ -4,12 +4,9 @@ pragma solidity >=0.8.27; import {Errors} from "@aztec/core/libraries/Errors.sol"; -import {SubmitEpochRootProofArgs, PublicInputArgs} from "@aztec/core/interfaces/IRollup.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {Timestamp, TimeLib, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; -import {EpochProofLib} from "./EpochProofLib.sol"; -import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; import {AttestationLib} from "@aztec/core/libraries/rollup/AttestationLib.sol"; import { ProposeLib, @@ -21,16 +18,16 @@ import { import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; /** - * @title RollupOperationsExtLib - External Rollup Library (Proposal and Proof Verification Functions) + * @title RollupOperationsExtLib - External Rollup Library (Proposal Functions) * @author Aztec Labs * @notice External library containing proposal-related functions for the Rollup contract to avoid exceeding max * contract size. * * @dev This library serves as an external library for the Rollup contract, splitting off proposal-related - * functionality to keep the main contract within the maximum contract size limit. The library contains - * external functions primarily focused on: + * functionality to keep the main contract within the maximum contract size limit. Epoch-proof functions + * live in EpochProofExtLib to keep this library itself deployable. The library contains external + * functions primarily focused on: * - Checkpoint proposal submission and validation - * - Epoch proof submission and verification * - Blob validation and commitment management * - Chain pruning operations */ @@ -39,10 +36,6 @@ library RollupOperationsExtLib { using TimeLib for Slot; using AttestationLib for CommitteeAttestations; - function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external { - EpochProofLib.submitEpochRootProof(_args); - } - function validateHeaderWithAttestations( ValidateHeaderArgs calldata _args, CommitteeAttestations calldata _attestations, @@ -78,16 +71,6 @@ library RollupOperationsExtLib { STFLib.prune(); } - function getEpochProofPublicInputs( - uint256 _start, - uint256 _end, - PublicInputArgs calldata _args, - ProposedHeader[] calldata _headers, - bytes calldata _blobPublicInputs - ) external view returns (bytes32[] memory) { - return EpochProofLib.getEpochProofPublicInputs(_start, _end, _args, _headers, _blobPublicInputs); - } - function validateBlobs(bytes calldata _blobsInput, bool _checkBlob) external view diff --git a/l1-contracts/src/core/libraries/rollup/STFLib.sol b/l1-contracts/src/core/libraries/rollup/STFLib.sol index d776e634157b..eca3e15e7ade 100644 --- a/l1-contracts/src/core/libraries/rollup/STFLib.sol +++ b/l1-contracts/src/core/libraries/rollup/STFLib.sol @@ -132,7 +132,12 @@ library STFLib { slotNumber: Slot.wrap(0), feeHeader: FeeHeader({ excessMana: 0, manaUsed: 0, ethPerFeeAsset: _initialEthPerFeeAsset, congestionCost: 0, proverCost: 0 - }) + }), + // Genesis Inbox consumption base case, matching the Inbox's genesis bucket-0 sentinel {0, 0, 0}, so + // checkpoint 1 validates its consumption against it. + inboxRollingHash: bytes32(0), + inboxMsgTotal: 0, + inboxConsumedBucket: 0 }).compress(); } @@ -305,6 +310,26 @@ library STFLib { return getStorageTempCheckpointLog(_checkpointNumber).slotNumber.decompress(); } + /** + * @notice Retrieves the cumulative Inbox message count consumed as of a checkpoint + * @dev Gas-efficient accessor reading only the streaming-inbox consumed total. Reverts if the checkpoint is stale. + * @param _checkpointNumber The checkpoint number to get the consumed total for + * @return The cumulative Inbox message count consumed as of the checkpoint + */ + function getInboxMsgTotal(uint256 _checkpointNumber) internal view returns (uint64) { + return getStorageTempCheckpointLog(_checkpointNumber).inboxMsgTotal; + } + + /** + * @notice Retrieves the Inbox rolling hash a checkpoint committed to + * @dev Gas-efficient accessor reading only the streaming-inbox rolling hash. Reverts if the checkpoint is stale. + * @param _checkpointNumber The checkpoint number to get the rolling hash for + * @return The consensus Inbox rolling hash recorded for the checkpoint + */ + function getInboxRollingHash(uint256 _checkpointNumber) internal view returns (bytes32) { + return getStorageTempCheckpointLog(_checkpointNumber).inboxRollingHash; + } + /** * @notice Gets the effective pending checkpoint number based on pruning eligibility * @dev Returns either the pending checkpoint number or proven checkpoint number depending on diff --git a/l1-contracts/src/core/messagebridge/Inbox.sol b/l1-contracts/src/core/messagebridge/Inbox.sol index 8355421b6178..fa1b0f5067e2 100644 --- a/l1-contracts/src/core/messagebridge/Inbox.sol +++ b/l1-contracts/src/core/messagebridge/Inbox.sol @@ -3,9 +3,8 @@ pragma solidity >=0.8.27; import {IRollup} from "@aztec/core/interfaces/IRollup.sol"; -import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; +import {IInbox, MAX_MSGS_PER_BUCKET} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; -import {FrontierLib} from "@aztec/core/libraries/crypto/FrontierLib.sol"; import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; @@ -13,6 +12,17 @@ import {FeeJuicePortal} from "@aztec/core/messagebridge/FeeJuicePortal.sol"; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; import {SafeCast} from "@oz/utils/math/SafeCast.sol"; +// Number of buckets in the rolling-hash ring. Sized far beyond normal consumption lag (the censorship +// cutoff bounds it to roughly one build frame); outages longer than the ring are handled by overwrite +// protection on unconsumed buckets, not by growing the ring. +uint256 constant INBOX_BUCKET_RING_SIZE = 1024; + +// Constructor floor for the bucket ring. The ring must cover the longest stall the chain recovers from on +// its own: the prune-and-repropose window of 64 checkpoints (2 epochs = 384 L1 blocks) at the natural cadence +// of one bucket per L1 block, so the buckets it must re-consume after a prune have not been overwritten. 384 +// rounded up to the next power of two, kept at or below the production ring. +uint256 constant MIN_BUCKET_RING_SIZE = 512; + /** * @title Inbox * @author Aztec Labs @@ -20,42 +30,30 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol"; */ contract Inbox is IInbox { using Hash for DataStructures.L1ToL2Msg; - using FrontierLib for FrontierLib.Forest; - using FrontierLib for FrontierLib.Tree; address public immutable ROLLUP; uint256 public immutable VERSION; address public immutable FEE_ASSET_PORTAL; - uint256 public immutable LAG; - - uint256 internal immutable HEIGHT; - uint256 internal immutable SIZE; - bytes32 internal immutable EMPTY_ROOT; // The root of an empty frontier tree + uint256 public immutable BUCKET_RING_SIZE; - // Practically immutable value as we only set it in the constructor. - FrontierLib.Forest internal forest; + // Ring of rolling-hash buckets, keyed by `bucketSeq % BUCKET_RING_SIZE`. Consumed by the streaming inbox + // checks at `propose`. + mapping(uint256 ringIndex => InboxBucket bucket) internal buckets; - mapping(uint256 checkpointNumber => FrontierLib.Tree tree) public trees; + uint64 internal currentBucketSeq; - InboxState internal state; - - constructor(address _rollup, IERC20 _feeAsset, uint256 _version, uint256 _height, uint256 _lag) { + constructor(address _rollup, IERC20 _feeAsset, uint256 _version, uint256 _bucketRingSize) { ROLLUP = _rollup; VERSION = _version; - HEIGHT = _height; - SIZE = 2 ** _height; - - require(_lag > 0, "LAG TOO SMALL"); - LAG = _lag; + require(_bucketRingSize >= MIN_BUCKET_RING_SIZE, "BUCKET RING TOO SMALL"); + BUCKET_RING_SIZE = _bucketRingSize; - state = InboxState({ - rollingHash: 0, totalMessagesInserted: 0, inProgress: SafeCast.toUint64(Constants.INITIAL_CHECKPOINT_NUMBER + LAG) - }); - - forest.initialize(_height); - EMPTY_ROOT = trees[type(uint256).max].root(forest, HEIGHT, SIZE); + // Genesis bucket: a checkpoint consuming no messages references the same bucket as its parent, so the + // first checkpoint against an empty Inbox references this one and no base case leaks into `propose`. + buckets[0] = + InboxBucket({rollingHash: 0, totalMsgCount: 0, timestamp: SafeCast.toUint64(block.timestamp), msgCount: 0}); FEE_ASSET_PORTAL = address(new FeeJuicePortal(IRollup(_rollup), _feeAsset, IInbox(this), VERSION)); } @@ -70,7 +68,7 @@ contract Inbox is IInbox { * @param _secretHash - The secret hash of the message (make it possible to hide when a specific message is consumed * on L2) * - * @return Hash of the sent message and its leaf index in the tree. + * @return Hash of the sent message and its compact cumulative index. */ function sendL2Message(DataStructures.L2Actor memory _recipient, bytes32 _content, bytes32 _secretHash) external @@ -82,24 +80,11 @@ contract Inbox is IInbox { require(uint256(_content) <= Constants.MAX_FIELD_VALUE, Errors.Inbox__ContentTooLarge(_content)); require(uint256(_secretHash) <= Constants.MAX_FIELD_VALUE, Errors.Inbox__SecretHashTooLarge(_secretHash)); - // Is this the best way to read a packed struct into local variables in a single SLOAD - // without having to use assembly and manual unpacking? - InboxState memory _state = state; - bytes16 rollingHash = _state.rollingHash; - uint64 totalMessagesInserted = _state.totalMessagesInserted; - uint64 inProgress = _state.inProgress; - - FrontierLib.Tree storage currentTree = trees[inProgress]; - - if (currentTree.isFull(SIZE)) { - inProgress += 1; - currentTree = trees[inProgress]; - } - - // this is the global leaf index and not index in the checkpoint subtree - // such that users can simply use it and don't need access to a node if they are to consume it in public. - // trees are constant size so global index = tree number * size + subtree index - uint256 index = (inProgress - Constants.INITIAL_CHECKPOINT_NUMBER) * SIZE + currentTree.nextIndex; + // Compact cumulative message index: the zero-based position of this message in the Inbox's + // insertion order, equal to the number of messages inserted before it. It matches the streaming L1-to-L2 tree's + // leaf count, so consumers do not need per-checkpoint tree geometry. Sourced from the current bucket's running + // total, which the absorb below then advances (a rollover carries the total forward unchanged). + uint256 index = _totalMessagesInserted(); // If the sender is the fee asset portal, we use a magic address to simpler have it initialized at genesis. // We assume that no-one will know the private key for this address and that the precompile won't change to @@ -115,66 +100,79 @@ contract Inbox is IInbox { }); bytes32 leaf = message.sha256ToField(); - currentTree.insertLeaf(leaf); - bytes16 updatedRollingHash = bytes16(keccak256(abi.encodePacked(rollingHash, leaf))); - state = InboxState({ - rollingHash: updatedRollingHash, totalMessagesInserted: totalMessagesInserted + 1, inProgress: inProgress - }); + (uint64 bucketSeq, bytes32 inboxRollingHash) = _absorbIntoBucket(leaf); - emit MessageSent(inProgress, index, leaf, updatedRollingHash); + emit MessageSent(index, leaf, inboxRollingHash, bucketSeq); return (leaf, index); } - /** - * @notice Consumes the current tree, and starts a new one if needed - * - * @dev Only callable by the rollup contract - * @dev In the first iteration we return empty tree root because first checkpoint's messages tree is always - * empty because there has to be a 1 checkpoint lag to prevent sequencer DOS attacks - * - * @param _toConsume - The checkpoint number to consume - * - * @return The root of the consumed tree - */ - function consume(uint256 _toConsume) external override(IInbox) returns (bytes32) { - require(msg.sender == ROLLUP, Errors.Inbox__Unauthorized()); - - uint64 inProgress = state.inProgress; - require(_toConsume < inProgress, Errors.Inbox__MustBuildBeforeConsume()); - - bytes32 root = EMPTY_ROOT; - if (_toConsume > Constants.INITIAL_CHECKPOINT_NUMBER) { - root = trees[_toConsume].root(forest, HEIGHT, SIZE); - } - - // Once consumption reaches the current lag boundary, open the next checkpoint - // so new inserts keep a full LAG-sized buffer ahead of the rollup. - if (_toConsume + LAG == inProgress) { - state.inProgress = inProgress + 1; - } + function getFeeAssetPortal() external view override(IInbox) returns (address) { + return FEE_ASSET_PORTAL; + } - return root; + function getState() external view override(IInbox) returns (InboxState memory) { + return InboxState({totalMessagesInserted: _totalMessagesInserted()}); } - function getFeeAssetPortal() external view override(IInbox) returns (address) { - return FEE_ASSET_PORTAL; + function getTotalMessagesInserted() external view override(IInbox) returns (uint64) { + return _totalMessagesInserted(); } - function getRoot(uint256 _checkpointNumber) external view override(IInbox) returns (bytes32) { - return trees[_checkpointNumber].root(forest, HEIGHT, SIZE); + function getCurrentBucketSeq() external view override(IInbox) returns (uint64) { + return currentBucketSeq; } - function getState() external view override(IInbox) returns (InboxState memory) { - return state; + function getBucket(uint256 _seq) external view override(IInbox) returns (InboxBucket memory) { + uint256 current = currentBucketSeq; + require(_seq <= current && current - _seq < BUCKET_RING_SIZE, Errors.Inbox__BucketOutOfWindow(_seq, current)); + return buckets[_seq % BUCKET_RING_SIZE]; } - function getTotalMessagesInserted() external view override(IInbox) returns (uint64) { - return state.totalMessagesInserted; + /** + * @notice Absorbs a message leaf into the consensus rolling hash and snapshots it into the bucket ring + * + * @dev A bucket only holds messages from a single L1 block, up to MAX_MSGS_PER_BUCKET; the first message + * of a new L1 block — or the message after a full bucket, spilling over within the same block — opens the + * next bucket, inheriting the rolling hash and cumulative count. Bucket 0 is the pristine genesis base + * case and never absorbs. Opening a bucket overwrites the ring entry from BUCKET_RING_SIZE buckets ago; + * protection against overwriting unconsumed buckets is not enforced yet. + * + * @param _leaf - The message leaf to absorb + * + * @return The sequence number of the bucket the leaf was absorbed into and the updated rolling hash + */ + function _absorbIntoBucket(bytes32 _leaf) internal returns (uint64, bytes32) { + uint64 bucketSeq = currentBucketSeq; + InboxBucket memory bucket = buckets[bucketSeq % BUCKET_RING_SIZE]; + + // Buckets are keyed by L1 block timestamp: a strictly larger timestamp opens a new bucket (a full bucket + // also rolls over within the same block). Post-merge Ethereum increases block.timestamp strictly per block, + // so messages from different L1 blocks always land in different buckets. Under anvil with manual mining two + // blocks can share a timestamp and therefore a bucket; this is harmless because the consumption cutoff is + // computed over timestamps, so co-timestamped blocks are indistinguishable to it. + if (bucketSeq == 0 || bucket.timestamp < block.timestamp || bucket.msgCount == MAX_MSGS_PER_BUCKET) { + bucketSeq += 1; + currentBucketSeq = bucketSeq; + bucket = InboxBucket({ + rollingHash: bucket.rollingHash, + totalMsgCount: bucket.totalMsgCount, + timestamp: SafeCast.toUint64(block.timestamp), + msgCount: 0 + }); + } + + bucket.rollingHash = Hash.accumulateInboxRollingHash(bucket.rollingHash, _leaf); + bucket.totalMsgCount += 1; + bucket.msgCount += 1; + buckets[bucketSeq % BUCKET_RING_SIZE] = bucket; + + return (bucketSeq, bucket.rollingHash); } - function getInProgress() external view override(IInbox) returns (uint64) { - return state.inProgress; + // Cumulative number of messages inserted into the Inbox, tracked by the current bucket's running total. + function _totalMessagesInserted() internal view returns (uint64) { + return buckets[currentBucketSeq % BUCKET_RING_SIZE].totalMsgCount; } } diff --git a/l1-contracts/test/Inbox.t.sol b/l1-contracts/test/Inbox.t.sol index daac928af500..d9661b10db02 100644 --- a/l1-contracts/test/Inbox.t.sol +++ b/l1-contracts/test/Inbox.t.sol @@ -17,21 +17,13 @@ import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; contract InboxTest is Test { using Hash for DataStructures.L1ToL2Msg; - uint256 internal constant FIRST_REAL_TREE_NUM = Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG; - // We set low depth (5) to ensure we sufficiently test the tree transitions - uint256 internal constant HEIGHT = 5; - uint256 internal constant SIZE = 2 ** HEIGHT; - InboxHarness internal inbox; uint256 internal version = 0; - uint256 internal checkpointNumber = Constants.INITIAL_CHECKPOINT_NUMBER; - bytes32 internal emptyTreeRoot; function setUp() public { address rollup = address(this); IERC20 feeAsset = new TestERC20("Fee Asset", "FA", address(this)); - inbox = new InboxHarness(rollup, feeAsset, version, HEIGHT, TestConstants.AZTEC_INBOX_LAG); - emptyTreeRoot = inbox.getEmptyRoot(); + inbox = new InboxHarness(rollup, feeAsset, version, TestConstants.AZTEC_INBOX_BUCKET_RING_SIZE); } function _fakeMessage() internal view returns (DataStructures.L1ToL2Msg memory) { @@ -46,10 +38,6 @@ contract InboxTest is Test { }); } - function _divideAndRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { - return (a + b - 1) / b; - } - function _boundMessage(DataStructures.L1ToL2Msg memory _message, uint256 _globalLeafIndex) internal view @@ -71,34 +59,17 @@ contract InboxTest is Test { return _message; } - // Since there is a LAG checkpoint lag between tree to be consumed and tree in progress the following invariant should - // never be violated - modifier checkInvariant() { - _; - assertLt(checkpointNumber, inbox.getInProgress()); - } - - function testRevertIfNotConsumingFromRollup() public { - vm.prank(address(0x1)); - vm.expectRevert(Errors.Inbox__Unauthorized.selector); - inbox.consume(checkpointNumber); - } - - function testRevertIFConsumingInFuture() public { - vm.expectRevert(Errors.Inbox__MustBuildBeforeConsume.selector); - inbox.consume(checkpointNumber + 1000); - } - - function testFuzzInsert(DataStructures.L1ToL2Msg memory _message) public checkInvariant { + function testFuzzInsert(DataStructures.L1ToL2Msg memory _message) public { Inbox.InboxState memory stateBefore = inbox.getState(); - uint256 globalLeafIndex = (FIRST_REAL_TREE_NUM - 1) * SIZE; + // Compact cumulative index: the message's index is the count inserted before it. + uint256 globalLeafIndex = stateBefore.totalMessagesInserted; DataStructures.L1ToL2Msg memory message = _boundMessage(_message, globalLeafIndex); bytes32 leaf = message.sha256ToField(); - bytes16 expectedRollingHash = bytes16(keccak256(abi.encodePacked(stateBefore.rollingHash, leaf))); + bytes32 expectedInboxRollingHash = Hash.accumulateInboxRollingHash(bytes32(0), leaf); vm.expectEmit(true, true, true, true); // event we expect - emit IInbox.MessageSent(FIRST_REAL_TREE_NUM, globalLeafIndex, leaf, expectedRollingHash); + emit IInbox.MessageSent(globalLeafIndex, leaf, expectedInboxRollingHash, 1); // event we will get (bytes32 insertedLeaf, uint256 insertedIndex) = inbox.sendL2Message(message.recipient, message.content, message.secretHash); @@ -108,19 +79,14 @@ contract InboxTest is Test { Inbox.InboxState memory stateAfter = inbox.getState(); assertEq(stateBefore.totalMessagesInserted + 1, stateAfter.totalMessagesInserted); - assertEq(expectedRollingHash, stateAfter.rollingHash); - assertEq(stateBefore.inProgress, stateAfter.inProgress); } - function testSendDuplicateL2Messages() public checkInvariant { + function testSendDuplicateL2Messages() public { DataStructures.L1ToL2Msg memory message = _fakeMessage(); (bytes32 leaf1, uint256 index1) = inbox.sendL2Message(message.recipient, message.content, message.secretHash); (bytes32 leaf2, uint256 index2) = inbox.sendL2Message(message.recipient, message.content, message.secretHash); (bytes32 leaf3, uint256 index3) = inbox.sendL2Message(message.recipient, message.content, message.secretHash); - // Only 1 tree should be non-zero - assertEq(inbox.getNumTrees(), TestConstants.AZTEC_INBOX_LAG); - // All the leaves should be different since the index gets mixed in assertNotEq(leaf1, leaf2); assertNotEq(leaf2, leaf3); @@ -157,70 +123,4 @@ contract InboxTest is Test { vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__SecretHashTooLarge.selector, message.secretHash)); inbox.sendL2Message(message.recipient, message.content, message.secretHash); } - - function testFuzzSendAndConsume( - DataStructures.L1ToL2Msg[] memory _messagesFirstBatch, - DataStructures.L1ToL2Msg[] memory _messagesSecondBatch, - uint256 _numTreesToConsumeFirstBatch, - uint256 _numTreesToConsumeSecondBatch - ) public { - // Send first batch of messages - _send(_messagesFirstBatch); - - // Consume first few trees - _consume(_numTreesToConsumeFirstBatch); - - // Send second batch of messages - _send(_messagesSecondBatch); - - // Consume second batch of trees - _consume(_numTreesToConsumeSecondBatch); - } - - function _send(DataStructures.L1ToL2Msg[] memory _messages) internal checkInvariant { - bytes32 toConsumeRoot = inbox.getToConsumeRoot(checkpointNumber); - - // We send the messages and then check that toConsume root did not change. - for (uint256 i = 0; i < _messages.length; i++) { - DataStructures.L1ToL2Msg memory message = _boundMessage(_messages[i], inbox.getNextMessageIndex()); - - // We check whether a new tree is correctly initialized when the one in progress is full - uint256 numTrees = inbox.getNumTrees(); - uint256 expectedNumTrees = inbox.treeInProgressFull() ? numTrees + 1 : numTrees; - - inbox.sendL2Message(message.recipient, message.content, message.secretHash); - - assertEq(inbox.getNumTrees(), expectedNumTrees, "Unexpected number of trees"); - } - - // Root of a tree waiting to be consumed should not change because we introduced a LAG checkpoint lag to prevent - // sequencer DOS attacks - assertEq( - inbox.getToConsumeRoot(checkpointNumber), toConsumeRoot, "Root of a tree waiting to be consumed should not change" - ); - } - - function _consume(uint256 _numTreesToConsume) internal checkInvariant { - uint256 initialNumTrees = inbox.getNumTrees(); - // We use (initialNumTrees * 2) as upper bound here because we want to test the case where we go beyond - // the currently initalized number of trees. When consuming the newly initialized trees we should get zero roots. - uint256 numTreesToConsume = bound(_numTreesToConsume, 1, initialNumTrees * 2); - - // Now we consume the trees - for (uint256 i = 0; i < numTreesToConsume; i++) { - uint256 numTrees = inbox.getNumTrees(); - uint256 expectedNumTrees = - (checkpointNumber + TestConstants.AZTEC_INBOX_LAG == inbox.getInProgress()) ? numTrees + 1 : numTrees; - bytes32 root = inbox.consume(checkpointNumber); - - // We check whether a new tree is correctly initialized when the one which was in progress was set as to consume - assertEq(inbox.getNumTrees(), expectedNumTrees, "Unexpected number of trees"); - - // If we go beyong the number of trees initialized before consuming we should get empty root - if (i > initialNumTrees) { - assertEq(root, emptyTreeRoot, "Root of a newly initialized tree not empty"); - } - checkpointNumber += 1; - } - } } diff --git a/l1-contracts/test/InboxBuckets.t.sol b/l1-contracts/test/InboxBuckets.t.sol new file mode 100644 index 000000000000..86037e2f86b4 --- /dev/null +++ b/l1-contracts/test/InboxBuckets.t.sol @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Aztec Labs. +pragma solidity >=0.8.27; + +import {Test} from "forge-std/Test.sol"; +import {TestERC20} from "src/mock/TestERC20.sol"; +import {IERC20} from "@oz/token/ERC20/IERC20.sol"; +import {IInbox, MAX_MSGS_PER_BUCKET} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; +import {MIN_BUCKET_RING_SIZE} from "@aztec/core/messagebridge/Inbox.sol"; +import {InboxHarness} from "./harnesses/InboxHarness.sol"; +import {TestConstants} from "./harnesses/TestConstants.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; +import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; + +contract InboxBucketsTest is Test { + InboxHarness internal inbox; + uint256 internal version = 0; + bytes32 internal expectedRollingHash; + + function setUp() public { + inbox = _deployInbox(TestConstants.AZTEC_INBOX_BUCKET_RING_SIZE); + } + + function _deployInbox(uint256 _ringSize) internal returns (InboxHarness) { + IERC20 feeAsset = new TestERC20("Fee Asset", "FA", address(this)); + return new InboxHarness(address(this), feeAsset, version, _ringSize); + } + + function _send(InboxHarness _inbox, uint256 _salt) internal returns (bytes32) { + (bytes32 leaf,) = _inbox.sendL2Message( + DataStructures.L2Actor({actor: bytes32(uint256(0x1000 + _salt)), version: version}), + bytes32(uint256(0x2000 + _salt)), + bytes32(uint256(0x3000 + _salt)) + ); + expectedRollingHash = Hash.accumulateInboxRollingHash(expectedRollingHash, leaf); + return leaf; + } + + // Sends a message and returns the gas consumed by the external `sendL2Message` call. The + // recipient/content/secretHash are built before the measurement window so only the call is timed. The + // figure is warm execution gas including the CALL overhead; it excludes the 21k intrinsic tx cost, calldata + // gas, and the cold-access surcharge a standalone EOA transaction pays on its first touch of each slot. + function _measureSend(InboxHarness _inbox, uint256 _salt) internal returns (uint256 gasUsed) { + DataStructures.L2Actor memory recipient = + DataStructures.L2Actor({actor: bytes32(uint256(0x1000 + _salt)), version: version}); + bytes32 content = bytes32(uint256(0x2000 + _salt)); + bytes32 secretHash = bytes32(uint256(0x3000 + _salt)); + + uint256 gasBefore = gasleft(); + _inbox.sendL2Message(recipient, content, secretHash); + gasUsed = gasBefore - gasleft(); + } + + // Shared test vectors for the rolling-hash chain, pinned across the noir circuits, the TS mirror, + // and this L1 implementation. Generated from an independent sha256 implementation. + function testRollingHashTestVectors() public pure { + bytes32 h = Hash.accumulateInboxRollingHash(bytes32(0), bytes32(uint256(11))); + assertEq(h, 0x00815fb1e9d2076ae5761439b6144ad11da69eb6c41ab2aca39e770407ad8d12, "chain(0, [11])"); + + h = Hash.accumulateInboxRollingHash(h, bytes32(uint256(22))); + h = Hash.accumulateInboxRollingHash(h, bytes32(uint256(33))); + assertEq(h, 0x0014cae968461979aab6d33266a2310ed234d3f6cf4472737c57551db07bd0da, "chain(0, [11, 22, 33])"); + + h = bytes32(0); + for (uint256 i = 1; i <= 256; i++) { + h = Hash.accumulateInboxRollingHash(h, bytes32(i)); + } + assertEq(h, 0x00ea95b96f17b75be03525b35a2a1918b42f03ad8c00a437cf641751825f3992, "chain(0, [1..=256])"); + + h = Hash.accumulateInboxRollingHash(bytes32(uint256(0x2a)), bytes32(uint256(7))); + assertEq(h, 0x0032a934005556d1b9d22708666ee8b05f91fafad624dd64a6ea878e048e5438, "chain(0x2a, [7])"); + + h = Hash.accumulateInboxRollingHash(h, bytes32(uint256(8))); + assertEq(h, 0x0054d96b8a074a5030a5838972d0a3c04ba47cf5956348c853e02e9566233f65, "chain(0x2a, [7, 8])"); + } + + function testGenesisBucket() public { + assertEq(inbox.getCurrentBucketSeq(), 0, "genesis seq"); + + IInbox.InboxBucket memory bucket = inbox.getBucket(0); + assertEq(bucket.rollingHash, bytes32(0), "genesis rolling hash"); + assertEq(bucket.totalMsgCount, 0, "genesis total"); + assertEq(bucket.timestamp, uint64(block.timestamp), "genesis timestamp"); + assertEq(bucket.msgCount, 0, "genesis msg count"); + + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, 1, 0)); + inbox.getBucket(1); + } + + function testFirstMessageOpensBucketOne() public { + // Even in the deployment block, the first message must not absorb into the genesis bucket: a + // checkpoint consuming no messages needs a bucket whose rolling hash matches its parent's chain + // position, which for the first checkpoint is the zero genesis bucket. + _send(inbox, 0); + + assertEq(inbox.getCurrentBucketSeq(), 1, "current seq"); + assertEq(inbox.getBucket(0).rollingHash, bytes32(0), "genesis untouched"); + assertEq(inbox.getBucket(0).msgCount, 0, "genesis still empty"); + assertEq(inbox.getBucket(1).msgCount, 1, "bucket 1 has the message"); + } + + function testAccumulationWithinSingleBlock() public { + bytes32 leaf1 = _send(inbox, 1); + bytes32 chain1 = Hash.accumulateInboxRollingHash(bytes32(0), leaf1); + bytes32 leaf2 = _send(inbox, 2); + bytes32 chain2 = Hash.accumulateInboxRollingHash(chain1, leaf2); + bytes32 leaf3 = _send(inbox, 3); + bytes32 chain3 = Hash.accumulateInboxRollingHash(chain2, leaf3); + + assertEq(inbox.getCurrentBucketSeq(), 1, "all messages share one bucket"); + + IInbox.InboxBucket memory bucket = inbox.getBucket(1); + assertEq(bucket.rollingHash, chain3, "bucket rolling hash"); + assertEq(bucket.totalMsgCount, 3, "bucket cumulative total"); + assertEq(bucket.timestamp, uint64(block.timestamp), "bucket timestamp"); + assertEq(bucket.msgCount, 3, "bucket msg count"); + } + + function testMessageSentEventCarriesBucketData() public { + DataStructures.L2Actor memory recipient = + DataStructures.L2Actor({actor: bytes32(uint256(0x1000)), version: version}); + bytes32 content = bytes32(uint256(0x2000)); + bytes32 secretHash = bytes32(uint256(0x3000)); + + DataStructures.L1ToL2Msg memory message = DataStructures.L1ToL2Msg({ + sender: DataStructures.L1Actor(address(this), block.chainid), + recipient: recipient, + content: content, + secretHash: secretHash, + // Compact cumulative index: the first message against a fresh Inbox has index 0. + index: inbox.getState().totalMessagesInserted + }); + bytes32 leaf = Hash.sha256ToField(message); + bytes32 inboxRollingHash = Hash.accumulateInboxRollingHash(bytes32(0), leaf); + + vm.expectEmit(true, true, true, true, address(inbox)); + emit IInbox.MessageSent(message.index, leaf, inboxRollingHash, 1); + inbox.sendL2Message(recipient, content, secretHash); + } + + function testSnapshotBoundariesAcrossBlocks() public { + _send(inbox, 1); + _send(inbox, 2); + IInbox.InboxBucket memory bucket1 = inbox.getBucket(1); + + vm.roll(block.number + 1); + vm.warp(block.timestamp + 12); + + bytes32 leaf3 = _send(inbox, 3); + + assertEq(inbox.getCurrentBucketSeq(), 2, "new block opens a new bucket"); + + // The previous bucket's snapshot is frozen at its end-of-block state. + IInbox.InboxBucket memory bucket1After = inbox.getBucket(1); + assertEq(bucket1After.rollingHash, bucket1.rollingHash, "bucket 1 rolling hash frozen"); + assertEq(bucket1After.totalMsgCount, 2, "bucket 1 total frozen"); + assertEq(bucket1After.msgCount, 2, "bucket 1 msg count frozen"); + assertEq(bucket1After.timestamp, bucket1.timestamp, "bucket 1 timestamp frozen"); + + // The new bucket continues the chain from the previous bucket. + IInbox.InboxBucket memory bucket2 = inbox.getBucket(2); + assertEq(bucket2.rollingHash, Hash.accumulateInboxRollingHash(bucket1.rollingHash, leaf3), "chain continuity"); + assertEq(bucket2.rollingHash, expectedRollingHash, "chain matches reference"); + assertEq(bucket2.totalMsgCount, 3, "cumulative total spans buckets"); + assertEq(bucket2.timestamp, uint64(block.timestamp), "bucket 2 timestamp"); + assertEq(bucket2.msgCount, 1, "bucket 2 msg count"); + } + + function testRolloverIntoNextBucket() public { + uint256 cap = MAX_MSGS_PER_BUCKET; + for (uint256 i = 0; i < cap; i++) { + _send(inbox, i); + } + assertEq(inbox.getCurrentBucketSeq(), 1, "cap messages fit in one bucket"); + IInbox.InboxBucket memory bucket1 = inbox.getBucket(1); + assertEq(bucket1.msgCount, cap, "bucket 1 full"); + + // The next message in the same L1 block spills over into a new bucket with the same timestamp. + bytes32 leaf = _send(inbox, cap); + assertEq(inbox.getCurrentBucketSeq(), 2, "rollover opened next bucket"); + + IInbox.InboxBucket memory bucket2 = inbox.getBucket(2); + assertEq(bucket2.rollingHash, Hash.accumulateInboxRollingHash(bucket1.rollingHash, leaf), "chain continuity"); + assertEq(bucket2.totalMsgCount, cap + 1, "cumulative total"); + assertEq(bucket2.timestamp, bucket1.timestamp, "same block, same timestamp"); + assertEq(bucket2.msgCount, 1, "spilled message only"); + + assertEq(inbox.getBucket(1).msgCount, cap, "bucket 1 untouched by rollover"); + } + + function testRingWraparound() public { + InboxHarness ringInbox = _deployInbox(MIN_BUCKET_RING_SIZE); + expectedRollingHash = 0; + + // One bucket per L1 block; after MIN_BUCKET_RING_SIZE + 1 buckets the ring has wrapped past bucket 1. + for (uint256 i = 1; i <= MIN_BUCKET_RING_SIZE + 1; i++) { + vm.roll(block.number + 1); + vm.warp(block.timestamp + 12); + _send(ringInbox, i); + } + + uint256 current = ringInbox.getCurrentBucketSeq(); + assertEq(current, MIN_BUCKET_RING_SIZE + 1, "one bucket per block"); + + // Buckets 0 and 1 have been overwritten: their ring slots were reused by buckets + // MIN_BUCKET_RING_SIZE and MIN_BUCKET_RING_SIZE + 1. + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, 0, current)); + ringInbox.getBucket(0); + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, 1, current)); + ringInbox.getBucket(1); + + // The live window is intact, with per-bucket data at the right ring slots. + uint64 previousTimestamp = 0; + for (uint256 seq = current - MIN_BUCKET_RING_SIZE + 1; seq <= current; seq++) { + IInbox.InboxBucket memory bucket = ringInbox.getBucket(seq); + assertEq(bucket.totalMsgCount, seq, "cumulative total"); + assertEq(bucket.msgCount, 1, "one message per bucket"); + assertGt(bucket.timestamp, previousTimestamp, "timestamps increase per bucket"); + previousTimestamp = bucket.timestamp; + } + assertEq(ringInbox.getBucket(current).rollingHash, expectedRollingHash, "chain matches reference"); + + // Buckets ahead of the current one do not exist yet. + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, current + 1, current)); + ringInbox.getBucket(current + 1); + } + + function testConstructorRevertsBelowRingFloor() public { + IERC20 feeAsset = new TestERC20("Fee Asset", "FA", address(this)); + vm.expectRevert("BUCKET RING TOO SMALL"); + new InboxHarness(address(this), feeAsset, version, MIN_BUCKET_RING_SIZE - 1); + } + + // Gas cost of a message absorbed into an already-open bucket (the common per-message case): the + // second message of an L1 block updates the live bucket in place without opening a new ring slot. + function testGasSendIntoExistingBucket() public { + _send(inbox, 0); + assertEq(inbox.getCurrentBucketSeq(), 1, "warmup opened bucket 1"); + + uint256 gasUsed = _measureSend(inbox, 1); + emit log_named_uint("gas: absorb into existing bucket", gasUsed); + + assertEq(inbox.getCurrentBucketSeq(), 1, "absorbed without opening a new bucket"); + } + + // Gas cost of the first message of a new L1 block: a larger timestamp opens the next bucket, + // writing a fresh ring slot. + function testGasSendFirstMessageOfNewBlock() public { + _send(inbox, 0); + assertEq(inbox.getCurrentBucketSeq(), 1, "warmup opened bucket 1"); + + vm.roll(block.number + 1); + vm.warp(block.timestamp + 12); + + uint256 gasUsed = _measureSend(inbox, 1); + emit log_named_uint("gas: first message of a new L1 block", gasUsed); + + assertEq(inbox.getCurrentBucketSeq(), 2, "new block opened bucket 2"); + } + + // Gas cost of a rollover opening mid-block: once a bucket reaches MAX_MSGS_PER_BUCKET, the next + // message in the same L1 block opens a new bucket even though the timestamp is unchanged. + function testGasSendRolloverMidBlock() public { + uint256 cap = MAX_MSGS_PER_BUCKET; + for (uint256 i = 0; i < cap; i++) { + _send(inbox, i); + } + assertEq(inbox.getCurrentBucketSeq(), 1, "cap messages fit in bucket 1"); + + uint256 gasUsed = _measureSend(inbox, cap); + emit log_named_uint("gas: rollover open mid-block", gasUsed); + + assertEq(inbox.getCurrentBucketSeq(), 2, "rollover opened bucket 2"); + } + + // Gas cost of the first-ever message against a freshly deployed Inbox: the rolling-hash slot and bucket 1 + // are written cold. This is the cold-storage case for the first message. + function testGasSendFirstEverMessage() public { + assertEq(inbox.getCurrentBucketSeq(), 0, "no message sent yet"); + + uint256 gasUsed = _measureSend(inbox, 0); + emit log_named_uint("gas: first-ever message", gasUsed); + + assertEq(inbox.getCurrentBucketSeq(), 1, "first message opened bucket 1"); + } +} diff --git a/l1-contracts/test/InboxBucketsFuzz.t.sol b/l1-contracts/test/InboxBucketsFuzz.t.sol new file mode 100644 index 000000000000..7378a1a8e6c2 --- /dev/null +++ b/l1-contracts/test/InboxBucketsFuzz.t.sol @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Aztec Labs. +pragma solidity >=0.8.27; + +import {Test} from "forge-std/Test.sol"; +import {TestERC20} from "src/mock/TestERC20.sol"; +import {IERC20} from "@oz/token/ERC20/IERC20.sol"; +import {IInbox, MAX_MSGS_PER_BUCKET} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; +import {InboxHarness} from "./harnesses/InboxHarness.sol"; +import {TestConstants} from "./harnesses/TestConstants.sol"; +import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; +import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; +import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; + +/** + * Randomized coverage of the Inbox send path: batches of messages spread over several L1 blocks, with batches + * large enough to exceed the per-bucket cap and roll over. Every run re-derives the whole bucket ring from the + * message leaves the Inbox returned and the per-L1-block batch sizes, so an accumulation, rollover, or + * snapshot-boundary bug shows up as a mismatch against the model rather than as a missing assertion. The + * hand-written boundary cases live in InboxBuckets.t.sol; consumption and ring wraparound are out of scope. + */ +contract InboxBucketsFuzzTest is Test { + // Number of L1 blocks a multi-block run spans. Small enough that the bucket ring never wraps. + uint256 internal constant L1_BLOCKS = 6; + + /// Where one L1 block's batch of messages landed: the contiguous run of buckets it opened. + struct BlockBatch { + uint256 timestamp; + uint256 firstSeq; + uint256 lastSeq; + uint256 msgCount; + } + + InboxHarness internal inbox; + uint256 internal version = 0; + uint256 internal cap; + + // Every leaf the Inbox returned, in insertion order. The rolling-hash chain is recomputed from these. + bytes32[] internal leaves; + + // One entry per L1 block that sent at least one message, in block order. + BlockBatch[] internal batches; + + function setUp() public { + IERC20 feeAsset = new TestERC20("Fee Asset", "FA", address(this)); + inbox = new InboxHarness(address(this), feeAsset, version, TestConstants.AZTEC_INBOX_BUCKET_RING_SIZE); + cap = MAX_MSGS_PER_BUCKET; + } + + /// forge-config: default.fuzz.runs = 128 + function testFuzzBucketsAcrossL1Blocks( + uint8[L1_BLOCKS] memory _msgsPerBlock, + uint16[L1_BLOCKS] memory _blockGaps, + uint8 _rolloverBlock, + uint16 _rolloverCount, + uint256 _seed + ) public { + // One block per run always crosses the per-bucket cap, so every run exercises a rollover alongside the + // ordinary same-block accumulation and new-block bucket opening. + uint256 rolloverBlock = bound(_rolloverBlock, 0, L1_BLOCKS - 1); + uint256 rolloverCount = bound(_rolloverCount, cap + 1, cap + 8); + + for (uint256 b = 0; b < L1_BLOCKS; b++) { + if (b > 0) { + vm.roll(block.number + 1); + vm.warp(block.timestamp + bound(_blockGaps[b], 1, 3600)); + } + _sendBlock(b == rolloverBlock ? rolloverCount : bound(_msgsPerBlock[b], 0, 12), _seed); + } + + _assertBucketRing(); + } + + /// forge-config: default.fuzz.runs = 32 + function testFuzzRolloverChainWithinOneL1Block(uint16 _msgCount, uint256 _seed) public { + // Several buckets' worth of messages in a single L1 block: each message arriving at a full bucket opens the + // next ring slot at the same timestamp, so the block owns a run of buckets rather than one. + _sendBlock(bound(_msgCount, cap + 1, 2 * cap + 5), _seed); + _assertBucketRing(); + } + + // Sends `_count` messages in the current L1 block and checks what the batch did to the ring: it opened one + // bucket per cap-sized slice, every bucket it opened carries this block's timestamp, and the bucket the + // previous L1 block left behind is frozen. + function _sendBlock(uint256 _count, uint256 _seed) internal { + uint256 seqBefore = inbox.getCurrentBucketSeq(); + IInbox.InboxBucket memory frozen = inbox.getBucket(seqBefore); + uint256 totalBefore = leaves.length; + + for (uint256 i = 0; i < _count; i++) { + _send(_seed); + } + + uint256 seqAfter = inbox.getCurrentBucketSeq(); + assertEq(seqAfter, seqBefore + (_count + cap - 1) / cap, "buckets opened by this L1 block"); + _assertBucketEq(inbox.getBucket(seqBefore), frozen, "bucket left by the previous L1 block is frozen"); + + if (_count == 0) { + return; + } + + for (uint256 seq = seqBefore + 1; seq <= seqAfter; seq++) { + IInbox.InboxBucket memory bucket = inbox.getBucket(seq); + uint256 sliceStart = (seq - seqBefore - 1) * cap; + uint256 sliceSize = _count - sliceStart < cap ? _count - sliceStart : cap; + assertEq(bucket.msgCount, sliceSize, "messages absorbed into bucket"); + assertEq(bucket.timestamp, block.timestamp, "bucket carries the sending L1 block's timestamp"); + assertEq(bucket.totalMsgCount, totalBefore + sliceStart + sliceSize, "bucket cumulative total"); + } + + batches.push(BlockBatch({timestamp: block.timestamp, firstSeq: seqBefore + 1, lastSeq: seqAfter, msgCount: _count})); + } + + // Sends one message with fuzz-derived contents, checking the Inbox agrees on its leaf and compact index. + function _send(uint256 _seed) internal { + uint256 index = leaves.length; + DataStructures.L2Actor memory recipient = DataStructures.L2Actor({actor: _field(_seed, index, 0), version: version}); + bytes32 content = _field(_seed, index, 1); + bytes32 secretHash = _field(_seed, index, 2); + + (bytes32 leaf, uint256 insertedIndex) = inbox.sendL2Message(recipient, content, secretHash); + + // The leaf commits to the message and to the compact index the Inbox assigned it, so recomputing it from the + // sent contents pins both, and the chain recomputed from these leaves is anchored to the message stream. + bytes32 expectedLeaf = Hash.sha256ToField( + DataStructures.L1ToL2Msg({ + sender: DataStructures.L1Actor(address(this), block.chainid), + recipient: recipient, + content: content, + secretHash: secretHash, + index: index + }) + ); + assertEq(insertedIndex, index, "compact message index"); + assertEq(leaf, expectedLeaf, "message leaf"); + + leaves.push(leaf); + } + + // Re-derives every bucket in the ring from the recorded leaves and per-L1-block batches. + function _assertBucketRing() internal { + uint256 current = inbox.getCurrentBucketSeq(); + bytes32 rollingHash = 0; + uint256 counted = 0; + uint256 previousTimestamp = 0; + + for (uint256 seq = 1; seq <= current; seq++) { + IInbox.InboxBucket memory bucket = inbox.getBucket(seq); + assertGt(bucket.msgCount, 0, "bucket holds at least one message"); + assertLe(bucket.msgCount, cap, "per-bucket cap"); + + for (uint256 i = 0; i < bucket.msgCount; i++) { + rollingHash = Hash.accumulateInboxRollingHash(rollingHash, leaves[counted + i]); + } + counted += bucket.msgCount; + + assertEq(bucket.rollingHash, rollingHash, "bucket rolling hash recomputed from the message leaves"); + assertEq(bucket.totalMsgCount, counted, "cumulative total is the sum of the per-bucket counts"); + assertGe(bucket.timestamp, previousTimestamp, "bucket timestamps never go backwards"); + previousTimestamp = bucket.timestamp; + } + + assertEq(counted, leaves.length, "every message sent is in a bucket"); + assertEq(inbox.getTotalMessagesInserted(), leaves.length, "inbox total matches messages sent"); + + // Bucket boundaries align with L1 blocks: each block owns a contiguous run of buckets holding exactly the + // messages it sent, all stamped with its own timestamp, so no later block extended an earlier block's bucket. + uint256 expectedFirstSeq = 1; + for (uint256 b = 0; b < batches.length; b++) { + BlockBatch memory batch = batches[b]; + assertEq(batch.firstSeq, expectedFirstSeq, "L1 block's buckets follow the previous block's"); + + uint256 batchCount = 0; + for (uint256 seq = batch.firstSeq; seq <= batch.lastSeq; seq++) { + IInbox.InboxBucket memory bucket = inbox.getBucket(seq); + assertEq(bucket.timestamp, batch.timestamp, "bucket timestamp is its L1 block's"); + batchCount += bucket.msgCount; + } + + assertEq(batchCount, batch.msgCount, "L1 block's messages are all in that block's buckets"); + expectedFirstSeq = batch.lastSeq + 1; + } + assertEq(expectedFirstSeq - 1, current, "no buckets outside the recorded L1 blocks"); + } + + function _assertBucketEq(IInbox.InboxBucket memory _actual, IInbox.InboxBucket memory _expected, string memory _err) + internal + { + assertEq(_actual.rollingHash, _expected.rollingHash, _err); + assertEq(_actual.totalMsgCount, _expected.totalMsgCount, _err); + assertEq(_actual.timestamp, _expected.timestamp, _err); + assertEq(_actual.msgCount, _expected.msgCount, _err); + } + + // Fuzz-derived field element, distinct per message and per message field. + function _field(uint256 _seed, uint256 _index, uint256 _tag) internal pure returns (bytes32) { + return bytes32(uint256(keccak256(abi.encodePacked(_seed, _index, _tag))) % Constants.P); + } +} diff --git a/l1-contracts/test/Parity.t.sol b/l1-contracts/test/Parity.t.sol deleted file mode 100644 index 8ed33bf99e75..000000000000 --- a/l1-contracts/test/Parity.t.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.27; - -import {Test} from "forge-std/Test.sol"; - -import {FrontierMerkle} from "./harnesses/Frontier.sol"; -import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; - -contract ParityTest is Test { - function setUp() public {} - - // Checks whether sha root matches output of base parity circuit - function testRootMatchesBaseParity() public { - uint248[256] memory msgs; - for (uint248 i = 0; i < msgs.length; i++) { - msgs[i] = i; - } - - // We can't use Constants.NUM_MSGS_PER_BASE_PARITY directly when defining the array so we do the check here to - // ensure it does not get outdated. - assertEq(msgs.length, Constants.NUM_MSGS_PER_BASE_PARITY, "NUM_MSGS_PER_BASE_PARITY changed, update msgs."); - - uint256 treeHeight = 8; // log_2(NUM_MSGS_PER_BASE_PARITY) - // We don't have log_2 directly accessible in solidity so I just do the following check here to ensure - // the hardcoded value is not outdated. - assertEq( - 2 ** treeHeight, - Constants.NUM_MSGS_PER_BASE_PARITY, - "Base parity circuit subtree height changed, update treeHeight." - ); - - FrontierMerkle frontier = new FrontierMerkle(treeHeight); - - for (uint256 i = 0; i < msgs.length; i++) { - frontier.insertLeaf(bytes32(bytes.concat(new bytes(1), bytes31(msgs[i])))); - } - // matches noir-protocol-circuits/crates/parity-lib/src/tests/parity_base_tests.nr - bytes32 expectedRoot = 0x00279d4d4dd5bcb9b1a4e742640588b917102f9f8bc97a6c95706ca4e7a8a76b; - assertEq(frontier.root(), expectedRoot, "Root does not match base parity circuit root"); - } - - // Checks whether sha root matches output of root parity circuit - function testRootMatchesRootParity() public { - // sha256 roots coming out of base parity circuits - // matches noir-protocol-circuits/crates/parity-lib/src/root/root_parity_inputs.nr - uint248[4] memory baseRoots = [ - 0xb3a3fc1968999f2c2d798b900bdf0de41311be2a4d20496a7e792a521fc8ab, - 0x43f78e0ebc9633ce336a8c086064d898c32fb5d7d6011f5427459c0b8d14e9, - 0x024259b6404280addcc9319bc5a32c9a5d56af5c93b2f941fa326064fbe963, - 0x53042d820859d80c474d4694e03778f8dc0ac88fc1c3a97b4369c1096e904a - ]; - - // We can't use Constants.NUM_BASE_PARITY_PER_ROOT_PARITY directly when defining the array so we do the check here - // to ensure it does not get outdated. - assertEq( - baseRoots.length, - Constants.NUM_BASE_PARITY_PER_ROOT_PARITY, - "NUM_BASE_PARITY_PER_ROOT_PARITY changed, update baseRoots." - ); - - uint256 treeHeight = 2; // log_2(NUM_BASE_PARITY_PER_ROOT_PARITY) - // We don't have log_2 directly accessible in solidity so I just do the following check here to ensure - // the hardcoded value is not outdated. - assertEq( - 2 ** treeHeight, - Constants.NUM_BASE_PARITY_PER_ROOT_PARITY, - "Root parity circuit subtree height changed, update treeHeight." - ); - - FrontierMerkle frontier = new FrontierMerkle(treeHeight); - - for (uint256 i = 0; i < baseRoots.length; i++) { - frontier.insertLeaf(bytes32(bytes.concat(new bytes(1), bytes31(baseRoots[i])))); - } - - bytes32 expectedRoot = 0x00a0c56543aa73140e5ca27231eee3107bd4e11d62164feb411d77c9d9b2da47; - assertEq(frontier.root(), expectedRoot, "Root does not match root parity circuit root"); - } -} diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index dafbe7b9a5d3..685ee2124b95 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -12,7 +12,7 @@ import {Registry} from "@aztec/governance/Registry.sol"; import {Inbox} from "@aztec/core/messagebridge/Inbox.sol"; import {Outbox} from "@aztec/core/messagebridge/Outbox.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; -import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; +import {ProposedHeader, ProposedHeaderLib} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol"; import { IRollupCore, @@ -171,16 +171,6 @@ contract RollupTest is RollupBase { function testPrune() public setUpFor("mixed_checkpoint_1") { _proposeCheckpoint("mixed_checkpoint_1", 1); - assertEq( - inbox.getInProgress(), - Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG + 1, - "Invalid in progress" - ); - - // @note Fetch the inbox root of checkpoint 2. This should be frozen when checkpoint 1 is proposed. - // Even if we end up reverting checkpoint 1, we should still see the same root in the inbox. - bytes32 inboxRoot2 = inbox.getRoot(2); - CheckpointLog memory checkpoint = rollup.getCheckpoint(1); Slot prunableAt = checkpoint.slotNumber + Epoch.wrap(2).toSlots(); @@ -191,11 +181,6 @@ contract RollupTest is RollupBase { assertEq(rollup.getProvenCheckpointNumber(), 0, "Invalid proven checkpoint number"); rollup.prune(); - assertEq( - inbox.getInProgress(), - Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG + 1, - "Invalid in progress" - ); assertEq(rollup.getPendingCheckpointNumber(), 0, "Invalid pending checkpoint number"); assertEq(rollup.getProvenCheckpointNumber(), 0, "Invalid proven checkpoint number"); @@ -207,12 +192,6 @@ contract RollupTest is RollupBase { // @note We prune the pending chain as part of the propose call. _proposeCheckpoint("empty_checkpoint_1", Slot.unwrap(prunableAt)); - assertEq( - inbox.getInProgress(), - Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG + 1, - "Invalid in progress" - ); - assertEq(inbox.getRoot(2), inboxRoot2, "Invalid inbox root"); assertEq(rollup.getPendingCheckpointNumber(), 1, "Invalid pending checkpoint number"); assertEq(rollup.getProvenCheckpointNumber(), 0, "Invalid proven checkpoint number"); } @@ -237,7 +216,8 @@ contract RollupTest is RollupBase { bytes32[] memory blobHashes = new bytes32[](1); blobHashes[0] = bytes32(uint256(1)); vm.blobhashes(blobHashes); - ProposeArgs memory args = ProposeArgs({header: data.header, archive: data.archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: data.header, archive: data.archive, oracleInput: OracleInput(0), bucketHint: 0}); bytes32 realBlobHash = this.getBlobHashes(data.blobCommitments)[0]; vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidBlobHash.selector, blobHashes[0], realBlobHash)); rollup.propose( @@ -326,7 +306,8 @@ contract RollupTest is RollupBase { skipBlobCheck(address(rollup)); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__NonZeroDaFee.selector)); - ProposeArgs memory args = ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -353,7 +334,8 @@ contract RollupTest is RollupBase { // When not canonical, we expect the fee to be 0 vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidManaMinFee.selector, expectedFee, 1)); - ProposeArgs memory args = ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -461,8 +443,12 @@ contract RollupTest is RollupBase { interim.feeAmount = interim.manaUsed * interim.minFee + interim.portalBalance; header.accumulatedFees = interim.feeAmount; + // Streaming Inbox: nothing is seeded here, so reference the genesis bucket (hash 0). + header.inboxRollingHash = bytes32(0); + // Assert that balance have NOT been increased by proposing the checkpoint - ProposeArgs memory args = ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: data.archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -668,7 +654,8 @@ contract RollupTest is RollupBase { skipBlobCheck(address(rollup)); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidTimestamp.selector, realTs, badTs)); - ProposeArgs memory args = ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -694,7 +681,8 @@ contract RollupTest is RollupBase { vm.blobhashes(blobHashes); skipBlobCheck(address(rollup)); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidCoinbase.selector)); - ProposeArgs memory args = ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -770,7 +758,8 @@ contract RollupTest is RollupBase { header.gasFees.feePerL2Gas = uint128(rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true)); vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__NoBlobsInCheckpoint.selector)); - ProposeArgs memory args = ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = + ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, AttestationLibHelper.packAttestations(attestations), @@ -874,6 +863,107 @@ contract RollupTest is RollupBase { assertEq(outbox.getRootData(Epoch.wrap(0), 2), outHash2, "Root at K=2 should be outHash2"); } + // getEpochProofPublicInputs is the view that the prover-publisher calls off-chain to validate its inputs before + // submitting. Because the fee recipient/value public inputs are taken from the supplied headers, the header check + // must run here too - not only on the submit path - so a mismatch is caught before publishing rather than reverting + // on-chain. + function testGetEpochProofPublicInputsVerifiesHeaders() public setUpFor("empty_checkpoint_1") { + _proposeCheckpoint("empty_checkpoint_1", 1); + + DecoderBase.Data memory data = load("empty_checkpoint_1").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + PublicInputArgs memory args = PublicInputArgs({ + previousArchive: checkpoint.archive, + endArchive: data.archive, + outHash: data.header.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: proposedHeaders[1].inboxRollingHash, + proverId: address(0) + }); + + ProposedHeader[] memory headers = new ProposedHeader[](1); + headers[0] = proposedHeaders[1]; + + // With the canonical header, the getter assembles the public inputs, sourcing the fee recipient/value from the + // header. + bytes32[] memory publicInputs = rollup.getEpochProofPublicInputs(1, 1, args, headers, data.batchedBlobInputs); + assertEq(publicInputs.length, Constants.ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH, "Unexpected public inputs length"); + + uint256 feesOffset = 5 + Constants.MAX_CHECKPOINTS_PER_EPOCH; + assertEq( + publicInputs[feesOffset], bytes32(uint256(uint160(headers[0].coinbase))), "Coinbase not sourced from header" + ); + assertEq( + publicInputs[feesOffset + 1], bytes32(headers[0].accumulatedFees), "Accumulated fees not sourced from header" + ); + + // Tamper a fee field so the header no longer hashes to the stored value; the getter must reject it. + bytes32 expectedHeaderHash = ProposedHeaderLib.hash(headers[0]); + headers[0].accumulatedFees += 1; + bytes32 providedHeaderHash = ProposedHeaderLib.hash(headers[0]); + + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InvalidCheckpointHeader.selector, expectedHeaderHash, providedHeaderHash) + ); + rollup.getEpochProofPublicInputs(1, 1, args, headers, data.batchedBlobInputs); + } + + // The epoch-proof anchoring pins the rolling-hash chain start to the record written at propose for checkpoint + // start - 1, mirroring previousArchive. A wrong previousInboxRollingHash must be rejected. + function testGetEpochProofPublicInputsRejectsWrongPreviousInboxRollingHash() public setUpFor("empty_checkpoint_1") { + _proposeCheckpoint("empty_checkpoint_1", 1); + + DecoderBase.Data memory data = load("empty_checkpoint_1").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + ProposedHeader[] memory headers = new ProposedHeader[](1); + headers[0] = proposedHeaders[1]; + + // Checkpoint 0 is genesis with a zero rolling hash, so any non-zero chain start is wrong. + bytes32 wrongPrevious = bytes32(uint256(1)); + PublicInputArgs memory args = PublicInputArgs({ + previousArchive: checkpoint.archive, + endArchive: data.archive, + outHash: data.header.outHash, + previousInboxRollingHash: wrongPrevious, + endInboxRollingHash: proposedHeaders[1].inboxRollingHash, + proverId: address(0) + }); + + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InvalidPreviousInboxRollingHash.selector, bytes32(0), wrongPrevious) + ); + rollup.getEpochProofPublicInputs(1, 1, args, headers, data.batchedBlobInputs); + } + + // The end of the rolling-hash chain segment is pinned to the hash recorded at propose for the epoch's last + // checkpoint, mirroring endArchive. A wrong endInboxRollingHash must be rejected here rather + // than surfacing as a generic proof-verification failure. + function testGetEpochProofPublicInputsRejectsWrongEndInboxRollingHash() public setUpFor("empty_checkpoint_1") { + _proposeCheckpoint("empty_checkpoint_1", 1); + + DecoderBase.Data memory data = load("empty_checkpoint_1").checkpoint; + CheckpointLog memory checkpoint = rollup.getCheckpoint(0); + + ProposedHeader[] memory headers = new ProposedHeader[](1); + headers[0] = proposedHeaders[1]; + + bytes32 expectedEnd = proposedHeaders[1].inboxRollingHash; + bytes32 wrongEnd = bytes32(uint256(expectedEnd) + 1); + PublicInputArgs memory args = PublicInputArgs({ + previousArchive: checkpoint.archive, + endArchive: data.archive, + outHash: data.header.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: wrongEnd, + proverId: address(0) + }); + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidEndInboxRollingHash.selector, expectedEnd, wrongEnd)); + rollup.getEpochProofPublicInputs(1, 1, args, headers, data.batchedBlobInputs); + } + function _submitEpochProof( uint256 _start, uint256 _end, @@ -895,7 +985,12 @@ contract RollupTest is RollupBase { address _prover ) internal { PublicInputArgs memory args = PublicInputArgs({ - previousArchive: _prevArchive, endArchive: _archive, outHash: _outHash, proverId: _prover + previousArchive: _prevArchive, + endArchive: _archive, + outHash: _outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: proposedHeaders[_end].inboxRollingHash, + proverId: _prover }); uint256 size = _end - _start + 1; diff --git a/l1-contracts/test/RollupFieldRange.t.sol b/l1-contracts/test/RollupFieldRange.t.sol index d10c187e9f75..a3d05d087ddd 100644 --- a/l1-contracts/test/RollupFieldRange.t.sol +++ b/l1-contracts/test/RollupFieldRange.t.sol @@ -164,7 +164,6 @@ contract RollupFieldRangeTest is RollupBase { vm.warp(max(block.timestamp, Timestamp.unwrap(ts))); _populateInbox(full.populate.sender, full.populate.recipient, full.populate.l1ToL2Content); - header.inHash = rollup.getInbox().getRoot(full.checkpoint.checkpointNumber); header.gasFees.feePerL2Gas = SafeCast.toUint128(rollup.getManaMinFeeAt(ts, true)); // Every field the range check guards, set to the maximal in-range value. @@ -175,7 +174,11 @@ contract RollupFieldRangeTest is RollupBase { vm.blobhashes(this.getBlobHashes(full.checkpoint.blobCommitments)); - ProposeArgs memory args = ProposeArgs({header: header, archive: bytes32(FIELD_MAX), oracleInput: OracleInput(0)}); + // Streaming Inbox: nothing is seeded here, so reference the genesis bucket (hash 0). + header.inboxRollingHash = bytes32(0); + + ProposeArgs memory args = + ProposeArgs({header: header, archive: bytes32(FIELD_MAX), oracleInput: OracleInput(0), bucketHint: 0}); rollup.propose( args, @@ -202,7 +205,8 @@ contract RollupFieldRangeTest is RollupBase { skipBlobCheck(address(rollup)); bytes32 archive = _useFixtureArchive ? full.checkpoint.archive : bytes32(_archive); - return ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0)}); + // Boundary tests revert on a field-range check before Inbox consumption; the genesis bucket hint suffices. + return ProposeArgs({header: header, archive: archive, oracleInput: OracleInput(0), bucketHint: 0}); } function _expectFieldOutOfRange(ProposeArgs memory _args, bytes32 _value) internal { diff --git a/l1-contracts/test/base/DecoderBase.sol b/l1-contracts/test/base/DecoderBase.sol index 24e74617950d..21f1431d7978 100644 --- a/l1-contracts/test/base/DecoderBase.sol +++ b/l1-contracts/test/base/DecoderBase.sol @@ -46,7 +46,7 @@ contract DecoderBase is TestBase { address coinbase; bytes32 feeRecipient; GasFees gasFees; - bytes32 inHash; + bytes32 inboxRollingHash; bytes32 lastArchiveRoot; bytes32 outHash; uint256 slotNumber; @@ -103,7 +103,7 @@ contract DecoderBase is TestBase { lastArchiveRoot: full.checkpoint.header.lastArchiveRoot, blockHeadersHash: full.checkpoint.header.blockHeadersHash, blobsHash: full.checkpoint.header.blobsHash, - inHash: full.checkpoint.header.inHash, + inboxRollingHash: full.checkpoint.header.inboxRollingHash, outHash: full.checkpoint.header.outHash, slotNumber: Slot.wrap(full.checkpoint.header.slotNumber), timestamp: Timestamp.wrap(full.checkpoint.header.timestamp), diff --git a/l1-contracts/test/base/RollupBase.sol b/l1-contracts/test/base/RollupBase.sol index 78829b61135d..cdf6ee4014a2 100644 --- a/l1-contracts/test/base/RollupBase.sol +++ b/l1-contracts/test/base/RollupBase.sol @@ -78,6 +78,10 @@ contract RollupBase is DecoderBase { previousArchive: parentCheckpointLog.archive, endArchive: endFull.checkpoint.archive, outHash: endFull.checkpoint.header.outHash, + // Anchor the rolling-hash chain start to the record written at propose for checkpoint start - 1. + // The end value is unchecked on L1 but supplied for completeness. + previousInboxRollingHash: proposedHeaders[startCheckpointNumber - 1].inboxRollingHash, + endInboxRollingHash: proposedHeaders[endCheckpointNumber].inboxRollingHash, proverId: _prover }); @@ -161,11 +165,16 @@ contract RollupBase is DecoderBase { checkpointFees[full.checkpoint.checkpointNumber] = _manaUsed * minFee; - // We jump to the time of the block. (unless it is in the past) - vm.warp(max(block.timestamp, Timestamp.unwrap(full.checkpoint.header.timestamp))); - + // Seed the Inbox before jumping to the checkpoint's L1 block: propose rejects a bucket that is still + // accumulating, and a bucket keeps accumulating for the whole L1 block that opened it. _populateInbox(full.populate.sender, full.populate.recipient, full.populate.l1ToL2Content); - full.checkpoint.header.inHash = rollup.getInbox().getRoot(full.checkpoint.checkpointNumber); + + // We jump to the time of the block, always past the L1 block the messages above landed in. + vm.warp(max(block.timestamp + 1, Timestamp.unwrap(full.checkpoint.header.timestamp))); + // Streaming Inbox: reference the newest bucket so the checkpoint consumes all messages + // seeded above and the mandatory-consumption assert is trivially satisfied (a wrong ref could only revert). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + full.checkpoint.header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; { bytes32[] memory blobHashes; @@ -195,8 +204,12 @@ contract RollupBase is DecoderBase { proposedHeaders[full.checkpoint.checkpointNumber] = full.checkpoint.header; - ProposeArgs memory args = - ProposeArgs({header: full.checkpoint.header, archive: full.checkpoint.archive, oracleInput: OracleInput(0)}); + ProposeArgs memory args = ProposeArgs({ + header: full.checkpoint.header, + archive: full.checkpoint.archive, + oracleInput: OracleInput(0), + bucketHint: bucketHint + }); if (_revertMsg.length > 0) { vm.expectRevert(_revertMsg); diff --git a/l1-contracts/test/benchmark/happy.t.sol b/l1-contracts/test/benchmark/happy.t.sol index e558b9b6f2f2..7cbf18d9f0da 100644 --- a/l1-contracts/test/benchmark/happy.t.sol +++ b/l1-contracts/test/benchmark/happy.t.sol @@ -274,10 +274,15 @@ contract BenchmarkRollupTest is FeeModelTestPoints, DecoderBase { header.totalManaUsed = manaSpent; header.accumulatedFees = uint256(manaMinFee) * manaSpent; + // Streaming Inbox: reference the newest bucket (nothing seeded here, so the genesis bucket). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + ProposeArgs memory proposeArgs = ProposeArgs({ header: header, archive: archiveRoot, - oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}), + bucketHint: bucketHint }); CommitteeAttestation[] memory attestations; @@ -511,6 +516,8 @@ contract BenchmarkRollupTest is FeeModelTestPoints, DecoderBase { previousArchive: rollup.getCheckpoint(start).archive, endArchive: endCheckpoint.archive, outHash: endCheckpoint.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: address(0) }); diff --git a/l1-contracts/test/builder/RollupBuilder.sol b/l1-contracts/test/builder/RollupBuilder.sol index 6d01ae12d3bc..e32fa8f97f58 100644 --- a/l1-contracts/test/builder/RollupBuilder.sol +++ b/l1-contracts/test/builder/RollupBuilder.sol @@ -164,11 +164,6 @@ contract RollupBuilder is Test { return this; } - function setInboxLag(uint256 _inboxLag) public returns (RollupBuilder) { - config.rollupConfigInput.inboxLag = _inboxLag; - return this; - } - function setSlotDuration(uint256 _slotDuration) public returns (RollupBuilder) { config.rollupConfigInput.aztecSlotDuration = _slotDuration; return this; diff --git a/l1-contracts/test/compression/PreHeating.t.sol b/l1-contracts/test/compression/PreHeating.t.sol index e3b891e195b2..7bce6f907c2f 100644 --- a/l1-contracts/test/compression/PreHeating.t.sol +++ b/l1-contracts/test/compression/PreHeating.t.sol @@ -263,6 +263,8 @@ contract PreHeatingTest is FeeModelTestPoints, DecoderBase { previousArchive: rollup.getCheckpoint(start).archive, endArchive: endCheckpoint.archive, outHash: endCheckpoint.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: address(0) }); @@ -325,10 +327,15 @@ contract PreHeatingTest is FeeModelTestPoints, DecoderBase { header.totalManaUsed = manaSpent; header.accumulatedFees = uint256(manaMinFee) * manaSpent; + // Streaming Inbox: reference the newest bucket (nothing seeded here, so the genesis bucket). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + ProposeArgs memory proposeArgs = ProposeArgs({ header: header, archive: archiveRoot, - oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}), + bucketHint: bucketHint }); CommitteeAttestation[] memory attestations; diff --git a/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol b/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol index 61f679d78805..ea22ac757e75 100644 --- a/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol +++ b/l1-contracts/test/escape-hatch/integration/EscapeHatchIntegrationBase.sol @@ -130,18 +130,18 @@ abstract contract EscapeHatchIntegrationBase is ValidatorSelectionTestBase { * @dev Uses: * - archive: GENESIS_ARCHIVE_ROOT * - oracleInput: zero - * - header fields from fixture for blockHeadersHash/blobsHash/inHash/outHash, rest overridden + * - header fields from fixture for blockHeadersHash/blobsHash/outHash, rest overridden */ function _buildProposeArgs(address _proposer) internal view returns (ProposeArgs memory args, bytes memory blobs) { bytes32 archive = bytes32(Constants.GENESIS_ARCHIVE_ROOT); Slot slotNumber = rollup.getCurrentSlot(); - // Build header fresh, only copying blockHeadersHash/blobsHash/inHash/outHash from fixture + // Build header fresh, only copying blockHeadersHash/blobsHash/outHash from fixture ProposedHeader memory header = ProposedHeader({ lastArchiveRoot: archive, blockHeadersHash: full.checkpoint.header.blockHeadersHash, blobsHash: full.checkpoint.header.blobsHash, - inHash: full.checkpoint.header.inHash, + inboxRollingHash: full.checkpoint.header.inboxRollingHash, outHash: full.checkpoint.header.outHash, slotNumber: slotNumber, timestamp: rollup.getTimestampForSlot(slotNumber), @@ -154,7 +154,13 @@ abstract contract EscapeHatchIntegrationBase is ValidatorSelectionTestBase { accumulatedFees: 0 }); - args = ProposeArgs({header: header, archive: archive, oracleInput: OracleInput({feeAssetPriceModifier: 0})}); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + + args = ProposeArgs({ + header: header, archive: archive, oracleInput: OracleInput({feeAssetPriceModifier: 0}), bucketHint: bucketHint + }); blobs = full.checkpoint.blobCommitments; } @@ -204,8 +210,13 @@ abstract contract EscapeHatchIntegrationBase is ValidatorSelectionTestBase { header.gasFees.feePerL2Gas = manaMinFee; } - ProposeArgs memory proposeArgs = - ProposeArgs({header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0)}); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + + ProposeArgs memory proposeArgs = ProposeArgs({ + header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0), bucketHint: bucketHint + }); skipBlobCheck(address(rollup)); @@ -324,6 +335,8 @@ abstract contract EscapeHatchIntegrationBase is ValidatorSelectionTestBase { previousArchive: previousArchive, endArchive: endArchive, outHash: endFull.checkpoint.header.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: _prover }); diff --git a/l1-contracts/test/escape-hatch/integration/invalidate.t.sol b/l1-contracts/test/escape-hatch/integration/invalidate.t.sol index f4709a59eabf..de6808f2a11e 100644 --- a/l1-contracts/test/escape-hatch/integration/invalidate.t.sol +++ b/l1-contracts/test/escape-hatch/integration/invalidate.t.sol @@ -139,8 +139,13 @@ contract invalidateTest is EscapeHatchIntegrationBase { header.gasFees.feePerL2Gas = manaMinFee; } - ProposeArgs memory proposeArgs = - ProposeArgs({header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0)}); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + + ProposeArgs memory proposeArgs = ProposeArgs({ + header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0), bucketHint: bucketHint + }); skipBlobCheck(address(rollup)); diff --git a/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol b/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol index 72b48358d16a..5baa9903924d 100644 --- a/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol +++ b/l1-contracts/test/escape-hatch/integration/regression/OutHashValidationSkipped.t.sol @@ -60,6 +60,8 @@ contract OutHashValidationSkippedTest is EscapeHatchIntegrationBase { previousArchive: rollup.archiveAt(0), endArchive: rollup.archiveAt(1), outHash: wrongOutHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: address(this) }); diff --git a/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol b/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol index 4e57aef3f5f6..6e46a60fad48 100644 --- a/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol +++ b/l1-contracts/test/escape-hatch/integration/submitEpochRootProof.t.sol @@ -112,7 +112,12 @@ contract submitEpochRootProofTest is EscapeHatchIntegrationBase { bytes32 outHash = rollup.getCheckpoint(1).outHash; PublicInputArgs memory args = PublicInputArgs({ - previousArchive: previousArchive, endArchive: endArchive, outHash: outHash, proverId: address(this) + previousArchive: previousArchive, + endArchive: endArchive, + outHash: outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, + proverId: address(this) }); ProposedHeader[] memory headers = new ProposedHeader[](1); diff --git a/l1-contracts/test/fee_portal/depositToAztecPublic.t.sol b/l1-contracts/test/fee_portal/depositToAztecPublic.t.sol index 0a4b0c99374d..0c17e677d395 100644 --- a/l1-contracts/test/fee_portal/depositToAztecPublic.t.sol +++ b/l1-contracts/test/fee_portal/depositToAztecPublic.t.sol @@ -9,8 +9,6 @@ import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol"; import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {IERC20Errors} from "@oz/interfaces/draft-IERC6093.sol"; import {Rollup} from "@aztec/core/Rollup.sol"; -import {IRollup} from "@aztec/core/interfaces/IRollup.sol"; -import {TestConstants} from "../harnesses/TestConstants.sol"; import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; @@ -30,23 +28,6 @@ contract DepositToAztecPublic is Test { address internal constant MAGIC_FEE_JUICE_ADDRESS = address(uint160(Constants.FEE_JUICE_ADDRESS)); - struct InboxLagTestState { - Rollup testRollup; - FeeJuicePortal testFeeJuicePortal; - TestERC20 testToken; - Inbox testInbox; - uint256 lag; - uint256 SIZE; - uint256 initialInProgress; - bytes32 to; - bytes32 secretHash1; - bytes32 secretHash2; - uint256 amount; - uint256 expectedIndex1; - uint256 expectedIndex2; - uint256 expectedInProgress; - } - function setUp() public { RollupBuilder builder = new RollupBuilder(address(this)); builder.deploy(); @@ -82,12 +63,8 @@ contract DepositToAztecPublic is Test { uint256 amount = 100 ether; Inbox inbox = Inbox(address(Rollup(address(registry.getCanonicalRollup())).getInbox())); - // The first message goes into tree (INITIAL_CHECKPOINT_NUMBER + LAG) at index 0 - // Global index = (inProgress - INITIAL_CHECKPOINT_NUMBER) * SIZE + 0 - // = ((INITIAL_CHECKPOINT_NUMBER + LAG) - INITIAL_CHECKPOINT_NUMBER) * SIZE - // = LAG * SIZE - uint256 SIZE = 2 ** Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT; - uint256 expectedIndex = TestConstants.AZTEC_INBOX_LAG * SIZE; + // Compact cumulative index: the first message against a fresh Inbox has index 0. + uint256 expectedIndex = 0; // The purpose of including the function selector is to make the message unique to that specific call. Note that // it has nothing to do with calling the function. @@ -109,10 +86,9 @@ contract DepositToAztecPublic is Test { assertEq(inbox.getTotalMessagesInserted(), 0); - bytes16 expectedHash = bytes16(keccak256(abi.encodePacked(inbox.getState().rollingHash, expectedKey))); - uint256 expectedInProgress = Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG; + bytes32 expectedInboxRollingHash = Hash.accumulateInboxRollingHash(bytes32(0), expectedKey); vm.expectEmit(true, true, true, true, address(inbox)); - emit IInbox.MessageSent(expectedInProgress, expectedIndex, expectedKey, expectedHash); + emit IInbox.MessageSent(expectedIndex, expectedKey, expectedInboxRollingHash, 1); vm.expectEmit(true, true, true, true, address(feeJuicePortal)); emit IFeeJuicePortal.DepositToAztecPublic(to, amount, secretHash, expectedKey, expectedIndex); @@ -122,110 +98,4 @@ contract DepositToAztecPublic is Test { assertEq(key, expectedKey); assertEq(index, expectedIndex); } - - function testFuzz_InboxLag(uint256 _lag) external { - // Bound lag to reasonable values (1-10) to test different lag configurations - uint256 lag = bound(_lag, 1, 10); - - RollupBuilder builder = new RollupBuilder(address(this)); - builder.setInboxLag(lag); - builder.deploy(); - - InboxLagTestState memory state = InboxLagTestState({ - testRollup: builder.getConfig().rollup, - testFeeJuicePortal: FeeJuicePortal(address(builder.getConfig().rollup.getFeeAssetPortal())), - testToken: builder.getConfig().testERC20, - testInbox: Inbox(address(builder.getConfig().rollup.getInbox())), - lag: lag, - SIZE: 2 ** Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT, - initialInProgress: 0, // Will be set below - to: bytes32(0x0), - secretHash1: bytes32(uint256(0x01)), - secretHash2: bytes32(uint256(0x02)), - amount: 100 ether, - expectedIndex1: 0, // Will be set below - expectedIndex2: 0, // Will be set below - expectedInProgress: Constants.INITIAL_CHECKPOINT_NUMBER + lag - }); - - // Verify initial state: inProgress should be INITIAL_CHECKPOINT_NUMBER + lag - assertEq( - state.testInbox.getInProgress(), - state.expectedInProgress, - "Initial inProgress should be INITIAL_CHECKPOINT_NUMBER + lag" - ); - state.initialInProgress = state.testInbox.getInProgress(); - state.expectedIndex1 = state.lag * state.SIZE; - state.expectedIndex2 = state.lag * state.SIZE + 1; - - vm.prank(state.testToken.owner()); - state.testToken.mint(address(this), state.amount * 2); - state.testToken.approve(address(state.testFeeJuicePortal), state.amount * 2); - - // Send first message - (, uint256 index1) = state.testFeeJuicePortal.depositToAztecPublic(state.to, state.amount, state.secretHash1); - assertEq(index1, state.expectedIndex1, "First message index should be lag * SIZE"); - assertEq( - state.testInbox.getInProgress(), - state.expectedInProgress, - "inProgress should not change after sending first message" - ); - assertEq(state.testInbox.getTotalMessagesInserted(), 1, "Should have 1 message after first deposit"); - - // Send second message - (, uint256 index2) = state.testFeeJuicePortal.depositToAztecPublic(state.to, state.amount, state.secretHash2); - assertEq(index2, state.expectedIndex2, "Second message index should be lag * SIZE + 1"); - assertEq( - state.testInbox.getInProgress(), - state.expectedInProgress, - "inProgress should not change after sending second message" - ); - assertEq(state.testInbox.getTotalMessagesInserted(), 2, "Should have 2 messages after second deposit"); - - // Test consume logic: consume checkpoints to verify lag behavior - // Initially: inProgress = INITIAL_CHECKPOINT_NUMBER + lag - // When checkpoint N is consumed: - // - If N + lag == inProgress, then inProgress advances to inProgress + 1 - // - Otherwise, inProgress stays the same - - // Consume checkpoints starting from INITIAL_CHECKPOINT_NUMBER - // We need to consume them sequentially to test the lag behavior - for ( - uint256 checkpointNum = Constants.INITIAL_CHECKPOINT_NUMBER; - checkpointNum < state.initialInProgress; - checkpointNum++ - ) { - uint256 inProgressBefore = state.testInbox.getInProgress(); - - // Call consume as the rollup - vm.prank(address(state.testRollup)); - bytes32 root = state.testInbox.consume(checkpointNum); - - uint256 inProgressAfter = state.testInbox.getInProgress(); - bool shouldAdvance = (checkpointNum + state.lag == inProgressBefore); - - if (shouldAdvance) { - assertEq( - inProgressAfter, inProgressBefore + 1, "inProgress should advance when checkpointNum + lag == inProgress" - ); - } else { - assertEq( - inProgressAfter, inProgressBefore, "inProgress should not advance when checkpointNum + lag != inProgress" - ); - } - - // Verify root is correct for non-initial checkpoints - if (checkpointNum > Constants.INITIAL_CHECKPOINT_NUMBER) { - assertEq(root, state.testInbox.getRoot(checkpointNum), "Root should match getRoot for checkpoint"); - } - } - - // After consuming all checkpoints up to the lag point, inProgress should have advanced - uint256 finalInProgress = state.testInbox.getInProgress(); - assertEq( - finalInProgress, - state.initialInProgress + state.lag, - "Final inProgress should advance by lag after consuming all checkpoints" - ); - } } diff --git a/l1-contracts/test/fees/FeeHeaderOverflow.t.sol b/l1-contracts/test/fees/FeeHeaderOverflow.t.sol index ed8a7e208798..4d5057bc1112 100644 --- a/l1-contracts/test/fees/FeeHeaderOverflow.t.sol +++ b/l1-contracts/test/fees/FeeHeaderOverflow.t.sol @@ -98,11 +98,20 @@ contract FeeHeaderOverflowTest is DecoderBase { header.gasFees.feePerDaGas = 0; header.totalManaUsed = 0; + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = _rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = _rollup.getInbox().getBucket(bucketHint).rollingHash; + CommitteeAttestation[] memory attestations = new CommitteeAttestation[](0); address[] memory signers = new address[](0); return ( - ProposeArgs({header: header, archive: archiveRoot, oracleInput: OracleInput({feeAssetPriceModifier: 0})}), + ProposeArgs({ + header: header, + archive: archiveRoot, + oracleInput: OracleInput({feeAssetPriceModifier: 0}), + bucketHint: bucketHint + }), AttestationLibHelper.packAttestations(attestations), signers ); diff --git a/l1-contracts/test/fees/FeeRollup.t.sol b/l1-contracts/test/fees/FeeRollup.t.sol index e34b85ed6677..52219fd3e200 100644 --- a/l1-contracts/test/fees/FeeRollup.t.sol +++ b/l1-contracts/test/fees/FeeRollup.t.sol @@ -236,6 +236,8 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { previousArchive: rollup.getCheckpoint(_start).archive, endArchive: endCheckpoint.archive, outHash: endCheckpoint.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: address(0) }); @@ -267,13 +269,17 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { if (rollup.getCurrentSlot() == nextSlot) { TestPoint memory point = points[Slot.unwrap(nextSlot) - 1]; Checkpoint memory b = getCheckpoint(); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + b.header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; skipBlobCheck(address(rollup)); checkpointHeaders[rollup.getPendingCheckpointNumber() + 1] = b.header; rollup.propose( ProposeArgs({ header: b.header, archive: b.archive, - oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}), + bucketHint: bucketHint }), AttestationLibHelper.packAttestations(b.attestations), b.signers, @@ -359,13 +365,17 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { Checkpoint memory b = getCheckpoint(); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + b.header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; skipBlobCheck(address(rollup)); checkpointHeaders[rollup.getPendingCheckpointNumber() + 1] = b.header; rollup.propose( ProposeArgs({ header: b.header, archive: b.archive, - oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}) + oracleInput: OracleInput({feeAssetPriceModifier: point.oracle_input.fee_asset_price_modifier}), + bucketHint: bucketHint }), AttestationLibHelper.packAttestations(b.attestations), b.signers, diff --git a/l1-contracts/test/fees/MinimalFeeModel.sol b/l1-contracts/test/fees/MinimalFeeModel.sol index f37d6dd4fd7f..24d433406390 100644 --- a/l1-contracts/test/fees/MinimalFeeModel.sol +++ b/l1-contracts/test/fees/MinimalFeeModel.sol @@ -126,7 +126,10 @@ contract MinimalFeeModel { attestationsHash: bytes32(0), payloadDigest: bytes32(0), slotNumber: Slot.wrap(0), - feeHeader: FeeLib.computeFeeHeader(checkpointNumber, _oracleInput.feeAssetPriceModifier, _manaUsed, 0, 0) + feeHeader: FeeLib.computeFeeHeader(checkpointNumber, _oracleInput.feeAssetPriceModifier, _manaUsed, 0, 0), + inboxRollingHash: bytes32(0), + inboxMsgTotal: 0, + inboxConsumedBucket: 0 }) ); // FeeLib.writeFeeHeader(++populatedThrough, _oracleInput.feeAssetPriceModifier, _manaUsed, 0, 0); diff --git a/l1-contracts/test/fixtures/empty_checkpoint_1.json b/l1-contracts/test/fixtures/empty_checkpoint_1.json index a59c66145db8..eb94728b3ccd 100644 --- a/l1-contracts/test/fixtures/empty_checkpoint_1.json +++ b/l1-contracts/test/fixtures/empty_checkpoint_1.json @@ -34,7 +34,7 @@ "lastArchiveRoot": "0x177a4955b31ecaafad999753938a44e526b54c5ba5d536688227f85f15cfbdf5", "blockHeadersHash": "0x2e3e0911389bc48fa8126a93273d016cc7dc08019f8ffc5f1f5ae7d90745eaa2", "blobsHash": "0x00e5b752fe6bc2154155ff3a979c4c5fa91d3ac0d716169ac521e1560fd83b2b", - "inHash": "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223", + "inboxRollingHash": "0x00cad6497cf81748167158f149ba70c31f34c68b0ae1b156117de63e073d14b5", "outHash": "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093", "slotNumber": 99, "timestamp": 1776857814, @@ -47,7 +47,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x0069eb49ccf7b0dd2902a19712dd167fd3b5d890df7f0711fdcfe4d2987838ad", + "headerHash": "0x00230a553b85ec7931eded45ec1ea096e47789226758b16dca0403f5ab53f3d6", "numTxs": 0 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/fixtures/empty_checkpoint_2.json b/l1-contracts/test/fixtures/empty_checkpoint_2.json index 52323cc08975..5ee1a899f2f8 100644 --- a/l1-contracts/test/fixtures/empty_checkpoint_2.json +++ b/l1-contracts/test/fixtures/empty_checkpoint_2.json @@ -34,7 +34,7 @@ "lastArchiveRoot": "0x09d45c1e01b8596153838a068ddb470ead95e6e1e151f40b4d48664c1e311af6", "blockHeadersHash": "0x0b3bda1754ca30707b8c0bbe72760c68e574cf23309e7e4fd7cabea36b4078da", "blobsHash": "0x000e9acabf609c9c113078ecb383ba6310573ce246958b605452132617d2c960", - "inHash": "0x006504de282a40084bb8098456a915c645d53482d351db52fa9433b6cd638763", + "inboxRollingHash": "0x0080dbf2bd9576e81fd99fc0f9d35bfd7fc15a6221d0b6e1e92a1884f14d0c84", "outHash": "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093", "slotNumber": 102, "timestamp": 1776858030, @@ -47,7 +47,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x0004d4907090fd10f0c7fa759b7ce89c3b7055385423b585c5f7e959c17290ef", + "headerHash": "0x00a184a160ada9af4ba75961ba596043d76f56c75b2e7e9652a0c162a7bf59b9", "numTxs": 0 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/fixtures/mixed_checkpoint_1.json b/l1-contracts/test/fixtures/mixed_checkpoint_1.json index 6e47dc89c331..fda840d182d1 100644 --- a/l1-contracts/test/fixtures/mixed_checkpoint_1.json +++ b/l1-contracts/test/fixtures/mixed_checkpoint_1.json @@ -67,7 +67,7 @@ "lastArchiveRoot": "0x177a4955b31ecaafad999753938a44e526b54c5ba5d536688227f85f15cfbdf5", "blockHeadersHash": "0x087b6f59388fa4207876ee1b50521ff838d6eed422d0ad07ff996393f32a77e6", "blobsHash": "0x001bef3ff3f657c565ff86d5072186f7f2bfddb8a31ca0714562c164fe954d84", - "inHash": "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223", + "inboxRollingHash": "0x00cad6497cf81748167158f149ba70c31f34c68b0ae1b156117de63e073d14b5", "outHash": "0x00cffdbb0e7f5e164d314d781d38ae31230910a3bae4c34e7df6222df71b1539", "slotNumber": 99, "timestamp": 1776857848, @@ -80,7 +80,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x003ce6d2bb91ea8852841510f5485595dfbddbaa0420e083caf37f182be2140a", + "headerHash": "0x00f1c11fddfca8ff6073d1715c8b886d501facad96b7b032fb440462849697b8", "numTxs": 4 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/fixtures/mixed_checkpoint_2.json b/l1-contracts/test/fixtures/mixed_checkpoint_2.json index 577e335441eb..2fdaa2de220d 100644 --- a/l1-contracts/test/fixtures/mixed_checkpoint_2.json +++ b/l1-contracts/test/fixtures/mixed_checkpoint_2.json @@ -67,7 +67,7 @@ "lastArchiveRoot": "0x0c87f76b6c5cc918111d2acc975bf7f2133f5c3cc23c8cf6cc1c3e78f5c84a3e", "blockHeadersHash": "0x144dbe32a03df9ccc672207c93cd22099eb91e44a71e1676148cd3c6c6c98b9e", "blobsHash": "0x008bd0b669b942b57ccf85d3401214db65cde3608afa0b2ae0e57f35ec60d72e", - "inHash": "0x006504de282a40084bb8098456a915c645d53482d351db52fa9433b6cd638763", + "inboxRollingHash": "0x0080dbf2bd9576e81fd99fc0f9d35bfd7fc15a6221d0b6e1e92a1884f14d0c84", "outHash": "0x008a85da85a596471f2e5fe402fde332723da8d24b6e7affd60d16c7cb7e9020", "slotNumber": 102, "timestamp": 1776858064, @@ -80,7 +80,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x00eb0f37a51d2df835ea48d6cdde28398df86078d8507d467f34434dac062456", + "headerHash": "0x00e0c076d07c17d50e3aefe9ca264ba7a4894fab4956272bfbea600e9e34bb0f", "numTxs": 4 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/fixtures/single_tx_checkpoint_1.json b/l1-contracts/test/fixtures/single_tx_checkpoint_1.json index 83aa2756dd96..1969d1dfa7f7 100644 --- a/l1-contracts/test/fixtures/single_tx_checkpoint_1.json +++ b/l1-contracts/test/fixtures/single_tx_checkpoint_1.json @@ -43,7 +43,7 @@ "lastArchiveRoot": "0x177a4955b31ecaafad999753938a44e526b54c5ba5d536688227f85f15cfbdf5", "blockHeadersHash": "0x07db5c24565ad9a2c9d39ef7d9a4446e9742d6090567ff28aef9a45f4738a5cb", "blobsHash": "0x00ec2400a7cfc9d975cb0802980d49387588738160a0cf0301f07e1abad6456c", - "inHash": "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223", + "inboxRollingHash": "0x00cad6497cf81748167158f149ba70c31f34c68b0ae1b156117de63e073d14b5", "outHash": "0x007c92c6cf05665e1c02a305370a4d38bcb8b555261c6b39c862f8c067d6bcb7", "slotNumber": 99, "timestamp": 1776857833, @@ -56,7 +56,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x00628120df9716928e25a69ca7b1ac2497f22fdaab439f64315ad4daf7bc5191", + "headerHash": "0x0018784f81057f236b2da6a1e9bc20cb7c931343cbecb2035b605dc8ca5dd3cb", "numTxs": 1 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/fixtures/single_tx_checkpoint_2.json b/l1-contracts/test/fixtures/single_tx_checkpoint_2.json index b4b8e0a60a51..5487087aed88 100644 --- a/l1-contracts/test/fixtures/single_tx_checkpoint_2.json +++ b/l1-contracts/test/fixtures/single_tx_checkpoint_2.json @@ -43,7 +43,7 @@ "lastArchiveRoot": "0x0f198bb13b63a3a8791a8b9994167bbe1554811a106fda0acb5e6c6539b1713e", "blockHeadersHash": "0x12813725f2d16ce92088d2401ffa4a53ce6061bf75b77320ca7b8ef6c5145adf", "blobsHash": "0x002b8ae4c9f405529e2b689b829852ad52f77acdac57d1dbac3dabea1760affc", - "inHash": "0x006504de282a40084bb8098456a915c645d53482d351db52fa9433b6cd638763", + "inboxRollingHash": "0x0080dbf2bd9576e81fd99fc0f9d35bfd7fc15a6221d0b6e1e92a1884f14d0c84", "outHash": "0x0007eac1d76cddf92b28b8f11cd292f199f35dfc588376092986575cef487f59", "slotNumber": 102, "timestamp": 1776858049, @@ -56,7 +56,7 @@ "totalManaUsed": 0, "accumulatedFees": 0 }, - "headerHash": "0x00f2d5075ed8fdbb50bc0171790cb495308b229325c0aa3e1c3fadd5772d11f4", + "headerHash": "0x00782cfd7fa9f4e407c734be2832e8afb818d2ef8a0a11d288a3df34bcae0047", "numTxs": 1 } -} \ No newline at end of file +} diff --git a/l1-contracts/test/harnesses/Frontier.sol b/l1-contracts/test/harnesses/Frontier.sol deleted file mode 100644 index 719e5692c8b5..000000000000 --- a/l1-contracts/test/harnesses/Frontier.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.27; - -import {FrontierLib} from "@aztec/core/libraries/crypto/FrontierLib.sol"; - -import {Ownable} from "@oz/access/Ownable.sol"; - -// This truncates each hash and hash preimage to 31 bytes to follow Noir. -// It follows the logic in /noir-protocol-circuits/crates/parity-lib/src/utils/sha256_merkle_tree.nr -// TODO(Miranda): Possibly nuke this contract, and use a generic version which can either use -// regular sha256 or sha256ToField when emulating circuits -contract FrontierMerkle is Ownable { - using FrontierLib for FrontierLib.Tree; - using FrontierLib for FrontierLib.Forest; - - uint256 public immutable HEIGHT; - uint256 public immutable SIZE; - - // Practically immutable value as we only set it in the constructor. - FrontierLib.Forest internal forest; - - FrontierLib.Tree internal tree; - - constructor(uint256 _height) Ownable(msg.sender) { - HEIGHT = _height; - SIZE = 2 ** _height; - forest.initialize(_height); - } - - function insertLeaf(bytes32 _leaf) external onlyOwner returns (uint256) { - return tree.insertLeaf(_leaf); - } - - function root() external view returns (bytes32) { - return tree.root(forest, HEIGHT, SIZE); - } - - function isFull() external view returns (bool) { - return tree.isFull(SIZE); - } -} diff --git a/l1-contracts/test/harnesses/InboxHarness.sol b/l1-contracts/test/harnesses/InboxHarness.sol index 5257aa8a196b..983710628b48 100644 --- a/l1-contracts/test/harnesses/InboxHarness.sol +++ b/l1-contracts/test/harnesses/InboxHarness.sol @@ -4,44 +4,14 @@ pragma solidity >=0.8.27; import {Inbox} from "@aztec/core/messagebridge/Inbox.sol"; import {IERC20} from "@oz/token/ERC20/IERC20.sol"; -import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; -import {FrontierLib} from "@aztec/core/libraries/crypto/FrontierLib.sol"; contract InboxHarness is Inbox { - using FrontierLib for FrontierLib.Tree; - - constructor(address _rollup, IERC20 _feeAsset, uint256 _version, uint256 _height, uint256 _lag) - Inbox(_rollup, _feeAsset, _version, _height, _lag) + constructor(address _rollup, IERC20 _feeAsset, uint256 _version, uint256 _ringSize) + Inbox(_rollup, _feeAsset, _version, _ringSize) {} - function getSize() external view returns (uint256) { - return SIZE; - } - - function getEmptyRoot() external view returns (bytes32) { - return EMPTY_ROOT; - } - - function treeInProgressFull() external view returns (bool) { - return trees[state.inProgress].isFull(SIZE); - } - - function getToConsumeRoot(uint256 _toConsume) external view returns (bytes32) { - bytes32 root = EMPTY_ROOT; - if (_toConsume > Constants.INITIAL_CHECKPOINT_NUMBER) { - root = trees[_toConsume].root(forest, HEIGHT, SIZE); - } - return root; - } - - function getNumTrees() external view returns (uint256) { - // -INITIAL_CHECKPOINT_NUMBER because tree number INITIAL_CHECKPOINT_NUMBER is not real - return state.inProgress - Constants.INITIAL_CHECKPOINT_NUMBER; - } - function getNextMessageIndex() external view returns (uint256) { - FrontierLib.Tree storage currentTree = trees[state.inProgress]; - uint256 index = (state.inProgress - Constants.INITIAL_CHECKPOINT_NUMBER) * SIZE + currentTree.nextIndex; - return index; + // Compact cumulative index: the next message's index is the count inserted so far. + return _totalMessagesInserted(); } } diff --git a/l1-contracts/test/harnesses/TestConstants.sol b/l1-contracts/test/harnesses/TestConstants.sol index c0d7a6738981..dceae35f5020 100644 --- a/l1-contracts/test/harnesses/TestConstants.sol +++ b/l1-contracts/test/harnesses/TestConstants.sol @@ -25,7 +25,7 @@ library TestConstants { uint256 internal constant AZTEC_TARGET_COMMITTEE_SIZE = 48; uint256 internal constant AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET = 3; uint256 internal constant AZTEC_LAG_IN_EPOCHS_FOR_RANDAO = 2; - uint256 internal constant AZTEC_INBOX_LAG = 2; + uint256 internal constant AZTEC_INBOX_BUCKET_RING_SIZE = 1024; uint256 internal constant AZTEC_PROOF_SUBMISSION_EPOCHS = 1; uint256 internal constant AZTEC_SLASHING_QUORUM = 17; // Must be > ROUND_SIZE / 2 (ROUND_SIZE derived from // EPOCH_DURATION) @@ -132,7 +132,6 @@ library TestConstants { config.slashAmounts = slashAmounts; config.slasherEnabled = false; config.localEjectionThreshold = 0; - config.inboxLag = AZTEC_INBOX_LAG; // For the version we derive it based on the config (with a 0 version) // TODO(https://linear.app/aztec-labs/issue/TMNT-139/version-at-deployment) diff --git a/l1-contracts/test/merkle/Frontier.t.sol b/l1-contracts/test/merkle/Frontier.t.sol deleted file mode 100644 index b6b8e3844a90..000000000000 --- a/l1-contracts/test/merkle/Frontier.t.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Aztec Labs. -pragma solidity >=0.8.27; - -import {Test} from "forge-std/Test.sol"; - -import {NaiveMerkle} from "./Naive.sol"; -import {FrontierMerkle} from "../harnesses/Frontier.sol"; - -contract FrontierTest is Test { - function setUp() public { - // Pause gas metering as calculating the root on each insert is expensive - vm.pauseGasMetering(); - } - - function testFrontier() public { - uint256 depth = 10; - - NaiveMerkle merkle = new NaiveMerkle(depth); - FrontierMerkle frontier = new FrontierMerkle(depth); - - uint256 upper = frontier.SIZE(); - for (uint256 i = 0; i < upper; i++) { - bytes32 leaf = sha256(abi.encode(i + 1)); - merkle.insertLeaf(leaf); - frontier.insertLeaf(leaf); - assertEq(merkle.computeRoot(), frontier.root(), "Frontier Roots should be equal"); - } - } -} diff --git a/l1-contracts/test/portals/TokenPortal.t.sol b/l1-contracts/test/portals/TokenPortal.t.sol index 47e341d38f68..a91f111003a5 100644 --- a/l1-contracts/test/portals/TokenPortal.t.sol +++ b/l1-contracts/test/portals/TokenPortal.t.sol @@ -11,7 +11,6 @@ import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; import {Epoch} from "@aztec/core/libraries/TimeLib.sol"; -import {TestConstants} from "../harnesses/TestConstants.sol"; import {Inbox} from "@aztec/core/messagebridge/Inbox.sol"; // Interfaces @@ -34,9 +33,6 @@ contract TokenPortalTest is Test { event MessageConsumed(bytes32 indexed messageHash, address indexed recipient); - uint256 internal constant FIRST_REAL_TREE_NUM = Constants.INITIAL_CHECKPOINT_NUMBER + TestConstants.AZTEC_INBOX_LAG; - uint256 internal constant L1_TO_L2_MSG_SUBTREE_SIZE = 2 ** Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT; - Registry internal registry; RewardDistributor internal rewardDistributor; Inbox internal inbox; @@ -118,16 +114,17 @@ contract TokenPortalTest is Test { testERC20.mint(address(this), mintAmount); testERC20.approve(address(tokenPortal), mintAmount); - // Check for the expected message - uint256 expectedIndex = (FIRST_REAL_TREE_NUM - 1) * L1_TO_L2_MSG_SUBTREE_SIZE; + // Check for the expected message. + // Compact cumulative index: the first message against a fresh Inbox has index 0. + uint256 expectedIndex = 0; DataStructures.L1ToL2Msg memory expectedMessage = _createExpectedMintPrivateL1ToL2Message(expectedIndex); bytes32 expectedLeaf = expectedMessage.sha256ToField(); - bytes16 expectedHash = bytes16(keccak256(abi.encodePacked(inbox.getState().rollingHash, expectedLeaf))); + bytes32 expectedInboxRollingHash = Hash.accumulateInboxRollingHash(bytes32(0), expectedLeaf); // Check the event was emitted vm.expectEmit(true, true, true, true); // event we expect - emit IInbox.MessageSent(FIRST_REAL_TREE_NUM, expectedIndex, expectedLeaf, expectedHash); + emit IInbox.MessageSent(expectedIndex, expectedLeaf, expectedInboxRollingHash, 1); // event we will get // Perform op @@ -145,16 +142,17 @@ contract TokenPortalTest is Test { testERC20.mint(address(this), mintAmount); testERC20.approve(address(tokenPortal), mintAmount); - // Check for the expected message - uint256 expectedIndex = (FIRST_REAL_TREE_NUM - 1) * L1_TO_L2_MSG_SUBTREE_SIZE; + // Check for the expected message. + // Compact cumulative index: the first message against a fresh Inbox has index 0. + uint256 expectedIndex = 0; DataStructures.L1ToL2Msg memory expectedMessage = _createExpectedMintPublicL1ToL2Message(expectedIndex); bytes32 expectedLeaf = expectedMessage.sha256ToField(); - bytes16 expectedHash = bytes16(keccak256(abi.encodePacked(inbox.getState().rollingHash, expectedLeaf))); + bytes32 expectedInboxRollingHash = Hash.accumulateInboxRollingHash(bytes32(0), expectedLeaf); // Check the event was emitted vm.expectEmit(true, true, true, true); // event we expect - emit IInbox.MessageSent(FIRST_REAL_TREE_NUM, expectedIndex, expectedLeaf, expectedHash); + emit IInbox.MessageSent(expectedIndex, expectedLeaf, expectedInboxRollingHash, 1); // Perform op (bytes32 leaf, uint256 index) = tokenPortal.depositToAztecPublic(to, amount, secretHashForL2MessageConsumption); diff --git a/l1-contracts/test/rollup/ProposeInboxConsumption.t.sol b/l1-contracts/test/rollup/ProposeInboxConsumption.t.sol new file mode 100644 index 000000000000..f3749c8ac3b2 --- /dev/null +++ b/l1-contracts/test/rollup/ProposeInboxConsumption.t.sol @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Aztec Labs. +pragma solidity >=0.8.27; + +import {Test} from "forge-std/Test.sol"; +import {TestERC20} from "src/mock/TestERC20.sol"; +import {IERC20} from "@oz/token/ERC20/IERC20.sol"; +import {IInbox, MAX_MSGS_PER_BUCKET} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; +import {ProposeLib} from "@aztec/core/libraries/rollup/ProposeLib.sol"; +import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; +import {TimeLib, Slot, Timestamp} from "@aztec/core/libraries/TimeLib.sol"; +import {Errors} from "@aztec/core/libraries/Errors.sol"; +import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; +import {MIN_BUCKET_RING_SIZE} from "@aztec/core/messagebridge/Inbox.sol"; +import {InboxHarness} from "../harnesses/InboxHarness.sol"; +import {TestConstants} from "../harnesses/TestConstants.sol"; + +contract ProposeLibHarness { + constructor(uint256 _genesisTime, uint256 _slotDuration, uint256 _epochDuration) { + TimeLib.initialize(_genesisTime, _slotDuration, _epochDuration, 1); + } + + function validateInboxConsumption( + IInbox _inbox, + bytes32 _inboxRollingHash, + uint256 _bucketHint, + Slot _slotNumber, + uint256 _parentTotalMsgCount + ) external view returns (uint256) { + return ProposeLib.validateInboxConsumption( + _inbox, _inboxRollingHash, _bucketHint, _slotNumber, _parentTotalMsgCount + ); + } +} + +contract ProposeInboxConsumptionTest is Test { + uint256 internal constant GENESIS_TIME = 100_000; + uint256 internal constant SLOT_DURATION = 36; + uint256 internal constant EPOCH_DURATION = 32; + + Slot internal constant SLOT = Slot.wrap(10); + + ProposeLibHarness internal rollup; + InboxHarness internal inbox; + uint256 internal version = 0; + + // Start of the build frame for a checkpoint proposed in SLOT: it is built during the previous slot. + uint256 internal buildFrameStart = GENESIS_TIME + (Slot.unwrap(SLOT) - 1) * SLOT_DURATION; + // Buckets at or before the cutoff must be consumed by the checkpoint. + uint256 internal cutoff = buildFrameStart - Constants.INBOX_LAG_SECONDS; + + function setUp() public { + vm.warp(GENESIS_TIME); + rollup = new ProposeLibHarness(GENESIS_TIME, SLOT_DURATION, EPOCH_DURATION); + inbox = _deployInbox(TestConstants.AZTEC_INBOX_BUCKET_RING_SIZE); + } + + function _deployInbox(uint256 _ringSize) internal returns (InboxHarness) { + IERC20 feeAsset = new TestERC20("Fee Asset", "FA", address(this)); + return new InboxHarness(address(rollup), feeAsset, version, _ringSize); + } + + function _send(uint256 _salt) internal { + inbox.sendL2Message( + DataStructures.L2Actor({actor: bytes32(uint256(0x1000 + _salt)), version: version}), + bytes32(uint256(0x2000 + _salt)), + bytes32(uint256(0x3000 + _salt)) + ); + } + + function _sendMany(uint256 _count) internal { + for (uint256 i = 0; i < _count; i++) { + _send(i); + } + } + + function testEmptyInbox() public { + // The genesis bucket carries the Inbox's deployment timestamp and never absorbs messages, so it is settled + // from the start: referencing it works even in the L1 block the Inbox was deployed in. + uint256 consumed = rollup.validateInboxConsumption(inbox, bytes32(0), 0, SLOT, 0); + assertEq(consumed, 0, "consumed nothing on empty inbox"); + } + + function testEmptyInboxRejectsNonZeroHash() public { + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InvalidInboxRollingHash.selector, bytes32(0), bytes32(uint256(1))) + ); + rollup.validateInboxConsumption(inbox, bytes32(uint256(1)), 0, SLOT, 0); + } + + function testConsumeUpToLatestBucket() public { + vm.warp(cutoff); + _sendMany(3); + bytes32 endHash = inbox.getBucket(1).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + uint256 consumed = rollup.validateInboxConsumption(inbox, endHash, 1, SLOT, 0); + assertEq(consumed, 3, "consumed all three messages"); + } + + function testExactCutoffBucketMustBeConsumed() public { + // A bucket created exactly at the cutoff is the "latest bucket at/before build-frame start minus lag": + // consuming nothing is no longer allowed. + vm.warp(cutoff); + _send(0); + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__UnconsumedInboxMessages.selector, 1)); + rollup.validateInboxConsumption(inbox, bytes32(0), 0, SLOT, 0); + } + + function testBucketPastCutoffNeedNotBeConsumed() public { + vm.warp(cutoff + 1); + _send(0); + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + uint256 consumed = rollup.validateInboxConsumption(inbox, bytes32(0), 0, SLOT, 0); + assertEq(consumed, 0, "nothing consumed"); + } + + function testCapEscape() public { + // One more message than the checkpoint cap, all before the cutoff. They spill over into buckets + // 1..4 of 256 (the per-bucket cap) plus bucket 5 with the single excess message. + vm.warp(cutoff - 100); + _sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1); + assertEq(inbox.getCurrentBucketSeq(), 5, "expected five buckets"); + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + + // Consuming through bucket 4 exhausts the cap exactly, so bucket 5 escapes the censorship assert + // even though it is old. + bytes32 endHash = inbox.getBucket(4).rollingHash; + uint256 consumed = rollup.validateInboxConsumption(inbox, endHash, 4, SLOT, 0); + assertEq(consumed, Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, "consumed the full cap"); + } + + function testNoCapEscapeAtExactCap() public { + vm.warp(cutoff - 100); + _sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1); + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + + // Stopping at bucket 3 leaves bucket 4 unconsumed; consuming through it would total exactly the cap, + // which fits in one checkpoint, so there is no escape and the old bucket must be consumed. + bytes32 endHash = inbox.getBucket(3).rollingHash; + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__UnconsumedInboxMessages.selector, 4)); + rollup.validateInboxConsumption(inbox, endHash, 3, SLOT, 0); + } + + function testCapEscapeAccountsForParentTotal() public { + // Same layout as testCapEscape, but the parent checkpoint had already consumed one message: + // buckets 2..5 then hold cap messages total, which fit in one checkpoint, so no escape from bucket 1. + vm.warp(cutoff - 100); + _sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1); + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + + bytes32 endHash = inbox.getBucket(4).rollingHash; + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__UnconsumedInboxMessages.selector, 5)); + rollup.validateInboxConsumption(inbox, endHash, 4, SLOT, 1); + } + + function testStaleHashRejection() public { + vm.warp(cutoff); + _send(0); + vm.roll(block.number + 1); + vm.warp(cutoff + 10); + _send(1); + + bytes32 staleHash = inbox.getBucket(1).rollingHash; + bytes32 currentHash = inbox.getBucket(2).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidInboxRollingHash.selector, currentHash, staleHash)); + rollup.validateInboxConsumption(inbox, staleHash, 2, SLOT, 0); + } + + function testUnknownHashRejection() public { + vm.warp(cutoff); + _send(0); + + bytes32 unknownHash = bytes32(uint256(0xdead)); + bytes32 bucketHash = inbox.getBucket(1).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InvalidInboxRollingHash.selector, bucketHash, unknownHash)); + rollup.validateInboxConsumption(inbox, unknownHash, 1, SLOT, 0); + } + + function testHintBeyondCurrentBucketRejected() public { + vm.warp(cutoff); + _send(0); + + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, 2, 1)); + rollup.validateInboxConsumption(inbox, bytes32(0), 2, SLOT, 0); + } + + function testHintOnOverwrittenBucketRejected() public { + InboxHarness ringInbox = _deployInbox(MIN_BUCKET_RING_SIZE); + + // One bucket per L1 block; after MIN_BUCKET_RING_SIZE + 1 buckets the ring has wrapped past bucket 1, + // so a hint pointing at it must be rejected before any cutoff logic runs. + for (uint256 i = 1; i <= MIN_BUCKET_RING_SIZE + 1; i++) { + vm.roll(block.number + 1); + vm.warp(block.timestamp + 1); + ringInbox.sendL2Message( + DataStructures.L2Actor({actor: bytes32(uint256(0x1000 + i)), version: version}), + bytes32(uint256(0x2000 + i)), + bytes32(uint256(0x3000 + i)) + ); + } + + // No proposal-time warp: the loop above has already moved past SLOT's proposal time, and the revert fires + // in getBucket before any cutoff logic reads the clock. + vm.expectRevert(abi.encodeWithSelector(Errors.Inbox__BucketOutOfWindow.selector, 1, MIN_BUCKET_RING_SIZE + 1)); + rollup.validateInboxConsumption(ringInbox, bytes32(0), 1, SLOT, 0); + } + + function testCurrentBlockBucketRejected() public { + // A proposer that bundles `sendL2Message` and `propose` into a single L1 transaction can reference a + // bucket that is still accumulating and then mutate it with a trailing send. The snapshot the checkpoint + // committed to would afterwards exist nowhere: not on L1, where it was overwritten in place, and not in + // any node, which only ever observes a bucket's end-of-block state. + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + _send(0); + bytes32 liveHash = inbox.getBucket(1).rollingHash; + + vm.expectRevert(abi.encodeWithSelector(Errors.Rollup__InboxBucketStillMutable.selector, 1)); + rollup.validateInboxConsumption(inbox, liveHash, 1, SLOT, 0); + + // Nothing prevents the trailing send that erases the referenced snapshot, so the reference itself is what + // has to be rejected. + _send(1); + assertTrue(inbox.getBucket(1).rollingHash != liveHash, "bucket mutated in place within one L1 block"); + } + + function testFullBucketInCurrentBlockAccepted() public { + // A bucket at the per-bucket cap cannot absorb another message: the next send in the same L1 block opens + // a new bucket, so the snapshot is already final and referencing it within that block is safe. + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + uint256 cap = MAX_MSGS_PER_BUCKET; + _sendMany(cap); + assertEq(inbox.getBucket(1).msgCount, cap, "bucket 1 is at the per-bucket cap"); + assertEq(inbox.getBucket(1).timestamp, block.timestamp, "bucket 1 was opened in this L1 block"); + + bytes32 endHash = inbox.getBucket(1).rollingHash; + uint256 consumed = rollup.validateInboxConsumption(inbox, endHash, 1, SLOT, 0); + assertEq(consumed, cap, "a full bucket is consumable in the block it was opened in"); + } + + function testConsumeBackwardsReverts() public { + // Buckets 1 and 2 exist with distinct cumulative totals. A proposal that references bucket 1 while its + // parent already consumed through bucket 2 would move consumption backwards. + vm.warp(cutoff - 100); + _send(0); + vm.roll(block.number + 1); + vm.warp(cutoff - 50); + _send(1); + + uint256 parentTotal = inbox.getBucket(2).totalMsgCount; + uint256 bucketTotal = inbox.getBucket(1).totalMsgCount; + bytes32 bucketHash = inbox.getBucket(1).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InboxConsumptionBehindParent.selector, parentTotal, bucketTotal) + ); + rollup.validateInboxConsumption(inbox, bucketHash, 1, SLOT, parentTotal); + } + + function testEqualReferenceConsumesNothing() public { + // The parent already consumed the current bucket; re-referencing it with an equal parent total consumes + // nothing and returns the unchanged cumulative total. No newer pre-cutoff bucket exists. + vm.warp(cutoff); + _sendMany(2); + uint256 total = inbox.getBucket(1).totalMsgCount; + bytes32 endHash = inbox.getBucket(1).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + uint256 consumed = rollup.validateInboxConsumption(inbox, endHash, 1, SLOT, total); + assertEq(consumed, total, "equal reference returns the unchanged total"); + } + + function testCapUpperBoundReverts() public { + // One more message than the checkpoint cap, all before the cutoff, referenced in a single proposal from + // a fresh parent: the consumed delta exceeds what the circuits can insert. + vm.warp(cutoff - 100); + _sendMany(Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1); + assertEq(inbox.getCurrentBucketSeq(), 5, "expected five buckets"); + + bytes32 endHash = inbox.getBucket(5).rollingHash; + + vm.warp(GENESIS_TIME + Slot.unwrap(SLOT) * SLOT_DURATION); + vm.expectRevert( + abi.encodeWithSelector( + Errors.Rollup__TooManyInboxMessagesConsumed.selector, Constants.MAX_L1_TO_L2_MSGS_PER_CHECKPOINT + 1 + ) + ); + rollup.validateInboxConsumption(inbox, endHash, 5, SLOT, 0); + } +} diff --git a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol index dc37e84e3757..4aa2a583739e 100644 --- a/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol +++ b/l1-contracts/test/rollup/libraries/rewardlib/RewardLibWrapper.sol @@ -116,7 +116,10 @@ contract RewardLibWrapper { attestationsHash: bytes32(0), payloadDigest: bytes32(0), slotNumber: Slot.wrap(0), - feeHeader: _feeHeader + feeHeader: _feeHeader, + inboxRollingHash: bytes32(0), + inboxMsgTotal: 0, + inboxConsumedBucket: 0 }) ); } diff --git a/l1-contracts/test/script/DeployAztecL1Contracts.t.sol b/l1-contracts/test/script/DeployAztecL1Contracts.t.sol index b450e0a778b4..cd98934b568f 100644 --- a/l1-contracts/test/script/DeployAztecL1Contracts.t.sol +++ b/l1-contracts/test/script/DeployAztecL1Contracts.t.sol @@ -30,7 +30,6 @@ contract DeployAztecL1ContractsTest is Test { // Timing config vm.setEnv("AZTEC_SLOT_DURATION", vm.toString(json.readUint(".AZTEC_SLOT_DURATION"))); vm.setEnv("AZTEC_EPOCH_DURATION", vm.toString(json.readUint(".AZTEC_EPOCH_DURATION"))); - vm.setEnv("AZTEC_INBOX_LAG", vm.toString(json.readUint(".AZTEC_INBOX_LAG"))); vm.setEnv("AZTEC_PROOF_SUBMISSION_EPOCHS", vm.toString(json.readUint(".AZTEC_PROOF_SUBMISSION_EPOCHS"))); // Validator config diff --git a/l1-contracts/test/script/DeployRollupForUpgrade.t.sol b/l1-contracts/test/script/DeployRollupForUpgrade.t.sol index 11714808a0d3..0303ceb639f3 100644 --- a/l1-contracts/test/script/DeployRollupForUpgrade.t.sol +++ b/l1-contracts/test/script/DeployRollupForUpgrade.t.sol @@ -41,7 +41,6 @@ contract DeployRollupForUpgradeTest is Test { // Timing config vm.setEnv("AZTEC_SLOT_DURATION", vm.toString(json.readUint(".AZTEC_SLOT_DURATION"))); vm.setEnv("AZTEC_EPOCH_DURATION", vm.toString(json.readUint(".AZTEC_EPOCH_DURATION"))); - vm.setEnv("AZTEC_INBOX_LAG", vm.toString(json.readUint(".AZTEC_INBOX_LAG"))); vm.setEnv("AZTEC_PROOF_SUBMISSION_EPOCHS", vm.toString(json.readUint(".AZTEC_PROOF_SUBMISSION_EPOCHS"))); // Validator config diff --git a/l1-contracts/test/tmnt419.t.sol b/l1-contracts/test/tmnt419.t.sol index 525df4ff47f2..2cd12d72c9d5 100644 --- a/l1-contracts/test/tmnt419.t.sol +++ b/l1-contracts/test/tmnt419.t.sol @@ -173,8 +173,13 @@ contract Tmnt419Test is RollupBase { header.gasFees.feePerL2Gas = SafeCast.toUint128(rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true)); header.totalManaUsed = MANA_TARGET; - ProposeArgs memory proposeArgs = - ProposeArgs({header: header, archive: archiveRoot, oracleInput: OracleInput({feeAssetPriceModifier: 0})}); + // Streaming Inbox: reference the newest bucket so any seeded messages are consumed. + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + + ProposeArgs memory proposeArgs = ProposeArgs({ + header: header, archive: archiveRoot, oracleInput: OracleInput({feeAssetPriceModifier: 0}), bucketHint: bucketHint + }); CommitteeAttestation[] memory attestations = new CommitteeAttestation[](0); address[] memory signers = new address[](0); diff --git a/l1-contracts/test/validator-selection/ValidatorSelection.t.sol b/l1-contracts/test/validator-selection/ValidatorSelection.t.sol index 0062c9b6e58f..a968be6d803f 100644 --- a/l1-contracts/test/validator-selection/ValidatorSelection.t.sol +++ b/l1-contracts/test/validator-selection/ValidatorSelection.t.sol @@ -531,11 +531,13 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase { DecoderBase.Full memory full = load(_name); ProposedHeader memory header = full.checkpoint.header; - // We jump to the time of the block. (unless it is in the past) - vm.warp(max(block.timestamp, Timestamp.unwrap(full.checkpoint.header.timestamp))); - + // Seed the Inbox before jumping to the checkpoint's L1 block: propose rejects a bucket that is still + // accumulating, and a bucket keeps accumulating for the whole L1 block that opened it. _populateInbox(full.populate.sender, full.populate.recipient, full.populate.l1ToL2Content); + // We jump to the time of the block, always past the L1 block the messages above landed in. + vm.warp(max(block.timestamp + 1, Timestamp.unwrap(full.checkpoint.header.timestamp))); + rollup.setupEpoch(); ree.proposer = rollup.getCurrentProposer(); @@ -544,12 +546,16 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase { { uint128 manaMinFee = SafeCast.toUint128(rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true)); - bytes32 inHash = inbox.getRoot(full.checkpoint.checkpointNumber); - header.inHash = inHash; header.gasFees.feePerL2Gas = manaMinFee; } - ree.proposeArgs = ProposeArgs({header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0)}); + // Streaming Inbox: reference the newest bucket, consuming the messages seeded above. + uint256 bucketHint = inbox.getCurrentBucketSeq(); + header.inboxRollingHash = inbox.getBucket(bucketHint).rollingHash; + + ree.proposeArgs = ProposeArgs({ + header: header, archive: full.checkpoint.archive, oracleInput: OracleInput(0), bucketHint: bucketHint + }); skipBlobCheck(address(rollup)); @@ -745,6 +751,8 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase { previousArchive: parentCheckpointLog.archive, endArchive: endFull.checkpoint.archive, outHash: endFull.checkpoint.header.outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: proposedHeaders[endCheckpointNumber].inboxRollingHash, proverId: prover }); diff --git a/l1-contracts/test/validator-selection/tmnt207.t.sol b/l1-contracts/test/validator-selection/tmnt207.t.sol index 89bd948f5541..f01f9b6440a2 100644 --- a/l1-contracts/test/validator-selection/tmnt207.t.sol +++ b/l1-contracts/test/validator-selection/tmnt207.t.sol @@ -230,6 +230,8 @@ contract Tmnt207Test is RollupBase { previousArchive: rollup.getCheckpoint(0).archive, endArchive: rollup.getCheckpoint(1).archive, outHash: rollup.getCheckpoint(1).outHash, + previousInboxRollingHash: 0, + endInboxRollingHash: 0, proverId: address(0) }), headers: headers, @@ -261,8 +263,13 @@ contract Tmnt207Test is RollupBase { header.gasFees.feePerL2Gas = SafeCast.toUint128(rollup.getManaMinFeeAt(Timestamp.wrap(block.timestamp), true)); header.totalManaUsed = MANA_TARGET; - ProposeArgs memory proposeArgs = - ProposeArgs({header: header, archive: archiveRoot, oracleInput: OracleInput({feeAssetPriceModifier: 0})}); + // Streaming Inbox: reference the newest bucket (genesis here; nothing is seeded). + uint256 bucketHint = rollup.getInbox().getCurrentBucketSeq(); + header.inboxRollingHash = rollup.getInbox().getBucket(bucketHint).rollingHash; + + ProposeArgs memory proposeArgs = ProposeArgs({ + header: header, archive: archiveRoot, oracleInput: OracleInput({feeAssetPriceModifier: 0}), bucketHint: bucketHint + }); CommitteeAttestation[] memory attestations; address[] memory signers; diff --git a/noir-projects/noir-protocol-circuits/Nargo.template.toml b/noir-projects/noir-protocol-circuits/Nargo.template.toml index 17a33b4a805f..bed788a6a6af 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.template.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.template.toml @@ -8,8 +8,9 @@ members = [ "crates/types", "crates/protocol-test-utils", "crates/blob", - "crates/parity-base", - "crates/parity-root", + "crates/inbox-parity-64", + "crates/inbox-parity-256", + "crates/inbox-parity-1024", "crates/private-kernel-lib", "crates/private-kernel-init", "crates/private-kernel-init-2", @@ -47,6 +48,7 @@ members = [ "crates/rollup-block-root-first-single-tx", "crates/rollup-block-root-first-single-tx-simulated", "crates/rollup-block-root-first-empty-tx", + "crates/rollup-block-root-msgs-only", "crates/rollup-block-merge", "crates/rollup-checkpoint-root", "crates/rollup-checkpoint-root-simulated", diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 0935d9655913..b3b30fd2b3a7 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -272,6 +272,7 @@ function test_cmds { rollup-block-root-first-empty-tx rollup-block-root rollup-block-root-single-tx + rollup-block-root-msgs-only rollup-block-merge rollup-checkpoint-root rollup-checkpoint-root-single-block diff --git a/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/Nargo.toml new file mode 100644 index 000000000000..0186b566d843 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "inbox_parity_1024" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +rollup_lib = { path = "../rollup-lib" } diff --git a/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/src/main.nr b/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/src/main.nr new file mode 100644 index 000000000000..4ab29c082f3e --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-1024/src/main.nr @@ -0,0 +1,5 @@ +use rollup_lib::parity::{inbox_parity, InboxParityPrivateInputs, ParityPublicInputs}; + +fn main(inputs: InboxParityPrivateInputs<1024>) -> pub ParityPublicInputs { + inbox_parity::execute(inputs) +} diff --git a/noir-projects/noir-protocol-circuits/crates/parity-root/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/inbox-parity-256/Nargo.toml similarity index 82% rename from noir-projects/noir-protocol-circuits/crates/parity-root/Nargo.toml rename to noir-projects/noir-protocol-circuits/crates/inbox-parity-256/Nargo.toml index 5ed4b0ad0143..02a1149ed59a 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-root/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-256/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "parity_root" +name = "inbox_parity_256" type = "bin" authors = [""] compiler_version = ">=0.18.0" diff --git a/noir-projects/noir-protocol-circuits/crates/inbox-parity-256/src/main.nr b/noir-projects/noir-protocol-circuits/crates/inbox-parity-256/src/main.nr new file mode 100644 index 000000000000..a9d07fab4cb8 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-256/src/main.nr @@ -0,0 +1,5 @@ +use rollup_lib::parity::{inbox_parity, InboxParityPrivateInputs, ParityPublicInputs}; + +fn main(inputs: InboxParityPrivateInputs<256>) -> pub ParityPublicInputs { + inbox_parity::execute(inputs) +} diff --git a/noir-projects/noir-protocol-circuits/crates/parity-base/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/inbox-parity-64/Nargo.toml similarity index 83% rename from noir-projects/noir-protocol-circuits/crates/parity-base/Nargo.toml rename to noir-projects/noir-protocol-circuits/crates/inbox-parity-64/Nargo.toml index 8ca6ed0f8a73..f15275a8050a 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-base/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-64/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "parity_base" +name = "inbox_parity_64" type = "bin" authors = [""] compiler_version = ">=0.18.0" diff --git a/noir-projects/noir-protocol-circuits/crates/inbox-parity-64/src/main.nr b/noir-projects/noir-protocol-circuits/crates/inbox-parity-64/src/main.nr new file mode 100644 index 000000000000..437cadc80912 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/inbox-parity-64/src/main.nr @@ -0,0 +1,5 @@ +use rollup_lib::parity::{inbox_parity, InboxParityPrivateInputs, ParityPublicInputs}; + +fn main(inputs: InboxParityPrivateInputs<64>) -> pub ParityPublicInputs { + inbox_parity::execute(inputs) +} diff --git a/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr b/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr deleted file mode 100644 index f0e7e161db8d..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr +++ /dev/null @@ -1,5 +0,0 @@ -use rollup_lib::parity::{parity_base, ParityBasePrivateInputs, ParityPublicInputs}; - -fn main(inputs: ParityBasePrivateInputs) -> pub ParityPublicInputs { - parity_base::execute(inputs) -} diff --git a/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr b/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr deleted file mode 100644 index 3cdbf50eb41f..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr +++ /dev/null @@ -1,5 +0,0 @@ -use rollup_lib::parity::{parity_root, ParityPublicInputs, ParityRootPrivateInputs}; - -fn main(inputs: ParityRootPrivateInputs) -> pub ParityPublicInputs { - parity_root::execute(inputs) -} diff --git a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/vk_tree.nr b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/vk_tree.nr index 7c511b3d8ae4..96c4818d3fa7 100644 --- a/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/vk_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/protocol-test-utils/src/fixtures/vk_tree.nr @@ -1,13 +1,14 @@ use crate::utils::pad_end; use types::{ constants::{ - HIDING_KERNEL_TO_PUBLIC_VK_INDEX, MEGA_KERNEL_VK_LENGTH_IN_FIELDS, PARITY_BASE_VK_INDEX, - PARITY_ROOT_VK_INDEX, PRIVATE_KERNEL_INIT_2_VK_INDEX, PRIVATE_KERNEL_INIT_3_VK_INDEX, - PRIVATE_KERNEL_INIT_4_VK_INDEX, PRIVATE_KERNEL_INIT_5_VK_INDEX, - PRIVATE_KERNEL_INNER_2_VK_INDEX, PRIVATE_KERNEL_INNER_3_VK_INDEX, - PRIVATE_KERNEL_INNER_4_VK_INDEX, PRIVATE_KERNEL_INNER_5_VK_INDEX, - PRIVATE_KERNEL_RESET_VK_INDEX, ROOT_ROLLUP_VK_INDEX, ULTRA_VK_LENGTH_IN_FIELDS, - VK_TREE_HEIGHT, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, HIDING_KERNEL_TO_PUBLIC_VK_INDEX, + INBOX_PARITY_1024_VK_INDEX, INBOX_PARITY_256_VK_INDEX, INBOX_PARITY_64_VK_INDEX, + MEGA_KERNEL_VK_LENGTH_IN_FIELDS, PRIVATE_KERNEL_INIT_2_VK_INDEX, + PRIVATE_KERNEL_INIT_3_VK_INDEX, PRIVATE_KERNEL_INIT_4_VK_INDEX, + PRIVATE_KERNEL_INIT_5_VK_INDEX, PRIVATE_KERNEL_INNER_2_VK_INDEX, + PRIVATE_KERNEL_INNER_3_VK_INDEX, PRIVATE_KERNEL_INNER_4_VK_INDEX, + PRIVATE_KERNEL_INNER_5_VK_INDEX, PRIVATE_KERNEL_RESET_VK_INDEX, ROOT_ROLLUP_VK_INDEX, + ULTRA_VK_LENGTH_IN_FIELDS, VK_TREE_HEIGHT, }, merkle_tree::merkle_tree::MerkleTree, proof::{verification_key::VerificationKey, vk_data::VkData}, @@ -69,15 +70,23 @@ pub global VK_MERKLE_TREE: MerkleTree = { leaves[PRIVATE_KERNEL_INNER_5_VK_INDEX] = generate_fake_chonk_vk_for_index(PRIVATE_KERNEL_INNER_5_VK_INDEX).hash; + // The message-only block root lives past the reset-variant range, so it's not covered by the rollup-honk loop below. + leaves[BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX] = + generate_fake_rollup_honk_vk_for_index(BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX).hash; + // Rollup Honk for i in HIDING_KERNEL_TO_PUBLIC_VK_INDEX + 1..PRIVATE_KERNEL_RESET_VK_INDEX { leaves[i] = generate_fake_rollup_honk_vk_for_index(i).hash; } // Honk - // Override some of the above with Honk Vks. - leaves[PARITY_BASE_VK_INDEX] = generate_fake_honk_vk_for_index(PARITY_BASE_VK_INDEX).hash; - leaves[PARITY_ROOT_VK_INDEX] = generate_fake_honk_vk_for_index(PARITY_ROOT_VK_INDEX).hash; + // The inbox parity ladder circuits are plain UltraHonk (not rollup-honk) and live past the reset range. + leaves[INBOX_PARITY_64_VK_INDEX] = + generate_fake_honk_vk_for_index(INBOX_PARITY_64_VK_INDEX).hash; + leaves[INBOX_PARITY_256_VK_INDEX] = + generate_fake_honk_vk_for_index(INBOX_PARITY_256_VK_INDEX).hash; + leaves[INBOX_PARITY_1024_VK_INDEX] = + generate_fake_honk_vk_for_index(INBOX_PARITY_1024_VK_INDEX).hash; leaves[ROOT_ROLLUP_VK_INDEX] = generate_fake_honk_vk_for_index(ROOT_ROLLUP_VK_INDEX).hash; MerkleTree::new(leaves) diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml index 8ee6d1ad2363..1231e5014923 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-merge/Prover.toml @@ -484,17 +484,17 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x2ff8cd98ff5236e0b4da99b109c2b3d39850c2efd663bf50f63f9e39c7f4389e" - in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" - out_hash = "0x0018febbd74d861e38064a4ff9d3b5ed7a39b398576ef75e104848700819a700" + block_headers_hash = "0x2e450da805541fab42c2a1d292724206564176008fcaa12f905f5a0e993a1005" + is_first_block = true + out_hash = "0x006bd7618b0cf7b40e3f107022eee2d411bcc5850fbb774dacc46a15957659c4" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x2ec9fc22ae7001e2ada488cbd0ea07e1cf7f54e151dc2bb766e561636b02eece" + root = "0x0eab3e829cc7fe4fad08d43de98c4d400e7349bca7558dce0e7aebe7df63680b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -533,20 +533,20 @@ root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.note_hash_tree] -root = "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.end_state.partial.nullifier_tree] -root = "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.end_state.partial.public_data_tree] -root = "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -567,80 +567,116 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000552" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004d4" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d", - "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9", - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" + "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684", + "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" ] state = [ - "0x0e2949060fe0f2aa67a11a1f8c7449f74124ab122ca0bfcc6d1dc19dde1e5268", - "0x06620ebc6d7abb78fe8de2f9f66c4cabbe323d277ef8de952dd1b59cd36bee17", - "0x129daea73c37f015b42271c76bad72aadcb53b8a12b8fb40b708f528315f16a8", - "0x0bfe4f9fb5d9e711aff1b1f4c96be770b3717443ed65ea7907957428c2f24702" + "0x134552dc5a3183a8ed29944bea3f1ece700d5a858b7f100d79e637b5a1bac408", + "0x30083cd298bdbeedb36f277787041a4cf106837d26372fb435a25505e18f8fdc", + "0x21c04f5b66d17a0db8d7db79b8641856250619429f5320aa8b6f393809318cbd", + "0x0e5c1e939ba31ff15394300cc98dcf8600a6e6b5262a7d75966f12188e08743c" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false + [inputs.previous_rollups.public_inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.previous_rollups.public_inputs.start_msg_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.end_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.end_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false + [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" sibling_path = [ - "0x22f4e6497a7b25cb4baa538d7485c88094a612f07795194d171fa482dd7d50cd", - "0x14006eaa287c9ad153160a93307e789266c077e1c656dba37a430d1a966bfc4f", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x0b5802278aa8eb5ab2fcbd2c97df88eaf72e224d2c9e2bd6677b39ff3560d1af", + "0x0fce3d763e56ccd931e3e9536681a7df5fe092534a25d45edf794268d3d86405", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x0000000000000000000000000000000000000000000000000000000000000014", + "0x000000000000000000000000000000000000000000000000000000000000005a", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000aee5a6496fa3a661700c83acd517281844", - "0x00000000000000000000000000000000001c11e90eb2e15ecb7f1ba74a9e724c", - "0x0000000000000000000000000000004b67867b7c12f4d25dd039ea4b65e20a6a", - "0x0000000000000000000000000000000000155c9172c95566dd1c8b452ef68e22", - "0x000000000000000000000000000000ab4c33bf6a832e7630320a1aebd3a0a92e", - "0x000000000000000000000000000000000013ce11b3674d67e72f0f9ab13884e1", - "0x0000000000000000000000000000009ba8a4d221cf75901708c65b3bf697ef05", - "0x00000000000000000000000000000000002a1c7e0ffd43eb569f294936abd107", - "0x00000000000000000000000000000027fae31667436475ebda753a1707bb43e1", - "0x00000000000000000000000000000000002188318688f9d6076c39a76936e736", - "0x000000000000000000000000000000f07f330468b108c481a0360c6530436b9e", - "0x00000000000000000000000000000000000927e0cf9230ff9f85ffc2dc29c577", - "0x000000000000000000000000000000db572957a679dfa7233087e335184be5c0", - "0x0000000000000000000000000000000000193e2223973bb9e17b46bfb526226e", - "0x00000000000000000000000000000057881e47be28987fed5fb648b6a920ada4", - "0x00000000000000000000000000000000002ac4687d1af85a3985a58fbbf0df68", - "0x000000000000000000000000000000e3c9ae330392908131edeb2060b0c3a770", - "0x00000000000000000000000000000000002dce10f29bad8d706af353a9e3f1fe", - "0x00000000000000000000000000000068c345af3c51001882c5b4a4313a0c6e47", - "0x00000000000000000000000000000000000edf3e1c9e89dd449c894d6cd3c53e", - "0x00000000000000000000000000000087b408c013e09c4fa25fead652a828415a", - "0x0000000000000000000000000000000000120e1e724dccd2546cebeb9c541068", - "0x0000000000000000000000000000006631372634c9f7022dacf4e4e0ac76f32f", - "0x00000000000000000000000000000000000bd9710830435bbf46b22522f07598", - "0x0000000000000000000000000000001058263227d31b4cc3dacdb2cb4aabe92c", - "0x000000000000000000000000000000000025ceb14bcba3643bfbfa01be6bdb05", - "0x000000000000000000000000000000fcf6e6eccb38071546ccd021686fdf17e4", - "0x00000000000000000000000000000000001a820777e0253b1c6b3c595b887ed1", - "0x00000000000000000000000000000068469d53e72f55318a25e47b4cf13e2d6b", - "0x00000000000000000000000000000000002ee8d23d41c9b8afe617964a273a30", - "0x000000000000000000000000000000ef5ac6a00417869ecca8f41b9142e343e7", - "0x0000000000000000000000000000000000241c88aa98ad8cde8c010c8baf65d1", + "0x0000000000000000000000000000000863bfc3058a9396c65faed4d98170d1cf", + "0x000000000000000000000000000000000010b9123fceebfeade3474ec9d92f09", + "0x000000000000000000000000000000d0356291699afa5f6269d2408d80440468", + "0x00000000000000000000000000000000001f8d470c6857ef1912813e544d334b", + "0x000000000000000000000000000000c5ccd13d02bd22b72d2dd66ae124296529", + "0x00000000000000000000000000000000002d00f1c49beb37efafc9aceee6b342", + "0x000000000000000000000000000000f9ebdea9a02093a6485ef41d584d183068", + "0x000000000000000000000000000000000025c6a3e85046cc192d3634d58d1e8d", + "0x000000000000000000000000000000354e7b6c456c12065e528e03b3fd5a4725", + "0x000000000000000000000000000000000030074aafe511c840f3c482aa946020", + "0x000000000000000000000000000000403ffec0c36aecc018ff412ca8c0d087e8", + "0x00000000000000000000000000000000002c0a28b3f32c4fa3e96095d877010f", + "0x000000000000000000000000000000f52de4549e6e7fc42797f1ed8bc6d48102", + "0x00000000000000000000000000000000000ca91bcb0614b5e92f72012b68bd08", + "0x000000000000000000000000000000a0d144ae22b64fcaf1dd9699699a6e2db0", + "0x000000000000000000000000000000000009667587a846717e3296800540cebd", + "0x00000000000000000000000000000039e7edd0fc036552af05295dccf0cb1b79", + "0x00000000000000000000000000000000002aa1de043788c597ecf0e687473a63", + "0x0000000000000000000000000000007e980dfdc1f71eae14ad5783011488fb99", + "0x00000000000000000000000000000000001a224e2c71da8b80e4b9decb4a781e", + "0x0000000000000000000000000000005a1d15118c95c34784230d556bc0a502d5", + "0x0000000000000000000000000000000000063ec3d44dd9c7d54a9a8b6787dd96", + "0x00000000000000000000000000000009e2e8403a10ae61254f9fbf1ef258efc6", + "0x00000000000000000000000000000000000ad6648851555fb6fdb1e1e69e9b96", + "0x000000000000000000000000000000bb37ec0d795d50026f9684546838932ff2", + "0x0000000000000000000000000000000000300c6c333f8c9ba25c54a81b7ecf06", + "0x000000000000000000000000000000417513465a056ed49cba09d7d6b3831e72", + "0x00000000000000000000000000000000002d890d41b1ea7067b06b88f6a2ebf4", + "0x00000000000000000000000000000019b684bd6973ee9c6eabf10ee049e1dacd", + "0x0000000000000000000000000000000000238d3476aa4b33442a76f6827f536c", + "0x00000000000000000000000000000082b730b1b2bdfb1648d5e066d8fb00006a", + "0x00000000000000000000000000000000000ec9c78aa914e22cbb886002c89f94", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x00000000000000000000000000000054d6eae72b14fc4dde2071b7056010e6b1", - "0x00000000000000000000000000000000002b35ea76bd0402a8617a0903dd6cbc", - "0x000000000000000000000000000000b65b0dac635188f8bb81647d0a1f8ca151", - "0x0000000000000000000000000000000000223f7db48b4fca146caa761dbb3c94", + "0x000000000000000000000000000000042216632bac2f8e1f88ee2e5a639e8449", + "0x00000000000000000000000000000000001783a09bbd6e6c96615a715c40df58", + "0x000000000000000000000000000000ae2d0c8b24808f2464127b02456c99c2e6", + "0x0000000000000000000000000000000000227b603b87310bcbbf5ccb9f41e92f", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -661,60 +697,60 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000075bb41cafcfe782f8df8a2e4cdd8d5392", - "0x000000000000000000000000000000000025beb638ee1aa3023eaeb0037db6bf", - "0x000000000000000000000000000000536131ae5a40f7ed22751054b75a27e259", - "0x00000000000000000000000000000000002c0857f9472e89fed30cf9f7554904", - "0x00000000000000000000000000000025566cbef76bf6deca97778e208b16128b", - "0x00000000000000000000000000000000002052141e0934e9ac5e3d25f0a5f13b", - "0x000000000000000000000000000000ea0eeaa5c6d8910591d876d099e02d8e09", - "0x000000000000000000000000000000000026d4c9e0cec52ec9b6fd4268dbd17b", - "0x000000000000000000000000000000fc0ac2ac970971a77b9f335947c41b19b7", - "0x0000000000000000000000000000000000094991889e0ee754f762f24a72f5a9", - "0x0000000000000000000000000000002985e3a4f79e8a589da09b6630f5c58eae", - "0x0000000000000000000000000000000000227bb2abbecc90484ed52967233eb7", - "0x00000000000000000000000000000033692154a048cdd9ba831328975c8d3feb", - "0x00000000000000000000000000000000001b1afa6ec22c2121b14f2add6c229b", - "0x00000000000000000000000000000054869872b138fbcee2ce101617e0728be1", - "0x000000000000000000000000000000000023c613e3289ce2b5dbe02fd14007a7", - "0x000000000000000000000000000000a69f691a705d9913032652dfb1f8a45315", - "0x000000000000000000000000000000000003e86f111b8b64338847a1bcb5da23", - "0x000000000000000000000000000000d45e898c6c39b38f7159c2c19996ffc7d2", - "0x00000000000000000000000000000000000b492395dfb30d2d58f1b351322451", - "0x000000000000000000000000000000f7c224482b327308e4096909073465ad4b", - "0x00000000000000000000000000000000000f8ef4d1e3565050a007be36575fdf", - "0x0000000000000000000000000000009742cd64032a8809b9ffb80dafa618f515", - "0x00000000000000000000000000000000002e6e9a9301fc2f98b875dc38042163", - "0x0000000000000000000000000000003c7355558cce2984b65e1b57e3d3343d98", - "0x000000000000000000000000000000000026e8d11386fe0c0b86d1024636c4a9", - "0x000000000000000000000000000000f0c7e6fac74cbb2607023ba61d8a94b49b", - "0x000000000000000000000000000000000019a32ca8eb2427c10358ffb0597f44", - "0x0000000000000000000000000000002a6c50c2559db69dcac9c03c33cf20519a", - "0x0000000000000000000000000000000000295c503b2caa82d1f0f81507233e0f", - "0x00000000000000000000000000000047cf9e2fee1fa0b1707a62198b29e2b92c", - "0x00000000000000000000000000000000001ed99f7a731f120fed39f23a249979", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000008311045d79f1af4e6ab4da30950dbda122", - "0x00000000000000000000000000000000001f5225293633b8dcf201a35833ab9f", - "0x000000000000000000000000000000de8cf54bf8761134b2727a783c47fa7caa", - "0x0000000000000000000000000000000000100902da337b6f1c4d4cb136742807", - "0x000000000000000000000000000000f3f72d81f9e9005b37f61a42cc134a059e", - "0x00000000000000000000000000000000001a8c13fc64e5ea813c4f2aac247704", - "0x000000000000000000000000000000e4a50df20cc397bad7b16b984049c0e4e8", - "0x0000000000000000000000000000000000276278012ea0a3d68b2e86592425d7", - "0x000000000000000000000000000000040337ca657bec2011d89bfcbe67fce8f3", - "0x00000000000000000000000000000000001aa81ac813877b8530b548b34a519b", - "0x000000000000000000000000000000273b87fe7d60adfe7718ce2d7cd92dba00", - "0x00000000000000000000000000000000001c0838e71383534ed742e8e6b96795", - "0x00000000000000000000000000000028de0c0f13a7f95474e891a50d39992da1", - "0x00000000000000000000000000000000000a6aa94a1643918ec7010295f9c54a", - "0x00000000000000000000000000000016dd915dc0c3f4af8520cb7fbebbe39c3a", - "0x000000000000000000000000000000000025a1c2d5387b9a26ed012a0a12b95f" + "0x0000000000000000000000000000006647f52bd701b7d7d5d303fa40d7d68342", + "0x00000000000000000000000000000000001046711db14e129c39ed36a09c5110", + "0x000000000000000000000000000000dd591f8e7d7b9a3ce47445f7fb042c0245", + "0x000000000000000000000000000000000023906a638afcd3b1159d8edb5a8a19", + "0x000000000000000000000000000000f21f13d94eae7391c255cc161fc91bd21b", + "0x000000000000000000000000000000000022659d1ffe279bd0d335eadb8ec610", + "0x0000000000000000000000000000006c479df29ad3d6c7b64bda16c45cd978ff", + "0x0000000000000000000000000000000000062ceaa9c7e7f89dfacbe0308c1d94", + "0x000000000000000000000000000000f82da85c44c1f6fd583f01f792c45b1317", + "0x00000000000000000000000000000000000d0a2b325c7bf79e88d0ab7190b262", + "0x0000000000000000000000000000002c16587ba23ce95e639755686ab0dc866d", + "0x00000000000000000000000000000000000d5a05ea6f6558f3240212fdc2cfbc", + "0x000000000000000000000000000000756816bfdd159f2b3f6c2cdcf993c491c5", + "0x00000000000000000000000000000000000eef4ae3f693df70f9918c87d0c3d9", + "0x000000000000000000000000000000016f82c7e1db6d06727fb3072e8d1ac6df", + "0x000000000000000000000000000000000008233d5bc84a39c9dc1b34db5be3ce", + "0x000000000000000000000000000000d25c509f4f4170ef61312a4715f3ee9696", + "0x000000000000000000000000000000000006a53da2e3fc22ef13f8176aab716e", + "0x0000000000000000000000000000004f67a455335480d91a25209cecc21cd3a5", + "0x000000000000000000000000000000000008e04bba65af356660e2c261bfc4a9", + "0x000000000000000000000000000000938509ca0af7df0b80c17798c946a5bd1e", + "0x00000000000000000000000000000000001fccddfb2a1b6a3f663be987530069", + "0x0000000000000000000000000000009ce377afba39675fed8b933511c48f541d", + "0x00000000000000000000000000000000001e5b3418c82a3de6832f656520aff4", + "0x000000000000000000000000000000974505e3f7f7491a9c6b98708d76ee3deb", + "0x00000000000000000000000000000000001b29d9167fa2353a8fe5fe60a6c38c", + "0x0000000000000000000000000000004b9f4019604dbac913ab02cc4f3e600afb", + "0x00000000000000000000000000000000000b9586a1e3639fda3a3b8de09a5b90", + "0x000000000000000000000000000000e824781c7bcc656bbd44031c2615865032", + "0x00000000000000000000000000000000001e726850a0cf5f1335406aa6752958", + "0x00000000000000000000000000000087e1c761b6b5bbe95cd43769f81888ac51", + "0x0000000000000000000000000000000000058e54231cc45079309aceda624640", + "0x0000000000000000000000000000006e6e3fb990ecab69f2236aef840af09c46", + "0x0000000000000000000000000000000000047b4804b57192ec74a9a4b631064e", + "0x000000000000000000000000000000c8121630834caefa033191eaf7666d8882", + "0x000000000000000000000000000000000014d844beb76c49f7a806696b2e0780", + "0x0000000000000000000000000000008c76a7e5c518d1a66113550c2c35bc8e76", + "0x0000000000000000000000000000000000025e5be2f5b3a09b18f3a3fb9b2fec", + "0x0000000000000000000000000000006977f16d181313b6f66dc86bd9c9093ab6", + "0x000000000000000000000000000000000011fd080c51ab5ef3576e4f06431d86", + "0x00000000000000000000000000000086593ea92c45d5eaabcffe0aa79046bf08", + "0x00000000000000000000000000000000001094b66d729b68a41cdea5dfbf439d", + "0x00000000000000000000000000000067310d34c647c8d2fcd3337e237eab56f0", + "0x000000000000000000000000000000000006d7bf21d0e011c4c8039068490b67", + "0x000000000000000000000000000000a0682fb7f909ed93eeee25af729d7d46c1", + "0x00000000000000000000000000000000002739f68e02570e33fa918f80c929d3", + "0x000000000000000000000000000000167935dd0c6a17f9898e2868c29f28b939", + "0x00000000000000000000000000000000002173d2fa70cbb5279c9cac9374bc1a", + "0x000000000000000000000000000000ac54c792b0dbd0274013f6ad67b7d881f7", + "0x00000000000000000000000000000000000be04280b913bc9fa33b9bc04ee9ee", + "0x0000000000000000000000000000002c6a5ede81af69adc554e2ec1c3340e0f9", + "0x000000000000000000000000000000000012cb1121de794d3cb6249b7f541b6c" ] - hash = "0x21e596b78e2d114b02fc7196c6899097a27c84e90b5fe3f5f38bdfd9dee10369" + hash = "0x08aa7cad4ad4cc2aac0bc46bd25ebe810137ecf1cf2552e254cfb5906108d5e8" [[inputs.previous_rollups]] proof = [ @@ -1202,8 +1238,8 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x144a37283715921f3d25fa41b95ed787b28fe418ff6c384c1a350e4815c823cc" - in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + block_headers_hash = "0x0f0e5c6c4eb1a2ec4d1f8b50a0cfed0aa2374fe8162415f8287d82fb120778ea" + is_first_block = false out_hash = "0x00abb50b8989a7f19fd4526d43e15a1ab5d2a43af413cc8ca91e82a3c8828625" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1211,8 +1247,8 @@ proof = [ [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,142 +1263,174 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x2ec9fc22ae7001e2ada488cbd0ea07e1cf7f54e151dc2bb766e561636b02eece" + root = "0x0eab3e829cc7fe4fad08d43de98c4d400e7349bca7558dce0e7aebe7df63680b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x02c1e55021910a8552fe034bd1dad5769dec59fc837d88b03d9cf7a8bba0a348" + root = "0x29fde061771e275677f732d70886777109f0477a1215ce9c07480b1539d82335" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.start_state.partial.note_hash_tree] -root = "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.start_state.partial.nullifier_tree] -root = "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.start_state.partial.public_data_tree] -root = "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_state.partial.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000552" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004d4" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d", - "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9", - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" + "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684", + "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" ] state = [ - "0x0e2949060fe0f2aa67a11a1f8c7449f74124ab122ca0bfcc6d1dc19dde1e5268", - "0x06620ebc6d7abb78fe8de2f9f66c4cabbe323d277ef8de952dd1b59cd36bee17", - "0x129daea73c37f015b42271c76bad72aadcb53b8a12b8fb40b708f528315f16a8", - "0x0bfe4f9fb5d9e711aff1b1f4c96be770b3717443ed65ea7907957428c2f24702" + "0x134552dc5a3183a8ed29944bea3f1ece700d5a858b7f100d79e637b5a1bac408", + "0x30083cd298bdbeedb36f277787041a4cf106837d26372fb435a25505e18f8fdc", + "0x21c04f5b66d17a0db8d7db79b8641856250619429f5320aa8b6f393809318cbd", + "0x0e5c1e939ba31ff15394300cc98dcf8600a6e6b5262a7d75966f12188e08743c" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000aa3" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a26" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", - "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f", - "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" ] state = [ - "0x15da51316f6d05717039ebdac951746a67f2039305acba3dde6937f37537a3be", - "0x18d3719d0b48c48b53ca67a10f27a44337f426a5765bad3dacedaacfb6ccac97", - "0x14aff5482ea838000d13644e493656299d3e8d89a40030dbe5ca9bfc7ca80e9b", - "0x101f0785768c74cde83892e08bc25e14d7aff6304b2281bbcdee77377417c602" + "0x0722b05c2b0f06abd176de7a071a9055ff39a497d4d63d6d2c39d5140ecb52f8", + "0x29ec3c21f8d02e220855f5c5b4a260a5090fe1f8f35f4769d3df98f1c7d34d5c", + "0x2185bd14d30b97a5c4276078635b7240e0d410a867a6b0852bcca7c9a10799fc", + "0x2512de60fc10d6e204b7bf99bfc72943582ad3610981748d0aa56b4c10dcd953" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.start_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.end_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.end_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x06b2006cb3575a42771e0becfe866fcfcef2d52af8bc19f613cabdb3122f2dc7", - "0x279cfadc25df7db3e8d0a15e10ff6e5f4bcb741888255ef55ded2c7e7f364ffe", - "0x1944964394682423d7fc879430c65da6feda679bf7aba3c1e99a6cbd464ada9a", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x227ea6d4336f178d19a6c3a96a9c67886365943c547eba8bc3264352c58d49b5", + "0x0ab64a8ec7844b84698532feb08dd86e85cb6e4fec68c5b4161142c43c49ae83", + "0x20bf663f55e9d2ee08565dee96b424f44f3d6254d1f95848fd9bd35f34b6ed3f", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", - "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x000000000000000000000000000000000000000000000000000000000000005a", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000f68447ed8472d9f9aecf573652a9d9a928", - "0x0000000000000000000000000000000000130b78833f316a05f0ac3ebb960dd6", - "0x000000000000000000000000000000b1b7566b1bdad938d7329c4055a9d3b44b", - "0x00000000000000000000000000000000000f95bf795c56af943937121ccabb11", - "0x0000000000000000000000000000007e871cbdb15c3280bb41589af6d4bf4600", - "0x0000000000000000000000000000000000005841a06f458a5220f323f6e67389", - "0x00000000000000000000000000000037a8be1964e1c1bf15fa90bbade2ae533e", - "0x00000000000000000000000000000000002fd8adf54cbe47073d8c68ab7231c7", - "0x0000000000000000000000000000007e2dfa58dd9e40bb6ee06db57e6892ad8e", - "0x0000000000000000000000000000000000228189c3a773ff5454da3c52426f43", - "0x000000000000000000000000000000ce262d6729da8006583c8f4a499313308d", - "0x0000000000000000000000000000000000121dc58a8b11eda0e11e988dc148f3", - "0x000000000000000000000000000000d483c67a2dd422d558a2bc6a0dc65c5441", - "0x00000000000000000000000000000000001436c8685ec282c19bacd9671e3424", - "0x000000000000000000000000000000505cfbf25a6b529a79d93da8a67a535226", - "0x0000000000000000000000000000000000277d585acb24a736a24c1c8715e0aa", - "0x0000000000000000000000000000000f71609653b0671afa25e611656d7024e2", - "0x000000000000000000000000000000000026075d31cd834975ea2ca0b120b383", - "0x000000000000000000000000000000307b6f68e4b5f4b0b1f1c7bf03a5442d7c", - "0x00000000000000000000000000000000001ef258df94844ef33b6ebc66098df9", - "0x000000000000000000000000000000366ab50465812874d088c1c47734295381", - "0x0000000000000000000000000000000000065332753549245a04b0f54d60d47d", - "0x00000000000000000000000000000016902f2c8fd7591bd62d52226e951c25b0", - "0x00000000000000000000000000000000002c90216fa88bb7b51a01c3ef4a320e", - "0x000000000000000000000000000000bbb432c76b363d49388741cd8557e22106", - "0x00000000000000000000000000000000002565b0ddbf8d6afaa067b84cb1f12e", - "0x000000000000000000000000000000974b3ad2190f2582dda8748859d47859a0", - "0x00000000000000000000000000000000000b31cf0fb5ec5e6d8541057aa4e2f2", - "0x000000000000000000000000000000025960f9968c5bbf83d3f7a484672b98d8", - "0x000000000000000000000000000000000013026001fd1b1981ad17e862f15a34", - "0x0000000000000000000000000000006e292910e9382851ed4de1b3ee3474c02c", - "0x00000000000000000000000000000000000c2fb93933722953cc5775728b35ec", + "0x000000000000000000000000000000171745e04bf3b398c7f018d6c6ae85b3ef", + "0x00000000000000000000000000000000002d29010b4f67617c7fa29ecf4da7bd", + "0x0000000000000000000000000000007e142d358ce3025e203266340fadcb38c0", + "0x00000000000000000000000000000000001acb070656c346e11208f8dca55fae", + "0x000000000000000000000000000000e3e90c58fa5859e2d0aa0fb6b90ae9d265", + "0x000000000000000000000000000000000022783a0a9afc9c35031a0b19c7252e", + "0x000000000000000000000000000000c3a8425b7dcf2974de08a6bea90bfb0e1d", + "0x00000000000000000000000000000000002bd5d0e482013f36dda8eccbf7a069", + "0x0000000000000000000000000000002c67a6a29b02e9d70e2d9c2a7c96ba325e", + "0x000000000000000000000000000000000006313947f257232e74af2725539a51", + "0x000000000000000000000000000000f96f7f92eb52e2421e05bf6726e5f7e46b", + "0x0000000000000000000000000000000000124964611e1e45432d534a938db40a", + "0x00000000000000000000000000000086b5767bea5905c98b657e7d7c5df5be52", + "0x00000000000000000000000000000000000b5d55777d6fbbbfedb0ab4159fe8e", + "0x000000000000000000000000000000f6cb975fc5e09435cab1575065181c9c2c", + "0x00000000000000000000000000000000001f582f62643dea4ddeff66741e8701", + "0x000000000000000000000000000000c1cc0960b5deade01b39fb1f622cae521a", + "0x00000000000000000000000000000000001580775480fdb3833934a90121e165", + "0x000000000000000000000000000000774ea1c3c41ff817e476e5530bca26eaab", + "0x000000000000000000000000000000000006bda2f1bb3dc2cbc0d79d978af377", + "0x000000000000000000000000000000419449bd1437352776172dd6816ce01dd2", + "0x00000000000000000000000000000000002e348f228b7408ea46fe5e1e025505", + "0x0000000000000000000000000000007ce1205f647113997b2de73126f283392e", + "0x00000000000000000000000000000000002d5e513e28ac080651a3520945c0dd", + "0x000000000000000000000000000000ad4992f90698806c2026a963d6c03b5db0", + "0x00000000000000000000000000000000001299de9aa8babae826bf90a96c3cbd", + "0x0000000000000000000000000000005baecf5414ff1c3aa1e099c5c2895f939f", + "0x00000000000000000000000000000000000c43f1a9a1c99f5f121a8672e1ad98", + "0x000000000000000000000000000000053cf0a6319726d0a4e166968e5b693d5d", + "0x000000000000000000000000000000000013003ee93f6bba3ca2dc482d747dd8", + "0x000000000000000000000000000000caa294c2200f26ea3353353f2abbab015a", + "0x0000000000000000000000000000000000174b38a5ed5ae78a18ca17193a5d66", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000239e2f11ea91c867d7080a159fc15e5711", - "0x000000000000000000000000000000000020983a3f65fd98715524f3be6a4d48", - "0x0000000000000000000000000000006251dee2124c8e8689c942362741d1b770", - "0x00000000000000000000000000000000002990e25ef65b37a0c14b2a53e370aa", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000811ba385bb8164bb5124cb1ae0b3ccb0c8", + "0x000000000000000000000000000000000014a46f70f1518de5fada5f535fab0d", + "0x000000000000000000000000000000cd91281c2f45667dcbe30858ef08312a30", + "0x00000000000000000000000000000000000ed382566771a880cc4467c7948f6b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1379,57 +1447,61 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005202c34600815583df0c2d0e0b711d9da9", - "0x000000000000000000000000000000000013c8db79f7fdf811172fde1144dee9", - "0x00000000000000000000000000000052109b26b144a2cdc1af4e5e60c04be21a", - "0x00000000000000000000000000000000002393c00b1515c1404d7d61513a265f", - "0x0000000000000000000000000000007241727fbbf4010a2c843195cdbeafd157", - "0x00000000000000000000000000000000000a795ef6998b55f779b66ac9d12933", - "0x0000000000000000000000000000001aee6f0314cb405e0bb90e540c1d4b5825", - "0x0000000000000000000000000000000000224ad4b3d1292b0599b3a2d611f162", - "0x000000000000000000000000000000f91ff5901f79ce2e9d2658719987ab0623", - "0x00000000000000000000000000000000001805237be733c97c8936141b767f20", - "0x000000000000000000000000000000a463dafbf5544b77b523e6d0b2e184f1b7", - "0x00000000000000000000000000000000000dd5ca5243a5f9287374bfe50d7231", - "0x000000000000000000000000000000d9d38a9ffb02c68fde1512e5bd4c4c14a1", - "0x00000000000000000000000000000000001feb05f2a116d8eb36aa9d0d39a059", - "0x00000000000000000000000000000036722e643e3ae6ed827a7a3545cb08d7af", - "0x00000000000000000000000000000000002a3543973beaa6206a0c0a81bc4d00", - "0x000000000000000000000000000000df116db890832c4330270e033c9c5b4672", - "0x000000000000000000000000000000000023249bec10f97d4e917ac37cd51f84", - "0x0000000000000000000000000000008c2ac8784c4c7231ef13cf8a40238cde28", - "0x00000000000000000000000000000000001a796365a3f5248fe27f83bbdfc204", - "0x0000000000000000000000000000004d37afbe9da8f90b8baf6fc91e16d8d686", - "0x0000000000000000000000000000000000239d7a93793b18511f1718afa60011", - "0x0000000000000000000000000000006553c4d22e787acd03956f3b68568d5af6", - "0x000000000000000000000000000000000019f0fa65aacb4f914e73a29b12ff95", - "0x00000000000000000000000000000021f7c2075b834340682cd55e057cd40797", - "0x000000000000000000000000000000000020cf3ed909b8b916f364f3e092d695", - "0x000000000000000000000000000000560c871bf2b8a17f94e0ee25d928b95ba5", - "0x000000000000000000000000000000000024ae77e31b4f17dd55e0eec865690d", - "0x00000000000000000000000000000084690b7ac3d1dddfcaa97b06bda3931daf", - "0x00000000000000000000000000000000002e5eea7caf51d4bf55b60a155b924a", - "0x0000000000000000000000000000004739db956c4c8cadd30b1ddf710b76bef3", - "0x00000000000000000000000000000000000c167a87058b33567470ed345dd62c", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000f358d0d158178b8c1c5d1ab306fc824c6e", - "0x00000000000000000000000000000000001bfd8927e824b9139109755ac78ae8", - "0x0000000000000000000000000000009f633351b5460cd99ae56aa83c0a509e80", - "0x000000000000000000000000000000000007a02b5dd7f155aba055ff7b97cefc", - "0x000000000000000000000000000000b4411838e9bff24af3fd0a5d83f0c11530", - "0x0000000000000000000000000000000000151208bcc3e48a87e85b4589c38db6", - "0x000000000000000000000000000000c97cd77b3a0e92086255723ecaf28d7e38", - "0x00000000000000000000000000000000000200b49f18b0213dd44e92f80d6c8f", - "0x000000000000000000000000000000ca55dc2b5233494a2fec946463b3580977", - "0x000000000000000000000000000000000002f0544254905ba4070d96e3cad8f5", - "0x000000000000000000000000000000a64246255e19fd5bfda22d42dfa6f33a06", - "0x00000000000000000000000000000000000f00cca836c24c894ef5b80652121b", - "0x00000000000000000000000000000064af99efc74cc9f94032445418dfe0ca63", - "0x00000000000000000000000000000000002ccbc5204c523afd51ef21b0d7297a", - "0x000000000000000000000000000000d3014926288a126140b79c57f8a1e3adf4", - "0x00000000000000000000000000000000002ea5f5bf7c4bbd05edf988f1b9319d" + "0x000000000000000000000000000000d08dc4216b73b18e4c3ed59f21747b058f", + "0x00000000000000000000000000000000000f066d4a5afea9a9b17ac7a4a7cc99", + "0x000000000000000000000000000000ae5a45c00369f87fd89e22ed8e9ae1b26c", + "0x00000000000000000000000000000000001772032f7513bfb4ec87cb3c381466", + "0x000000000000000000000000000000e844445263c1d09569b0a208a43dac22b0", + "0x0000000000000000000000000000000000200746d0ebd31e3100e54785e10a4e", + "0x000000000000000000000000000000e3abbce6e85aa82777100e42a403024f3b", + "0x00000000000000000000000000000000000edcdda7c859a9d532c0ecfb8ae20d", + "0x00000000000000000000000000000077654349e6de2d9f54eecec593fad39688", + "0x00000000000000000000000000000000001858d1181a4a332e734715b230cc59", + "0x000000000000000000000000000000175f205fe38af64c31f7109fe199ec1900", + "0x00000000000000000000000000000000001dc0769cc520d9832a85f6fc6ad2f0", + "0x000000000000000000000000000000b21544115e91a3e87e82672d838b37ba80", + "0x0000000000000000000000000000000000304b97f5ba72167a15c0b833fc6e8d", + "0x00000000000000000000000000000000a28a8d6a681bfedafbb78c8f05565163", + "0x00000000000000000000000000000000002617676042a6adddc34ef4325149de", + "0x00000000000000000000000000000087ed1863d8e1416fb7158da65866e4905c", + "0x0000000000000000000000000000000000297bf50f0815ed89b57efede14c221", + "0x000000000000000000000000000000ae75086dec67f3335af3eb56b5b59b46a8", + "0x00000000000000000000000000000000002f0ba91e3b0790f289a7a77033e944", + "0x0000000000000000000000000000008f1dc7ef52a66f9709b8276541459e5095", + "0x00000000000000000000000000000000001b8b733300f4a04e62e2b50cc13537", + "0x000000000000000000000000000000120c29128fdee9cac819e27d5e59b62c29", + "0x000000000000000000000000000000000007f266f7b45c332f902e07fdd930bb", + "0x000000000000000000000000000000673453fb2c427268658bd000eeff115cb1", + "0x00000000000000000000000000000000000bc9ee806b99e82569edbb5f01728f", + "0x00000000000000000000000000000060ede2f231b1961d20baa0c6b4195e45bf", + "0x00000000000000000000000000000000001a9ea1cc089db77b86d97e1b446b29", + "0x000000000000000000000000000000a240272a1d5cf9035d901f1e883f40dd04", + "0x00000000000000000000000000000000000d1d8059a04690c9ff079bc8e360ab", + "0x0000000000000000000000000000001ed32f48f420b19033840fedaab24a3671", + "0x00000000000000000000000000000000002a73ca315ef97290b6770ea6777586", + "0x0000000000000000000000000000005e496c48f730a346769ce8bc2fa408dd59", + "0x00000000000000000000000000000000001f44c5be9e8cb3632b163f9dce5b20", + "0x0000000000000000000000000000009a00247b355a24abf0fb6c6c38110e74ea", + "0x0000000000000000000000000000000000186011779c1a4f37f6ab96ec86ba1a", + "0x0000000000000000000000000000002c0ae96c1361972ddb673c19f868179414", + "0x000000000000000000000000000000000029aaace5fe8f52e2ffdb68539bf235", + "0x0000000000000000000000000000006d052b1eff6e35a175c1929237f54f145b", + "0x00000000000000000000000000000000000f79b8aa3c77ea22fec93ed13cc5db", + "0x0000000000000000000000000000008052b188ebeacba7640c39ca287fb43e02", + "0x00000000000000000000000000000000002c779c488a957ccbecd16bc0cef28f", + "0x0000000000000000000000000000003f0e4e60d839ab664210af647497054ec0", + "0x000000000000000000000000000000000017ac139d9ed663f80bc8f3bf9186eb", + "0x000000000000000000000000000000cd1b57f96c184006a7673bf67a70da6652", + "0x000000000000000000000000000000000008708c2dfc9b753226ad22fe6c36b3", + "0x0000000000000000000000000000006bcef5e19dcef445d5a8db81b6d9045df9", + "0x0000000000000000000000000000000000249f0fa7bf3615dc480813e351a6fc", + "0x000000000000000000000000000000edcc29049f239f4a6a6713f3d83c690c5c", + "0x000000000000000000000000000000000021e16eb6b2964938cc952d8f835ae7", + "0x00000000000000000000000000000065b062c409079f27e1fbcaa3227ce4c2f7", + "0x00000000000000000000000000000000001ef55120570e943466eefd433a3ebf" ] - hash = "0x01343c2fd6c1ffb7f74e657666d03b4842aa647357eeafa82c9a740c7ab7c0f5" + hash = "0x1aef2e89b01e4e061677cac5349fec0eb6935d55d28eef632d06e59bf9063afd" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml index 725258425a8f..5bc4ab2feb61 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-empty-tx/Prover.toml @@ -1,6 +1,16 @@ [inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" -new_l1_to_l2_message_subtree_root_sibling_path = [ +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", @@ -61,558 +71,6 @@ new_archive_sibling_path = [ "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" ] - [inputs.parity_root] - proof = [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x000000000000000000000000000000000000000000000000000000000000000d", - "0x000000000000000000000000000000000000000000000000000000000000000e", - "0x000000000000000000000000000000000000000000000000000000000000000f", - "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000011", - "0x0000000000000000000000000000000000000000000000000000000000000012", - "0x0000000000000000000000000000000000000000000000000000000000000013", - "0x0000000000000000000000000000000000000000000000000000000000000014", - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x0000000000000000000000000000000000000000000000000000000000000017", - "0x0000000000000000000000000000000000000000000000000000000000000018", - "0x0000000000000000000000000000000000000000000000000000000000000019", - "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x000000000000000000000000000000000000000000000000000000000000001b", - "0x000000000000000000000000000000000000000000000000000000000000001c", - "0x000000000000000000000000000000000000000000000000000000000000001d", - "0x000000000000000000000000000000000000000000000000000000000000001e", - "0x000000000000000000000000000000000000000000000000000000000000001f", - "0x0000000000000000000000000000000000000000000000000000000000000020", - "0x0000000000000000000000000000000000000000000000000000000000000021", - "0x0000000000000000000000000000000000000000000000000000000000000022", - "0x0000000000000000000000000000000000000000000000000000000000000023", - "0x0000000000000000000000000000000000000000000000000000000000000024", - "0x0000000000000000000000000000000000000000000000000000000000000025", - "0x0000000000000000000000000000000000000000000000000000000000000026", - "0x0000000000000000000000000000000000000000000000000000000000000027", - "0x0000000000000000000000000000000000000000000000000000000000000028", - "0x0000000000000000000000000000000000000000000000000000000000000029", - "0x000000000000000000000000000000000000000000000000000000000000002a", - "0x000000000000000000000000000000000000000000000000000000000000002b", - "0x000000000000000000000000000000000000000000000000000000000000002c", - "0x000000000000000000000000000000000000000000000000000000000000002d", - "0x000000000000000000000000000000000000000000000000000000000000002e", - "0x000000000000000000000000000000000000000000000000000000000000002f", - "0x0000000000000000000000000000000000000000000000000000000000000030", - "0x0000000000000000000000000000000000000000000000000000000000000031", - "0x0000000000000000000000000000000000000000000000000000000000000032", - "0x0000000000000000000000000000000000000000000000000000000000000033", - "0x0000000000000000000000000000000000000000000000000000000000000034", - "0x0000000000000000000000000000000000000000000000000000000000000035", - "0x0000000000000000000000000000000000000000000000000000000000000036", - "0x0000000000000000000000000000000000000000000000000000000000000037", - "0x0000000000000000000000000000000000000000000000000000000000000038", - "0x0000000000000000000000000000000000000000000000000000000000000039", - "0x000000000000000000000000000000000000000000000000000000000000003a", - "0x000000000000000000000000000000000000000000000000000000000000003b", - "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x000000000000000000000000000000000000000000000000000000000000003d", - "0x000000000000000000000000000000000000000000000000000000000000003e", - "0x000000000000000000000000000000000000000000000000000000000000003f", - "0x0000000000000000000000000000000000000000000000000000000000000040", - "0x0000000000000000000000000000000000000000000000000000000000000041", - "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000043", - "0x0000000000000000000000000000000000000000000000000000000000000044", - "0x0000000000000000000000000000000000000000000000000000000000000045", - "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000047", - "0x0000000000000000000000000000000000000000000000000000000000000048", - "0x0000000000000000000000000000000000000000000000000000000000000049", - "0x000000000000000000000000000000000000000000000000000000000000004a", - "0x000000000000000000000000000000000000000000000000000000000000004b", - "0x000000000000000000000000000000000000000000000000000000000000004c", - "0x000000000000000000000000000000000000000000000000000000000000004d", - "0x000000000000000000000000000000000000000000000000000000000000004e", - "0x000000000000000000000000000000000000000000000000000000000000004f", - "0x0000000000000000000000000000000000000000000000000000000000000050", - "0x0000000000000000000000000000000000000000000000000000000000000051", - "0x0000000000000000000000000000000000000000000000000000000000000052", - "0x0000000000000000000000000000000000000000000000000000000000000053", - "0x0000000000000000000000000000000000000000000000000000000000000054", - "0x0000000000000000000000000000000000000000000000000000000000000055", - "0x0000000000000000000000000000000000000000000000000000000000000056", - "0x0000000000000000000000000000000000000000000000000000000000000057", - "0x0000000000000000000000000000000000000000000000000000000000000058", - "0x0000000000000000000000000000000000000000000000000000000000000059", - "0x000000000000000000000000000000000000000000000000000000000000005a", - "0x000000000000000000000000000000000000000000000000000000000000005b", - "0x000000000000000000000000000000000000000000000000000000000000005c", - "0x000000000000000000000000000000000000000000000000000000000000005d", - "0x000000000000000000000000000000000000000000000000000000000000005e", - "0x000000000000000000000000000000000000000000000000000000000000005f", - "0x0000000000000000000000000000000000000000000000000000000000000060", - "0x0000000000000000000000000000000000000000000000000000000000000061", - "0x0000000000000000000000000000000000000000000000000000000000000062", - "0x0000000000000000000000000000000000000000000000000000000000000063", - "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000065", - "0x0000000000000000000000000000000000000000000000000000000000000066", - "0x0000000000000000000000000000000000000000000000000000000000000067", - "0x0000000000000000000000000000000000000000000000000000000000000068", - "0x0000000000000000000000000000000000000000000000000000000000000069", - "0x000000000000000000000000000000000000000000000000000000000000006a", - "0x000000000000000000000000000000000000000000000000000000000000006b", - "0x000000000000000000000000000000000000000000000000000000000000006c", - "0x000000000000000000000000000000000000000000000000000000000000006d", - "0x000000000000000000000000000000000000000000000000000000000000006e", - "0x000000000000000000000000000000000000000000000000000000000000006f", - "0x0000000000000000000000000000000000000000000000000000000000000070", - "0x0000000000000000000000000000000000000000000000000000000000000071", - "0x0000000000000000000000000000000000000000000000000000000000000072", - "0x0000000000000000000000000000000000000000000000000000000000000073", - "0x0000000000000000000000000000000000000000000000000000000000000074", - "0x0000000000000000000000000000000000000000000000000000000000000075", - "0x0000000000000000000000000000000000000000000000000000000000000076", - "0x0000000000000000000000000000000000000000000000000000000000000077", - "0x0000000000000000000000000000000000000000000000000000000000000078", - "0x0000000000000000000000000000000000000000000000000000000000000079", - "0x000000000000000000000000000000000000000000000000000000000000007a", - "0x000000000000000000000000000000000000000000000000000000000000007b", - "0x000000000000000000000000000000000000000000000000000000000000007c", - "0x000000000000000000000000000000000000000000000000000000000000007d", - "0x000000000000000000000000000000000000000000000000000000000000007e", - "0x000000000000000000000000000000000000000000000000000000000000007f", - "0x0000000000000000000000000000000000000000000000000000000000000080", - "0x0000000000000000000000000000000000000000000000000000000000000081", - "0x0000000000000000000000000000000000000000000000000000000000000082", - "0x0000000000000000000000000000000000000000000000000000000000000083", - "0x0000000000000000000000000000000000000000000000000000000000000084", - "0x0000000000000000000000000000000000000000000000000000000000000085", - "0x0000000000000000000000000000000000000000000000000000000000000086", - "0x0000000000000000000000000000000000000000000000000000000000000087", - "0x0000000000000000000000000000000000000000000000000000000000000088", - "0x0000000000000000000000000000000000000000000000000000000000000089", - "0x000000000000000000000000000000000000000000000000000000000000008a", - "0x000000000000000000000000000000000000000000000000000000000000008b", - "0x000000000000000000000000000000000000000000000000000000000000008c", - "0x000000000000000000000000000000000000000000000000000000000000008d", - "0x000000000000000000000000000000000000000000000000000000000000008e", - "0x000000000000000000000000000000000000000000000000000000000000008f", - "0x0000000000000000000000000000000000000000000000000000000000000090", - "0x0000000000000000000000000000000000000000000000000000000000000091", - "0x0000000000000000000000000000000000000000000000000000000000000092", - "0x0000000000000000000000000000000000000000000000000000000000000093", - "0x0000000000000000000000000000000000000000000000000000000000000094", - "0x0000000000000000000000000000000000000000000000000000000000000095", - "0x0000000000000000000000000000000000000000000000000000000000000096", - "0x0000000000000000000000000000000000000000000000000000000000000097", - "0x0000000000000000000000000000000000000000000000000000000000000098", - "0x0000000000000000000000000000000000000000000000000000000000000099", - "0x000000000000000000000000000000000000000000000000000000000000009a", - "0x000000000000000000000000000000000000000000000000000000000000009b", - "0x000000000000000000000000000000000000000000000000000000000000009c", - "0x000000000000000000000000000000000000000000000000000000000000009d", - "0x000000000000000000000000000000000000000000000000000000000000009e", - "0x000000000000000000000000000000000000000000000000000000000000009f", - "0x00000000000000000000000000000000000000000000000000000000000000a0", - "0x00000000000000000000000000000000000000000000000000000000000000a1", - "0x00000000000000000000000000000000000000000000000000000000000000a2", - "0x00000000000000000000000000000000000000000000000000000000000000a3", - "0x00000000000000000000000000000000000000000000000000000000000000a4", - "0x00000000000000000000000000000000000000000000000000000000000000a5", - "0x00000000000000000000000000000000000000000000000000000000000000a6", - "0x00000000000000000000000000000000000000000000000000000000000000a7", - "0x00000000000000000000000000000000000000000000000000000000000000a8", - "0x00000000000000000000000000000000000000000000000000000000000000a9", - "0x00000000000000000000000000000000000000000000000000000000000000aa", - "0x00000000000000000000000000000000000000000000000000000000000000ab", - "0x00000000000000000000000000000000000000000000000000000000000000ac", - "0x00000000000000000000000000000000000000000000000000000000000000ad", - "0x00000000000000000000000000000000000000000000000000000000000000ae", - "0x00000000000000000000000000000000000000000000000000000000000000af", - "0x00000000000000000000000000000000000000000000000000000000000000b0", - "0x00000000000000000000000000000000000000000000000000000000000000b1", - "0x00000000000000000000000000000000000000000000000000000000000000b2", - "0x00000000000000000000000000000000000000000000000000000000000000b3", - "0x00000000000000000000000000000000000000000000000000000000000000b4", - "0x00000000000000000000000000000000000000000000000000000000000000b5", - "0x00000000000000000000000000000000000000000000000000000000000000b6", - "0x00000000000000000000000000000000000000000000000000000000000000b7", - "0x00000000000000000000000000000000000000000000000000000000000000b8", - "0x00000000000000000000000000000000000000000000000000000000000000b9", - "0x00000000000000000000000000000000000000000000000000000000000000ba", - "0x00000000000000000000000000000000000000000000000000000000000000bb", - "0x00000000000000000000000000000000000000000000000000000000000000bc", - "0x00000000000000000000000000000000000000000000000000000000000000bd", - "0x00000000000000000000000000000000000000000000000000000000000000be", - "0x00000000000000000000000000000000000000000000000000000000000000bf", - "0x00000000000000000000000000000000000000000000000000000000000000c0", - "0x00000000000000000000000000000000000000000000000000000000000000c1", - "0x00000000000000000000000000000000000000000000000000000000000000c2", - "0x00000000000000000000000000000000000000000000000000000000000000c3", - "0x00000000000000000000000000000000000000000000000000000000000000c4", - "0x00000000000000000000000000000000000000000000000000000000000000c5", - "0x00000000000000000000000000000000000000000000000000000000000000c6", - "0x00000000000000000000000000000000000000000000000000000000000000c7", - "0x00000000000000000000000000000000000000000000000000000000000000c8", - "0x00000000000000000000000000000000000000000000000000000000000000c9", - "0x00000000000000000000000000000000000000000000000000000000000000ca", - "0x00000000000000000000000000000000000000000000000000000000000000cb", - "0x00000000000000000000000000000000000000000000000000000000000000cc", - "0x00000000000000000000000000000000000000000000000000000000000000cd", - "0x00000000000000000000000000000000000000000000000000000000000000ce", - "0x00000000000000000000000000000000000000000000000000000000000000cf", - "0x00000000000000000000000000000000000000000000000000000000000000d0", - "0x00000000000000000000000000000000000000000000000000000000000000d1", - "0x00000000000000000000000000000000000000000000000000000000000000d2", - "0x00000000000000000000000000000000000000000000000000000000000000d3", - "0x00000000000000000000000000000000000000000000000000000000000000d4", - "0x00000000000000000000000000000000000000000000000000000000000000d5", - "0x00000000000000000000000000000000000000000000000000000000000000d6", - "0x00000000000000000000000000000000000000000000000000000000000000d7", - "0x00000000000000000000000000000000000000000000000000000000000000d8", - "0x00000000000000000000000000000000000000000000000000000000000000d9", - "0x00000000000000000000000000000000000000000000000000000000000000da", - "0x00000000000000000000000000000000000000000000000000000000000000db", - "0x00000000000000000000000000000000000000000000000000000000000000dc", - "0x00000000000000000000000000000000000000000000000000000000000000dd", - "0x00000000000000000000000000000000000000000000000000000000000000de", - "0x00000000000000000000000000000000000000000000000000000000000000df", - "0x00000000000000000000000000000000000000000000000000000000000000e0", - "0x00000000000000000000000000000000000000000000000000000000000000e1", - "0x00000000000000000000000000000000000000000000000000000000000000e2", - "0x00000000000000000000000000000000000000000000000000000000000000e3", - "0x00000000000000000000000000000000000000000000000000000000000000e4", - "0x00000000000000000000000000000000000000000000000000000000000000e5", - "0x00000000000000000000000000000000000000000000000000000000000000e6", - "0x00000000000000000000000000000000000000000000000000000000000000e7", - "0x00000000000000000000000000000000000000000000000000000000000000e8", - "0x00000000000000000000000000000000000000000000000000000000000000e9", - "0x00000000000000000000000000000000000000000000000000000000000000ea", - "0x00000000000000000000000000000000000000000000000000000000000000eb", - "0x00000000000000000000000000000000000000000000000000000000000000ec", - "0x00000000000000000000000000000000000000000000000000000000000000ed", - "0x00000000000000000000000000000000000000000000000000000000000000ee", - "0x00000000000000000000000000000000000000000000000000000000000000ef", - "0x00000000000000000000000000000000000000000000000000000000000000f0", - "0x00000000000000000000000000000000000000000000000000000000000000f1", - "0x00000000000000000000000000000000000000000000000000000000000000f2", - "0x00000000000000000000000000000000000000000000000000000000000000f3", - "0x00000000000000000000000000000000000000000000000000000000000000f4", - "0x00000000000000000000000000000000000000000000000000000000000000f5", - "0x00000000000000000000000000000000000000000000000000000000000000f6", - "0x00000000000000000000000000000000000000000000000000000000000000f7", - "0x00000000000000000000000000000000000000000000000000000000000000f8", - "0x00000000000000000000000000000000000000000000000000000000000000f9", - "0x00000000000000000000000000000000000000000000000000000000000000fa", - "0x00000000000000000000000000000000000000000000000000000000000000fb", - "0x00000000000000000000000000000000000000000000000000000000000000fc", - "0x00000000000000000000000000000000000000000000000000000000000000fd", - "0x00000000000000000000000000000000000000000000000000000000000000fe", - "0x00000000000000000000000000000000000000000000000000000000000000ff", - "0x0000000000000000000000000000000000000000000000000000000000000100", - "0x0000000000000000000000000000000000000000000000000000000000000101", - "0x0000000000000000000000000000000000000000000000000000000000000102", - "0x0000000000000000000000000000000000000000000000000000000000000103", - "0x0000000000000000000000000000000000000000000000000000000000000104", - "0x0000000000000000000000000000000000000000000000000000000000000105", - "0x0000000000000000000000000000000000000000000000000000000000000106", - "0x0000000000000000000000000000000000000000000000000000000000000107", - "0x0000000000000000000000000000000000000000000000000000000000000108", - "0x0000000000000000000000000000000000000000000000000000000000000109", - "0x000000000000000000000000000000000000000000000000000000000000010a", - "0x000000000000000000000000000000000000000000000000000000000000010b", - "0x000000000000000000000000000000000000000000000000000000000000010c", - "0x000000000000000000000000000000000000000000000000000000000000010d", - "0x000000000000000000000000000000000000000000000000000000000000010e", - "0x000000000000000000000000000000000000000000000000000000000000010f", - "0x0000000000000000000000000000000000000000000000000000000000000110", - "0x0000000000000000000000000000000000000000000000000000000000000111", - "0x0000000000000000000000000000000000000000000000000000000000000112", - "0x0000000000000000000000000000000000000000000000000000000000000113", - "0x0000000000000000000000000000000000000000000000000000000000000114", - "0x0000000000000000000000000000000000000000000000000000000000000115", - "0x0000000000000000000000000000000000000000000000000000000000000116", - "0x0000000000000000000000000000000000000000000000000000000000000117", - "0x0000000000000000000000000000000000000000000000000000000000000118", - "0x0000000000000000000000000000000000000000000000000000000000000119", - "0x000000000000000000000000000000000000000000000000000000000000011a", - "0x000000000000000000000000000000000000000000000000000000000000011b", - "0x000000000000000000000000000000000000000000000000000000000000011c", - "0x000000000000000000000000000000000000000000000000000000000000011d", - "0x000000000000000000000000000000000000000000000000000000000000011e", - "0x000000000000000000000000000000000000000000000000000000000000011f", - "0x0000000000000000000000000000000000000000000000000000000000000120", - "0x0000000000000000000000000000000000000000000000000000000000000121", - "0x0000000000000000000000000000000000000000000000000000000000000122", - "0x0000000000000000000000000000000000000000000000000000000000000123", - "0x0000000000000000000000000000000000000000000000000000000000000124", - "0x0000000000000000000000000000000000000000000000000000000000000125", - "0x0000000000000000000000000000000000000000000000000000000000000126", - "0x0000000000000000000000000000000000000000000000000000000000000127", - "0x0000000000000000000000000000000000000000000000000000000000000128", - "0x0000000000000000000000000000000000000000000000000000000000000129", - "0x000000000000000000000000000000000000000000000000000000000000012a", - "0x000000000000000000000000000000000000000000000000000000000000012b", - "0x000000000000000000000000000000000000000000000000000000000000012c", - "0x000000000000000000000000000000000000000000000000000000000000012d", - "0x000000000000000000000000000000000000000000000000000000000000012e", - "0x000000000000000000000000000000000000000000000000000000000000012f", - "0x0000000000000000000000000000000000000000000000000000000000000130", - "0x0000000000000000000000000000000000000000000000000000000000000131", - "0x0000000000000000000000000000000000000000000000000000000000000132", - "0x0000000000000000000000000000000000000000000000000000000000000133", - "0x0000000000000000000000000000000000000000000000000000000000000134", - "0x0000000000000000000000000000000000000000000000000000000000000135", - "0x0000000000000000000000000000000000000000000000000000000000000136", - "0x0000000000000000000000000000000000000000000000000000000000000137", - "0x0000000000000000000000000000000000000000000000000000000000000138", - "0x0000000000000000000000000000000000000000000000000000000000000139", - "0x000000000000000000000000000000000000000000000000000000000000013a", - "0x000000000000000000000000000000000000000000000000000000000000013b", - "0x000000000000000000000000000000000000000000000000000000000000013c", - "0x000000000000000000000000000000000000000000000000000000000000013d", - "0x000000000000000000000000000000000000000000000000000000000000013e", - "0x000000000000000000000000000000000000000000000000000000000000013f", - "0x0000000000000000000000000000000000000000000000000000000000000140", - "0x0000000000000000000000000000000000000000000000000000000000000141", - "0x0000000000000000000000000000000000000000000000000000000000000142", - "0x0000000000000000000000000000000000000000000000000000000000000143", - "0x0000000000000000000000000000000000000000000000000000000000000144", - "0x0000000000000000000000000000000000000000000000000000000000000145", - "0x0000000000000000000000000000000000000000000000000000000000000146", - "0x0000000000000000000000000000000000000000000000000000000000000147", - "0x0000000000000000000000000000000000000000000000000000000000000148", - "0x0000000000000000000000000000000000000000000000000000000000000149", - "0x000000000000000000000000000000000000000000000000000000000000014a", - "0x000000000000000000000000000000000000000000000000000000000000014b", - "0x000000000000000000000000000000000000000000000000000000000000014c", - "0x000000000000000000000000000000000000000000000000000000000000014d", - "0x000000000000000000000000000000000000000000000000000000000000014e", - "0x000000000000000000000000000000000000000000000000000000000000014f", - "0x0000000000000000000000000000000000000000000000000000000000000150", - "0x0000000000000000000000000000000000000000000000000000000000000151", - "0x0000000000000000000000000000000000000000000000000000000000000152", - "0x0000000000000000000000000000000000000000000000000000000000000153", - "0x0000000000000000000000000000000000000000000000000000000000000154", - "0x0000000000000000000000000000000000000000000000000000000000000155", - "0x0000000000000000000000000000000000000000000000000000000000000156", - "0x0000000000000000000000000000000000000000000000000000000000000157", - "0x0000000000000000000000000000000000000000000000000000000000000158", - "0x0000000000000000000000000000000000000000000000000000000000000159", - "0x000000000000000000000000000000000000000000000000000000000000015a", - "0x000000000000000000000000000000000000000000000000000000000000015b", - "0x000000000000000000000000000000000000000000000000000000000000015c", - "0x000000000000000000000000000000000000000000000000000000000000015d", - "0x000000000000000000000000000000000000000000000000000000000000015e", - "0x000000000000000000000000000000000000000000000000000000000000015f", - "0x0000000000000000000000000000000000000000000000000000000000000160", - "0x0000000000000000000000000000000000000000000000000000000000000161", - "0x0000000000000000000000000000000000000000000000000000000000000162", - "0x0000000000000000000000000000000000000000000000000000000000000163", - "0x0000000000000000000000000000000000000000000000000000000000000164", - "0x0000000000000000000000000000000000000000000000000000000000000165", - "0x0000000000000000000000000000000000000000000000000000000000000166", - "0x0000000000000000000000000000000000000000000000000000000000000167", - "0x0000000000000000000000000000000000000000000000000000000000000168", - "0x0000000000000000000000000000000000000000000000000000000000000169", - "0x000000000000000000000000000000000000000000000000000000000000016a", - "0x000000000000000000000000000000000000000000000000000000000000016b", - "0x000000000000000000000000000000000000000000000000000000000000016c", - "0x000000000000000000000000000000000000000000000000000000000000016d", - "0x000000000000000000000000000000000000000000000000000000000000016e", - "0x000000000000000000000000000000000000000000000000000000000000016f", - "0x0000000000000000000000000000000000000000000000000000000000000170", - "0x0000000000000000000000000000000000000000000000000000000000000171", - "0x0000000000000000000000000000000000000000000000000000000000000172", - "0x0000000000000000000000000000000000000000000000000000000000000173", - "0x0000000000000000000000000000000000000000000000000000000000000174", - "0x0000000000000000000000000000000000000000000000000000000000000175", - "0x0000000000000000000000000000000000000000000000000000000000000176", - "0x0000000000000000000000000000000000000000000000000000000000000177", - "0x0000000000000000000000000000000000000000000000000000000000000178", - "0x0000000000000000000000000000000000000000000000000000000000000179", - "0x000000000000000000000000000000000000000000000000000000000000017a", - "0x000000000000000000000000000000000000000000000000000000000000017b", - "0x000000000000000000000000000000000000000000000000000000000000017c", - "0x000000000000000000000000000000000000000000000000000000000000017d", - "0x000000000000000000000000000000000000000000000000000000000000017e", - "0x000000000000000000000000000000000000000000000000000000000000017f", - "0x0000000000000000000000000000000000000000000000000000000000000180", - "0x0000000000000000000000000000000000000000000000000000000000000181", - "0x0000000000000000000000000000000000000000000000000000000000000182", - "0x0000000000000000000000000000000000000000000000000000000000000183", - "0x0000000000000000000000000000000000000000000000000000000000000184", - "0x0000000000000000000000000000000000000000000000000000000000000185", - "0x0000000000000000000000000000000000000000000000000000000000000186", - "0x0000000000000000000000000000000000000000000000000000000000000187", - "0x0000000000000000000000000000000000000000000000000000000000000188", - "0x0000000000000000000000000000000000000000000000000000000000000189", - "0x000000000000000000000000000000000000000000000000000000000000018a", - "0x000000000000000000000000000000000000000000000000000000000000018b", - "0x000000000000000000000000000000000000000000000000000000000000018c", - "0x000000000000000000000000000000000000000000000000000000000000018d", - "0x000000000000000000000000000000000000000000000000000000000000018e", - "0x000000000000000000000000000000000000000000000000000000000000018f", - "0x0000000000000000000000000000000000000000000000000000000000000190", - "0x0000000000000000000000000000000000000000000000000000000000000191", - "0x0000000000000000000000000000000000000000000000000000000000000192", - "0x0000000000000000000000000000000000000000000000000000000000000193", - "0x0000000000000000000000000000000000000000000000000000000000000194", - "0x0000000000000000000000000000000000000000000000000000000000000195", - "0x0000000000000000000000000000000000000000000000000000000000000196", - "0x0000000000000000000000000000000000000000000000000000000000000197", - "0x0000000000000000000000000000000000000000000000000000000000000198", - "0x0000000000000000000000000000000000000000000000000000000000000199", - "0x000000000000000000000000000000000000000000000000000000000000019a" -] - - [inputs.parity_root.public_inputs] - sha_root = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" - converted_root = "0x2f7247450c6d856804ef9fade0d5af92e4b87b1576f07ec88359012bf4c21abf" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" - - [inputs.parity_root.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" - sibling_path = [ - "0x0f32425668cad3847a3ac0f871f98e235c4df15eb323b35d1bcee45576cff894", - "0x265fc4a3319a624ef133d498afc59fa5976e915d1e6770f924dd2913c001ae1d", - "0x1c47417eb2dc267d6e655a2150a05647d9280b96be65539aa158c6c46ca26969", - "0x2741ff7d37d2b0c0b75babfe4e7c3c94262ecd1a7aa5cde310a785c22821ba43", - "0x0f562a30dbca79c1e0123045d842e92b28e6d47450898bf672592537e3b86163", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" -] - - [inputs.parity_root.vk_data.vk] - key = [ - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000ffe755d8b3c57a1ab614512a4bedf19549", - "0x00000000000000000000000000000000000534da51986a838ae9c1792f2626e5", - "0x0000000000000000000000000000006ec5a4c07aa9de1b4d1622c25d851173b7", - "0x00000000000000000000000000000000001f7cc23b1a4486149ad1e8f97bc8fe", - "0x000000000000000000000000000000c65b28eb1be8ff3fba908d84f31181e8d1", - "0x000000000000000000000000000000000025b7e8b68a99cbf3a62e5a122483a3", - "0x000000000000000000000000000000bc231c09845555a404d388207beb4e797f", - "0x000000000000000000000000000000000016e17e8b5bfd5f0f0f274e3353ca27", - "0x0000000000000000000000000000001f0e86a5ee3b8134d872edb4a60d5ff6f1", - "0x00000000000000000000000000000000002a0177d3ec4ad4c379c0e2cf7189f7", - "0x00000000000000000000000000000007f4c0a1986540d335d55141ca6b084401", - "0x00000000000000000000000000000000000afc61b084b6c1333e18f61907bce6", - "0x000000000000000000000000000000945e9e96b7f2fc82278b5b6872e9971cfd", - "0x00000000000000000000000000000000002fcd10bc1f098fd35129cf5028c20a", - "0x000000000000000000000000000000d660c3c7aa2141f169e733f8624cdfaf30", - "0x00000000000000000000000000000000002d136c80a84a6cc3d0edc85f1ddb5e", - "0x00000000000000000000000000000019b846fcf3cbd0fe88fb0ea0a36dcc317c", - "0x00000000000000000000000000000000001f6e082c765eb5f7751204bc42a5d4", - "0x000000000000000000000000000000c1892b383cec3510bf322c430821c6f092", - "0x00000000000000000000000000000000000b1872d98dc6e92c02a654071f8189", - "0x0000000000000000000000000000005a50e192dd251cb43ea57484becf366e85", - "0x000000000000000000000000000000000003ba6440f3f173c213b050800e042f", - "0x0000000000000000000000000000007944d08a075210d9dd10d1662ff8e5878e", - "0x00000000000000000000000000000000000a02396b3dbafce1dc3bcd2851bced", - "0x000000000000000000000000000000ce97a1200ac29836f9aa4b2b6e7a0f85a8", - "0x0000000000000000000000000000000000114252197e7829a46578e5f6f14e35", - "0x00000000000000000000000000000089644b4427a04f25fd862da89ef02b47c4", - "0x00000000000000000000000000000000001b70d9301a5c36773bcded3edd6c80", - "0x0000000000000000000000000000007ed1a5255c653cda257387c8755336e3ef", - "0x0000000000000000000000000000000000098bbdc9e2200ccd02cfc0889201a3", - "0x000000000000000000000000000000700b1f800cc62fc982ba222a3c836e28ab", - "0x00000000000000000000000000000000000440c58c9932c8b4a645dd7bf1f8f6", - "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", - "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", - "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", - "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000e74a52afca5802c96d87095252c73242ed", - "0x00000000000000000000000000000000001921ed8f6aa19d3b01e136443e9c43", - "0x000000000000000000000000000000e8e94042f88a31b913e55169c6fc9fd899", - "0x00000000000000000000000000000000001b38acf2cbe1b8745e483f83e05f4b", - "0x0000000000000000000000000000006eed465622852dce8a0702c5327cff0583", - "0x000000000000000000000000000000000022b0941f412859d1cc37a757ca4375", - "0x0000000000000000000000000000008bef872c634b8c03bfe7ff37c00a727192", - "0x000000000000000000000000000000000004906c8767a040a562b166a360c43b", - "0x0000000000000000000000000000002196aef3cb99415b3ac5297aac8f112fc6", - "0x0000000000000000000000000000000000202bc7de55cc5837eb14b1c9170f8b", - "0x000000000000000000000000000000bdf27b518418573439ed9eae4c5e5fb565", - "0x000000000000000000000000000000000017b3d9bbe6a673b931642f99c5da31", - "0x000000000000000000000000000000f02ba591cd0b41bb042d8e128595192f02", - "0x00000000000000000000000000000000000e91c21c980b16cf781f41a63337b6", - "0x000000000000000000000000000000df236435bb93d1ba03853ec32ce9bac516", - "0x00000000000000000000000000000000000c79c6f2ebdbb8e9a9ced4fe147b70", - "0x0000000000000000000000000000003fffb3aa510e7f700cf1014e5872d9c836", - "0x00000000000000000000000000000000002a8a152385a9322608448c3b903a25", - "0x000000000000000000000000000000e0e29574c018f3c6738e2e39d4c5add9a0", - "0x00000000000000000000000000000000000fc61b53a775b4a4abe28883bd4cae", - "0x00000000000000000000000000000015ad8f2e516ea41308c308441bd42c61e8", - "0x00000000000000000000000000000000002ae1b82b97d47244a5cbf6785de890", - "0x000000000000000000000000000000c903532912619760836806241aafc8d682", - "0x00000000000000000000000000000000000ad9c58de8e6372d34bc7aac8d1aca", - "0x000000000000000000000000000000c6e9efa1c758924d7de45017a05726fca7", - "0x00000000000000000000000000000000001da169f438cfc870048ea757c938a9", - "0x000000000000000000000000000000173aa01a946f89910fbc61ce0978f11df6", - "0x000000000000000000000000000000000010511a8cf921804a7d1a6f7d6b7e4a", - "0x000000000000000000000000000000d9292eae3d7214cf357ecbfd5450e48dc5", - "0x00000000000000000000000000000000002c4fdd575051b7aed86ed22911ebaf", - "0x000000000000000000000000000000d14cc302deb68c94d33c31626af7c943d5", - "0x00000000000000000000000000000000001fa409243e8e0d777188a76d20f835", - "0x000000000000000000000000000000f9d9dceb4a21921fa5d9edf02aa5383e77", - "0x000000000000000000000000000000000002acc34aa553acf2a60116f38df796", - "0x0000000000000000000000000000002c76aa33d3ada3dc142abb8e0a3e1191e1", - "0x0000000000000000000000000000000000147d02c32b9568f5252f6c9e1f108f", - "0x00000000000000000000000000000088a07098dc2dbe19a768a0a19614ae8f47", - "0x0000000000000000000000000000000000006f5dc4ddaf221bb7b9034c756597", - "0x000000000000000000000000000000631dc92a76396edbb65457f05dedc64864", - "0x00000000000000000000000000000000001a23a09ca622bd72a07792694d2931", - "0x00000000000000000000000000000061cb9c09b369db2c419adba705d0f8ddb3", - "0x00000000000000000000000000000000001377787d2f2084b9263c965fbf2e2c", - "0x00000000000000000000000000000099eb45fd3667ef5b823282f9deb302de03", - "0x00000000000000000000000000000000001d090be973bf574d0eb446d4ad64b2", - "0x000000000000000000000000000000c63f86d07e1aff3f0052511400edb2be2e", - "0x00000000000000000000000000000000002c65a1bf4ceba12047a3072eb5f2e0", - "0x0000000000000000000000000000002b8a4436889976e6b5cce13fb8b12327ac", - "0x00000000000000000000000000000000000585cb3553e38f6e8404d11734d67a", - "0x000000000000000000000000000000cfaf000e5b5293d4e63f49f1944eb2e05c", - "0x000000000000000000000000000000000011ddb77ef38de130795dcbc345f56e", - "0x000000000000000000000000000000c61f53c944f6d05ab07a3ee14f114138eb", - "0x000000000000000000000000000000000009ad7168055eddbe696b65fb3bddca", - "0x000000000000000000000000000000fe83caf00dfb98e145f37f5a24108f0e34", - "0x000000000000000000000000000000000013b57406261bf3d6d6f4e866b9da62", - "0x000000000000000000000000000000b9220b111331f6f8ee0ad8f6ebbaaaf462", - "0x00000000000000000000000000000000000e0f9e959f65b073ee1bedcc1efbc0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000f034a50a2cc8ad7a610cacc87072f43b5e", - "0x000000000000000000000000000000000001b28e2039ba8b5fbb9a9b41d0b3d0", - "0x00000000000000000000000000000031581f609d92eb3f3edff4da364c25b2bc", - "0x000000000000000000000000000000000021cc73a6c61c10620816b6e866bb7e", - "0x000000000000000000000000000000968f7c89583557986b83af0d7c0380ffe9", - "0x0000000000000000000000000000000000071667384c3711bafccd202668b90c", - "0x000000000000000000000000000000ef6589f0004fbcb285a722163a045bb641", - "0x0000000000000000000000000000000000260b419489bfa802ea5c3746bd25a7", - "0x0000000000000000000000000000004e5ee61d5b7c158e8ee0ad7719a6118e14", - "0x00000000000000000000000000000000001eae1e642fd268200645995c408b86", - "0x000000000000000000000000000000e21942e59156a86d6dc7f28247aa5f07b8", - "0x000000000000000000000000000000000026429839f94d5b20f11ec2e82466ec", - "0x000000000000000000000000000000d881564b3e134e51c9f4a3d32e94ce84e4", - "0x00000000000000000000000000000000002ee2ded9a98c582833347ed5a0becb", - "0x000000000000000000000000000000122abebbcfad7ec560153c58baf5d58580", - "0x000000000000000000000000000000000003913b06b8b4b8b5dd5d594546c439" -] - hash = "0x2311de417e915bc1373f7386131344407c960c21a9c0dd41d74d57a53aef3eec" - [inputs.previous_archive] root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" @@ -636,8 +94,8 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -650,3 +108,264 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.constants.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.message_bundle] + messages = [ + "0x00000000000000000000000000000000000000000000000000000000000005dc", + "0x00000000000000000000000000000000000000000000000000000000000005dd", + "0x00000000000000000000000000000000000000000000000000000000000005de", + "0x00000000000000000000000000000000000000000000000000000000000005df", + "0x00000000000000000000000000000000000000000000000000000000000005e0", + "0x00000000000000000000000000000000000000000000000000000000000005e1", + "0x00000000000000000000000000000000000000000000000000000000000005e2", + "0x00000000000000000000000000000000000000000000000000000000000005e3", + "0x00000000000000000000000000000000000000000000000000000000000005e4", + "0x00000000000000000000000000000000000000000000000000000000000005e5", + "0x00000000000000000000000000000000000000000000000000000000000005e6", + "0x00000000000000000000000000000000000000000000000000000000000005e7", + "0x00000000000000000000000000000000000000000000000000000000000005e8", + "0x00000000000000000000000000000000000000000000000000000000000005e9", + "0x00000000000000000000000000000000000000000000000000000000000005ea", + "0x00000000000000000000000000000000000000000000000000000000000005eb", + "0x00000000000000000000000000000000000000000000000000000000000005ec", + "0x00000000000000000000000000000000000000000000000000000000000005ed", + "0x00000000000000000000000000000000000000000000000000000000000005ee", + "0x00000000000000000000000000000000000000000000000000000000000005ef", + "0x00000000000000000000000000000000000000000000000000000000000005f0", + "0x00000000000000000000000000000000000000000000000000000000000005f1", + "0x00000000000000000000000000000000000000000000000000000000000005f2", + "0x00000000000000000000000000000000000000000000000000000000000005f3", + "0x00000000000000000000000000000000000000000000000000000000000005f4", + "0x00000000000000000000000000000000000000000000000000000000000005f5", + "0x00000000000000000000000000000000000000000000000000000000000005f6", + "0x00000000000000000000000000000000000000000000000000000000000005f7", + "0x00000000000000000000000000000000000000000000000000000000000005f8", + "0x00000000000000000000000000000000000000000000000000000000000005f9", + "0x00000000000000000000000000000000000000000000000000000000000005fa", + "0x00000000000000000000000000000000000000000000000000000000000005fb", + "0x00000000000000000000000000000000000000000000000000000000000005fc", + "0x00000000000000000000000000000000000000000000000000000000000005fd", + "0x00000000000000000000000000000000000000000000000000000000000005fe", + "0x00000000000000000000000000000000000000000000000000000000000005ff", + "0x0000000000000000000000000000000000000000000000000000000000000600", + "0x0000000000000000000000000000000000000000000000000000000000000601", + "0x0000000000000000000000000000000000000000000000000000000000000602", + "0x0000000000000000000000000000000000000000000000000000000000000603", + "0x0000000000000000000000000000000000000000000000000000000000000604", + "0x0000000000000000000000000000000000000000000000000000000000000605", + "0x0000000000000000000000000000000000000000000000000000000000000606", + "0x0000000000000000000000000000000000000000000000000000000000000607", + "0x0000000000000000000000000000000000000000000000000000000000000608", + "0x0000000000000000000000000000000000000000000000000000000000000609", + "0x000000000000000000000000000000000000000000000000000000000000060a", + "0x000000000000000000000000000000000000000000000000000000000000060b", + "0x000000000000000000000000000000000000000000000000000000000000060c", + "0x000000000000000000000000000000000000000000000000000000000000060d", + "0x000000000000000000000000000000000000000000000000000000000000060e", + "0x000000000000000000000000000000000000000000000000000000000000060f", + "0x0000000000000000000000000000000000000000000000000000000000000610", + "0x0000000000000000000000000000000000000000000000000000000000000611", + "0x0000000000000000000000000000000000000000000000000000000000000612", + "0x0000000000000000000000000000000000000000000000000000000000000613", + "0x0000000000000000000000000000000000000000000000000000000000000614", + "0x0000000000000000000000000000000000000000000000000000000000000615", + "0x0000000000000000000000000000000000000000000000000000000000000616", + "0x0000000000000000000000000000000000000000000000000000000000000617", + "0x0000000000000000000000000000000000000000000000000000000000000618", + "0x0000000000000000000000000000000000000000000000000000000000000619", + "0x000000000000000000000000000000000000000000000000000000000000061a", + "0x000000000000000000000000000000000000000000000000000000000000061b", + "0x000000000000000000000000000000000000000000000000000000000000061c", + "0x000000000000000000000000000000000000000000000000000000000000061d", + "0x000000000000000000000000000000000000000000000000000000000000061e", + "0x000000000000000000000000000000000000000000000000000000000000061f", + "0x0000000000000000000000000000000000000000000000000000000000000620", + "0x0000000000000000000000000000000000000000000000000000000000000621", + "0x0000000000000000000000000000000000000000000000000000000000000622", + "0x0000000000000000000000000000000000000000000000000000000000000623", + "0x0000000000000000000000000000000000000000000000000000000000000624", + "0x0000000000000000000000000000000000000000000000000000000000000625", + "0x0000000000000000000000000000000000000000000000000000000000000626", + "0x0000000000000000000000000000000000000000000000000000000000000627", + "0x0000000000000000000000000000000000000000000000000000000000000628", + "0x0000000000000000000000000000000000000000000000000000000000000629", + "0x000000000000000000000000000000000000000000000000000000000000062a", + "0x000000000000000000000000000000000000000000000000000000000000062b", + "0x000000000000000000000000000000000000000000000000000000000000062c", + "0x000000000000000000000000000000000000000000000000000000000000062d", + "0x000000000000000000000000000000000000000000000000000000000000062e", + "0x000000000000000000000000000000000000000000000000000000000000062f", + "0x0000000000000000000000000000000000000000000000000000000000000630", + "0x0000000000000000000000000000000000000000000000000000000000000631", + "0x0000000000000000000000000000000000000000000000000000000000000632", + "0x0000000000000000000000000000000000000000000000000000000000000633", + "0x0000000000000000000000000000000000000000000000000000000000000634", + "0x0000000000000000000000000000000000000000000000000000000000000635", + "0x0000000000000000000000000000000000000000000000000000000000000636", + "0x0000000000000000000000000000000000000000000000000000000000000637", + "0x0000000000000000000000000000000000000000000000000000000000000638", + "0x0000000000000000000000000000000000000000000000000000000000000639", + "0x000000000000000000000000000000000000000000000000000000000000063a", + "0x000000000000000000000000000000000000000000000000000000000000063b", + "0x000000000000000000000000000000000000000000000000000000000000063c", + "0x000000000000000000000000000000000000000000000000000000000000063d", + "0x000000000000000000000000000000000000000000000000000000000000063e", + "0x000000000000000000000000000000000000000000000000000000000000063f", + "0x0000000000000000000000000000000000000000000000000000000000000640", + "0x0000000000000000000000000000000000000000000000000000000000000641", + "0x0000000000000000000000000000000000000000000000000000000000000642", + "0x0000000000000000000000000000000000000000000000000000000000000643", + "0x0000000000000000000000000000000000000000000000000000000000000644", + "0x0000000000000000000000000000000000000000000000000000000000000645", + "0x0000000000000000000000000000000000000000000000000000000000000646", + "0x0000000000000000000000000000000000000000000000000000000000000647", + "0x0000000000000000000000000000000000000000000000000000000000000648", + "0x0000000000000000000000000000000000000000000000000000000000000649", + "0x000000000000000000000000000000000000000000000000000000000000064a", + "0x000000000000000000000000000000000000000000000000000000000000064b", + "0x000000000000000000000000000000000000000000000000000000000000064c", + "0x000000000000000000000000000000000000000000000000000000000000064d", + "0x000000000000000000000000000000000000000000000000000000000000064e", + "0x000000000000000000000000000000000000000000000000000000000000064f", + "0x0000000000000000000000000000000000000000000000000000000000000650", + "0x0000000000000000000000000000000000000000000000000000000000000651", + "0x0000000000000000000000000000000000000000000000000000000000000652", + "0x0000000000000000000000000000000000000000000000000000000000000653", + "0x0000000000000000000000000000000000000000000000000000000000000654", + "0x0000000000000000000000000000000000000000000000000000000000000655", + "0x0000000000000000000000000000000000000000000000000000000000000656", + "0x0000000000000000000000000000000000000000000000000000000000000657", + "0x0000000000000000000000000000000000000000000000000000000000000658", + "0x0000000000000000000000000000000000000000000000000000000000000659", + "0x000000000000000000000000000000000000000000000000000000000000065a", + "0x000000000000000000000000000000000000000000000000000000000000065b", + "0x000000000000000000000000000000000000000000000000000000000000065c", + "0x000000000000000000000000000000000000000000000000000000000000065d", + "0x000000000000000000000000000000000000000000000000000000000000065e", + "0x000000000000000000000000000000000000000000000000000000000000065f", + "0x0000000000000000000000000000000000000000000000000000000000000660", + "0x0000000000000000000000000000000000000000000000000000000000000661", + "0x0000000000000000000000000000000000000000000000000000000000000662", + "0x0000000000000000000000000000000000000000000000000000000000000663", + "0x0000000000000000000000000000000000000000000000000000000000000664", + "0x0000000000000000000000000000000000000000000000000000000000000665", + "0x0000000000000000000000000000000000000000000000000000000000000666", + "0x0000000000000000000000000000000000000000000000000000000000000667", + "0x0000000000000000000000000000000000000000000000000000000000000668", + "0x0000000000000000000000000000000000000000000000000000000000000669", + "0x000000000000000000000000000000000000000000000000000000000000066a", + "0x000000000000000000000000000000000000000000000000000000000000066b", + "0x000000000000000000000000000000000000000000000000000000000000066c", + "0x000000000000000000000000000000000000000000000000000000000000066d", + "0x000000000000000000000000000000000000000000000000000000000000066e", + "0x000000000000000000000000000000000000000000000000000000000000066f", + "0x0000000000000000000000000000000000000000000000000000000000000670", + "0x0000000000000000000000000000000000000000000000000000000000000671", + "0x0000000000000000000000000000000000000000000000000000000000000672", + "0x0000000000000000000000000000000000000000000000000000000000000673", + "0x0000000000000000000000000000000000000000000000000000000000000674", + "0x0000000000000000000000000000000000000000000000000000000000000675", + "0x0000000000000000000000000000000000000000000000000000000000000676", + "0x0000000000000000000000000000000000000000000000000000000000000677", + "0x0000000000000000000000000000000000000000000000000000000000000678", + "0x0000000000000000000000000000000000000000000000000000000000000679", + "0x000000000000000000000000000000000000000000000000000000000000067a", + "0x000000000000000000000000000000000000000000000000000000000000067b", + "0x000000000000000000000000000000000000000000000000000000000000067c", + "0x000000000000000000000000000000000000000000000000000000000000067d", + "0x000000000000000000000000000000000000000000000000000000000000067e", + "0x000000000000000000000000000000000000000000000000000000000000067f", + "0x0000000000000000000000000000000000000000000000000000000000000680", + "0x0000000000000000000000000000000000000000000000000000000000000681", + "0x0000000000000000000000000000000000000000000000000000000000000682", + "0x0000000000000000000000000000000000000000000000000000000000000683", + "0x0000000000000000000000000000000000000000000000000000000000000684", + "0x0000000000000000000000000000000000000000000000000000000000000685", + "0x0000000000000000000000000000000000000000000000000000000000000686", + "0x0000000000000000000000000000000000000000000000000000000000000687", + "0x0000000000000000000000000000000000000000000000000000000000000688", + "0x0000000000000000000000000000000000000000000000000000000000000689", + "0x000000000000000000000000000000000000000000000000000000000000068a", + "0x000000000000000000000000000000000000000000000000000000000000068b", + "0x000000000000000000000000000000000000000000000000000000000000068c", + "0x000000000000000000000000000000000000000000000000000000000000068d", + "0x000000000000000000000000000000000000000000000000000000000000068e", + "0x000000000000000000000000000000000000000000000000000000000000068f", + "0x0000000000000000000000000000000000000000000000000000000000000690", + "0x0000000000000000000000000000000000000000000000000000000000000691", + "0x0000000000000000000000000000000000000000000000000000000000000692", + "0x0000000000000000000000000000000000000000000000000000000000000693", + "0x0000000000000000000000000000000000000000000000000000000000000694", + "0x0000000000000000000000000000000000000000000000000000000000000695", + "0x0000000000000000000000000000000000000000000000000000000000000696", + "0x0000000000000000000000000000000000000000000000000000000000000697", + "0x0000000000000000000000000000000000000000000000000000000000000698", + "0x0000000000000000000000000000000000000000000000000000000000000699", + "0x000000000000000000000000000000000000000000000000000000000000069a", + "0x000000000000000000000000000000000000000000000000000000000000069b", + "0x000000000000000000000000000000000000000000000000000000000000069c", + "0x000000000000000000000000000000000000000000000000000000000000069d", + "0x000000000000000000000000000000000000000000000000000000000000069e", + "0x000000000000000000000000000000000000000000000000000000000000069f", + "0x00000000000000000000000000000000000000000000000000000000000006a0", + "0x00000000000000000000000000000000000000000000000000000000000006a1", + "0x00000000000000000000000000000000000000000000000000000000000006a2", + "0x00000000000000000000000000000000000000000000000000000000000006a3", + "0x00000000000000000000000000000000000000000000000000000000000006a4", + "0x00000000000000000000000000000000000000000000000000000000000006a5", + "0x00000000000000000000000000000000000000000000000000000000000006a6", + "0x00000000000000000000000000000000000000000000000000000000000006a7", + "0x00000000000000000000000000000000000000000000000000000000000006a8", + "0x00000000000000000000000000000000000000000000000000000000000006a9", + "0x00000000000000000000000000000000000000000000000000000000000006aa", + "0x00000000000000000000000000000000000000000000000000000000000006ab", + "0x00000000000000000000000000000000000000000000000000000000000006ac", + "0x00000000000000000000000000000000000000000000000000000000000006ad", + "0x00000000000000000000000000000000000000000000000000000000000006ae", + "0x00000000000000000000000000000000000000000000000000000000000006af", + "0x00000000000000000000000000000000000000000000000000000000000006b0", + "0x00000000000000000000000000000000000000000000000000000000000006b1", + "0x00000000000000000000000000000000000000000000000000000000000006b2", + "0x00000000000000000000000000000000000000000000000000000000000006b3", + "0x00000000000000000000000000000000000000000000000000000000000006b4", + "0x00000000000000000000000000000000000000000000000000000000000006b5", + "0x00000000000000000000000000000000000000000000000000000000000006b6", + "0x00000000000000000000000000000000000000000000000000000000000006b7", + "0x00000000000000000000000000000000000000000000000000000000000006b8", + "0x00000000000000000000000000000000000000000000000000000000000006b9", + "0x00000000000000000000000000000000000000000000000000000000000006ba", + "0x00000000000000000000000000000000000000000000000000000000000006bb", + "0x00000000000000000000000000000000000000000000000000000000000006bc", + "0x00000000000000000000000000000000000000000000000000000000000006bd", + "0x00000000000000000000000000000000000000000000000000000000000006be", + "0x00000000000000000000000000000000000000000000000000000000000006bf", + "0x00000000000000000000000000000000000000000000000000000000000006c0", + "0x00000000000000000000000000000000000000000000000000000000000006c1", + "0x00000000000000000000000000000000000000000000000000000000000006c2", + "0x00000000000000000000000000000000000000000000000000000000000006c3", + "0x00000000000000000000000000000000000000000000000000000000000006c4", + "0x00000000000000000000000000000000000000000000000000000000000006c5", + "0x00000000000000000000000000000000000000000000000000000000000006c6", + "0x00000000000000000000000000000000000000000000000000000000000006c7", + "0x00000000000000000000000000000000000000000000000000000000000006c8", + "0x00000000000000000000000000000000000000000000000000000000000006c9", + "0x00000000000000000000000000000000000000000000000000000000000006ca", + "0x00000000000000000000000000000000000000000000000000000000000006cb", + "0x00000000000000000000000000000000000000000000000000000000000006cc", + "0x00000000000000000000000000000000000000000000000000000000000006cd", + "0x00000000000000000000000000000000000000000000000000000000000006ce", + "0x00000000000000000000000000000000000000000000000000000000000006cf", + "0x00000000000000000000000000000000000000000000000000000000000006d0", + "0x00000000000000000000000000000000000000000000000000000000000006d1", + "0x00000000000000000000000000000000000000000000000000000000000006d2", + "0x00000000000000000000000000000000000000000000000000000000000006d3", + "0x00000000000000000000000000000000000000000000000000000000000006d4", + "0x00000000000000000000000000000000000000000000000000000000000006d5", + "0x00000000000000000000000000000000000000000000000000000000000006d6", + "0x00000000000000000000000000000000000000000000000000000000000006d7", + "0x00000000000000000000000000000000000000000000000000000000000006d8", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da", + "0x00000000000000000000000000000000000000000000000000000000000006db" +] + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000100" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml index c442ddae4801..45f8d72b3dbb 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first-single-tx/Prover.toml @@ -1,5 +1,15 @@ [inputs] -new_l1_to_l2_message_subtree_root_sibling_path = [ +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", @@ -28,10 +38,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x049956c594a170be3bf34aa7c0365893406beb1ac5ee53f9e26797bc0b6c7a56", + "0x03f4c32538d42652fb32a5cb2aee4307443fe38382028580e7aa46e43182df55", "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x09308d0807f5aed64dd43d2014519a161c32f9a52ea75992cc18bec0bcde410e", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -60,558 +70,6 @@ new_archive_sibling_path = [ "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" ] - [inputs.parity_root] - proof = [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x000000000000000000000000000000000000000000000000000000000000000d", - "0x000000000000000000000000000000000000000000000000000000000000000e", - "0x000000000000000000000000000000000000000000000000000000000000000f", - "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000011", - "0x0000000000000000000000000000000000000000000000000000000000000012", - "0x0000000000000000000000000000000000000000000000000000000000000013", - "0x0000000000000000000000000000000000000000000000000000000000000014", - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x0000000000000000000000000000000000000000000000000000000000000017", - "0x0000000000000000000000000000000000000000000000000000000000000018", - "0x0000000000000000000000000000000000000000000000000000000000000019", - "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x000000000000000000000000000000000000000000000000000000000000001b", - "0x000000000000000000000000000000000000000000000000000000000000001c", - "0x000000000000000000000000000000000000000000000000000000000000001d", - "0x000000000000000000000000000000000000000000000000000000000000001e", - "0x000000000000000000000000000000000000000000000000000000000000001f", - "0x0000000000000000000000000000000000000000000000000000000000000020", - "0x0000000000000000000000000000000000000000000000000000000000000021", - "0x0000000000000000000000000000000000000000000000000000000000000022", - "0x0000000000000000000000000000000000000000000000000000000000000023", - "0x0000000000000000000000000000000000000000000000000000000000000024", - "0x0000000000000000000000000000000000000000000000000000000000000025", - "0x0000000000000000000000000000000000000000000000000000000000000026", - "0x0000000000000000000000000000000000000000000000000000000000000027", - "0x0000000000000000000000000000000000000000000000000000000000000028", - "0x0000000000000000000000000000000000000000000000000000000000000029", - "0x000000000000000000000000000000000000000000000000000000000000002a", - "0x000000000000000000000000000000000000000000000000000000000000002b", - "0x000000000000000000000000000000000000000000000000000000000000002c", - "0x000000000000000000000000000000000000000000000000000000000000002d", - "0x000000000000000000000000000000000000000000000000000000000000002e", - "0x000000000000000000000000000000000000000000000000000000000000002f", - "0x0000000000000000000000000000000000000000000000000000000000000030", - "0x0000000000000000000000000000000000000000000000000000000000000031", - "0x0000000000000000000000000000000000000000000000000000000000000032", - "0x0000000000000000000000000000000000000000000000000000000000000033", - "0x0000000000000000000000000000000000000000000000000000000000000034", - "0x0000000000000000000000000000000000000000000000000000000000000035", - "0x0000000000000000000000000000000000000000000000000000000000000036", - "0x0000000000000000000000000000000000000000000000000000000000000037", - "0x0000000000000000000000000000000000000000000000000000000000000038", - "0x0000000000000000000000000000000000000000000000000000000000000039", - "0x000000000000000000000000000000000000000000000000000000000000003a", - "0x000000000000000000000000000000000000000000000000000000000000003b", - "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x000000000000000000000000000000000000000000000000000000000000003d", - "0x000000000000000000000000000000000000000000000000000000000000003e", - "0x000000000000000000000000000000000000000000000000000000000000003f", - "0x0000000000000000000000000000000000000000000000000000000000000040", - "0x0000000000000000000000000000000000000000000000000000000000000041", - "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000043", - "0x0000000000000000000000000000000000000000000000000000000000000044", - "0x0000000000000000000000000000000000000000000000000000000000000045", - "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000047", - "0x0000000000000000000000000000000000000000000000000000000000000048", - "0x0000000000000000000000000000000000000000000000000000000000000049", - "0x000000000000000000000000000000000000000000000000000000000000004a", - "0x000000000000000000000000000000000000000000000000000000000000004b", - "0x000000000000000000000000000000000000000000000000000000000000004c", - "0x000000000000000000000000000000000000000000000000000000000000004d", - "0x000000000000000000000000000000000000000000000000000000000000004e", - "0x000000000000000000000000000000000000000000000000000000000000004f", - "0x0000000000000000000000000000000000000000000000000000000000000050", - "0x0000000000000000000000000000000000000000000000000000000000000051", - "0x0000000000000000000000000000000000000000000000000000000000000052", - "0x0000000000000000000000000000000000000000000000000000000000000053", - "0x0000000000000000000000000000000000000000000000000000000000000054", - "0x0000000000000000000000000000000000000000000000000000000000000055", - "0x0000000000000000000000000000000000000000000000000000000000000056", - "0x0000000000000000000000000000000000000000000000000000000000000057", - "0x0000000000000000000000000000000000000000000000000000000000000058", - "0x0000000000000000000000000000000000000000000000000000000000000059", - "0x000000000000000000000000000000000000000000000000000000000000005a", - "0x000000000000000000000000000000000000000000000000000000000000005b", - "0x000000000000000000000000000000000000000000000000000000000000005c", - "0x000000000000000000000000000000000000000000000000000000000000005d", - "0x000000000000000000000000000000000000000000000000000000000000005e", - "0x000000000000000000000000000000000000000000000000000000000000005f", - "0x0000000000000000000000000000000000000000000000000000000000000060", - "0x0000000000000000000000000000000000000000000000000000000000000061", - "0x0000000000000000000000000000000000000000000000000000000000000062", - "0x0000000000000000000000000000000000000000000000000000000000000063", - "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000065", - "0x0000000000000000000000000000000000000000000000000000000000000066", - "0x0000000000000000000000000000000000000000000000000000000000000067", - "0x0000000000000000000000000000000000000000000000000000000000000068", - "0x0000000000000000000000000000000000000000000000000000000000000069", - "0x000000000000000000000000000000000000000000000000000000000000006a", - "0x000000000000000000000000000000000000000000000000000000000000006b", - "0x000000000000000000000000000000000000000000000000000000000000006c", - "0x000000000000000000000000000000000000000000000000000000000000006d", - "0x000000000000000000000000000000000000000000000000000000000000006e", - "0x000000000000000000000000000000000000000000000000000000000000006f", - "0x0000000000000000000000000000000000000000000000000000000000000070", - "0x0000000000000000000000000000000000000000000000000000000000000071", - "0x0000000000000000000000000000000000000000000000000000000000000072", - "0x0000000000000000000000000000000000000000000000000000000000000073", - "0x0000000000000000000000000000000000000000000000000000000000000074", - "0x0000000000000000000000000000000000000000000000000000000000000075", - "0x0000000000000000000000000000000000000000000000000000000000000076", - "0x0000000000000000000000000000000000000000000000000000000000000077", - "0x0000000000000000000000000000000000000000000000000000000000000078", - "0x0000000000000000000000000000000000000000000000000000000000000079", - "0x000000000000000000000000000000000000000000000000000000000000007a", - "0x000000000000000000000000000000000000000000000000000000000000007b", - "0x000000000000000000000000000000000000000000000000000000000000007c", - "0x000000000000000000000000000000000000000000000000000000000000007d", - "0x000000000000000000000000000000000000000000000000000000000000007e", - "0x000000000000000000000000000000000000000000000000000000000000007f", - "0x0000000000000000000000000000000000000000000000000000000000000080", - "0x0000000000000000000000000000000000000000000000000000000000000081", - "0x0000000000000000000000000000000000000000000000000000000000000082", - "0x0000000000000000000000000000000000000000000000000000000000000083", - "0x0000000000000000000000000000000000000000000000000000000000000084", - "0x0000000000000000000000000000000000000000000000000000000000000085", - "0x0000000000000000000000000000000000000000000000000000000000000086", - "0x0000000000000000000000000000000000000000000000000000000000000087", - "0x0000000000000000000000000000000000000000000000000000000000000088", - "0x0000000000000000000000000000000000000000000000000000000000000089", - "0x000000000000000000000000000000000000000000000000000000000000008a", - "0x000000000000000000000000000000000000000000000000000000000000008b", - "0x000000000000000000000000000000000000000000000000000000000000008c", - "0x000000000000000000000000000000000000000000000000000000000000008d", - "0x000000000000000000000000000000000000000000000000000000000000008e", - "0x000000000000000000000000000000000000000000000000000000000000008f", - "0x0000000000000000000000000000000000000000000000000000000000000090", - "0x0000000000000000000000000000000000000000000000000000000000000091", - "0x0000000000000000000000000000000000000000000000000000000000000092", - "0x0000000000000000000000000000000000000000000000000000000000000093", - "0x0000000000000000000000000000000000000000000000000000000000000094", - "0x0000000000000000000000000000000000000000000000000000000000000095", - "0x0000000000000000000000000000000000000000000000000000000000000096", - "0x0000000000000000000000000000000000000000000000000000000000000097", - "0x0000000000000000000000000000000000000000000000000000000000000098", - "0x0000000000000000000000000000000000000000000000000000000000000099", - "0x000000000000000000000000000000000000000000000000000000000000009a", - "0x000000000000000000000000000000000000000000000000000000000000009b", - "0x000000000000000000000000000000000000000000000000000000000000009c", - "0x000000000000000000000000000000000000000000000000000000000000009d", - "0x000000000000000000000000000000000000000000000000000000000000009e", - "0x000000000000000000000000000000000000000000000000000000000000009f", - "0x00000000000000000000000000000000000000000000000000000000000000a0", - "0x00000000000000000000000000000000000000000000000000000000000000a1", - "0x00000000000000000000000000000000000000000000000000000000000000a2", - "0x00000000000000000000000000000000000000000000000000000000000000a3", - "0x00000000000000000000000000000000000000000000000000000000000000a4", - "0x00000000000000000000000000000000000000000000000000000000000000a5", - "0x00000000000000000000000000000000000000000000000000000000000000a6", - "0x00000000000000000000000000000000000000000000000000000000000000a7", - "0x00000000000000000000000000000000000000000000000000000000000000a8", - "0x00000000000000000000000000000000000000000000000000000000000000a9", - "0x00000000000000000000000000000000000000000000000000000000000000aa", - "0x00000000000000000000000000000000000000000000000000000000000000ab", - "0x00000000000000000000000000000000000000000000000000000000000000ac", - "0x00000000000000000000000000000000000000000000000000000000000000ad", - "0x00000000000000000000000000000000000000000000000000000000000000ae", - "0x00000000000000000000000000000000000000000000000000000000000000af", - "0x00000000000000000000000000000000000000000000000000000000000000b0", - "0x00000000000000000000000000000000000000000000000000000000000000b1", - "0x00000000000000000000000000000000000000000000000000000000000000b2", - "0x00000000000000000000000000000000000000000000000000000000000000b3", - "0x00000000000000000000000000000000000000000000000000000000000000b4", - "0x00000000000000000000000000000000000000000000000000000000000000b5", - "0x00000000000000000000000000000000000000000000000000000000000000b6", - "0x00000000000000000000000000000000000000000000000000000000000000b7", - "0x00000000000000000000000000000000000000000000000000000000000000b8", - "0x00000000000000000000000000000000000000000000000000000000000000b9", - "0x00000000000000000000000000000000000000000000000000000000000000ba", - "0x00000000000000000000000000000000000000000000000000000000000000bb", - "0x00000000000000000000000000000000000000000000000000000000000000bc", - "0x00000000000000000000000000000000000000000000000000000000000000bd", - "0x00000000000000000000000000000000000000000000000000000000000000be", - "0x00000000000000000000000000000000000000000000000000000000000000bf", - "0x00000000000000000000000000000000000000000000000000000000000000c0", - "0x00000000000000000000000000000000000000000000000000000000000000c1", - "0x00000000000000000000000000000000000000000000000000000000000000c2", - "0x00000000000000000000000000000000000000000000000000000000000000c3", - "0x00000000000000000000000000000000000000000000000000000000000000c4", - "0x00000000000000000000000000000000000000000000000000000000000000c5", - "0x00000000000000000000000000000000000000000000000000000000000000c6", - "0x00000000000000000000000000000000000000000000000000000000000000c7", - "0x00000000000000000000000000000000000000000000000000000000000000c8", - "0x00000000000000000000000000000000000000000000000000000000000000c9", - "0x00000000000000000000000000000000000000000000000000000000000000ca", - "0x00000000000000000000000000000000000000000000000000000000000000cb", - "0x00000000000000000000000000000000000000000000000000000000000000cc", - "0x00000000000000000000000000000000000000000000000000000000000000cd", - "0x00000000000000000000000000000000000000000000000000000000000000ce", - "0x00000000000000000000000000000000000000000000000000000000000000cf", - "0x00000000000000000000000000000000000000000000000000000000000000d0", - "0x00000000000000000000000000000000000000000000000000000000000000d1", - "0x00000000000000000000000000000000000000000000000000000000000000d2", - "0x00000000000000000000000000000000000000000000000000000000000000d3", - "0x00000000000000000000000000000000000000000000000000000000000000d4", - "0x00000000000000000000000000000000000000000000000000000000000000d5", - "0x00000000000000000000000000000000000000000000000000000000000000d6", - "0x00000000000000000000000000000000000000000000000000000000000000d7", - "0x00000000000000000000000000000000000000000000000000000000000000d8", - "0x00000000000000000000000000000000000000000000000000000000000000d9", - "0x00000000000000000000000000000000000000000000000000000000000000da", - "0x00000000000000000000000000000000000000000000000000000000000000db", - "0x00000000000000000000000000000000000000000000000000000000000000dc", - "0x00000000000000000000000000000000000000000000000000000000000000dd", - "0x00000000000000000000000000000000000000000000000000000000000000de", - "0x00000000000000000000000000000000000000000000000000000000000000df", - "0x00000000000000000000000000000000000000000000000000000000000000e0", - "0x00000000000000000000000000000000000000000000000000000000000000e1", - "0x00000000000000000000000000000000000000000000000000000000000000e2", - "0x00000000000000000000000000000000000000000000000000000000000000e3", - "0x00000000000000000000000000000000000000000000000000000000000000e4", - "0x00000000000000000000000000000000000000000000000000000000000000e5", - "0x00000000000000000000000000000000000000000000000000000000000000e6", - "0x00000000000000000000000000000000000000000000000000000000000000e7", - "0x00000000000000000000000000000000000000000000000000000000000000e8", - "0x00000000000000000000000000000000000000000000000000000000000000e9", - "0x00000000000000000000000000000000000000000000000000000000000000ea", - "0x00000000000000000000000000000000000000000000000000000000000000eb", - "0x00000000000000000000000000000000000000000000000000000000000000ec", - "0x00000000000000000000000000000000000000000000000000000000000000ed", - "0x00000000000000000000000000000000000000000000000000000000000000ee", - "0x00000000000000000000000000000000000000000000000000000000000000ef", - "0x00000000000000000000000000000000000000000000000000000000000000f0", - "0x00000000000000000000000000000000000000000000000000000000000000f1", - "0x00000000000000000000000000000000000000000000000000000000000000f2", - "0x00000000000000000000000000000000000000000000000000000000000000f3", - "0x00000000000000000000000000000000000000000000000000000000000000f4", - "0x00000000000000000000000000000000000000000000000000000000000000f5", - "0x00000000000000000000000000000000000000000000000000000000000000f6", - "0x00000000000000000000000000000000000000000000000000000000000000f7", - "0x00000000000000000000000000000000000000000000000000000000000000f8", - "0x00000000000000000000000000000000000000000000000000000000000000f9", - "0x00000000000000000000000000000000000000000000000000000000000000fa", - "0x00000000000000000000000000000000000000000000000000000000000000fb", - "0x00000000000000000000000000000000000000000000000000000000000000fc", - "0x00000000000000000000000000000000000000000000000000000000000000fd", - "0x00000000000000000000000000000000000000000000000000000000000000fe", - "0x00000000000000000000000000000000000000000000000000000000000000ff", - "0x0000000000000000000000000000000000000000000000000000000000000100", - "0x0000000000000000000000000000000000000000000000000000000000000101", - "0x0000000000000000000000000000000000000000000000000000000000000102", - "0x0000000000000000000000000000000000000000000000000000000000000103", - "0x0000000000000000000000000000000000000000000000000000000000000104", - "0x0000000000000000000000000000000000000000000000000000000000000105", - "0x0000000000000000000000000000000000000000000000000000000000000106", - "0x0000000000000000000000000000000000000000000000000000000000000107", - "0x0000000000000000000000000000000000000000000000000000000000000108", - "0x0000000000000000000000000000000000000000000000000000000000000109", - "0x000000000000000000000000000000000000000000000000000000000000010a", - "0x000000000000000000000000000000000000000000000000000000000000010b", - "0x000000000000000000000000000000000000000000000000000000000000010c", - "0x000000000000000000000000000000000000000000000000000000000000010d", - "0x000000000000000000000000000000000000000000000000000000000000010e", - "0x000000000000000000000000000000000000000000000000000000000000010f", - "0x0000000000000000000000000000000000000000000000000000000000000110", - "0x0000000000000000000000000000000000000000000000000000000000000111", - "0x0000000000000000000000000000000000000000000000000000000000000112", - "0x0000000000000000000000000000000000000000000000000000000000000113", - "0x0000000000000000000000000000000000000000000000000000000000000114", - "0x0000000000000000000000000000000000000000000000000000000000000115", - "0x0000000000000000000000000000000000000000000000000000000000000116", - "0x0000000000000000000000000000000000000000000000000000000000000117", - "0x0000000000000000000000000000000000000000000000000000000000000118", - "0x0000000000000000000000000000000000000000000000000000000000000119", - "0x000000000000000000000000000000000000000000000000000000000000011a", - "0x000000000000000000000000000000000000000000000000000000000000011b", - "0x000000000000000000000000000000000000000000000000000000000000011c", - "0x000000000000000000000000000000000000000000000000000000000000011d", - "0x000000000000000000000000000000000000000000000000000000000000011e", - "0x000000000000000000000000000000000000000000000000000000000000011f", - "0x0000000000000000000000000000000000000000000000000000000000000120", - "0x0000000000000000000000000000000000000000000000000000000000000121", - "0x0000000000000000000000000000000000000000000000000000000000000122", - "0x0000000000000000000000000000000000000000000000000000000000000123", - "0x0000000000000000000000000000000000000000000000000000000000000124", - "0x0000000000000000000000000000000000000000000000000000000000000125", - "0x0000000000000000000000000000000000000000000000000000000000000126", - "0x0000000000000000000000000000000000000000000000000000000000000127", - "0x0000000000000000000000000000000000000000000000000000000000000128", - "0x0000000000000000000000000000000000000000000000000000000000000129", - "0x000000000000000000000000000000000000000000000000000000000000012a", - "0x000000000000000000000000000000000000000000000000000000000000012b", - "0x000000000000000000000000000000000000000000000000000000000000012c", - "0x000000000000000000000000000000000000000000000000000000000000012d", - "0x000000000000000000000000000000000000000000000000000000000000012e", - "0x000000000000000000000000000000000000000000000000000000000000012f", - "0x0000000000000000000000000000000000000000000000000000000000000130", - "0x0000000000000000000000000000000000000000000000000000000000000131", - "0x0000000000000000000000000000000000000000000000000000000000000132", - "0x0000000000000000000000000000000000000000000000000000000000000133", - "0x0000000000000000000000000000000000000000000000000000000000000134", - "0x0000000000000000000000000000000000000000000000000000000000000135", - "0x0000000000000000000000000000000000000000000000000000000000000136", - "0x0000000000000000000000000000000000000000000000000000000000000137", - "0x0000000000000000000000000000000000000000000000000000000000000138", - "0x0000000000000000000000000000000000000000000000000000000000000139", - "0x000000000000000000000000000000000000000000000000000000000000013a", - "0x000000000000000000000000000000000000000000000000000000000000013b", - "0x000000000000000000000000000000000000000000000000000000000000013c", - "0x000000000000000000000000000000000000000000000000000000000000013d", - "0x000000000000000000000000000000000000000000000000000000000000013e", - "0x000000000000000000000000000000000000000000000000000000000000013f", - "0x0000000000000000000000000000000000000000000000000000000000000140", - "0x0000000000000000000000000000000000000000000000000000000000000141", - "0x0000000000000000000000000000000000000000000000000000000000000142", - "0x0000000000000000000000000000000000000000000000000000000000000143", - "0x0000000000000000000000000000000000000000000000000000000000000144", - "0x0000000000000000000000000000000000000000000000000000000000000145", - "0x0000000000000000000000000000000000000000000000000000000000000146", - "0x0000000000000000000000000000000000000000000000000000000000000147", - "0x0000000000000000000000000000000000000000000000000000000000000148", - "0x0000000000000000000000000000000000000000000000000000000000000149", - "0x000000000000000000000000000000000000000000000000000000000000014a", - "0x000000000000000000000000000000000000000000000000000000000000014b", - "0x000000000000000000000000000000000000000000000000000000000000014c", - "0x000000000000000000000000000000000000000000000000000000000000014d", - "0x000000000000000000000000000000000000000000000000000000000000014e", - "0x000000000000000000000000000000000000000000000000000000000000014f", - "0x0000000000000000000000000000000000000000000000000000000000000150", - "0x0000000000000000000000000000000000000000000000000000000000000151", - "0x0000000000000000000000000000000000000000000000000000000000000152", - "0x0000000000000000000000000000000000000000000000000000000000000153", - "0x0000000000000000000000000000000000000000000000000000000000000154", - "0x0000000000000000000000000000000000000000000000000000000000000155", - "0x0000000000000000000000000000000000000000000000000000000000000156", - "0x0000000000000000000000000000000000000000000000000000000000000157", - "0x0000000000000000000000000000000000000000000000000000000000000158", - "0x0000000000000000000000000000000000000000000000000000000000000159", - "0x000000000000000000000000000000000000000000000000000000000000015a", - "0x000000000000000000000000000000000000000000000000000000000000015b", - "0x000000000000000000000000000000000000000000000000000000000000015c", - "0x000000000000000000000000000000000000000000000000000000000000015d", - "0x000000000000000000000000000000000000000000000000000000000000015e", - "0x000000000000000000000000000000000000000000000000000000000000015f", - "0x0000000000000000000000000000000000000000000000000000000000000160", - "0x0000000000000000000000000000000000000000000000000000000000000161", - "0x0000000000000000000000000000000000000000000000000000000000000162", - "0x0000000000000000000000000000000000000000000000000000000000000163", - "0x0000000000000000000000000000000000000000000000000000000000000164", - "0x0000000000000000000000000000000000000000000000000000000000000165", - "0x0000000000000000000000000000000000000000000000000000000000000166", - "0x0000000000000000000000000000000000000000000000000000000000000167", - "0x0000000000000000000000000000000000000000000000000000000000000168", - "0x0000000000000000000000000000000000000000000000000000000000000169", - "0x000000000000000000000000000000000000000000000000000000000000016a", - "0x000000000000000000000000000000000000000000000000000000000000016b", - "0x000000000000000000000000000000000000000000000000000000000000016c", - "0x000000000000000000000000000000000000000000000000000000000000016d", - "0x000000000000000000000000000000000000000000000000000000000000016e", - "0x000000000000000000000000000000000000000000000000000000000000016f", - "0x0000000000000000000000000000000000000000000000000000000000000170", - "0x0000000000000000000000000000000000000000000000000000000000000171", - "0x0000000000000000000000000000000000000000000000000000000000000172", - "0x0000000000000000000000000000000000000000000000000000000000000173", - "0x0000000000000000000000000000000000000000000000000000000000000174", - "0x0000000000000000000000000000000000000000000000000000000000000175", - "0x0000000000000000000000000000000000000000000000000000000000000176", - "0x0000000000000000000000000000000000000000000000000000000000000177", - "0x0000000000000000000000000000000000000000000000000000000000000178", - "0x0000000000000000000000000000000000000000000000000000000000000179", - "0x000000000000000000000000000000000000000000000000000000000000017a", - "0x000000000000000000000000000000000000000000000000000000000000017b", - "0x000000000000000000000000000000000000000000000000000000000000017c", - "0x000000000000000000000000000000000000000000000000000000000000017d", - "0x000000000000000000000000000000000000000000000000000000000000017e", - "0x000000000000000000000000000000000000000000000000000000000000017f", - "0x0000000000000000000000000000000000000000000000000000000000000180", - "0x0000000000000000000000000000000000000000000000000000000000000181", - "0x0000000000000000000000000000000000000000000000000000000000000182", - "0x0000000000000000000000000000000000000000000000000000000000000183", - "0x0000000000000000000000000000000000000000000000000000000000000184", - "0x0000000000000000000000000000000000000000000000000000000000000185", - "0x0000000000000000000000000000000000000000000000000000000000000186", - "0x0000000000000000000000000000000000000000000000000000000000000187", - "0x0000000000000000000000000000000000000000000000000000000000000188", - "0x0000000000000000000000000000000000000000000000000000000000000189", - "0x000000000000000000000000000000000000000000000000000000000000018a", - "0x000000000000000000000000000000000000000000000000000000000000018b", - "0x000000000000000000000000000000000000000000000000000000000000018c", - "0x000000000000000000000000000000000000000000000000000000000000018d", - "0x000000000000000000000000000000000000000000000000000000000000018e", - "0x000000000000000000000000000000000000000000000000000000000000018f", - "0x0000000000000000000000000000000000000000000000000000000000000190", - "0x0000000000000000000000000000000000000000000000000000000000000191", - "0x0000000000000000000000000000000000000000000000000000000000000192", - "0x0000000000000000000000000000000000000000000000000000000000000193", - "0x0000000000000000000000000000000000000000000000000000000000000194", - "0x0000000000000000000000000000000000000000000000000000000000000195", - "0x0000000000000000000000000000000000000000000000000000000000000196", - "0x0000000000000000000000000000000000000000000000000000000000000197", - "0x0000000000000000000000000000000000000000000000000000000000000198", - "0x0000000000000000000000000000000000000000000000000000000000000199", - "0x000000000000000000000000000000000000000000000000000000000000019a" -] - - [inputs.parity_root.public_inputs] - sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" - converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - - [inputs.parity_root.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" - sibling_path = [ - "0x005a4d59d6486e10a3eefab398cca5d3c8e89e178a566d9885c5d7e478e46338", - "0x1fa32700cbe47fec502423d9419340fdfc6b73c146a1b1e42189b4dee5ddb4cc", - "0x07250f720369414b8956bab70d3dbfbe4a5912f128405eedb1c920009dcea92c", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" -] - - [inputs.parity_root.vk_data.vk] - key = [ - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x00000000000000000000000000000051b95d468aa9edbdd7a1e0f23a986c062f", - "0x00000000000000000000000000000000001bad5c453d035ced539f73b9ad9856", - "0x000000000000000000000000000000b9f20b33b45f2cd16ad5d036ab4e3b3e29", - "0x000000000000000000000000000000000024ea357fc8a07811c9d33358737ae6", - "0x000000000000000000000000000000ecd08e9e55edf496bac0902ec569099076", - "0x00000000000000000000000000000000002545be4c6d35893482ac43aecf9ca3", - "0x0000000000000000000000000000007b0429d81df3d0e6f023ad3023885f5d80", - "0x00000000000000000000000000000000001c682d1353fe66ef71491f339cde4c", - "0x00000000000000000000000000000021d27796a33c109672b6cdddafb1014772", - "0x00000000000000000000000000000000002cb8cb3972a4653468363f5cb656aa", - "0x000000000000000000000000000000253a50863b978d9398edeaaadb777a07a1", - "0x00000000000000000000000000000000000ef2db12c6ccbb131452091724f6a1", - "0x0000000000000000000000000000007abf7d869e61f461bad9f630ddf9594b05", - "0x00000000000000000000000000000000001111371317a103bc201e8123d6908b", - "0x00000000000000000000000000000055c64593831da4543a3d4b133e864eaf93", - "0x00000000000000000000000000000000000007aad0d55eaa03d5a23d84a35e60", - "0x000000000000000000000000000000165b401eb09f11cdbf56ba958577c91870", - "0x000000000000000000000000000000000024870f45c37a1866cbe92a8e88bbdd", - "0x00000000000000000000000000000022fabd7922e17d5369ed9c82423af1e455", - "0x000000000000000000000000000000000006649913c8489e9ddf864cbfba7f06", - "0x00000000000000000000000000000069115033b40ed21b2de75356921ceab9bb", - "0x000000000000000000000000000000000017967decbb04dea0b3c47f6cc805ed", - "0x000000000000000000000000000000b28d6694439fbe07553cdd206c5dfedebb", - "0x00000000000000000000000000000000000b08cdac94cf3e333b9195d9397ebe", - "0x000000000000000000000000000000cbe98014674062efea69339e44ebb83efc", - "0x00000000000000000000000000000000001e2260b0e077ac85ce74aaae4e72ef", - "0x000000000000000000000000000000bd27cf39ab646d638453f2fc0af16ba04b", - "0x00000000000000000000000000000000000473943ee569fdf17acac9c955c46f", - "0x000000000000000000000000000000864b31708b62da3d34b9f7ae5931f9696e", - "0x00000000000000000000000000000000000df5131cd2846d3102e898fa953ea0", - "0x000000000000000000000000000000d199787d243d0e9f7198c7f8993b47f431", - "0x0000000000000000000000000000000000161ef18b1311eebfa3ea1e312d40fc", - "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", - "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", - "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", - "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x0000000000000000000000000000006e4a0bfce0ed1188f9db0a6dd0de01ff56", - "0x000000000000000000000000000000000028ffb06695207e8e7beefe7ddd9bf2", - "0x000000000000000000000000000000c3bd4e37af8f5cb75f1e44ee1ac1a27822", - "0x00000000000000000000000000000000001a0419b42f40069bfbfb08563363e5", - "0x0000000000000000000000000000006eed465622852dce8a0702c5327cff0583", - "0x000000000000000000000000000000000022b0941f412859d1cc37a757ca4375", - "0x0000000000000000000000000000008bef872c634b8c03bfe7ff37c00a727192", - "0x000000000000000000000000000000000004906c8767a040a562b166a360c43b", - "0x0000000000000000000000000000002196aef3cb99415b3ac5297aac8f112fc6", - "0x0000000000000000000000000000000000202bc7de55cc5837eb14b1c9170f8b", - "0x000000000000000000000000000000bdf27b518418573439ed9eae4c5e5fb565", - "0x000000000000000000000000000000000017b3d9bbe6a673b931642f99c5da31", - "0x000000000000000000000000000000f02ba591cd0b41bb042d8e128595192f02", - "0x00000000000000000000000000000000000e91c21c980b16cf781f41a63337b6", - "0x000000000000000000000000000000df236435bb93d1ba03853ec32ce9bac516", - "0x00000000000000000000000000000000000c79c6f2ebdbb8e9a9ced4fe147b70", - "0x0000000000000000000000000000003fffb3aa510e7f700cf1014e5872d9c836", - "0x00000000000000000000000000000000002a8a152385a9322608448c3b903a25", - "0x000000000000000000000000000000e0e29574c018f3c6738e2e39d4c5add9a0", - "0x00000000000000000000000000000000000fc61b53a775b4a4abe28883bd4cae", - "0x00000000000000000000000000000015ad8f2e516ea41308c308441bd42c61e8", - "0x00000000000000000000000000000000002ae1b82b97d47244a5cbf6785de890", - "0x000000000000000000000000000000c903532912619760836806241aafc8d682", - "0x00000000000000000000000000000000000ad9c58de8e6372d34bc7aac8d1aca", - "0x0000000000000000000000000000008fa9fb6ea15481186d7cd1fc51794441c9", - "0x000000000000000000000000000000000011ecbb05712b264440c324636f313a", - "0x000000000000000000000000000000f56e21c6f0aaefba2220f3a94f80dab6ce", - "0x00000000000000000000000000000000000a6f225feab651d61030c107381417", - "0x0000000000000000000000000000006367da8ecf84e7656d58a4cf7cc1ef2a74", - "0x00000000000000000000000000000000002856f12f04dfa0785028992bc70c8a", - "0x000000000000000000000000000000540359f38ff410089ec6db690c67f8c0a6", - "0x00000000000000000000000000000000002f7ebc5d4a3f260e4a7008711317cd", - "0x0000000000000000000000000000002b55a45f77effa85ca159aaf39ada36b48", - "0x00000000000000000000000000000000001977d307b0175c7c38a065098ee4f0", - "0x00000000000000000000000000000065d17036201631ee10ae596434d01e5faf", - "0x000000000000000000000000000000000028a0ca170089439ba99c006abb5337", - "0x00000000000000000000000000000061b4a81da9a47d25c6a023ce9989052d14", - "0x000000000000000000000000000000000024f0d3b3ea4a55b1ef68ef0706d74d", - "0x0000000000000000000000000000001e9474df0627017ae3a6588c6675e5d37c", - "0x00000000000000000000000000000000000f9309e016418c2988a76cb9a7e6d0", - "0x0000000000000000000000000000005aabd337c2b20b92b5cd9f68fc113fa8fc", - "0x0000000000000000000000000000000000267e283433e6948f6e830121cf07d6", - "0x000000000000000000000000000000e63c28dcb1403d1abd520e3be26f5ea912", - "0x00000000000000000000000000000000000b8e7e8a4f0ee43c9adb3118d1c77c", - "0x00000000000000000000000000000001cb5edebf7fec67758257f420eb739626", - "0x00000000000000000000000000000000002ac6f62034a546864c00f263827917", - "0x0000000000000000000000000000006ffb02c7e19870982b9368ed26a1a90e5b", - "0x000000000000000000000000000000000021d8e1392945c72edde14af5a71989", - "0x000000000000000000000000000000035fe29e7aa320fcacba3b59ca25bc6419", - "0x000000000000000000000000000000000007f147299102f19d56530c50361528", - "0x000000000000000000000000000000e5be284aab52d0591e1613d5674ab90345", - "0x0000000000000000000000000000000000121e8ab82e001622ed0bacd52bbe03", - "0x00000000000000000000000000000003fa9212b7d0d61e9db75b0d68d8b35153", - "0x00000000000000000000000000000000000fb55f91f49661936a9e62dd35a4ce", - "0x00000000000000000000000000000030c134112f5d817a22a316654112fd7714", - "0x00000000000000000000000000000000000a528aa7ced2566011573552cf302e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000003b87ae780740d3d14ff8f9a547b2926c1b", - "0x00000000000000000000000000000000001cbcc9a266eec40328a8057d238ebd", - "0x0000000000000000000000000000003f6ec85bee0641c92db9ca4fcc5fa3c24a", - "0x00000000000000000000000000000000002f189078dffab22dd8076b731348c8", - "0x0000000000000000000000000000001fad48d68c46c8ce6bd9b67aa6e588bbe0", - "0x00000000000000000000000000000000002fcda688d3b990ca6451a5841e39c1", - "0x000000000000000000000000000000f44fc69aa2dcf70ea4a66b7a9b23c9ab95", - "0x0000000000000000000000000000000000016f201ae57c6fd54a72dba17e156d", - "0x0000000000000000000000000000007b1d6e61b0d5254c9fba726ae7ae9cc66f", - "0x000000000000000000000000000000000002f7da015e525c659a66da56ae616b", - "0x0000000000000000000000000000004f7b93f9c23397a77423f2d327b024943e", - "0x00000000000000000000000000000000001d4011b86d37adeccdf00f76b47447", - "0x0000000000000000000000000000004a4deb709a4b4c26e852e64bf9f8e3d854", - "0x00000000000000000000000000000000002fdd2702a68fda431a1aae6bb8a36a", - "0x0000000000000000000000000000005bc0bd35cd7f4765aadf5249b6d0a58b74", - "0x00000000000000000000000000000000000d439321d69f2e8851f3a88e18f6cf" -] - hash = "0x269f5cc6356c1bfd4868c38cebcc39f9edcae4cb0f5b72ae04bd23bed6d25ddb" - [inputs.previous_rollup] proof = [ "0x0000000000000000000000000000000000000000000000000000000000000001", @@ -1098,63 +556,63 @@ new_archive_sibling_path = [ [inputs.previous_rollup.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" - out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x00000000000000000000000000000000000000000000000000198e45581dc500" - accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + out_hash = "0x006bd7618b0cf7b40e3f107022eee2d411bcc5850fbb774dacc46a15957659c4" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x1842a814b068f699565f4df77ab9139f1cfab687ef959bf92ba0bb3adf93d8dd" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollup.public_inputs.constants.global_variables] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000009" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000044" - timestamp = "0x000000000000000000000000000000000000000000000000000000006a4d22fd" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000001" + slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" + timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" [inputs.previous_rollup.public_inputs.constants.global_variables.coinbase] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000002f8e08bc0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" +root = "0x2590f2aab19dd791700b4a43d3f52bb88ef2409a3731da8e848663559202e4c6" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x1c13b69ab508e560dc7c25e4f77aed48439749310a58609f31475734efe7287b" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" +root = "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x073b8408b98dbac4d5f0c84d47161ee954b8d8e7920e620bf14bc44cb50d07d5" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollup.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x00260be7577812f167b02eb1c2fa10efc5f169fe19845ada374d4c1518af35f4" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollup.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x2536a3212b711359308d274b8a92fa44465b6ce091dd9369c1331f1ffdeaa8ca" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,19 +633,19 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000080" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004cd" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x003c0402012600000305072d0003082d0004092300000baa2d0108062d040609", - "0x00000008020800000902090c0008070a2400000a00000b982600000000000000", - "0x0000220902092d0e020900220902093c0e07082a0100010575fef108377c8a4f" + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c" ] state = [ - "0x0f33f43fb0c44c5e40fdc435630bc7c0216039609097d27d68379cddd3933586", - "0x1cff8078046c1471e788b79130c434cf28c76659cad09a138fefc7715f36b1f9", - "0x176eb17265134a6a87e84f75dbe0a646bc9ad9a317c90773a8c53d59822f4ab5", - "0x1a1440d4df7e4daf64ffa2db4bc1a07844c5992eb81b78c813b4fb385bbf32dc" + "0x086afa1d86cfb4ed9f753293a8b14449836e16c2dff9933a7d5594fb7c9074a3", + "0x18a8eede640428ee295aba5443291c50394e921b4ad66343d5252a80f7e393fe", + "0x24712615d744d2e54ef472f1e3b244f172b1270d869af3aa9d71e2d36372d295", + "0x1ba041871bb8371a777900511c8cb999dbdd7a84debc60769c76ae522d82481e" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -1197,11 +655,11 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 sibling_path = [ "0x1fc39d0a428c8536dbca551ea79848acf67d89d090fd8c643c7d90f2e8f32340", "0x12ce5a49a1ceca53ada7bee003f929bbd65abaa74e8072a81f304c2c96c44e31", - "0x2dd71474f7775d87b6c2986ace5f654686583f0970d7400b1ccf8096dad131b5", - "0x0b5fd0fa25267d5406b05329f1e13e2be58d683fcc8c4ef293934007bf1fedf3", - "0x2a17b9f268be22deec2941ce8de06f485f2d164710a5177d262a4ae86b7c351f", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x276f60617ee2c3b406af56bfe9216a7d99be56ad316ff557cee0446f08e14135", + "0x1dab7bce1884db3c7fa09243adb445f93156a1a0546582123d8c1d6c89e7fe41", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollup.vk_data.vk] @@ -1209,46 +667,46 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000165ae78531927a33f65caca2e363cc772e", - "0x00000000000000000000000000000000001241b6b86155467b26edfdab7ad6fb", - "0x000000000000000000000000000000b2d0f5b63f894b62d0e60089db80e58d27", - "0x000000000000000000000000000000000008244c501ee23523df6c834feb0e11", - "0x0000000000000000000000000000008672371fd2ce392b4b429418037d12162a", - "0x00000000000000000000000000000000002c7ce75950c33d18096163daf9cab6", - "0x000000000000000000000000000000d87658c101442505855988d5a754acdd88", - "0x0000000000000000000000000000000000137ad22d525a7eff2a2109fcdcae7a", - "0x0000000000000000000000000000006d12443f95a71b142723a798780c49adbd", - "0x000000000000000000000000000000000004e32eeb2532de9b992573f60e45dd", - "0x000000000000000000000000000000df1cbb627e3caab74cabc8712ac00362e9", - "0x000000000000000000000000000000000002e2f623a0fc048dcc89df75393191", - "0x0000000000000000000000000000000b53b2e19c6b1e9cd32e3cf643c416a59d", - "0x000000000000000000000000000000000020bf4d595cc2a10d2be49c507e7e96", - "0x000000000000000000000000000000a86601635b08eeb4993a1cf4033bf9d227", - "0x00000000000000000000000000000000001024c89eaa5827b94a3e6a6f6e2abf", - "0x000000000000000000000000000000f969a6c5173db0b28983bdd5834d3f6474", - "0x00000000000000000000000000000000001ef6a1853c5a97d42e27f8f509574e", - "0x000000000000000000000000000000c1e8d3777151f0521862bfc28f127f0258", - "0x00000000000000000000000000000000002172f71d7b12ef29e40e35f0eb792e", - "0x000000000000000000000000000000d1cf7d66f4a4f6d8e6dcd87fae8754a47c", - "0x0000000000000000000000000000000000281939574f4672879eb703d4d4de39", - "0x0000000000000000000000000000007c7be15eb86fc3e2098e8d224df92270e9", - "0x0000000000000000000000000000000000067d8f76b31d288f52990d7b851906", - "0x0000000000000000000000000000004e4d9ad79291ec12365024f1d5fee16595", - "0x000000000000000000000000000000000020c38b4a8b779b59231117e040791e", - "0x0000000000000000000000000000006fb68858ec3efdae8d238910eb3d7c1caf", - "0x00000000000000000000000000000000002e13d2da09f5dcceb4c2a40e0771c3", - "0x00000000000000000000000000000005ee27483337e5bd9c68e2d9b8685ea567", - "0x00000000000000000000000000000000002785f7e22fca9657887d9b32a7a423", - "0x0000000000000000000000000000005691107b72691b16467cd087d930a639e9", - "0x000000000000000000000000000000000026d6131e96f4a016e33fac0ba06f18", + "0x00000000000000000000000000000002dae7e831ed78b9726034fdf56e583ace", + "0x00000000000000000000000000000000002b3f4d616e8027a20f8edc16cfbe3b", + "0x0000000000000000000000000000004c72b92cbd48ecea19ad5642f7d557f5a4", + "0x0000000000000000000000000000000000168654a45c7d8664e75623ab72ffab", + "0x00000000000000000000000000000083005b55cabaef097051546fbfd7685d43", + "0x0000000000000000000000000000000000085264859c243091d0290fee66961d", + "0x000000000000000000000000000000a3609a137f0c64e9af9d672c82bb879030", + "0x00000000000000000000000000000000002f2816311eb3afd6c30a91f05a906c", + "0x000000000000000000000000000000e4511cf49697e16a74e0d6730d364cd6e4", + "0x00000000000000000000000000000000000d9b15c1ab4aafa9870030fb1f01f1", + "0x0000000000000000000000000000006dde861e212bf26640ef1436d7bdc4f201", + "0x00000000000000000000000000000000001ffaf73c05b99d1722a697b54ea994", + "0x000000000000000000000000000000396ba274703ebf4a03e4339dbc26d099a0", + "0x0000000000000000000000000000000000022e3ee5ffc2dc0533c2bbeb9099ec", + "0x000000000000000000000000000000e6e227b60dc9057a88f8cb4471a9fea86a", + "0x0000000000000000000000000000000000246959db6c3a295438492d935eaacb", + "0x0000000000000000000000000000003191ffb83d7d42b1add187223d067540a7", + "0x00000000000000000000000000000000001c6597787b5ebaa53b48a9fecacda8", + "0x000000000000000000000000000000e9f6be3f78c38204280bc224a2fd27c65d", + "0x00000000000000000000000000000000001c3e420965e904cac372ef32dc7923", + "0x0000000000000000000000000000007da218400340a430b8cf011f7892173af8", + "0x00000000000000000000000000000000000a31a316504c8be7ae5701acb98ced", + "0x0000000000000000000000000000003cf75706f021e6a661df64ef16d9a42b55", + "0x0000000000000000000000000000000000177148b7da28c2bf2cfe5737c85963", + "0x000000000000000000000000000000e0bc19695db19d2b16f525fa63874ddd68", + "0x00000000000000000000000000000000000ad3d70c629c5446ac4b2065893923", + "0x0000000000000000000000000000001617d14d968bc2679b85973347963a6329", + "0x00000000000000000000000000000000002c77cb09381821d1d62a74c81bcafb", + "0x000000000000000000000000000000915addec4b02be7e5599bbb1f41fbb9e0f", + "0x000000000000000000000000000000000028bcf441b36723bf95e0be039533f0", + "0x000000000000000000000000000000954535ac3a2cb2b7ea19315aca8ffff3bd", + "0x00000000000000000000000000000000000473d4f91369383b78b9324f8d83a3", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000eb965cf70d77f0e2216d04c748f3ab7f5c", - "0x00000000000000000000000000000000001beaa0afc9b05bdf71db514a814532", - "0x0000000000000000000000000000006cd09b0a30f4a93136c9860b93dcdb5bcd", - "0x00000000000000000000000000000000002dd6a841fe0c0bbe07a71c827501f5", + "0x000000000000000000000000000000a0309c5acf411dabd67697d4075710b60f", + "0x0000000000000000000000000000000000017125ed54d5f16d50c2be55f8d80b", + "0x000000000000000000000000000000c3884b62c59c37f43e8acad4f15afdba7a", + "0x00000000000000000000000000000000001a3bfaf919de7e9b9af2d6281c6374", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -1269,61 +727,322 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000c3b10f88e5436be1d5a5a4bb53bff9f86f", - "0x00000000000000000000000000000000000fb0a6d38afc343e251396adad53cf", - "0x00000000000000000000000000000070e87b913346fb9285cbb00737bd57cf7c", - "0x00000000000000000000000000000000002853427de22e10d72478e05c2f3f91", - "0x00000000000000000000000000000052cdddc8f97be52a13f243728d141d2901", - "0x000000000000000000000000000000000015b1139f895206b7e0178e1fc8ba75", - "0x000000000000000000000000000000c13228904b731ff23df21fb368c575405c", - "0x000000000000000000000000000000000025b350c9a547af501a922cd9867da0", - "0x000000000000000000000000000000561589ea814180f093543e48a620ad996c", - "0x00000000000000000000000000000000001fdfc3b1f7112d4ef57921ecde0909", - "0x000000000000000000000000000000099a453cc185766d9aada7cfdb2195d3b0", - "0x00000000000000000000000000000000000e551b1e35be8e8c1a41cbc889702a", - "0x0000000000000000000000000000007ba452ee5e06e123c1fb5cb50dc27007e4", - "0x000000000000000000000000000000000011a0d4e994b8faea474106b96afe46", - "0x000000000000000000000000000000f6ae6d824f37161f26c6515e95acfe76de", - "0x000000000000000000000000000000000029e3bcc9a024ac817c64d605e34fa2", - "0x0000000000000000000000000000002fec07757b3dde0584f30d7df6edc93ec9", - "0x0000000000000000000000000000000000233b6a495366005b18f14a21c37ede", - "0x000000000000000000000000000000d14f4d9f26fea64507ff561fa97d53d9ab", - "0x00000000000000000000000000000000001fb840c0913e222b1da7e26b2b556b", - "0x00000000000000000000000000000005442bad0ec64b17e4b69cc2da15241cdf", - "0x00000000000000000000000000000000002c438af2970405edbb8817c9f71d19", - "0x00000000000000000000000000000088fb3d8a9b6438b9ae1291865d3ab9f50e", - "0x000000000000000000000000000000000007c124e2aa719ddd02048950ed3154", - "0x00000000000000000000000000000034b5893e41adc3972f5ef17616f217463a", - "0x00000000000000000000000000000000002a2e5b545fa30305e181c35d58b00e", - "0x000000000000000000000000000000792d2f9cddf98914ba6ea9c36d9419444e", - "0x000000000000000000000000000000000025b1802368323e36444739ecf3ea7d", - "0x0000000000000000000000000000002d1b5d30f1396ec48b39dec6d2e1d5e9de", - "0x000000000000000000000000000000000026313ea541baf2d94c8ec1df8851be", - "0x000000000000000000000000000000f9b58828fdb3a2c664caf3cd2aa329120e", - "0x000000000000000000000000000000000013a9abade9e01b580cea0d4ec81be2", - "0x000000000000000000000000000000a253a5cc517aeb5355cc507dd13c01649b", - "0x00000000000000000000000000000000000eabf0702aeaf3687ccd37f915963f", - "0x000000000000000000000000000000fa09d1c5b7334edd245ca1c7484751a146", - "0x0000000000000000000000000000000000033a29b33b42df47e072f419ecf1e1", - "0x00000000000000000000000000000068402cb3387e20873c21b5cecbed30ac29", - "0x000000000000000000000000000000000022ea12e03f4fa8be007cfcb236a03d", - "0x000000000000000000000000000000cdddbfa9418b836e50ea09d17406c31e06", - "0x00000000000000000000000000000000002562102f34b4da4a0dc0855981d4ba", - "0x0000000000000000000000000000003fd5d827771206a607d5dffa24cd8c6c4e", - "0x000000000000000000000000000000000022d89961636344dbfb64fc460c980c", - "0x000000000000000000000000000000131a487254d372667a99dc85be24e5cd03", - "0x0000000000000000000000000000000000047b2d5e54f8007f15c8b2fd5c82be", - "0x000000000000000000000000000000976cc58ccb66e097253acb1b3888102f6f", - "0x0000000000000000000000000000000000080c14817c4a9e6eef9dd6ab5d3c16", - "0x000000000000000000000000000000639bb53c2654d493ce5072d8fc2d4954f5", - "0x00000000000000000000000000000000000d85125a9036e1ae1c5a69fb52d3b9", - "0x000000000000000000000000000000f3021896070f4b365fa4fb244174eaa223", - "0x00000000000000000000000000000000000c0f086a0470ef314c720b950ef2ea", - "0x000000000000000000000000000000497578c03ad3935905cf61ca910c7331f5", - "0x0000000000000000000000000000000000002398ed1decdb3cfc47f7457c1174" + "0x000000000000000000000000000000af74c853140d3b0cf48ac5426ad44e3a5c", + "0x00000000000000000000000000000000000cb504c2196f73934d76e059397164", + "0x000000000000000000000000000000684b219a630e4770c224f7391ce903b574", + "0x000000000000000000000000000000000003d04c0a020da0ff25d4d81a4d60cc", + "0x0000000000000000000000000000003a547a2ea7e16e11451dbbeff89a46927d", + "0x00000000000000000000000000000000000fe460a80b11f07f28d016ffcbbdd5", + "0x000000000000000000000000000000ef84584cfec94dd3c5125887edc8b15648", + "0x00000000000000000000000000000000002775675418cc4ce82c6c45ee105a60", + "0x000000000000000000000000000000a78629fdc8d0021839d214273a985802a3", + "0x000000000000000000000000000000000010a06e7102f85337eb4c8b60d97c25", + "0x000000000000000000000000000000518765c5253492c980ea80aac7e9986f75", + "0x00000000000000000000000000000000000a622d7d27836ced89d7a2c1ff2967", + "0x0000000000000000000000000000006460b6c05ba8ae4c71040cd807a630f6d8", + "0x00000000000000000000000000000000002879f62ac90caf8d067aa57f0a2cb6", + "0x00000000000000000000000000000071bf565e74a124d3587a0d63adc7f29b32", + "0x0000000000000000000000000000000000122c536450106d4844375b13d9ba2a", + "0x0000000000000000000000000000009133f308fcba6ba2e78c78f1540f56e805", + "0x00000000000000000000000000000000001cabb18101f26c315098c437934f63", + "0x0000000000000000000000000000002622d42a77800505a1cb7d4d76702cf100", + "0x000000000000000000000000000000000006b02f8ebd2ac84a9c6991c39dab4d", + "0x00000000000000000000000000000018d1dbeba31941616af05128326ec86ea5", + "0x000000000000000000000000000000000007c9f24379b75927ccb4d7ad3b8c82", + "0x00000000000000000000000000000092277632f048f820823839ad073172915a", + "0x00000000000000000000000000000000000a09bb921f8ca99cb19752b1bac91d", + "0x000000000000000000000000000000d91ca36caa7bd53f0c6da30743948a8639", + "0x000000000000000000000000000000000021e7290c49f78addda4ccd9eef9c8c", + "0x00000000000000000000000000000081b433648af06686217c238ce4b13cf535", + "0x00000000000000000000000000000000002047531ed8535e381cffae559b6bb0", + "0x0000000000000000000000000000007ffdec7092f6d520c0209c640bfadc695d", + "0x00000000000000000000000000000000000a26fbb3d9d87f4ab3dd718c3bb75e", + "0x000000000000000000000000000000c636bdd1555ebce8fb6a9751c48376b7dd", + "0x0000000000000000000000000000000000017cb50edda28183e752c7e00faa40", + "0x000000000000000000000000000000ec2af0c236db172d1e5c00f7de73ae4fef", + "0x0000000000000000000000000000000000053be81fcb74e5cbb36dc0f630a49a", + "0x000000000000000000000000000000080baf1731ad04c68e93e7045d03ef4fd3", + "0x00000000000000000000000000000000001e593590b8049fe6542e11d3606aa5", + "0x000000000000000000000000000000575f11519d26bc15d34402b3331befb097", + "0x00000000000000000000000000000000001b7eed68e0e1c24fbf77cbfa588283", + "0x000000000000000000000000000000e1cdf4c6808f1f53377d276a0214b9af54", + "0x000000000000000000000000000000000002c44f6a43320eb961560c6a40262b", + "0x0000000000000000000000000000009f48843445d33387ce0134c37a9b82037a", + "0x00000000000000000000000000000000000a2852b8f7464eefbba66e39124b2f", + "0x00000000000000000000000000000077e865b0eef6500d62b5ed5b71795e1fdd", + "0x00000000000000000000000000000000001bc28e177eaebca799a38f9b96bd41", + "0x0000000000000000000000000000008a3623ef604d2b654cbc7b6f898ab36fd2", + "0x0000000000000000000000000000000000239c355843996ddcf4f3330873dc58", + "0x0000000000000000000000000000001fd35d9c3df35c0ab05822a8a7672f307d", + "0x000000000000000000000000000000000008eff9c124dc7092426dbfef4f367f", + "0x000000000000000000000000000000045c0a8172f53ba9a5c8e00908c493018e", + "0x00000000000000000000000000000000002ca001cbe15bf21d7bc13cb56f8272", + "0x0000000000000000000000000000001842209bfe3ad1cfba506322320f9c1a8f", + "0x000000000000000000000000000000000005e47c6d153729d8788d2a9c9cd993" +] + hash = "0x035b62916d53f6a30d14dfd8245816108afd3d59028ddcf59607c26f190a855c" + + [inputs.message_bundle] + messages = [ + "0x00000000000000000000000000000000000000000000000000000000000005dc", + "0x00000000000000000000000000000000000000000000000000000000000005dd", + "0x00000000000000000000000000000000000000000000000000000000000005de", + "0x00000000000000000000000000000000000000000000000000000000000005df", + "0x00000000000000000000000000000000000000000000000000000000000005e0", + "0x00000000000000000000000000000000000000000000000000000000000005e1", + "0x00000000000000000000000000000000000000000000000000000000000005e2", + "0x00000000000000000000000000000000000000000000000000000000000005e3", + "0x00000000000000000000000000000000000000000000000000000000000005e4", + "0x00000000000000000000000000000000000000000000000000000000000005e5", + "0x00000000000000000000000000000000000000000000000000000000000005e6", + "0x00000000000000000000000000000000000000000000000000000000000005e7", + "0x00000000000000000000000000000000000000000000000000000000000005e8", + "0x00000000000000000000000000000000000000000000000000000000000005e9", + "0x00000000000000000000000000000000000000000000000000000000000005ea", + "0x00000000000000000000000000000000000000000000000000000000000005eb", + "0x00000000000000000000000000000000000000000000000000000000000005ec", + "0x00000000000000000000000000000000000000000000000000000000000005ed", + "0x00000000000000000000000000000000000000000000000000000000000005ee", + "0x00000000000000000000000000000000000000000000000000000000000005ef", + "0x00000000000000000000000000000000000000000000000000000000000005f0", + "0x00000000000000000000000000000000000000000000000000000000000005f1", + "0x00000000000000000000000000000000000000000000000000000000000005f2", + "0x00000000000000000000000000000000000000000000000000000000000005f3", + "0x00000000000000000000000000000000000000000000000000000000000005f4", + "0x00000000000000000000000000000000000000000000000000000000000005f5", + "0x00000000000000000000000000000000000000000000000000000000000005f6", + "0x00000000000000000000000000000000000000000000000000000000000005f7", + "0x00000000000000000000000000000000000000000000000000000000000005f8", + "0x00000000000000000000000000000000000000000000000000000000000005f9", + "0x00000000000000000000000000000000000000000000000000000000000005fa", + "0x00000000000000000000000000000000000000000000000000000000000005fb", + "0x00000000000000000000000000000000000000000000000000000000000005fc", + "0x00000000000000000000000000000000000000000000000000000000000005fd", + "0x00000000000000000000000000000000000000000000000000000000000005fe", + "0x00000000000000000000000000000000000000000000000000000000000005ff", + "0x0000000000000000000000000000000000000000000000000000000000000600", + "0x0000000000000000000000000000000000000000000000000000000000000601", + "0x0000000000000000000000000000000000000000000000000000000000000602", + "0x0000000000000000000000000000000000000000000000000000000000000603", + "0x0000000000000000000000000000000000000000000000000000000000000604", + "0x0000000000000000000000000000000000000000000000000000000000000605", + "0x0000000000000000000000000000000000000000000000000000000000000606", + "0x0000000000000000000000000000000000000000000000000000000000000607", + "0x0000000000000000000000000000000000000000000000000000000000000608", + "0x0000000000000000000000000000000000000000000000000000000000000609", + "0x000000000000000000000000000000000000000000000000000000000000060a", + "0x000000000000000000000000000000000000000000000000000000000000060b", + "0x000000000000000000000000000000000000000000000000000000000000060c", + "0x000000000000000000000000000000000000000000000000000000000000060d", + "0x000000000000000000000000000000000000000000000000000000000000060e", + "0x000000000000000000000000000000000000000000000000000000000000060f", + "0x0000000000000000000000000000000000000000000000000000000000000610", + "0x0000000000000000000000000000000000000000000000000000000000000611", + "0x0000000000000000000000000000000000000000000000000000000000000612", + "0x0000000000000000000000000000000000000000000000000000000000000613", + "0x0000000000000000000000000000000000000000000000000000000000000614", + "0x0000000000000000000000000000000000000000000000000000000000000615", + "0x0000000000000000000000000000000000000000000000000000000000000616", + "0x0000000000000000000000000000000000000000000000000000000000000617", + "0x0000000000000000000000000000000000000000000000000000000000000618", + "0x0000000000000000000000000000000000000000000000000000000000000619", + "0x000000000000000000000000000000000000000000000000000000000000061a", + "0x000000000000000000000000000000000000000000000000000000000000061b", + "0x000000000000000000000000000000000000000000000000000000000000061c", + "0x000000000000000000000000000000000000000000000000000000000000061d", + "0x000000000000000000000000000000000000000000000000000000000000061e", + "0x000000000000000000000000000000000000000000000000000000000000061f", + "0x0000000000000000000000000000000000000000000000000000000000000620", + "0x0000000000000000000000000000000000000000000000000000000000000621", + "0x0000000000000000000000000000000000000000000000000000000000000622", + "0x0000000000000000000000000000000000000000000000000000000000000623", + "0x0000000000000000000000000000000000000000000000000000000000000624", + "0x0000000000000000000000000000000000000000000000000000000000000625", + "0x0000000000000000000000000000000000000000000000000000000000000626", + "0x0000000000000000000000000000000000000000000000000000000000000627", + "0x0000000000000000000000000000000000000000000000000000000000000628", + "0x0000000000000000000000000000000000000000000000000000000000000629", + "0x000000000000000000000000000000000000000000000000000000000000062a", + "0x000000000000000000000000000000000000000000000000000000000000062b", + "0x000000000000000000000000000000000000000000000000000000000000062c", + "0x000000000000000000000000000000000000000000000000000000000000062d", + "0x000000000000000000000000000000000000000000000000000000000000062e", + "0x000000000000000000000000000000000000000000000000000000000000062f", + "0x0000000000000000000000000000000000000000000000000000000000000630", + "0x0000000000000000000000000000000000000000000000000000000000000631", + "0x0000000000000000000000000000000000000000000000000000000000000632", + "0x0000000000000000000000000000000000000000000000000000000000000633", + "0x0000000000000000000000000000000000000000000000000000000000000634", + "0x0000000000000000000000000000000000000000000000000000000000000635", + "0x0000000000000000000000000000000000000000000000000000000000000636", + "0x0000000000000000000000000000000000000000000000000000000000000637", + "0x0000000000000000000000000000000000000000000000000000000000000638", + "0x0000000000000000000000000000000000000000000000000000000000000639", + "0x000000000000000000000000000000000000000000000000000000000000063a", + "0x000000000000000000000000000000000000000000000000000000000000063b", + "0x000000000000000000000000000000000000000000000000000000000000063c", + "0x000000000000000000000000000000000000000000000000000000000000063d", + "0x000000000000000000000000000000000000000000000000000000000000063e", + "0x000000000000000000000000000000000000000000000000000000000000063f", + "0x0000000000000000000000000000000000000000000000000000000000000640", + "0x0000000000000000000000000000000000000000000000000000000000000641", + "0x0000000000000000000000000000000000000000000000000000000000000642", + "0x0000000000000000000000000000000000000000000000000000000000000643", + "0x0000000000000000000000000000000000000000000000000000000000000644", + "0x0000000000000000000000000000000000000000000000000000000000000645", + "0x0000000000000000000000000000000000000000000000000000000000000646", + "0x0000000000000000000000000000000000000000000000000000000000000647", + "0x0000000000000000000000000000000000000000000000000000000000000648", + "0x0000000000000000000000000000000000000000000000000000000000000649", + "0x000000000000000000000000000000000000000000000000000000000000064a", + "0x000000000000000000000000000000000000000000000000000000000000064b", + "0x000000000000000000000000000000000000000000000000000000000000064c", + "0x000000000000000000000000000000000000000000000000000000000000064d", + "0x000000000000000000000000000000000000000000000000000000000000064e", + "0x000000000000000000000000000000000000000000000000000000000000064f", + "0x0000000000000000000000000000000000000000000000000000000000000650", + "0x0000000000000000000000000000000000000000000000000000000000000651", + "0x0000000000000000000000000000000000000000000000000000000000000652", + "0x0000000000000000000000000000000000000000000000000000000000000653", + "0x0000000000000000000000000000000000000000000000000000000000000654", + "0x0000000000000000000000000000000000000000000000000000000000000655", + "0x0000000000000000000000000000000000000000000000000000000000000656", + "0x0000000000000000000000000000000000000000000000000000000000000657", + "0x0000000000000000000000000000000000000000000000000000000000000658", + "0x0000000000000000000000000000000000000000000000000000000000000659", + "0x000000000000000000000000000000000000000000000000000000000000065a", + "0x000000000000000000000000000000000000000000000000000000000000065b", + "0x000000000000000000000000000000000000000000000000000000000000065c", + "0x000000000000000000000000000000000000000000000000000000000000065d", + "0x000000000000000000000000000000000000000000000000000000000000065e", + "0x000000000000000000000000000000000000000000000000000000000000065f", + "0x0000000000000000000000000000000000000000000000000000000000000660", + "0x0000000000000000000000000000000000000000000000000000000000000661", + "0x0000000000000000000000000000000000000000000000000000000000000662", + "0x0000000000000000000000000000000000000000000000000000000000000663", + "0x0000000000000000000000000000000000000000000000000000000000000664", + "0x0000000000000000000000000000000000000000000000000000000000000665", + "0x0000000000000000000000000000000000000000000000000000000000000666", + "0x0000000000000000000000000000000000000000000000000000000000000667", + "0x0000000000000000000000000000000000000000000000000000000000000668", + "0x0000000000000000000000000000000000000000000000000000000000000669", + "0x000000000000000000000000000000000000000000000000000000000000066a", + "0x000000000000000000000000000000000000000000000000000000000000066b", + "0x000000000000000000000000000000000000000000000000000000000000066c", + "0x000000000000000000000000000000000000000000000000000000000000066d", + "0x000000000000000000000000000000000000000000000000000000000000066e", + "0x000000000000000000000000000000000000000000000000000000000000066f", + "0x0000000000000000000000000000000000000000000000000000000000000670", + "0x0000000000000000000000000000000000000000000000000000000000000671", + "0x0000000000000000000000000000000000000000000000000000000000000672", + "0x0000000000000000000000000000000000000000000000000000000000000673", + "0x0000000000000000000000000000000000000000000000000000000000000674", + "0x0000000000000000000000000000000000000000000000000000000000000675", + "0x0000000000000000000000000000000000000000000000000000000000000676", + "0x0000000000000000000000000000000000000000000000000000000000000677", + "0x0000000000000000000000000000000000000000000000000000000000000678", + "0x0000000000000000000000000000000000000000000000000000000000000679", + "0x000000000000000000000000000000000000000000000000000000000000067a", + "0x000000000000000000000000000000000000000000000000000000000000067b", + "0x000000000000000000000000000000000000000000000000000000000000067c", + "0x000000000000000000000000000000000000000000000000000000000000067d", + "0x000000000000000000000000000000000000000000000000000000000000067e", + "0x000000000000000000000000000000000000000000000000000000000000067f", + "0x0000000000000000000000000000000000000000000000000000000000000680", + "0x0000000000000000000000000000000000000000000000000000000000000681", + "0x0000000000000000000000000000000000000000000000000000000000000682", + "0x0000000000000000000000000000000000000000000000000000000000000683", + "0x0000000000000000000000000000000000000000000000000000000000000684", + "0x0000000000000000000000000000000000000000000000000000000000000685", + "0x0000000000000000000000000000000000000000000000000000000000000686", + "0x0000000000000000000000000000000000000000000000000000000000000687", + "0x0000000000000000000000000000000000000000000000000000000000000688", + "0x0000000000000000000000000000000000000000000000000000000000000689", + "0x000000000000000000000000000000000000000000000000000000000000068a", + "0x000000000000000000000000000000000000000000000000000000000000068b", + "0x000000000000000000000000000000000000000000000000000000000000068c", + "0x000000000000000000000000000000000000000000000000000000000000068d", + "0x000000000000000000000000000000000000000000000000000000000000068e", + "0x000000000000000000000000000000000000000000000000000000000000068f", + "0x0000000000000000000000000000000000000000000000000000000000000690", + "0x0000000000000000000000000000000000000000000000000000000000000691", + "0x0000000000000000000000000000000000000000000000000000000000000692", + "0x0000000000000000000000000000000000000000000000000000000000000693", + "0x0000000000000000000000000000000000000000000000000000000000000694", + "0x0000000000000000000000000000000000000000000000000000000000000695", + "0x0000000000000000000000000000000000000000000000000000000000000696", + "0x0000000000000000000000000000000000000000000000000000000000000697", + "0x0000000000000000000000000000000000000000000000000000000000000698", + "0x0000000000000000000000000000000000000000000000000000000000000699", + "0x000000000000000000000000000000000000000000000000000000000000069a", + "0x000000000000000000000000000000000000000000000000000000000000069b", + "0x000000000000000000000000000000000000000000000000000000000000069c", + "0x000000000000000000000000000000000000000000000000000000000000069d", + "0x000000000000000000000000000000000000000000000000000000000000069e", + "0x000000000000000000000000000000000000000000000000000000000000069f", + "0x00000000000000000000000000000000000000000000000000000000000006a0", + "0x00000000000000000000000000000000000000000000000000000000000006a1", + "0x00000000000000000000000000000000000000000000000000000000000006a2", + "0x00000000000000000000000000000000000000000000000000000000000006a3", + "0x00000000000000000000000000000000000000000000000000000000000006a4", + "0x00000000000000000000000000000000000000000000000000000000000006a5", + "0x00000000000000000000000000000000000000000000000000000000000006a6", + "0x00000000000000000000000000000000000000000000000000000000000006a7", + "0x00000000000000000000000000000000000000000000000000000000000006a8", + "0x00000000000000000000000000000000000000000000000000000000000006a9", + "0x00000000000000000000000000000000000000000000000000000000000006aa", + "0x00000000000000000000000000000000000000000000000000000000000006ab", + "0x00000000000000000000000000000000000000000000000000000000000006ac", + "0x00000000000000000000000000000000000000000000000000000000000006ad", + "0x00000000000000000000000000000000000000000000000000000000000006ae", + "0x00000000000000000000000000000000000000000000000000000000000006af", + "0x00000000000000000000000000000000000000000000000000000000000006b0", + "0x00000000000000000000000000000000000000000000000000000000000006b1", + "0x00000000000000000000000000000000000000000000000000000000000006b2", + "0x00000000000000000000000000000000000000000000000000000000000006b3", + "0x00000000000000000000000000000000000000000000000000000000000006b4", + "0x00000000000000000000000000000000000000000000000000000000000006b5", + "0x00000000000000000000000000000000000000000000000000000000000006b6", + "0x00000000000000000000000000000000000000000000000000000000000006b7", + "0x00000000000000000000000000000000000000000000000000000000000006b8", + "0x00000000000000000000000000000000000000000000000000000000000006b9", + "0x00000000000000000000000000000000000000000000000000000000000006ba", + "0x00000000000000000000000000000000000000000000000000000000000006bb", + "0x00000000000000000000000000000000000000000000000000000000000006bc", + "0x00000000000000000000000000000000000000000000000000000000000006bd", + "0x00000000000000000000000000000000000000000000000000000000000006be", + "0x00000000000000000000000000000000000000000000000000000000000006bf", + "0x00000000000000000000000000000000000000000000000000000000000006c0", + "0x00000000000000000000000000000000000000000000000000000000000006c1", + "0x00000000000000000000000000000000000000000000000000000000000006c2", + "0x00000000000000000000000000000000000000000000000000000000000006c3", + "0x00000000000000000000000000000000000000000000000000000000000006c4", + "0x00000000000000000000000000000000000000000000000000000000000006c5", + "0x00000000000000000000000000000000000000000000000000000000000006c6", + "0x00000000000000000000000000000000000000000000000000000000000006c7", + "0x00000000000000000000000000000000000000000000000000000000000006c8", + "0x00000000000000000000000000000000000000000000000000000000000006c9", + "0x00000000000000000000000000000000000000000000000000000000000006ca", + "0x00000000000000000000000000000000000000000000000000000000000006cb", + "0x00000000000000000000000000000000000000000000000000000000000006cc", + "0x00000000000000000000000000000000000000000000000000000000000006cd", + "0x00000000000000000000000000000000000000000000000000000000000006ce", + "0x00000000000000000000000000000000000000000000000000000000000006cf", + "0x00000000000000000000000000000000000000000000000000000000000006d0", + "0x00000000000000000000000000000000000000000000000000000000000006d1", + "0x00000000000000000000000000000000000000000000000000000000000006d2", + "0x00000000000000000000000000000000000000000000000000000000000006d3", + "0x00000000000000000000000000000000000000000000000000000000000006d4", + "0x00000000000000000000000000000000000000000000000000000000000006d5", + "0x00000000000000000000000000000000000000000000000000000000000006d6", + "0x00000000000000000000000000000000000000000000000000000000000006d7", + "0x00000000000000000000000000000000000000000000000000000000000006d8", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da", + "0x00000000000000000000000000000000000000000000000000000000000006db" ] - hash = "0x080a62f938a5f53f13c6f7f76c406722d810698e6354fed4f4e52ae528e124f5" + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml index 59d039325c74..dac20213e1b8 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-first/Prover.toml @@ -1,5 +1,15 @@ [inputs] -new_l1_to_l2_message_subtree_root_sibling_path = [ +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", @@ -28,10 +38,10 @@ new_l1_to_l2_message_subtree_root_sibling_path = [ "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" ] new_archive_sibling_path = [ - "0x01cbead9c751274331efa8f9a57e37296af41dfda8fde8b9dfad15e6df101932", + "0x03f4c32538d42652fb32a5cb2aee4307443fe38382028580e7aa46e43182df55", "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", - "0x26a143f9222c4ce37939deed6bf5daaa3020d99712c72f9303b3df89e6ce47fe", - "0x09308d0807f5aed64dd43d2014519a161c32f9a52ea75992cc18bec0bcde410e", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", @@ -60,558 +70,6 @@ new_archive_sibling_path = [ "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" ] - [inputs.parity_root] - proof = [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x000000000000000000000000000000000000000000000000000000000000000d", - "0x000000000000000000000000000000000000000000000000000000000000000e", - "0x000000000000000000000000000000000000000000000000000000000000000f", - "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000011", - "0x0000000000000000000000000000000000000000000000000000000000000012", - "0x0000000000000000000000000000000000000000000000000000000000000013", - "0x0000000000000000000000000000000000000000000000000000000000000014", - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x0000000000000000000000000000000000000000000000000000000000000017", - "0x0000000000000000000000000000000000000000000000000000000000000018", - "0x0000000000000000000000000000000000000000000000000000000000000019", - "0x000000000000000000000000000000000000000000000000000000000000001a", - "0x000000000000000000000000000000000000000000000000000000000000001b", - "0x000000000000000000000000000000000000000000000000000000000000001c", - "0x000000000000000000000000000000000000000000000000000000000000001d", - "0x000000000000000000000000000000000000000000000000000000000000001e", - "0x000000000000000000000000000000000000000000000000000000000000001f", - "0x0000000000000000000000000000000000000000000000000000000000000020", - "0x0000000000000000000000000000000000000000000000000000000000000021", - "0x0000000000000000000000000000000000000000000000000000000000000022", - "0x0000000000000000000000000000000000000000000000000000000000000023", - "0x0000000000000000000000000000000000000000000000000000000000000024", - "0x0000000000000000000000000000000000000000000000000000000000000025", - "0x0000000000000000000000000000000000000000000000000000000000000026", - "0x0000000000000000000000000000000000000000000000000000000000000027", - "0x0000000000000000000000000000000000000000000000000000000000000028", - "0x0000000000000000000000000000000000000000000000000000000000000029", - "0x000000000000000000000000000000000000000000000000000000000000002a", - "0x000000000000000000000000000000000000000000000000000000000000002b", - "0x000000000000000000000000000000000000000000000000000000000000002c", - "0x000000000000000000000000000000000000000000000000000000000000002d", - "0x000000000000000000000000000000000000000000000000000000000000002e", - "0x000000000000000000000000000000000000000000000000000000000000002f", - "0x0000000000000000000000000000000000000000000000000000000000000030", - "0x0000000000000000000000000000000000000000000000000000000000000031", - "0x0000000000000000000000000000000000000000000000000000000000000032", - "0x0000000000000000000000000000000000000000000000000000000000000033", - "0x0000000000000000000000000000000000000000000000000000000000000034", - "0x0000000000000000000000000000000000000000000000000000000000000035", - "0x0000000000000000000000000000000000000000000000000000000000000036", - "0x0000000000000000000000000000000000000000000000000000000000000037", - "0x0000000000000000000000000000000000000000000000000000000000000038", - "0x0000000000000000000000000000000000000000000000000000000000000039", - "0x000000000000000000000000000000000000000000000000000000000000003a", - "0x000000000000000000000000000000000000000000000000000000000000003b", - "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x000000000000000000000000000000000000000000000000000000000000003d", - "0x000000000000000000000000000000000000000000000000000000000000003e", - "0x000000000000000000000000000000000000000000000000000000000000003f", - "0x0000000000000000000000000000000000000000000000000000000000000040", - "0x0000000000000000000000000000000000000000000000000000000000000041", - "0x0000000000000000000000000000000000000000000000000000000000000042", - "0x0000000000000000000000000000000000000000000000000000000000000043", - "0x0000000000000000000000000000000000000000000000000000000000000044", - "0x0000000000000000000000000000000000000000000000000000000000000045", - "0x0000000000000000000000000000000000000000000000000000000000000046", - "0x0000000000000000000000000000000000000000000000000000000000000047", - "0x0000000000000000000000000000000000000000000000000000000000000048", - "0x0000000000000000000000000000000000000000000000000000000000000049", - "0x000000000000000000000000000000000000000000000000000000000000004a", - "0x000000000000000000000000000000000000000000000000000000000000004b", - "0x000000000000000000000000000000000000000000000000000000000000004c", - "0x000000000000000000000000000000000000000000000000000000000000004d", - "0x000000000000000000000000000000000000000000000000000000000000004e", - "0x000000000000000000000000000000000000000000000000000000000000004f", - "0x0000000000000000000000000000000000000000000000000000000000000050", - "0x0000000000000000000000000000000000000000000000000000000000000051", - "0x0000000000000000000000000000000000000000000000000000000000000052", - "0x0000000000000000000000000000000000000000000000000000000000000053", - "0x0000000000000000000000000000000000000000000000000000000000000054", - "0x0000000000000000000000000000000000000000000000000000000000000055", - "0x0000000000000000000000000000000000000000000000000000000000000056", - "0x0000000000000000000000000000000000000000000000000000000000000057", - "0x0000000000000000000000000000000000000000000000000000000000000058", - "0x0000000000000000000000000000000000000000000000000000000000000059", - "0x000000000000000000000000000000000000000000000000000000000000005a", - "0x000000000000000000000000000000000000000000000000000000000000005b", - "0x000000000000000000000000000000000000000000000000000000000000005c", - "0x000000000000000000000000000000000000000000000000000000000000005d", - "0x000000000000000000000000000000000000000000000000000000000000005e", - "0x000000000000000000000000000000000000000000000000000000000000005f", - "0x0000000000000000000000000000000000000000000000000000000000000060", - "0x0000000000000000000000000000000000000000000000000000000000000061", - "0x0000000000000000000000000000000000000000000000000000000000000062", - "0x0000000000000000000000000000000000000000000000000000000000000063", - "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000065", - "0x0000000000000000000000000000000000000000000000000000000000000066", - "0x0000000000000000000000000000000000000000000000000000000000000067", - "0x0000000000000000000000000000000000000000000000000000000000000068", - "0x0000000000000000000000000000000000000000000000000000000000000069", - "0x000000000000000000000000000000000000000000000000000000000000006a", - "0x000000000000000000000000000000000000000000000000000000000000006b", - "0x000000000000000000000000000000000000000000000000000000000000006c", - "0x000000000000000000000000000000000000000000000000000000000000006d", - "0x000000000000000000000000000000000000000000000000000000000000006e", - "0x000000000000000000000000000000000000000000000000000000000000006f", - "0x0000000000000000000000000000000000000000000000000000000000000070", - "0x0000000000000000000000000000000000000000000000000000000000000071", - "0x0000000000000000000000000000000000000000000000000000000000000072", - "0x0000000000000000000000000000000000000000000000000000000000000073", - "0x0000000000000000000000000000000000000000000000000000000000000074", - "0x0000000000000000000000000000000000000000000000000000000000000075", - "0x0000000000000000000000000000000000000000000000000000000000000076", - "0x0000000000000000000000000000000000000000000000000000000000000077", - "0x0000000000000000000000000000000000000000000000000000000000000078", - "0x0000000000000000000000000000000000000000000000000000000000000079", - "0x000000000000000000000000000000000000000000000000000000000000007a", - "0x000000000000000000000000000000000000000000000000000000000000007b", - "0x000000000000000000000000000000000000000000000000000000000000007c", - "0x000000000000000000000000000000000000000000000000000000000000007d", - "0x000000000000000000000000000000000000000000000000000000000000007e", - "0x000000000000000000000000000000000000000000000000000000000000007f", - "0x0000000000000000000000000000000000000000000000000000000000000080", - "0x0000000000000000000000000000000000000000000000000000000000000081", - "0x0000000000000000000000000000000000000000000000000000000000000082", - "0x0000000000000000000000000000000000000000000000000000000000000083", - "0x0000000000000000000000000000000000000000000000000000000000000084", - "0x0000000000000000000000000000000000000000000000000000000000000085", - "0x0000000000000000000000000000000000000000000000000000000000000086", - "0x0000000000000000000000000000000000000000000000000000000000000087", - "0x0000000000000000000000000000000000000000000000000000000000000088", - "0x0000000000000000000000000000000000000000000000000000000000000089", - "0x000000000000000000000000000000000000000000000000000000000000008a", - "0x000000000000000000000000000000000000000000000000000000000000008b", - "0x000000000000000000000000000000000000000000000000000000000000008c", - "0x000000000000000000000000000000000000000000000000000000000000008d", - "0x000000000000000000000000000000000000000000000000000000000000008e", - "0x000000000000000000000000000000000000000000000000000000000000008f", - "0x0000000000000000000000000000000000000000000000000000000000000090", - "0x0000000000000000000000000000000000000000000000000000000000000091", - "0x0000000000000000000000000000000000000000000000000000000000000092", - "0x0000000000000000000000000000000000000000000000000000000000000093", - "0x0000000000000000000000000000000000000000000000000000000000000094", - "0x0000000000000000000000000000000000000000000000000000000000000095", - "0x0000000000000000000000000000000000000000000000000000000000000096", - "0x0000000000000000000000000000000000000000000000000000000000000097", - "0x0000000000000000000000000000000000000000000000000000000000000098", - "0x0000000000000000000000000000000000000000000000000000000000000099", - "0x000000000000000000000000000000000000000000000000000000000000009a", - "0x000000000000000000000000000000000000000000000000000000000000009b", - "0x000000000000000000000000000000000000000000000000000000000000009c", - "0x000000000000000000000000000000000000000000000000000000000000009d", - "0x000000000000000000000000000000000000000000000000000000000000009e", - "0x000000000000000000000000000000000000000000000000000000000000009f", - "0x00000000000000000000000000000000000000000000000000000000000000a0", - "0x00000000000000000000000000000000000000000000000000000000000000a1", - "0x00000000000000000000000000000000000000000000000000000000000000a2", - "0x00000000000000000000000000000000000000000000000000000000000000a3", - "0x00000000000000000000000000000000000000000000000000000000000000a4", - "0x00000000000000000000000000000000000000000000000000000000000000a5", - "0x00000000000000000000000000000000000000000000000000000000000000a6", - "0x00000000000000000000000000000000000000000000000000000000000000a7", - "0x00000000000000000000000000000000000000000000000000000000000000a8", - "0x00000000000000000000000000000000000000000000000000000000000000a9", - "0x00000000000000000000000000000000000000000000000000000000000000aa", - "0x00000000000000000000000000000000000000000000000000000000000000ab", - "0x00000000000000000000000000000000000000000000000000000000000000ac", - "0x00000000000000000000000000000000000000000000000000000000000000ad", - "0x00000000000000000000000000000000000000000000000000000000000000ae", - "0x00000000000000000000000000000000000000000000000000000000000000af", - "0x00000000000000000000000000000000000000000000000000000000000000b0", - "0x00000000000000000000000000000000000000000000000000000000000000b1", - "0x00000000000000000000000000000000000000000000000000000000000000b2", - "0x00000000000000000000000000000000000000000000000000000000000000b3", - "0x00000000000000000000000000000000000000000000000000000000000000b4", - "0x00000000000000000000000000000000000000000000000000000000000000b5", - "0x00000000000000000000000000000000000000000000000000000000000000b6", - "0x00000000000000000000000000000000000000000000000000000000000000b7", - "0x00000000000000000000000000000000000000000000000000000000000000b8", - "0x00000000000000000000000000000000000000000000000000000000000000b9", - "0x00000000000000000000000000000000000000000000000000000000000000ba", - "0x00000000000000000000000000000000000000000000000000000000000000bb", - "0x00000000000000000000000000000000000000000000000000000000000000bc", - "0x00000000000000000000000000000000000000000000000000000000000000bd", - "0x00000000000000000000000000000000000000000000000000000000000000be", - "0x00000000000000000000000000000000000000000000000000000000000000bf", - "0x00000000000000000000000000000000000000000000000000000000000000c0", - "0x00000000000000000000000000000000000000000000000000000000000000c1", - "0x00000000000000000000000000000000000000000000000000000000000000c2", - "0x00000000000000000000000000000000000000000000000000000000000000c3", - "0x00000000000000000000000000000000000000000000000000000000000000c4", - "0x00000000000000000000000000000000000000000000000000000000000000c5", - "0x00000000000000000000000000000000000000000000000000000000000000c6", - "0x00000000000000000000000000000000000000000000000000000000000000c7", - "0x00000000000000000000000000000000000000000000000000000000000000c8", - "0x00000000000000000000000000000000000000000000000000000000000000c9", - "0x00000000000000000000000000000000000000000000000000000000000000ca", - "0x00000000000000000000000000000000000000000000000000000000000000cb", - "0x00000000000000000000000000000000000000000000000000000000000000cc", - "0x00000000000000000000000000000000000000000000000000000000000000cd", - "0x00000000000000000000000000000000000000000000000000000000000000ce", - "0x00000000000000000000000000000000000000000000000000000000000000cf", - "0x00000000000000000000000000000000000000000000000000000000000000d0", - "0x00000000000000000000000000000000000000000000000000000000000000d1", - "0x00000000000000000000000000000000000000000000000000000000000000d2", - "0x00000000000000000000000000000000000000000000000000000000000000d3", - "0x00000000000000000000000000000000000000000000000000000000000000d4", - "0x00000000000000000000000000000000000000000000000000000000000000d5", - "0x00000000000000000000000000000000000000000000000000000000000000d6", - "0x00000000000000000000000000000000000000000000000000000000000000d7", - "0x00000000000000000000000000000000000000000000000000000000000000d8", - "0x00000000000000000000000000000000000000000000000000000000000000d9", - "0x00000000000000000000000000000000000000000000000000000000000000da", - "0x00000000000000000000000000000000000000000000000000000000000000db", - "0x00000000000000000000000000000000000000000000000000000000000000dc", - "0x00000000000000000000000000000000000000000000000000000000000000dd", - "0x00000000000000000000000000000000000000000000000000000000000000de", - "0x00000000000000000000000000000000000000000000000000000000000000df", - "0x00000000000000000000000000000000000000000000000000000000000000e0", - "0x00000000000000000000000000000000000000000000000000000000000000e1", - "0x00000000000000000000000000000000000000000000000000000000000000e2", - "0x00000000000000000000000000000000000000000000000000000000000000e3", - "0x00000000000000000000000000000000000000000000000000000000000000e4", - "0x00000000000000000000000000000000000000000000000000000000000000e5", - "0x00000000000000000000000000000000000000000000000000000000000000e6", - "0x00000000000000000000000000000000000000000000000000000000000000e7", - "0x00000000000000000000000000000000000000000000000000000000000000e8", - "0x00000000000000000000000000000000000000000000000000000000000000e9", - "0x00000000000000000000000000000000000000000000000000000000000000ea", - "0x00000000000000000000000000000000000000000000000000000000000000eb", - "0x00000000000000000000000000000000000000000000000000000000000000ec", - "0x00000000000000000000000000000000000000000000000000000000000000ed", - "0x00000000000000000000000000000000000000000000000000000000000000ee", - "0x00000000000000000000000000000000000000000000000000000000000000ef", - "0x00000000000000000000000000000000000000000000000000000000000000f0", - "0x00000000000000000000000000000000000000000000000000000000000000f1", - "0x00000000000000000000000000000000000000000000000000000000000000f2", - "0x00000000000000000000000000000000000000000000000000000000000000f3", - "0x00000000000000000000000000000000000000000000000000000000000000f4", - "0x00000000000000000000000000000000000000000000000000000000000000f5", - "0x00000000000000000000000000000000000000000000000000000000000000f6", - "0x00000000000000000000000000000000000000000000000000000000000000f7", - "0x00000000000000000000000000000000000000000000000000000000000000f8", - "0x00000000000000000000000000000000000000000000000000000000000000f9", - "0x00000000000000000000000000000000000000000000000000000000000000fa", - "0x00000000000000000000000000000000000000000000000000000000000000fb", - "0x00000000000000000000000000000000000000000000000000000000000000fc", - "0x00000000000000000000000000000000000000000000000000000000000000fd", - "0x00000000000000000000000000000000000000000000000000000000000000fe", - "0x00000000000000000000000000000000000000000000000000000000000000ff", - "0x0000000000000000000000000000000000000000000000000000000000000100", - "0x0000000000000000000000000000000000000000000000000000000000000101", - "0x0000000000000000000000000000000000000000000000000000000000000102", - "0x0000000000000000000000000000000000000000000000000000000000000103", - "0x0000000000000000000000000000000000000000000000000000000000000104", - "0x0000000000000000000000000000000000000000000000000000000000000105", - "0x0000000000000000000000000000000000000000000000000000000000000106", - "0x0000000000000000000000000000000000000000000000000000000000000107", - "0x0000000000000000000000000000000000000000000000000000000000000108", - "0x0000000000000000000000000000000000000000000000000000000000000109", - "0x000000000000000000000000000000000000000000000000000000000000010a", - "0x000000000000000000000000000000000000000000000000000000000000010b", - "0x000000000000000000000000000000000000000000000000000000000000010c", - "0x000000000000000000000000000000000000000000000000000000000000010d", - "0x000000000000000000000000000000000000000000000000000000000000010e", - "0x000000000000000000000000000000000000000000000000000000000000010f", - "0x0000000000000000000000000000000000000000000000000000000000000110", - "0x0000000000000000000000000000000000000000000000000000000000000111", - "0x0000000000000000000000000000000000000000000000000000000000000112", - "0x0000000000000000000000000000000000000000000000000000000000000113", - "0x0000000000000000000000000000000000000000000000000000000000000114", - "0x0000000000000000000000000000000000000000000000000000000000000115", - "0x0000000000000000000000000000000000000000000000000000000000000116", - "0x0000000000000000000000000000000000000000000000000000000000000117", - "0x0000000000000000000000000000000000000000000000000000000000000118", - "0x0000000000000000000000000000000000000000000000000000000000000119", - "0x000000000000000000000000000000000000000000000000000000000000011a", - "0x000000000000000000000000000000000000000000000000000000000000011b", - "0x000000000000000000000000000000000000000000000000000000000000011c", - "0x000000000000000000000000000000000000000000000000000000000000011d", - "0x000000000000000000000000000000000000000000000000000000000000011e", - "0x000000000000000000000000000000000000000000000000000000000000011f", - "0x0000000000000000000000000000000000000000000000000000000000000120", - "0x0000000000000000000000000000000000000000000000000000000000000121", - "0x0000000000000000000000000000000000000000000000000000000000000122", - "0x0000000000000000000000000000000000000000000000000000000000000123", - "0x0000000000000000000000000000000000000000000000000000000000000124", - "0x0000000000000000000000000000000000000000000000000000000000000125", - "0x0000000000000000000000000000000000000000000000000000000000000126", - "0x0000000000000000000000000000000000000000000000000000000000000127", - "0x0000000000000000000000000000000000000000000000000000000000000128", - "0x0000000000000000000000000000000000000000000000000000000000000129", - "0x000000000000000000000000000000000000000000000000000000000000012a", - "0x000000000000000000000000000000000000000000000000000000000000012b", - "0x000000000000000000000000000000000000000000000000000000000000012c", - "0x000000000000000000000000000000000000000000000000000000000000012d", - "0x000000000000000000000000000000000000000000000000000000000000012e", - "0x000000000000000000000000000000000000000000000000000000000000012f", - "0x0000000000000000000000000000000000000000000000000000000000000130", - "0x0000000000000000000000000000000000000000000000000000000000000131", - "0x0000000000000000000000000000000000000000000000000000000000000132", - "0x0000000000000000000000000000000000000000000000000000000000000133", - "0x0000000000000000000000000000000000000000000000000000000000000134", - "0x0000000000000000000000000000000000000000000000000000000000000135", - "0x0000000000000000000000000000000000000000000000000000000000000136", - "0x0000000000000000000000000000000000000000000000000000000000000137", - "0x0000000000000000000000000000000000000000000000000000000000000138", - "0x0000000000000000000000000000000000000000000000000000000000000139", - "0x000000000000000000000000000000000000000000000000000000000000013a", - "0x000000000000000000000000000000000000000000000000000000000000013b", - "0x000000000000000000000000000000000000000000000000000000000000013c", - "0x000000000000000000000000000000000000000000000000000000000000013d", - "0x000000000000000000000000000000000000000000000000000000000000013e", - "0x000000000000000000000000000000000000000000000000000000000000013f", - "0x0000000000000000000000000000000000000000000000000000000000000140", - "0x0000000000000000000000000000000000000000000000000000000000000141", - "0x0000000000000000000000000000000000000000000000000000000000000142", - "0x0000000000000000000000000000000000000000000000000000000000000143", - "0x0000000000000000000000000000000000000000000000000000000000000144", - "0x0000000000000000000000000000000000000000000000000000000000000145", - "0x0000000000000000000000000000000000000000000000000000000000000146", - "0x0000000000000000000000000000000000000000000000000000000000000147", - "0x0000000000000000000000000000000000000000000000000000000000000148", - "0x0000000000000000000000000000000000000000000000000000000000000149", - "0x000000000000000000000000000000000000000000000000000000000000014a", - "0x000000000000000000000000000000000000000000000000000000000000014b", - "0x000000000000000000000000000000000000000000000000000000000000014c", - "0x000000000000000000000000000000000000000000000000000000000000014d", - "0x000000000000000000000000000000000000000000000000000000000000014e", - "0x000000000000000000000000000000000000000000000000000000000000014f", - "0x0000000000000000000000000000000000000000000000000000000000000150", - "0x0000000000000000000000000000000000000000000000000000000000000151", - "0x0000000000000000000000000000000000000000000000000000000000000152", - "0x0000000000000000000000000000000000000000000000000000000000000153", - "0x0000000000000000000000000000000000000000000000000000000000000154", - "0x0000000000000000000000000000000000000000000000000000000000000155", - "0x0000000000000000000000000000000000000000000000000000000000000156", - "0x0000000000000000000000000000000000000000000000000000000000000157", - "0x0000000000000000000000000000000000000000000000000000000000000158", - "0x0000000000000000000000000000000000000000000000000000000000000159", - "0x000000000000000000000000000000000000000000000000000000000000015a", - "0x000000000000000000000000000000000000000000000000000000000000015b", - "0x000000000000000000000000000000000000000000000000000000000000015c", - "0x000000000000000000000000000000000000000000000000000000000000015d", - "0x000000000000000000000000000000000000000000000000000000000000015e", - "0x000000000000000000000000000000000000000000000000000000000000015f", - "0x0000000000000000000000000000000000000000000000000000000000000160", - "0x0000000000000000000000000000000000000000000000000000000000000161", - "0x0000000000000000000000000000000000000000000000000000000000000162", - "0x0000000000000000000000000000000000000000000000000000000000000163", - "0x0000000000000000000000000000000000000000000000000000000000000164", - "0x0000000000000000000000000000000000000000000000000000000000000165", - "0x0000000000000000000000000000000000000000000000000000000000000166", - "0x0000000000000000000000000000000000000000000000000000000000000167", - "0x0000000000000000000000000000000000000000000000000000000000000168", - "0x0000000000000000000000000000000000000000000000000000000000000169", - "0x000000000000000000000000000000000000000000000000000000000000016a", - "0x000000000000000000000000000000000000000000000000000000000000016b", - "0x000000000000000000000000000000000000000000000000000000000000016c", - "0x000000000000000000000000000000000000000000000000000000000000016d", - "0x000000000000000000000000000000000000000000000000000000000000016e", - "0x000000000000000000000000000000000000000000000000000000000000016f", - "0x0000000000000000000000000000000000000000000000000000000000000170", - "0x0000000000000000000000000000000000000000000000000000000000000171", - "0x0000000000000000000000000000000000000000000000000000000000000172", - "0x0000000000000000000000000000000000000000000000000000000000000173", - "0x0000000000000000000000000000000000000000000000000000000000000174", - "0x0000000000000000000000000000000000000000000000000000000000000175", - "0x0000000000000000000000000000000000000000000000000000000000000176", - "0x0000000000000000000000000000000000000000000000000000000000000177", - "0x0000000000000000000000000000000000000000000000000000000000000178", - "0x0000000000000000000000000000000000000000000000000000000000000179", - "0x000000000000000000000000000000000000000000000000000000000000017a", - "0x000000000000000000000000000000000000000000000000000000000000017b", - "0x000000000000000000000000000000000000000000000000000000000000017c", - "0x000000000000000000000000000000000000000000000000000000000000017d", - "0x000000000000000000000000000000000000000000000000000000000000017e", - "0x000000000000000000000000000000000000000000000000000000000000017f", - "0x0000000000000000000000000000000000000000000000000000000000000180", - "0x0000000000000000000000000000000000000000000000000000000000000181", - "0x0000000000000000000000000000000000000000000000000000000000000182", - "0x0000000000000000000000000000000000000000000000000000000000000183", - "0x0000000000000000000000000000000000000000000000000000000000000184", - "0x0000000000000000000000000000000000000000000000000000000000000185", - "0x0000000000000000000000000000000000000000000000000000000000000186", - "0x0000000000000000000000000000000000000000000000000000000000000187", - "0x0000000000000000000000000000000000000000000000000000000000000188", - "0x0000000000000000000000000000000000000000000000000000000000000189", - "0x000000000000000000000000000000000000000000000000000000000000018a", - "0x000000000000000000000000000000000000000000000000000000000000018b", - "0x000000000000000000000000000000000000000000000000000000000000018c", - "0x000000000000000000000000000000000000000000000000000000000000018d", - "0x000000000000000000000000000000000000000000000000000000000000018e", - "0x000000000000000000000000000000000000000000000000000000000000018f", - "0x0000000000000000000000000000000000000000000000000000000000000190", - "0x0000000000000000000000000000000000000000000000000000000000000191", - "0x0000000000000000000000000000000000000000000000000000000000000192", - "0x0000000000000000000000000000000000000000000000000000000000000193", - "0x0000000000000000000000000000000000000000000000000000000000000194", - "0x0000000000000000000000000000000000000000000000000000000000000195", - "0x0000000000000000000000000000000000000000000000000000000000000196", - "0x0000000000000000000000000000000000000000000000000000000000000197", - "0x0000000000000000000000000000000000000000000000000000000000000198", - "0x0000000000000000000000000000000000000000000000000000000000000199", - "0x000000000000000000000000000000000000000000000000000000000000019a" -] - - [inputs.parity_root.public_inputs] - sha_root = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" - converted_root = "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - - [inputs.parity_root.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000016" - sibling_path = [ - "0x005a4d59d6486e10a3eefab398cca5d3c8e89e178a566d9885c5d7e478e46338", - "0x1fa32700cbe47fec502423d9419340fdfc6b73c146a1b1e42189b4dee5ddb4cc", - "0x07250f720369414b8956bab70d3dbfbe4a5912f128405eedb1c920009dcea92c", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" -] - - [inputs.parity_root.vk_data.vk] - key = [ - "0x0000000000000000000000000000000000000000000000000000000000000016", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x00000000000000000000000000000051b95d468aa9edbdd7a1e0f23a986c062f", - "0x00000000000000000000000000000000001bad5c453d035ced539f73b9ad9856", - "0x000000000000000000000000000000b9f20b33b45f2cd16ad5d036ab4e3b3e29", - "0x000000000000000000000000000000000024ea357fc8a07811c9d33358737ae6", - "0x000000000000000000000000000000ecd08e9e55edf496bac0902ec569099076", - "0x00000000000000000000000000000000002545be4c6d35893482ac43aecf9ca3", - "0x0000000000000000000000000000007b0429d81df3d0e6f023ad3023885f5d80", - "0x00000000000000000000000000000000001c682d1353fe66ef71491f339cde4c", - "0x00000000000000000000000000000021d27796a33c109672b6cdddafb1014772", - "0x00000000000000000000000000000000002cb8cb3972a4653468363f5cb656aa", - "0x000000000000000000000000000000253a50863b978d9398edeaaadb777a07a1", - "0x00000000000000000000000000000000000ef2db12c6ccbb131452091724f6a1", - "0x0000000000000000000000000000007abf7d869e61f461bad9f630ddf9594b05", - "0x00000000000000000000000000000000001111371317a103bc201e8123d6908b", - "0x00000000000000000000000000000055c64593831da4543a3d4b133e864eaf93", - "0x00000000000000000000000000000000000007aad0d55eaa03d5a23d84a35e60", - "0x000000000000000000000000000000165b401eb09f11cdbf56ba958577c91870", - "0x000000000000000000000000000000000024870f45c37a1866cbe92a8e88bbdd", - "0x00000000000000000000000000000022fabd7922e17d5369ed9c82423af1e455", - "0x000000000000000000000000000000000006649913c8489e9ddf864cbfba7f06", - "0x00000000000000000000000000000069115033b40ed21b2de75356921ceab9bb", - "0x000000000000000000000000000000000017967decbb04dea0b3c47f6cc805ed", - "0x000000000000000000000000000000b28d6694439fbe07553cdd206c5dfedebb", - "0x00000000000000000000000000000000000b08cdac94cf3e333b9195d9397ebe", - "0x000000000000000000000000000000cbe98014674062efea69339e44ebb83efc", - "0x00000000000000000000000000000000001e2260b0e077ac85ce74aaae4e72ef", - "0x000000000000000000000000000000bd27cf39ab646d638453f2fc0af16ba04b", - "0x00000000000000000000000000000000000473943ee569fdf17acac9c955c46f", - "0x000000000000000000000000000000864b31708b62da3d34b9f7ae5931f9696e", - "0x00000000000000000000000000000000000df5131cd2846d3102e898fa953ea0", - "0x000000000000000000000000000000d199787d243d0e9f7198c7f8993b47f431", - "0x0000000000000000000000000000000000161ef18b1311eebfa3ea1e312d40fc", - "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", - "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", - "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", - "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x0000000000000000000000000000006e4a0bfce0ed1188f9db0a6dd0de01ff56", - "0x000000000000000000000000000000000028ffb06695207e8e7beefe7ddd9bf2", - "0x000000000000000000000000000000c3bd4e37af8f5cb75f1e44ee1ac1a27822", - "0x00000000000000000000000000000000001a0419b42f40069bfbfb08563363e5", - "0x0000000000000000000000000000006eed465622852dce8a0702c5327cff0583", - "0x000000000000000000000000000000000022b0941f412859d1cc37a757ca4375", - "0x0000000000000000000000000000008bef872c634b8c03bfe7ff37c00a727192", - "0x000000000000000000000000000000000004906c8767a040a562b166a360c43b", - "0x0000000000000000000000000000002196aef3cb99415b3ac5297aac8f112fc6", - "0x0000000000000000000000000000000000202bc7de55cc5837eb14b1c9170f8b", - "0x000000000000000000000000000000bdf27b518418573439ed9eae4c5e5fb565", - "0x000000000000000000000000000000000017b3d9bbe6a673b931642f99c5da31", - "0x000000000000000000000000000000f02ba591cd0b41bb042d8e128595192f02", - "0x00000000000000000000000000000000000e91c21c980b16cf781f41a63337b6", - "0x000000000000000000000000000000df236435bb93d1ba03853ec32ce9bac516", - "0x00000000000000000000000000000000000c79c6f2ebdbb8e9a9ced4fe147b70", - "0x0000000000000000000000000000003fffb3aa510e7f700cf1014e5872d9c836", - "0x00000000000000000000000000000000002a8a152385a9322608448c3b903a25", - "0x000000000000000000000000000000e0e29574c018f3c6738e2e39d4c5add9a0", - "0x00000000000000000000000000000000000fc61b53a775b4a4abe28883bd4cae", - "0x00000000000000000000000000000015ad8f2e516ea41308c308441bd42c61e8", - "0x00000000000000000000000000000000002ae1b82b97d47244a5cbf6785de890", - "0x000000000000000000000000000000c903532912619760836806241aafc8d682", - "0x00000000000000000000000000000000000ad9c58de8e6372d34bc7aac8d1aca", - "0x0000000000000000000000000000008fa9fb6ea15481186d7cd1fc51794441c9", - "0x000000000000000000000000000000000011ecbb05712b264440c324636f313a", - "0x000000000000000000000000000000f56e21c6f0aaefba2220f3a94f80dab6ce", - "0x00000000000000000000000000000000000a6f225feab651d61030c107381417", - "0x0000000000000000000000000000006367da8ecf84e7656d58a4cf7cc1ef2a74", - "0x00000000000000000000000000000000002856f12f04dfa0785028992bc70c8a", - "0x000000000000000000000000000000540359f38ff410089ec6db690c67f8c0a6", - "0x00000000000000000000000000000000002f7ebc5d4a3f260e4a7008711317cd", - "0x0000000000000000000000000000002b55a45f77effa85ca159aaf39ada36b48", - "0x00000000000000000000000000000000001977d307b0175c7c38a065098ee4f0", - "0x00000000000000000000000000000065d17036201631ee10ae596434d01e5faf", - "0x000000000000000000000000000000000028a0ca170089439ba99c006abb5337", - "0x00000000000000000000000000000061b4a81da9a47d25c6a023ce9989052d14", - "0x000000000000000000000000000000000024f0d3b3ea4a55b1ef68ef0706d74d", - "0x0000000000000000000000000000001e9474df0627017ae3a6588c6675e5d37c", - "0x00000000000000000000000000000000000f9309e016418c2988a76cb9a7e6d0", - "0x0000000000000000000000000000005aabd337c2b20b92b5cd9f68fc113fa8fc", - "0x0000000000000000000000000000000000267e283433e6948f6e830121cf07d6", - "0x000000000000000000000000000000e63c28dcb1403d1abd520e3be26f5ea912", - "0x00000000000000000000000000000000000b8e7e8a4f0ee43c9adb3118d1c77c", - "0x00000000000000000000000000000001cb5edebf7fec67758257f420eb739626", - "0x00000000000000000000000000000000002ac6f62034a546864c00f263827917", - "0x0000000000000000000000000000006ffb02c7e19870982b9368ed26a1a90e5b", - "0x000000000000000000000000000000000021d8e1392945c72edde14af5a71989", - "0x000000000000000000000000000000035fe29e7aa320fcacba3b59ca25bc6419", - "0x000000000000000000000000000000000007f147299102f19d56530c50361528", - "0x000000000000000000000000000000e5be284aab52d0591e1613d5674ab90345", - "0x0000000000000000000000000000000000121e8ab82e001622ed0bacd52bbe03", - "0x00000000000000000000000000000003fa9212b7d0d61e9db75b0d68d8b35153", - "0x00000000000000000000000000000000000fb55f91f49661936a9e62dd35a4ce", - "0x00000000000000000000000000000030c134112f5d817a22a316654112fd7714", - "0x00000000000000000000000000000000000a528aa7ced2566011573552cf302e", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000003b87ae780740d3d14ff8f9a547b2926c1b", - "0x00000000000000000000000000000000001cbcc9a266eec40328a8057d238ebd", - "0x0000000000000000000000000000003f6ec85bee0641c92db9ca4fcc5fa3c24a", - "0x00000000000000000000000000000000002f189078dffab22dd8076b731348c8", - "0x0000000000000000000000000000001fad48d68c46c8ce6bd9b67aa6e588bbe0", - "0x00000000000000000000000000000000002fcda688d3b990ca6451a5841e39c1", - "0x000000000000000000000000000000f44fc69aa2dcf70ea4a66b7a9b23c9ab95", - "0x0000000000000000000000000000000000016f201ae57c6fd54a72dba17e156d", - "0x0000000000000000000000000000007b1d6e61b0d5254c9fba726ae7ae9cc66f", - "0x000000000000000000000000000000000002f7da015e525c659a66da56ae616b", - "0x0000000000000000000000000000004f7b93f9c23397a77423f2d327b024943e", - "0x00000000000000000000000000000000001d4011b86d37adeccdf00f76b47447", - "0x0000000000000000000000000000004a4deb709a4b4c26e852e64bf9f8e3d854", - "0x00000000000000000000000000000000002fdd2702a68fda431a1aae6bb8a36a", - "0x0000000000000000000000000000005bc0bd35cd7f4765aadf5249b6d0a58b74", - "0x00000000000000000000000000000000000d439321d69f2e8851f3a88e18f6cf" -] - hash = "0x269f5cc6356c1bfd4868c38cebcc39f9edcae4cb0f5b72ae04bd23bed6d25ddb" - [[inputs.previous_rollups]] proof = [ "0x0000000000000000000000000000000000000000000000000000000000000001", @@ -1097,64 +555,64 @@ new_archive_sibling_path = [ ] [inputs.previous_rollups.public_inputs] - num_txs = "0x0000000000000000000000000000000000000000000000000000000000000002" - out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x0000000000000000000000000000000000000000000000000000e0c2c3b9a200" - accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000011752b" + num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" + out_hash = "0x006bd7618b0cf7b40e3f107022eee2d411bcc5850fbb774dacc46a15957659c4" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x02b768bc715afcefe7acc2a4394dc1ec3d36e9051f52662c42c795597ad03956" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.constants.global_variables] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000d" - slot_number = "0x000000000000000000000000000000000000000000000000000000000000004b" - timestamp = "0x000000000000000000000000000000000000000000000000000000006a4d2351" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000001" + slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" + timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000cdfe600" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x0298ee00030f8d6a3ffea366a5874f37b247e09fcd4551957c2412304739f886" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000240" +root = "0x2590f2aab19dd791700b4a43d3f52bb88ef2409a3731da8e848663559202e4c6" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x2c7cf128d73c690cf7271c4879cec3ace4cac3228f5e03ea928e45a6f3722823" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x2c9dae5a1ef562cdfa66256c803675f421e47ccd4ffd869a29aaddba9e1626a9" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2ecc66f66ba34cbad2712824ccf19b8be619d1ed5d9a2941015091070f0c3bae" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x14a1f4a7aad9307a23a0ee3113720baeaea791b0536342955f020528e154c6f4" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x26abb36f6187a9d47bcdda82cc551f41e8596cc04bdc23ac11e4f7289147890c" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1175,84 +633,84 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004cd" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x1969a000ba533c2645eb9cea782dbb88f2ed154022b89045c5fba48927e9809a", - "0x2021e773cd9ca18af4f0f0901e25af18f03595de778f302aacfca09d6f6d641c", - "0x2506d48ea4ed2e11a5f4753f87c9a3970477bd31fcacd90bd33b10c2fd7005bd" + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c" ] state = [ - "0x2ea4469ea0669f8f5e980b18d51db0273c0c90e9ec79b8fe28ec1df5e6f8b601", - "0x192e404a9861f10ab23706910d050c568156471a904335368a357fd8582fd8c3", - "0x069f5d0c6f8417c0f0bdb02336db790eb741f768f31ca271e680322755ee4789", - "0x2b382f16e9441dbead7b83a912778cdc3a9042e6ba6af3d254fa612ed341e7c3" + "0x2c5737a1b8a42dac1cd14d222c8459c80e2cae66cb6274b16deb60c7f3f5a1ae", + "0x2d4fdf47df8cc8a1f92b08f664e30534ff9f0ef010d7a50286a59fa19534b85f", + "0x20f5664e6bd413127341beb4141e8b17c1f070d3bbbf52d1fc8fa2f5d0673289", + "0x03e2edc9d1c58eb638704b25e7aff835cee24781dca271b23f5cdf9c6382f060" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" sibling_path = [ - "0x1e73559df90b9ac652f39d057651493cf969d69cefd6a5ab110845f928273371", - "0x0f5051c9544348ed76ea21f6edbd6e24dcb243dba2f146d947505e6e88c20322", - "0x0a2818ba5dd5624d91f012822293d4135b8958ec1d8ab6cf952ee3de138bb8c4", - "0x0787c8cc4cfb80390c27cdc17cb24ae198faad7989508690070b3cf40a2ae4fd", - "0x2a17b9f268be22deec2941ce8de06f485f2d164710a5177d262a4ae86b7c351f", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x1fc39d0a428c8536dbca551ea79848acf67d89d090fd8c643c7d90f2e8f32340", + "0x12ce5a49a1ceca53ada7bee003f929bbd65abaa74e8072a81f304c2c96c44e31", + "0x276f60617ee2c3b406af56bfe9216a7d99be56ad316ff557cee0446f08e14135", + "0x1dab7bce1884db3c7fa09243adb445f93156a1a0546582123d8c1d6c89e7fe41", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000015", + "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000009c72edd2a247b98baee92d045e2e84cf39", - "0x000000000000000000000000000000000006f941fb29caf0fc1129d5b66480c3", - "0x0000000000000000000000000000000a95b0bf6f7d7b6636cfcf9d8aaffa758d", - "0x00000000000000000000000000000000001177d4ef4832d1e422fcb37067d50a", - "0x000000000000000000000000000000a2ca740b8e49052339fd574112d6932bb8", - "0x000000000000000000000000000000000030035f9db88b6837c7ea5bc44d96a4", - "0x0000000000000000000000000000006b49d4a6355cd8ef0ec5a00afafe0b2931", - "0x00000000000000000000000000000000000352522b8b5fd308113352ce4a8a80", - "0x000000000000000000000000000000c663b248762ead4627089ff3b231523661", - "0x0000000000000000000000000000000000133e833b90020e88c9eee0fda60c7e", - "0x000000000000000000000000000000d5f1cfdf57f47ac91b1a9d0f9cac93f955", - "0x0000000000000000000000000000000000225b8ca01cd09e0532e3205493333f", - "0x00000000000000000000000000000000e0007118055feb60eeb9420c695fe7eb", - "0x000000000000000000000000000000000021793910a5d6080a81f9876608a4ef", - "0x000000000000000000000000000000dda76904c41bc9035d0f7b33b9ee696ace", - "0x00000000000000000000000000000000002bba61344d9d95d75624f09128425e", - "0x000000000000000000000000000000390cb5146d68145a832fc688758da7dd64", - "0x0000000000000000000000000000000000164940b75a6dc9e6bdfd175e265b13", - "0x00000000000000000000000000000004e33bdd084c2836f34631aa6048630741", - "0x0000000000000000000000000000000000100c24a84e54f22c44c4a9a38e509a", - "0x0000000000000000000000000000000bd562a8c11d5e415d072167bbafde5fa0", - "0x00000000000000000000000000000000000173659ef499cda7d815e5d80a3774", - "0x000000000000000000000000000000be5b81e39bae1c45ac14a45196648e7f78", - "0x000000000000000000000000000000000014db1cefc28d3435ae0447f1d3cdf5", - "0x0000000000000000000000000000002c54e6c7c66b6dc1c91e9acbae78919983", - "0x00000000000000000000000000000000002265a0363e5b923e1e919725b5f2ab", - "0x00000000000000000000000000000010a9888d4dccc616d59bdc3c1c71b02cc7", - "0x00000000000000000000000000000000000307cb3b8050501351767ba67a7f10", - "0x00000000000000000000000000000005668180c604938afaec3a1ed0083770c3", - "0x00000000000000000000000000000000002022a06cd7f242b2861cf8268e51b9", - "0x0000000000000000000000000000006d2d6e4f136c99893fdcb826d1739ebd37", - "0x000000000000000000000000000000000025f20ff73fe959346ceb7533d0b8fb", + "0x00000000000000000000000000000002dae7e831ed78b9726034fdf56e583ace", + "0x00000000000000000000000000000000002b3f4d616e8027a20f8edc16cfbe3b", + "0x0000000000000000000000000000004c72b92cbd48ecea19ad5642f7d557f5a4", + "0x0000000000000000000000000000000000168654a45c7d8664e75623ab72ffab", + "0x00000000000000000000000000000083005b55cabaef097051546fbfd7685d43", + "0x0000000000000000000000000000000000085264859c243091d0290fee66961d", + "0x000000000000000000000000000000a3609a137f0c64e9af9d672c82bb879030", + "0x00000000000000000000000000000000002f2816311eb3afd6c30a91f05a906c", + "0x000000000000000000000000000000e4511cf49697e16a74e0d6730d364cd6e4", + "0x00000000000000000000000000000000000d9b15c1ab4aafa9870030fb1f01f1", + "0x0000000000000000000000000000006dde861e212bf26640ef1436d7bdc4f201", + "0x00000000000000000000000000000000001ffaf73c05b99d1722a697b54ea994", + "0x000000000000000000000000000000396ba274703ebf4a03e4339dbc26d099a0", + "0x0000000000000000000000000000000000022e3ee5ffc2dc0533c2bbeb9099ec", + "0x000000000000000000000000000000e6e227b60dc9057a88f8cb4471a9fea86a", + "0x0000000000000000000000000000000000246959db6c3a295438492d935eaacb", + "0x0000000000000000000000000000003191ffb83d7d42b1add187223d067540a7", + "0x00000000000000000000000000000000001c6597787b5ebaa53b48a9fecacda8", + "0x000000000000000000000000000000e9f6be3f78c38204280bc224a2fd27c65d", + "0x00000000000000000000000000000000001c3e420965e904cac372ef32dc7923", + "0x0000000000000000000000000000007da218400340a430b8cf011f7892173af8", + "0x00000000000000000000000000000000000a31a316504c8be7ae5701acb98ced", + "0x0000000000000000000000000000003cf75706f021e6a661df64ef16d9a42b55", + "0x0000000000000000000000000000000000177148b7da28c2bf2cfe5737c85963", + "0x000000000000000000000000000000e0bc19695db19d2b16f525fa63874ddd68", + "0x00000000000000000000000000000000000ad3d70c629c5446ac4b2065893923", + "0x0000000000000000000000000000001617d14d968bc2679b85973347963a6329", + "0x00000000000000000000000000000000002c77cb09381821d1d62a74c81bcafb", + "0x000000000000000000000000000000915addec4b02be7e5599bbb1f41fbb9e0f", + "0x000000000000000000000000000000000028bcf441b36723bf95e0be039533f0", + "0x000000000000000000000000000000954535ac3a2cb2b7ea19315aca8ffff3bd", + "0x00000000000000000000000000000000000473d4f91369383b78b9324f8d83a3", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000d2ffd9ee52010057d8f5eefa13a76f80c8", - "0x00000000000000000000000000000000002ba1cd0acd1931ea7ab4b5ecc65c1b", - "0x00000000000000000000000000000032ef1588d101fd366998e618306f4b235a", - "0x000000000000000000000000000000000027f476e633f01587475355c44617bd", - "0x000000000000000000000000000000b1795305b34f2f47e00fefef8e3ff03117", - "0x0000000000000000000000000000000000219d203b492d7debf5d8e7df9d2059", - "0x000000000000000000000000000000bfa96395c8478bacb512c36590c5b7b901", - "0x00000000000000000000000000000000001088537efb9ccd4bbaf4c519fb15ef", + "0x000000000000000000000000000000a0309c5acf411dabd67697d4075710b60f", + "0x0000000000000000000000000000000000017125ed54d5f16d50c2be55f8d80b", + "0x000000000000000000000000000000c3884b62c59c37f43e8acad4f15afdba7a", + "0x00000000000000000000000000000000001a3bfaf919de7e9b9af2d6281c6374", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", "0x00000000000000000000000000000016c08d152f9dc697daff20714fccf7a5ea", "0x000000000000000000000000000000000021414e160dd06b07bdc4cfc47e4e2c", "0x0000000000000000000000000000002a824f2fcf5190d78d4fc5975ad848a5d1", @@ -1269,60 +727,60 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000beda1aad6fd11d15d8da7d061508a3303b", - "0x00000000000000000000000000000000001a1c8dbcc3dd29dc34d7db1705f074", - "0x0000000000000000000000000000005321cb78a890c412428302292c7d82dc59", - "0x00000000000000000000000000000000002dc99f592725128b916102cb937e89", - "0x000000000000000000000000000000a764f06febb6fc246e9a869bf0978c820e", - "0x000000000000000000000000000000000008e3685916162ba4c1bae712cabfa0", - "0x0000000000000000000000000000001df817171be6114e3541f0a6d266e3dc05", - "0x0000000000000000000000000000000000134d97a0490ac8940e9f52236e72fb", - "0x00000000000000000000000000000035c851719afd23ac7449e114787843c22c", - "0x00000000000000000000000000000000001c983a9ff82027746c1aa37fcdcdc3", - "0x000000000000000000000000000000e919f5bc767230c80a03ebae7893e29c96", - "0x000000000000000000000000000000000001f3e2a62a856f0a8a91c2925c5128", - "0x000000000000000000000000000000d471fa1e5b35905eeb0d7276a6d1fc7041", - "0x00000000000000000000000000000000001cd2118b1c14bdfe36b3e62631e1b6", - "0x0000000000000000000000000000006a421ce3850766871be3eead987e61e85c", - "0x00000000000000000000000000000000002412ae02cce15169067e62841fc786", - "0x00000000000000000000000000000011394144e2ca692a4b47d3c512937c64f3", - "0x00000000000000000000000000000000001ca04b5cc6150d41684f2c7ce97452", - "0x000000000000000000000000000000e06ac7361cb7572090ad6f4b921e9edbc6", - "0x0000000000000000000000000000000000002fa895a811f7ef64954c78d0ad81", - "0x00000000000000000000000000000057c547da26c0df0139823c890d14a738d1", - "0x00000000000000000000000000000000002d5d33adf906dfda2d23a113216f81", - "0x000000000000000000000000000000d62f99c9a778404be4543cac8d156181b9", - "0x000000000000000000000000000000000005adb1db772c03ef8afdc5bf59731c", - "0x000000000000000000000000000000fe0629f41367116cfd1dda2341b90a91c0", - "0x000000000000000000000000000000000023d1184f7a974b21dcffa54cc244e2", - "0x0000000000000000000000000000009f5b02b5af8c549e5b4a714f417a26bcb3", - "0x000000000000000000000000000000000005cf6ba732df0c4332889d875fb568", - "0x00000000000000000000000000000014f8688324fbb37f15c506579fe433b5db", - "0x000000000000000000000000000000000011eca7766155663ff7d9aaec915b59", - "0x00000000000000000000000000000064fe789354986ddad3edea44a53d4e7380", - "0x0000000000000000000000000000000000234b3e7b42069697af4b43bc70677b", - "0x000000000000000000000000000000a768bd74ac653325edda6e149d08d76459", - "0x00000000000000000000000000000000000426f6b392743609fa1929ef4a9314", - "0x0000000000000000000000000000008a574a44f7559165e11bd16c5cf21b4e53", - "0x0000000000000000000000000000000000180fbf7d51033ad5da3cf5c16edc2d", - "0x00000000000000000000000000000053053085e1141ba3c94677f97f82ccafc5", - "0x00000000000000000000000000000000001914e8622f808571c83286d354b6b1", - "0x0000000000000000000000000000001a8f745d15bbfba9630f32aadeb7a2dde8", - "0x00000000000000000000000000000000000ee71d332f6aa68899712377dac0e9", - "0x00000000000000000000000000000025f97acf411c17e675f5bf8b34a67744e2", - "0x00000000000000000000000000000000000c464ca4ebe3f8c6ee36f0ef4c1000", - "0x000000000000000000000000000000848ba26aca63eafdf9bd6630b34c2ab8bb", - "0x000000000000000000000000000000000009a8af4fcca5ce396382099608d086", - "0x0000000000000000000000000000003841fbfce4ed2b25cebb016b2a40f1f266", - "0x00000000000000000000000000000000002f14fdee8e81f556947710f623695a", - "0x0000000000000000000000000000008d9fbe089fed6aec54fbaca46b3ff8dc27", - "0x00000000000000000000000000000000001fe11197043854e2bbc7a2913a3562", - "0x000000000000000000000000000000fd984b184c30d3af2350fbfdbdb1c322e2", - "0x000000000000000000000000000000000010794246a9eb75626b0bbd442f5972", - "0x000000000000000000000000000000170e5cec200f14cf4ea0cf1544cd35e2ea", - "0x000000000000000000000000000000000027b493797520c5cdf76fa07ecef3cc" + "0x000000000000000000000000000000af74c853140d3b0cf48ac5426ad44e3a5c", + "0x00000000000000000000000000000000000cb504c2196f73934d76e059397164", + "0x000000000000000000000000000000684b219a630e4770c224f7391ce903b574", + "0x000000000000000000000000000000000003d04c0a020da0ff25d4d81a4d60cc", + "0x0000000000000000000000000000003a547a2ea7e16e11451dbbeff89a46927d", + "0x00000000000000000000000000000000000fe460a80b11f07f28d016ffcbbdd5", + "0x000000000000000000000000000000ef84584cfec94dd3c5125887edc8b15648", + "0x00000000000000000000000000000000002775675418cc4ce82c6c45ee105a60", + "0x000000000000000000000000000000a78629fdc8d0021839d214273a985802a3", + "0x000000000000000000000000000000000010a06e7102f85337eb4c8b60d97c25", + "0x000000000000000000000000000000518765c5253492c980ea80aac7e9986f75", + "0x00000000000000000000000000000000000a622d7d27836ced89d7a2c1ff2967", + "0x0000000000000000000000000000006460b6c05ba8ae4c71040cd807a630f6d8", + "0x00000000000000000000000000000000002879f62ac90caf8d067aa57f0a2cb6", + "0x00000000000000000000000000000071bf565e74a124d3587a0d63adc7f29b32", + "0x0000000000000000000000000000000000122c536450106d4844375b13d9ba2a", + "0x0000000000000000000000000000009133f308fcba6ba2e78c78f1540f56e805", + "0x00000000000000000000000000000000001cabb18101f26c315098c437934f63", + "0x0000000000000000000000000000002622d42a77800505a1cb7d4d76702cf100", + "0x000000000000000000000000000000000006b02f8ebd2ac84a9c6991c39dab4d", + "0x00000000000000000000000000000018d1dbeba31941616af05128326ec86ea5", + "0x000000000000000000000000000000000007c9f24379b75927ccb4d7ad3b8c82", + "0x00000000000000000000000000000092277632f048f820823839ad073172915a", + "0x00000000000000000000000000000000000a09bb921f8ca99cb19752b1bac91d", + "0x000000000000000000000000000000d91ca36caa7bd53f0c6da30743948a8639", + "0x000000000000000000000000000000000021e7290c49f78addda4ccd9eef9c8c", + "0x00000000000000000000000000000081b433648af06686217c238ce4b13cf535", + "0x00000000000000000000000000000000002047531ed8535e381cffae559b6bb0", + "0x0000000000000000000000000000007ffdec7092f6d520c0209c640bfadc695d", + "0x00000000000000000000000000000000000a26fbb3d9d87f4ab3dd718c3bb75e", + "0x000000000000000000000000000000c636bdd1555ebce8fb6a9751c48376b7dd", + "0x0000000000000000000000000000000000017cb50edda28183e752c7e00faa40", + "0x000000000000000000000000000000ec2af0c236db172d1e5c00f7de73ae4fef", + "0x0000000000000000000000000000000000053be81fcb74e5cbb36dc0f630a49a", + "0x000000000000000000000000000000080baf1731ad04c68e93e7045d03ef4fd3", + "0x00000000000000000000000000000000001e593590b8049fe6542e11d3606aa5", + "0x000000000000000000000000000000575f11519d26bc15d34402b3331befb097", + "0x00000000000000000000000000000000001b7eed68e0e1c24fbf77cbfa588283", + "0x000000000000000000000000000000e1cdf4c6808f1f53377d276a0214b9af54", + "0x000000000000000000000000000000000002c44f6a43320eb961560c6a40262b", + "0x0000000000000000000000000000009f48843445d33387ce0134c37a9b82037a", + "0x00000000000000000000000000000000000a2852b8f7464eefbba66e39124b2f", + "0x00000000000000000000000000000077e865b0eef6500d62b5ed5b71795e1fdd", + "0x00000000000000000000000000000000001bc28e177eaebca799a38f9b96bd41", + "0x0000000000000000000000000000008a3623ef604d2b654cbc7b6f898ab36fd2", + "0x0000000000000000000000000000000000239c355843996ddcf4f3330873dc58", + "0x0000000000000000000000000000001fd35d9c3df35c0ab05822a8a7672f307d", + "0x000000000000000000000000000000000008eff9c124dc7092426dbfef4f367f", + "0x000000000000000000000000000000045c0a8172f53ba9a5c8e00908c493018e", + "0x00000000000000000000000000000000002ca001cbe15bf21d7bc13cb56f8272", + "0x0000000000000000000000000000001842209bfe3ad1cfba506322320f9c1a8f", + "0x000000000000000000000000000000000005e47c6d153729d8788d2a9c9cd993" ] - hash = "0x10b6730f1d1e9c6bf8d7c4b42b64b40d2603e3ae6ddbd464c3d8fcfb9e06e6d4" + hash = "0x035b62916d53f6a30d14dfd8245816108afd3d59028ddcf59607c26f190a855c" [[inputs.previous_rollups]] proof = [ @@ -1810,96 +1268,96 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" - out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x000000000000000000000000000000000000000000000000000083a35fe8cc00" - accumulated_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3982" + out_hash = "0x00abb50b8989a7f19fd4526d43e15a1ab5d2a43af413cc8ca91e82a3c8828625" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x02b768bc715afcefe7acc2a4394dc1ec3d36e9051f52662c42c795597ad03956" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002c00" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.constants.global_variables] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - block_number = "0x000000000000000000000000000000000000000000000000000000000000000d" - slot_number = "0x000000000000000000000000000000000000000000000000000000000000004b" - timestamp = "0x000000000000000000000000000000000000000000000000000000006a4d2351" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000001" + slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" + timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" [inputs.previous_rollups.public_inputs.constants.global_variables.coinbase] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x000000000000000000000000000000000000000000000000000000000cdfe600" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2ecc66f66ba34cbad2712824ccf19b8be619d1ed5d9a2941015091070f0c3bae" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000002c0" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x14a1f4a7aad9307a23a0ee3113720baeaea791b0536342955f020528e154c6f4" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000340" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x26abb36f6187a9d47bcdda82cc551f41e8596cc04bdc23ac11e4f7289147890c" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x2ecc66f66ba34cbad2712824ccf19b8be619d1ed5d9a2941015091070f0c3bae" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000300" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x05bbdb6d06db6265e0f848b38cdfefd38dda3b667d29aced0513238f2c471264" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000380" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x0041fb3365374b55867227ba19a841bd15da8d512da26a7a5aef327fa1f90ac1" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000045" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004cd" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x1969a000ba533c2645eb9cea782dbb88f2ed154022b89045c5fba48927e9809a", - "0x2021e773cd9ca18af4f0f0901e25af18f03595de778f302aacfca09d6f6d641c", - "0x2506d48ea4ed2e11a5f4753f87c9a3970477bd31fcacd90bd33b10c2fd7005bd" + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c" ] state = [ - "0x2ea4469ea0669f8f5e980b18d51db0273c0c90e9ec79b8fe28ec1df5e6f8b601", - "0x192e404a9861f10ab23706910d050c568156471a904335368a357fd8582fd8c3", - "0x069f5d0c6f8417c0f0bdb02336db790eb741f768f31ca271e680322755ee4789", - "0x2b382f16e9441dbead7b83a912778cdc3a9042e6ba6af3d254fa612ed341e7c3" + "0x2c5737a1b8a42dac1cd14d222c8459c80e2cae66cb6274b16deb60c7f3f5a1ae", + "0x2d4fdf47df8cc8a1f92b08f664e30534ff9f0ef010d7a50286a59fa19534b85f", + "0x20f5664e6bd413127341beb4141e8b17c1f070d3bbbf52d1fc8fa2f5d0673289", + "0x03e2edc9d1c58eb638704b25e7aff835cee24781dca271b23f5cdf9c6382f060" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x000000000000000000000000000000000000000000000000000000000000004f" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a18" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000021e0a6076caaa5a6380", - "0x000000000000000000000000000000000000000000000000000000000000076c", - "0x061ad0f0ed7065820b58cc64574e3bf863d19f7b368dc6d3594bc21208d48f6f" + "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34d" ] state = [ - "0x0d653cd16026629e1757daeea90a4181cd6d83ce6a6f8cc6311e0e774d3a6d6f", - "0x079fc610149becc66696cd184805c3357dab8e25aee4b276a916312951e81043", - "0x2a3910db26c4807e38ad955db3a385f3b73169e69e9426ea98c761a748276808", - "0x0a8ca0a5c53ae38174655581762e5a1ac0c71d91aa9d1a18a26f51bd27cf2055" + "0x03ac2cb6a213e90037ef7886c441579364cc7f017b122878939df7bbf57932b6", + "0x0d84b3aaa62a9c45dd75583bf4573014ce3be47a8b4c49af2c188778c2e98da3", + "0x01e88ae7362fb20ac2f50021ea2170b68911c428fb6538d3f80ea5cc7b8ca32e", + "0x01045708915736a70481db6c878eefc72a090d3995f68fbce0fe809e1d16eaea" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1908,12 +1366,12 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ "0x10b6730f1d1e9c6bf8d7c4b42b64b40d2603e3ae6ddbd464c3d8fcfb9e06e6d4", - "0x0f5051c9544348ed76ea21f6edbd6e24dcb243dba2f146d947505e6e88c20322", - "0x0a2818ba5dd5624d91f012822293d4135b8958ec1d8ab6cf952ee3de138bb8c4", - "0x0787c8cc4cfb80390c27cdc17cb24ae198faad7989508690070b3cf40a2ae4fd", - "0x2a17b9f268be22deec2941ce8de06f485f2d164710a5177d262a4ae86b7c351f", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x11017f6408ff020bf1556ed3f4d41fba9dfe9fe312cd5430ec7c1abf7e3a9bcc", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] @@ -1921,46 +1379,46 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000009328a328a1d7ae2aa50556292f6544ae6b", - "0x00000000000000000000000000000000000aa5d4c9f48e6dd058c09a1a7fb58d", - "0x000000000000000000000000000000b3eec467daffe4b53b9a863cc25ce83485", - "0x00000000000000000000000000000000002545f85f7cd444bfd463ef9464c127", - "0x000000000000000000000000000000a935dcd8f2f7c2b3d5707ac9e49f751396", - "0x00000000000000000000000000000000000219fb19f7e1f8c2ce2fc9e7792217", - "0x000000000000000000000000000000f2bce39af7c28c3daf14b6cc09d8861849", - "0x0000000000000000000000000000000000011e005fea17bc19ff878ba41e6675", - "0x00000000000000000000000000000047de99203b7ee2fda4db6fa36d746c5ab7", - "0x0000000000000000000000000000000000280ab1316f6e66eac9698dd616935d", - "0x00000000000000000000000000000002a3cecfefbb3065b83cd96a85af8f19e9", - "0x00000000000000000000000000000000002d439a34bc69bbaefa7bc3b8e9d8ca", - "0x000000000000000000000000000000d3ae6bfc445bbd5de744015690d8f93658", - "0x000000000000000000000000000000000016dd6a4d5d69290d171327327b8d6e", - "0x000000000000000000000000000000fbe6c638c966a777499a4d84a702652ea1", - "0x00000000000000000000000000000000001bbba64f59a5fd205ae0e7bf2e69aa", - "0x000000000000000000000000000000dfa788a7bd698c4f83e52100d3d5aed96b", - "0x00000000000000000000000000000000001dbf818746d111c66d328f6fdc0bb1", - "0x000000000000000000000000000000c407fcfd89b1aa059f800cf47b81baba5a", - "0x000000000000000000000000000000000023f10a84b2ee1b5e5e8ceb9dc0fa71", - "0x00000000000000000000000000000045cb054f71e399a8377914b741ac89423d", - "0x000000000000000000000000000000000006b94ebf9dcec725654e630044e4a8", - "0x000000000000000000000000000000e1376352416fe03d8711f23abdbcf5ba60", - "0x00000000000000000000000000000000000a7cc5fbbd3ac3e90bf41415a1fb0a", - "0x00000000000000000000000000000072c67e268debafed7b141bf7ea3170cf64", - "0x00000000000000000000000000000000002c669ba7507217d14a7ed66f47532e", - "0x0000000000000000000000000000008401feacc75ac63d2eb419f97aaec5c77a", - "0x00000000000000000000000000000000001f6986a262963375619443ccaa5c23", - "0x0000000000000000000000000000006fac0e0a31def3bb4c32fe284c99864b9a", - "0x000000000000000000000000000000000007a1ff2509f698f5c7d4374eb9c392", - "0x000000000000000000000000000000fe2bb606f3c248ee28465335c6d32f8fbf", - "0x000000000000000000000000000000000019710c99918555be474cf945692274", + "0x000000000000000000000000000000be3ef7df55faad770dd417b568b334bb61", + "0x0000000000000000000000000000000000020dbb5be28ee0dddbe361d4210575", + "0x0000000000000000000000000000002a9a30c0f428736335b3eb03271a7faa35", + "0x0000000000000000000000000000000000011eeab7deb21addfa7d56d1c588a1", + "0x000000000000000000000000000000cd7414d72fbdd24b1bad570941833708ea", + "0x0000000000000000000000000000000000125ab5466e467ad79893fe6fb71dac", + "0x000000000000000000000000000000275ffdc4a6a9c963cff9f4bfc97ff47ae5", + "0x000000000000000000000000000000000009b0fc1fdcf1eb4720e77df4bf579e", + "0x0000000000000000000000000000004b41b33ed09d6f2e0d1e2778bcc0a412bf", + "0x00000000000000000000000000000000002431de0fcb1f1e513962b6ddaff0cb", + "0x000000000000000000000000000000ceacbeb3107979529c12c1d0eee1557e98", + "0x000000000000000000000000000000000015157c061d1d61cf7dd3a7ce845922", + "0x0000000000000000000000000000003f7443a3cea90f0e6730b33675efbbda73", + "0x00000000000000000000000000000000002ca6b067638c1c24bbadd530a94798", + "0x000000000000000000000000000000f4d7b640687e4a07ea713f599fa766d14f", + "0x00000000000000000000000000000000001da3ebbf464dad0213d7cbb620146c", + "0x000000000000000000000000000000a5e9f66b74ff0bfcb7cb43d4ae9f154cf7", + "0x00000000000000000000000000000000001b50d6d924c13b8138405d313f1875", + "0x00000000000000000000000000000091dda1fdadf6e5bb631936d41c3e919572", + "0x0000000000000000000000000000000000218f9e93fa7efcdb8d89b8303acc50", + "0x000000000000000000000000000000f659c8815b22bacd330bee0c95d2a77cfd", + "0x00000000000000000000000000000000002aee8b729bc510e581461f3c3d3f20", + "0x000000000000000000000000000000d35405c664cefb21dd45302fa07ce6e1ae", + "0x0000000000000000000000000000000000168af130006e1ff22ea8737f0207e3", + "0x0000000000000000000000000000004b9beda85c743bfc49ac3aa711ccf95ca3", + "0x000000000000000000000000000000000028fb89c6da361c392f36475551e5c7", + "0x000000000000000000000000000000c5d8af9e91084202d30bd24e2ae1787dd1", + "0x00000000000000000000000000000000002ea1690f1652415522380675b4f298", + "0x00000000000000000000000000000004cc26069474a70fefc9e011a297d3659a", + "0x00000000000000000000000000000000002c4ca65f1f3ce11e955002f76823b7", + "0x000000000000000000000000000000caa9709b37a3f896da980148bd862f79ad", + "0x00000000000000000000000000000000001cdab1dc53ddf21433efb20a019aed", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000f8f16d93b4d40b6b37b47c60bb2e15968a", - "0x00000000000000000000000000000000001c66ae5d710e4f03e905237f56896c", - "0x00000000000000000000000000000062e3f05ba19f6d2ee7e046babbd221f7fe", - "0x0000000000000000000000000000000000187b562e03dda0dfccd55b54ad3f3e", + "0x00000000000000000000000000000091be1f8e738e8cf74c39dcff97e574049a", + "0x0000000000000000000000000000000000253b1d48e89dea2387345d1f190cf8", + "0x00000000000000000000000000000001f523e64316ec12df1d1fed701b1fc3ff", + "0x0000000000000000000000000000000000254e8bc817fd854d25dce4ca34bbb9", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -1981,61 +1439,322 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000900b39279bfc348fe557fb41d1f5d4c8b5", - "0x000000000000000000000000000000000029c825eb725af14205dfdb51bae5de", - "0x0000000000000000000000000000000f0273d62b0aa2ac98edd943d1f4c8f60b", - "0x000000000000000000000000000000000018af8bfa4415bb1e50212aca3d0dce", - "0x000000000000000000000000000000e36aaf472b0fe4d0e2458fe2fd2d3f36a5", - "0x000000000000000000000000000000000024990e730d8de48cc32b305eb892d3", - "0x00000000000000000000000000000046ec4ab852f8095bbde1355df6c9213674", - "0x00000000000000000000000000000000002d9f6208dd41a9391c5f2ff161723b", - "0x000000000000000000000000000000ff206faaa0603e94cf9012d38caf547b71", - "0x00000000000000000000000000000000002b090b6a8885d5642efd8ecb4a9967", - "0x000000000000000000000000000000cde3418169f1900f43c3e6562a3148b92b", - "0x00000000000000000000000000000000001a94d29546f4b269e6deea4d66d87f", - "0x0000000000000000000000000000006974ad4cb642ac7c4817fa36b7b6fa8d6e", - "0x00000000000000000000000000000000002b3a27229b370a8f69a852528a6eb1", - "0x000000000000000000000000000000ee3598685e7189bc323970020b18027714", - "0x000000000000000000000000000000000001ee4d7ef523491e7a7993648f6ee5", - "0x00000000000000000000000000000065af27b4e679703f76baeff7f9f8fde824", - "0x000000000000000000000000000000000013c02a8904a5078fbda6eea9287da5", - "0x000000000000000000000000000000f8054be82ae2c8c42416c32941ff5ff4a0", - "0x000000000000000000000000000000000003fc2699d2a0ff70836b78d9cc6988", - "0x00000000000000000000000000000073b0555261f63360b7869a394c8e7e90ef", - "0x0000000000000000000000000000000000172f74597312d749903182f4fd0e12", - "0x00000000000000000000000000000068c8346993c46672b64d812d6e5f379111", - "0x00000000000000000000000000000000002e1815eca8079dc41036f900b9c788", - "0x0000000000000000000000000000008aaff6db42d06baddf581bd9da6bd2dd5e", - "0x00000000000000000000000000000000000f4a770e94b16e157fc2173e760fd9", - "0x0000000000000000000000000000008971b6d90cc4bce45b75a18b31984bac9f", - "0x0000000000000000000000000000000000243812b999c56279eb2ed4461ddfb5", - "0x0000000000000000000000000000001c197b35b5d02d046ebe0fe0a3e978d15b", - "0x000000000000000000000000000000000014cf7eb2bd158e4a4aa1226de04329", - "0x000000000000000000000000000000fd0cdfc2e8908027336ec0d325f0b3f581", - "0x000000000000000000000000000000000015eea29fa83b4c6b7f71b92bb173d4", - "0x00000000000000000000000000000071c0383bd65ec4578f0a35b617628139ee", - "0x0000000000000000000000000000000000297e66b3248c15286954bde883bbb8", - "0x0000000000000000000000000000000a2c2dec5f0ab63d709ea86670d3ecae6e", - "0x00000000000000000000000000000000002a93ebbca35f379e0535fbce8fc034", - "0x00000000000000000000000000000050e646471d6aa448f5c82ad81bdf9f378d", - "0x00000000000000000000000000000000002dc1b94dc9cb15332fc1862826b86d", - "0x0000000000000000000000000000006ac66c092067851920be2fc0e432413ebf", - "0x000000000000000000000000000000000022ff1934508b1f94313f0a941cfa57", - "0x00000000000000000000000000000091370c3a85062dd23fd6e83c0922a25dd4", - "0x000000000000000000000000000000000003e76557875f4575a3226e83f0a240", - "0x00000000000000000000000000000051758a46a47e0bb3da237577bfca9059a9", - "0x000000000000000000000000000000000004ef694c61d62980e6e04d6aee6826", - "0x000000000000000000000000000000601c96b32be57ad228a169b76ff62df506", - "0x000000000000000000000000000000000024ef565e299f10b00eadc1a1deee3f", - "0x000000000000000000000000000000771bb043879978ce4a2bb82fcfd0be139b", - "0x0000000000000000000000000000000000172c152adac30c20871fab0ec0924b", - "0x0000000000000000000000000000005822c453d08cb7a175254d02adbc691b69", - "0x00000000000000000000000000000000000fda746bab7f21c8fa41a48aea9d61", - "0x0000000000000000000000000000005ac028874e611d55f51c6f227316c3a2b9", - "0x00000000000000000000000000000000001921c1ccbe180174c5e55da318a0c1" + "0x00000000000000000000000000000063a793166969e30306b1a33ee3140ab639", + "0x00000000000000000000000000000000000689ae6c5351a0c7d2bddd28760eba", + "0x000000000000000000000000000000e9e058e78b28069998e0b545635c751505", + "0x000000000000000000000000000000000029d041f64f9c7a4b574afdd84eb2bc", + "0x000000000000000000000000000000de0e873aad4dce9c296b5822c49119b396", + "0x00000000000000000000000000000000001e622a80763bdce9e84c5936947ea4", + "0x000000000000000000000000000000ff979afed880f8777a1d7edb65ce1450e3", + "0x000000000000000000000000000000000012be4428cf92f37d4329f288edd6d7", + "0x000000000000000000000000000000d68061ce1bad9ac1e54cdf86b65d18b89f", + "0x000000000000000000000000000000000020fdf737ed00586f6db007044965a8", + "0x000000000000000000000000000000946bb34bc2173c2659e824f5fd377a3cbf", + "0x000000000000000000000000000000000022da84ec41699f355efa9e9550e4e4", + "0x0000000000000000000000000000008b0f4ef158c13087ed0e80688fe8373342", + "0x00000000000000000000000000000000002a4cae8c1411ba84463b850ab1844a", + "0x00000000000000000000000000000081d9bb13936c0676b987efe4a7ccd38a7e", + "0x00000000000000000000000000000000001e527e0c58ebec97285f8d47471778", + "0x000000000000000000000000000000c17602371eddd69a1e0e5b82a51441f2d3", + "0x000000000000000000000000000000000010fd74deb218f4d0d58aee589c31a6", + "0x000000000000000000000000000000dc8cd28e055e13b175149f797af895f0f4", + "0x000000000000000000000000000000000014d50f3e5a64cc7500ed82e02796e5", + "0x000000000000000000000000000000c61024b9433cc9b608636d33133501734f", + "0x0000000000000000000000000000000000080ffdff074611822ac0029ae9ac87", + "0x000000000000000000000000000000251c0f33e1f84d4365571cd965fc9b951c", + "0x00000000000000000000000000000000002e7e699ac6cc777970c0d5dd410bc0", + "0x0000000000000000000000000000009e1f4030259589018ce84f6f1dd736ae5d", + "0x000000000000000000000000000000000006154a1e0fea69f24bf7ac004afb7a", + "0x000000000000000000000000000000189020ea1ed822257549ab99ac2b33647e", + "0x00000000000000000000000000000000002a384f4831d00b56c6219abcb3b785", + "0x00000000000000000000000000000035fb02b0d2e793607a238e08539424c438", + "0x00000000000000000000000000000000001d0e75eecc618b087887f7d14ddf24", + "0x000000000000000000000000000000eae70e5ed566bcad446daa8f1059119fb5", + "0x00000000000000000000000000000000001f16d342675b048447aec1d841ea6f", + "0x000000000000000000000000000000dec8287d2ca445b6611951692aceb93f09", + "0x00000000000000000000000000000000000d237ea339d430164ddcf07c98eebb", + "0x00000000000000000000000000000069bd0705898ec802324165e180c23cca88", + "0x00000000000000000000000000000000002b2487b0a0cad2ab8b703eda79048b", + "0x000000000000000000000000000000526f89287c9fa8d0869c89341b300cd057", + "0x00000000000000000000000000000000000da86b460feb2479d72b91bad3aa4e", + "0x000000000000000000000000000000aba6055db467fa492b870fccd9251c0cb4", + "0x000000000000000000000000000000000022e849a8f64faebc36288439518d4b", + "0x000000000000000000000000000000ab679268e81d4770ddc1861ac7485ac4e8", + "0x000000000000000000000000000000000009a186caa2f074b8b5d3d26afddfc5", + "0x000000000000000000000000000000694fbc055e1f0045837b2bcf0d60f82934", + "0x00000000000000000000000000000000000ffba7e4a28991553a68d277bf2aa3", + "0x000000000000000000000000000000de4a494414853cc677e6f0de0f19a070c8", + "0x000000000000000000000000000000000004485188f222785e8455584b3632e6", + "0x0000000000000000000000000000001e68682a2d646f241b36838e8627fe4258", + "0x00000000000000000000000000000000001cd86d75f808b92947367db49e99b3", + "0x000000000000000000000000000000a21f994888d69ad0e60ea74b527f54a7ed", + "0x00000000000000000000000000000000001bbdaa75acb6eb653db71e1666d066", + "0x000000000000000000000000000000eb0694220d1a490792b0165b98d9b8bf71", + "0x000000000000000000000000000000000025729291a976e4cbed01962ee0b0d0" +] + hash = "0x242e942739553143b651d041e96bc6bc5e09baa6142d959488ffa864ce063d69" + + [inputs.message_bundle] + messages = [ + "0x00000000000000000000000000000000000000000000000000000000000005dc", + "0x00000000000000000000000000000000000000000000000000000000000005dd", + "0x00000000000000000000000000000000000000000000000000000000000005de", + "0x00000000000000000000000000000000000000000000000000000000000005df", + "0x00000000000000000000000000000000000000000000000000000000000005e0", + "0x00000000000000000000000000000000000000000000000000000000000005e1", + "0x00000000000000000000000000000000000000000000000000000000000005e2", + "0x00000000000000000000000000000000000000000000000000000000000005e3", + "0x00000000000000000000000000000000000000000000000000000000000005e4", + "0x00000000000000000000000000000000000000000000000000000000000005e5", + "0x00000000000000000000000000000000000000000000000000000000000005e6", + "0x00000000000000000000000000000000000000000000000000000000000005e7", + "0x00000000000000000000000000000000000000000000000000000000000005e8", + "0x00000000000000000000000000000000000000000000000000000000000005e9", + "0x00000000000000000000000000000000000000000000000000000000000005ea", + "0x00000000000000000000000000000000000000000000000000000000000005eb", + "0x00000000000000000000000000000000000000000000000000000000000005ec", + "0x00000000000000000000000000000000000000000000000000000000000005ed", + "0x00000000000000000000000000000000000000000000000000000000000005ee", + "0x00000000000000000000000000000000000000000000000000000000000005ef", + "0x00000000000000000000000000000000000000000000000000000000000005f0", + "0x00000000000000000000000000000000000000000000000000000000000005f1", + "0x00000000000000000000000000000000000000000000000000000000000005f2", + "0x00000000000000000000000000000000000000000000000000000000000005f3", + "0x00000000000000000000000000000000000000000000000000000000000005f4", + "0x00000000000000000000000000000000000000000000000000000000000005f5", + "0x00000000000000000000000000000000000000000000000000000000000005f6", + "0x00000000000000000000000000000000000000000000000000000000000005f7", + "0x00000000000000000000000000000000000000000000000000000000000005f8", + "0x00000000000000000000000000000000000000000000000000000000000005f9", + "0x00000000000000000000000000000000000000000000000000000000000005fa", + "0x00000000000000000000000000000000000000000000000000000000000005fb", + "0x00000000000000000000000000000000000000000000000000000000000005fc", + "0x00000000000000000000000000000000000000000000000000000000000005fd", + "0x00000000000000000000000000000000000000000000000000000000000005fe", + "0x00000000000000000000000000000000000000000000000000000000000005ff", + "0x0000000000000000000000000000000000000000000000000000000000000600", + "0x0000000000000000000000000000000000000000000000000000000000000601", + "0x0000000000000000000000000000000000000000000000000000000000000602", + "0x0000000000000000000000000000000000000000000000000000000000000603", + "0x0000000000000000000000000000000000000000000000000000000000000604", + "0x0000000000000000000000000000000000000000000000000000000000000605", + "0x0000000000000000000000000000000000000000000000000000000000000606", + "0x0000000000000000000000000000000000000000000000000000000000000607", + "0x0000000000000000000000000000000000000000000000000000000000000608", + "0x0000000000000000000000000000000000000000000000000000000000000609", + "0x000000000000000000000000000000000000000000000000000000000000060a", + "0x000000000000000000000000000000000000000000000000000000000000060b", + "0x000000000000000000000000000000000000000000000000000000000000060c", + "0x000000000000000000000000000000000000000000000000000000000000060d", + "0x000000000000000000000000000000000000000000000000000000000000060e", + "0x000000000000000000000000000000000000000000000000000000000000060f", + "0x0000000000000000000000000000000000000000000000000000000000000610", + "0x0000000000000000000000000000000000000000000000000000000000000611", + "0x0000000000000000000000000000000000000000000000000000000000000612", + "0x0000000000000000000000000000000000000000000000000000000000000613", + "0x0000000000000000000000000000000000000000000000000000000000000614", + "0x0000000000000000000000000000000000000000000000000000000000000615", + "0x0000000000000000000000000000000000000000000000000000000000000616", + "0x0000000000000000000000000000000000000000000000000000000000000617", + "0x0000000000000000000000000000000000000000000000000000000000000618", + "0x0000000000000000000000000000000000000000000000000000000000000619", + "0x000000000000000000000000000000000000000000000000000000000000061a", + "0x000000000000000000000000000000000000000000000000000000000000061b", + "0x000000000000000000000000000000000000000000000000000000000000061c", + "0x000000000000000000000000000000000000000000000000000000000000061d", + "0x000000000000000000000000000000000000000000000000000000000000061e", + "0x000000000000000000000000000000000000000000000000000000000000061f", + "0x0000000000000000000000000000000000000000000000000000000000000620", + "0x0000000000000000000000000000000000000000000000000000000000000621", + "0x0000000000000000000000000000000000000000000000000000000000000622", + "0x0000000000000000000000000000000000000000000000000000000000000623", + "0x0000000000000000000000000000000000000000000000000000000000000624", + "0x0000000000000000000000000000000000000000000000000000000000000625", + "0x0000000000000000000000000000000000000000000000000000000000000626", + "0x0000000000000000000000000000000000000000000000000000000000000627", + "0x0000000000000000000000000000000000000000000000000000000000000628", + "0x0000000000000000000000000000000000000000000000000000000000000629", + "0x000000000000000000000000000000000000000000000000000000000000062a", + "0x000000000000000000000000000000000000000000000000000000000000062b", + "0x000000000000000000000000000000000000000000000000000000000000062c", + "0x000000000000000000000000000000000000000000000000000000000000062d", + "0x000000000000000000000000000000000000000000000000000000000000062e", + "0x000000000000000000000000000000000000000000000000000000000000062f", + "0x0000000000000000000000000000000000000000000000000000000000000630", + "0x0000000000000000000000000000000000000000000000000000000000000631", + "0x0000000000000000000000000000000000000000000000000000000000000632", + "0x0000000000000000000000000000000000000000000000000000000000000633", + "0x0000000000000000000000000000000000000000000000000000000000000634", + "0x0000000000000000000000000000000000000000000000000000000000000635", + "0x0000000000000000000000000000000000000000000000000000000000000636", + "0x0000000000000000000000000000000000000000000000000000000000000637", + "0x0000000000000000000000000000000000000000000000000000000000000638", + "0x0000000000000000000000000000000000000000000000000000000000000639", + "0x000000000000000000000000000000000000000000000000000000000000063a", + "0x000000000000000000000000000000000000000000000000000000000000063b", + "0x000000000000000000000000000000000000000000000000000000000000063c", + "0x000000000000000000000000000000000000000000000000000000000000063d", + "0x000000000000000000000000000000000000000000000000000000000000063e", + "0x000000000000000000000000000000000000000000000000000000000000063f", + "0x0000000000000000000000000000000000000000000000000000000000000640", + "0x0000000000000000000000000000000000000000000000000000000000000641", + "0x0000000000000000000000000000000000000000000000000000000000000642", + "0x0000000000000000000000000000000000000000000000000000000000000643", + "0x0000000000000000000000000000000000000000000000000000000000000644", + "0x0000000000000000000000000000000000000000000000000000000000000645", + "0x0000000000000000000000000000000000000000000000000000000000000646", + "0x0000000000000000000000000000000000000000000000000000000000000647", + "0x0000000000000000000000000000000000000000000000000000000000000648", + "0x0000000000000000000000000000000000000000000000000000000000000649", + "0x000000000000000000000000000000000000000000000000000000000000064a", + "0x000000000000000000000000000000000000000000000000000000000000064b", + "0x000000000000000000000000000000000000000000000000000000000000064c", + "0x000000000000000000000000000000000000000000000000000000000000064d", + "0x000000000000000000000000000000000000000000000000000000000000064e", + "0x000000000000000000000000000000000000000000000000000000000000064f", + "0x0000000000000000000000000000000000000000000000000000000000000650", + "0x0000000000000000000000000000000000000000000000000000000000000651", + "0x0000000000000000000000000000000000000000000000000000000000000652", + "0x0000000000000000000000000000000000000000000000000000000000000653", + "0x0000000000000000000000000000000000000000000000000000000000000654", + "0x0000000000000000000000000000000000000000000000000000000000000655", + "0x0000000000000000000000000000000000000000000000000000000000000656", + "0x0000000000000000000000000000000000000000000000000000000000000657", + "0x0000000000000000000000000000000000000000000000000000000000000658", + "0x0000000000000000000000000000000000000000000000000000000000000659", + "0x000000000000000000000000000000000000000000000000000000000000065a", + "0x000000000000000000000000000000000000000000000000000000000000065b", + "0x000000000000000000000000000000000000000000000000000000000000065c", + "0x000000000000000000000000000000000000000000000000000000000000065d", + "0x000000000000000000000000000000000000000000000000000000000000065e", + "0x000000000000000000000000000000000000000000000000000000000000065f", + "0x0000000000000000000000000000000000000000000000000000000000000660", + "0x0000000000000000000000000000000000000000000000000000000000000661", + "0x0000000000000000000000000000000000000000000000000000000000000662", + "0x0000000000000000000000000000000000000000000000000000000000000663", + "0x0000000000000000000000000000000000000000000000000000000000000664", + "0x0000000000000000000000000000000000000000000000000000000000000665", + "0x0000000000000000000000000000000000000000000000000000000000000666", + "0x0000000000000000000000000000000000000000000000000000000000000667", + "0x0000000000000000000000000000000000000000000000000000000000000668", + "0x0000000000000000000000000000000000000000000000000000000000000669", + "0x000000000000000000000000000000000000000000000000000000000000066a", + "0x000000000000000000000000000000000000000000000000000000000000066b", + "0x000000000000000000000000000000000000000000000000000000000000066c", + "0x000000000000000000000000000000000000000000000000000000000000066d", + "0x000000000000000000000000000000000000000000000000000000000000066e", + "0x000000000000000000000000000000000000000000000000000000000000066f", + "0x0000000000000000000000000000000000000000000000000000000000000670", + "0x0000000000000000000000000000000000000000000000000000000000000671", + "0x0000000000000000000000000000000000000000000000000000000000000672", + "0x0000000000000000000000000000000000000000000000000000000000000673", + "0x0000000000000000000000000000000000000000000000000000000000000674", + "0x0000000000000000000000000000000000000000000000000000000000000675", + "0x0000000000000000000000000000000000000000000000000000000000000676", + "0x0000000000000000000000000000000000000000000000000000000000000677", + "0x0000000000000000000000000000000000000000000000000000000000000678", + "0x0000000000000000000000000000000000000000000000000000000000000679", + "0x000000000000000000000000000000000000000000000000000000000000067a", + "0x000000000000000000000000000000000000000000000000000000000000067b", + "0x000000000000000000000000000000000000000000000000000000000000067c", + "0x000000000000000000000000000000000000000000000000000000000000067d", + "0x000000000000000000000000000000000000000000000000000000000000067e", + "0x000000000000000000000000000000000000000000000000000000000000067f", + "0x0000000000000000000000000000000000000000000000000000000000000680", + "0x0000000000000000000000000000000000000000000000000000000000000681", + "0x0000000000000000000000000000000000000000000000000000000000000682", + "0x0000000000000000000000000000000000000000000000000000000000000683", + "0x0000000000000000000000000000000000000000000000000000000000000684", + "0x0000000000000000000000000000000000000000000000000000000000000685", + "0x0000000000000000000000000000000000000000000000000000000000000686", + "0x0000000000000000000000000000000000000000000000000000000000000687", + "0x0000000000000000000000000000000000000000000000000000000000000688", + "0x0000000000000000000000000000000000000000000000000000000000000689", + "0x000000000000000000000000000000000000000000000000000000000000068a", + "0x000000000000000000000000000000000000000000000000000000000000068b", + "0x000000000000000000000000000000000000000000000000000000000000068c", + "0x000000000000000000000000000000000000000000000000000000000000068d", + "0x000000000000000000000000000000000000000000000000000000000000068e", + "0x000000000000000000000000000000000000000000000000000000000000068f", + "0x0000000000000000000000000000000000000000000000000000000000000690", + "0x0000000000000000000000000000000000000000000000000000000000000691", + "0x0000000000000000000000000000000000000000000000000000000000000692", + "0x0000000000000000000000000000000000000000000000000000000000000693", + "0x0000000000000000000000000000000000000000000000000000000000000694", + "0x0000000000000000000000000000000000000000000000000000000000000695", + "0x0000000000000000000000000000000000000000000000000000000000000696", + "0x0000000000000000000000000000000000000000000000000000000000000697", + "0x0000000000000000000000000000000000000000000000000000000000000698", + "0x0000000000000000000000000000000000000000000000000000000000000699", + "0x000000000000000000000000000000000000000000000000000000000000069a", + "0x000000000000000000000000000000000000000000000000000000000000069b", + "0x000000000000000000000000000000000000000000000000000000000000069c", + "0x000000000000000000000000000000000000000000000000000000000000069d", + "0x000000000000000000000000000000000000000000000000000000000000069e", + "0x000000000000000000000000000000000000000000000000000000000000069f", + "0x00000000000000000000000000000000000000000000000000000000000006a0", + "0x00000000000000000000000000000000000000000000000000000000000006a1", + "0x00000000000000000000000000000000000000000000000000000000000006a2", + "0x00000000000000000000000000000000000000000000000000000000000006a3", + "0x00000000000000000000000000000000000000000000000000000000000006a4", + "0x00000000000000000000000000000000000000000000000000000000000006a5", + "0x00000000000000000000000000000000000000000000000000000000000006a6", + "0x00000000000000000000000000000000000000000000000000000000000006a7", + "0x00000000000000000000000000000000000000000000000000000000000006a8", + "0x00000000000000000000000000000000000000000000000000000000000006a9", + "0x00000000000000000000000000000000000000000000000000000000000006aa", + "0x00000000000000000000000000000000000000000000000000000000000006ab", + "0x00000000000000000000000000000000000000000000000000000000000006ac", + "0x00000000000000000000000000000000000000000000000000000000000006ad", + "0x00000000000000000000000000000000000000000000000000000000000006ae", + "0x00000000000000000000000000000000000000000000000000000000000006af", + "0x00000000000000000000000000000000000000000000000000000000000006b0", + "0x00000000000000000000000000000000000000000000000000000000000006b1", + "0x00000000000000000000000000000000000000000000000000000000000006b2", + "0x00000000000000000000000000000000000000000000000000000000000006b3", + "0x00000000000000000000000000000000000000000000000000000000000006b4", + "0x00000000000000000000000000000000000000000000000000000000000006b5", + "0x00000000000000000000000000000000000000000000000000000000000006b6", + "0x00000000000000000000000000000000000000000000000000000000000006b7", + "0x00000000000000000000000000000000000000000000000000000000000006b8", + "0x00000000000000000000000000000000000000000000000000000000000006b9", + "0x00000000000000000000000000000000000000000000000000000000000006ba", + "0x00000000000000000000000000000000000000000000000000000000000006bb", + "0x00000000000000000000000000000000000000000000000000000000000006bc", + "0x00000000000000000000000000000000000000000000000000000000000006bd", + "0x00000000000000000000000000000000000000000000000000000000000006be", + "0x00000000000000000000000000000000000000000000000000000000000006bf", + "0x00000000000000000000000000000000000000000000000000000000000006c0", + "0x00000000000000000000000000000000000000000000000000000000000006c1", + "0x00000000000000000000000000000000000000000000000000000000000006c2", + "0x00000000000000000000000000000000000000000000000000000000000006c3", + "0x00000000000000000000000000000000000000000000000000000000000006c4", + "0x00000000000000000000000000000000000000000000000000000000000006c5", + "0x00000000000000000000000000000000000000000000000000000000000006c6", + "0x00000000000000000000000000000000000000000000000000000000000006c7", + "0x00000000000000000000000000000000000000000000000000000000000006c8", + "0x00000000000000000000000000000000000000000000000000000000000006c9", + "0x00000000000000000000000000000000000000000000000000000000000006ca", + "0x00000000000000000000000000000000000000000000000000000000000006cb", + "0x00000000000000000000000000000000000000000000000000000000000006cc", + "0x00000000000000000000000000000000000000000000000000000000000006cd", + "0x00000000000000000000000000000000000000000000000000000000000006ce", + "0x00000000000000000000000000000000000000000000000000000000000006cf", + "0x00000000000000000000000000000000000000000000000000000000000006d0", + "0x00000000000000000000000000000000000000000000000000000000000006d1", + "0x00000000000000000000000000000000000000000000000000000000000006d2", + "0x00000000000000000000000000000000000000000000000000000000000006d3", + "0x00000000000000000000000000000000000000000000000000000000000006d4", + "0x00000000000000000000000000000000000000000000000000000000000006d5", + "0x00000000000000000000000000000000000000000000000000000000000006d6", + "0x00000000000000000000000000000000000000000000000000000000000006d7", + "0x00000000000000000000000000000000000000000000000000000000000006d8", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da", + "0x00000000000000000000000000000000000000000000000000000000000006db" ] - hash = "0x1e73559df90b9ac652f39d057651493cf969d69cefd6a5ab110845f928273371" + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_l1_to_l2] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000002800" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Nargo.toml new file mode 100644 index 000000000000..01ba21dedeb3 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rollup_block_root_msgs_only" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +rollup_lib = { path = "../rollup-lib" } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Prover.toml new file mode 100644 index 000000000000..36e76bb3b076 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/Prover.toml @@ -0,0 +1,407 @@ +[inputs] +timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0147835c94611898d22eb8d49ebce0db42b5f553b40b0d905e08db109622da55", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", + "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", + "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", + "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", + "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", + "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", + "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", + "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", + "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", + "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", + "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", + "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", + "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", + "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", + "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", + "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", + "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", + "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", + "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", + "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", + "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c", + "0x2403f18ba27f090c40c95fc6724d67b4b7d537b967ee15656c79e55284df9d6b", + "0x13404ebc0eed291ffb14cad19114bad8df35bae99793ea99e4dde966cb4e53ad", + "0x006a1008132293c19aafbe7130eda035bd1b90065032894071b1f390f4946844", + "0x03ff3b6c066342b657a8583acef6fadbc8e390be6e1fff8dc1526a05f16f2005", + "0x294aa2b063a035c26fe57d58d15931cdc79a6a94edf097d5347277f6e4b0f9da", + "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" +] +new_archive_sibling_path = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x02c31fdc99899006a751407bca0604cdb73f20734b97d1408ab110d02bcc60f5", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", + "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", + "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", + "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", + "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", + "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", + "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", + "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", + "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", + "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", + "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", + "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", + "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", + "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", + "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", + "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", + "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", + "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", + "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", + "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", + "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" +] + + [inputs.previous_archive] + root = "0x0fa865407ce646d4e00240c98b133f9bb5017f48e493fef156747d9a1b23b097" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + +[inputs.previous_state.l1_to_l2_message_tree] +root = "0x141653e4c04837aba0830a28648767ceea6fcbcefaa4d401d0a37f89f5d88fa2" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + +[inputs.previous_state.partial.note_hash_tree] +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" + +[inputs.previous_state.partial.nullifier_tree] +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" + +[inputs.previous_state.partial.public_data_tree] +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" + + [inputs.constants] + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" + + [inputs.constants.coinbase] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.constants.fee_recipient] + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.constants.gas_fees] + fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.start_sponge_blob] + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004d4" + + [inputs.start_sponge_blob.sponge] + cache = [ + "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684", + "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9", + "0x141653e4c04837aba0830a28648767ceea6fcbcefaa4d401d0a37f89f5d88fa2" +] + state = [ + "0x161e8c5faa0f915b0094299da17306a72f55bc7dbbdd141fc41c29868cd76d8c", + "0x293c9868338ad33e48e9a735ba322e58e785b6a0324395cc46c5aaad59aaf7d4", + "0x28b8112829b1199a54c3873bd29e7cb8960b8170dee6bb3d1f180546821d8c61", + "0x2670175288aa3a3911816476409579b9470f296b63236eb82b7cf63dea4a7dfd" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + squeeze_mode = false + + [inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [inputs.start_msg_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000900", + "0x0000000000000000000000000000000000000000000000000000000000000901", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + squeeze_mode = false + + [inputs.message_bundle] + messages = [ + "0x0000000000000000000000000000000000000000000000000000000000000a00", + "0x0000000000000000000000000000000000000000000000000000000000000a01", + "0x0000000000000000000000000000000000000000000000000000000000000a02", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000003" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/src/main.nr b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/src/main.nr new file mode 100644 index 000000000000..6b2a522ff1e7 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-msgs-only/src/main.nr @@ -0,0 +1,7 @@ +use rollup_lib::block_root::{ + block_root_msgs_only_rollup, BlockRollupPublicInputs, BlockRootMsgsOnlyRollupPrivateInputs, +}; + +fn main(inputs: BlockRootMsgsOnlyRollupPrivateInputs) -> pub BlockRollupPublicInputs { + block_root_msgs_only_rollup::execute(inputs) +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml index 55da03b4c7d9..a09c8b5c9d88 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root-single-tx/Prover.toml @@ -1,7 +1,45 @@ [inputs] +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x28de0afc3b7c36426727790810acf92fb799c6ad75ea95773df7373ffa47a2d5", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", + "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", + "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", + "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", + "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", + "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", + "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", + "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", + "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", + "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", + "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", + "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", + "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", + "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", + "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", + "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", + "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", + "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", + "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", + "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", + "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c", + "0x2403f18ba27f090c40c95fc6724d67b4b7d537b967ee15656c79e55284df9d6b", + "0x13404ebc0eed291ffb14cad19114bad8df35bae99793ea99e4dde966cb4e53ad", + "0x006a1008132293c19aafbe7130eda035bd1b90065032894071b1f390f4946844", + "0x03ff3b6c066342b657a8583acef6fadbc8e390be6e1fff8dc1526a05f16f2005", + "0x294aa2b063a035c26fe57d58d15931cdc79a6a94edf097d5347277f6e4b0f9da", + "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" +] new_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x11adf5c71bf95b1412dc14e3b7ec67fb80c20c436e0cd47b4b6140ff146679a4", + "0x013e70425a498e03e2c24c9aab5c8300db073ddc404f224a356aba8a85c25207", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", @@ -523,17 +561,17 @@ new_archive_sibling_path = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants] - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.last_archive] - root = "0x2ec9fc22ae7001e2ada488cbd0ea07e1cf7f54e151dc2bb766e561636b02eece" + root = "0x0eab3e829cc7fe4fad08d43de98c4d400e7349bca7558dce0e7aebe7df63680b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollup.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollup.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -553,49 +591,49 @@ new_archive_sibling_path = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollup.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollup.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollup.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollup.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000552" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004d4" [inputs.previous_rollup.public_inputs.start_sponge_blob.sponge] cache = [ - "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d", - "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9", - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" + "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684", + "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" ] state = [ - "0x0e2949060fe0f2aa67a11a1f8c7449f74124ab122ca0bfcc6d1dc19dde1e5268", - "0x06620ebc6d7abb78fe8de2f9f66c4cabbe323d277ef8de952dd1b59cd36bee17", - "0x129daea73c37f015b42271c76bad72aadcb53b8a12b8fb40b708f528315f16a8", - "0x0bfe4f9fb5d9e711aff1b1f4c96be770b3717443ed65ea7907957428c2f24702" + "0x134552dc5a3183a8ed29944bea3f1ece700d5a858b7f100d79e637b5a1bac408", + "0x30083cd298bdbeedb36f277787041a4cf106837d26372fb435a25505e18f8fdc", + "0x21c04f5b66d17a0db8d7db79b8641856250619429f5320aa8b6f393809318cbd", + "0x0e5c1e939ba31ff15394300cc98dcf8600a6e6b5262a7d75966f12188e08743c" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a9d" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a1f" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ @@ -604,10 +642,10 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" ] state = [ - "0x251647a367a8890a0f46a380c4abec7d4fc45dca0d143b8bf2a7cab6ceddeacd", - "0x14836cbe2cbe01805d670f7f2eb6897f238ded38492f38c58e87151837510c83", - "0x2abc8296d1c1b8a8fd8d517bd914bef6b2449373e5c5faef8fc8ec0b9d245412", - "0x0b49d4c777c2e81c0a25196c5bb03afdebef659fec11fe6945142517ae1a02fd" + "0x1274ff2c9f61c494716bc3f7e123cd59194ae4a237fe3e022f3594e8a7f69a3c", + "0x0bead5cc46d4d7eae20a703256115e41461c115eea8ccb8f1aebd8652a140d38", + "0x0657a38ee503b41bb9559df57b7e453fb9d2f3c1eda50ad260f44b051a94344d", + "0x181919e10da8c75a0622cedf1018289a2ee63b4093ba509e43a01e28c344bcaa" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false @@ -615,13 +653,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollup.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x20ab775da5bb45344ffe17866237142b9321b97b2e93ccfb1c299476a262e0b5", - "0x2a9ef81b082ec4212c08eba71c46e645efc1ae573e9cca5b480785be9dcc4d21", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x10b6730f1d1e9c6bf8d7c4b42b64b40d2603e3ae6ddbd464c3d8fcfb9e06e6d4", + "0x11017f6408ff020bf1556ed3f4d41fba9dfe9fe312cd5430ec7c1abf7e3a9bcc", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollup.vk_data.vk] @@ -629,46 +667,46 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001393476211d0127a80dce177bd2139b525", - "0x00000000000000000000000000000000000a64db7a774dad381e4034cb2457f3", - "0x000000000000000000000000000000d5fb425ef17d829bcbd2f2212397cc69ba", - "0x00000000000000000000000000000000002902ad5d5e880ce9d3ff8815ad1554", - "0x0000000000000000000000000000009b94b4b71ebf49ca1ccee622099eb37a96", - "0x0000000000000000000000000000000000217517f2a6d3c0ad2a63c69b28d392", - "0x00000000000000000000000000000038d8df60934ce84e0ed3e7f5ca09c1ee4d", - "0x000000000000000000000000000000000013384c8161e64209078ece69fcaa19", - "0x00000000000000000000000000000093c2a0c6ec49f39474bd6782c5cd6b01b2", - "0x000000000000000000000000000000000008ff5813561afc758759d27f19b55c", - "0x00000000000000000000000000000097291956465f3aa94d25b11bc567a6c287", - "0x000000000000000000000000000000000007f14a03af147b21368785d869ca98", - "0x0000000000000000000000000000006a811b91c5970c9c2acd7a754d7b7f9cb1", - "0x0000000000000000000000000000000000190a1ac15c24fdafc83b205b9a284b", - "0x000000000000000000000000000000b61bdc9c40c5c1e94e290d7b383b2ee122", - "0x00000000000000000000000000000000002f5117ca48de83b07881d30427d341", - "0x00000000000000000000000000000012095bbac1cead43059d0a230818a027b7", - "0x00000000000000000000000000000000001c7b3a018ad17b7cbb3752d56c6f80", - "0x00000000000000000000000000000018c18cff602c8434b90273cb1ff38dd751", - "0x000000000000000000000000000000000003bd5bfa0c05c005fcbde355422947", - "0x0000000000000000000000000000009dac7aa803151cb1966b812422755d8e9e", - "0x000000000000000000000000000000000010f818617b14b429abcd3acd46653c", - "0x0000000000000000000000000000007951c87d59a7b4319ddc32a19635675d94", - "0x000000000000000000000000000000000005be6b96d6eb897429b815388db99b", - "0x000000000000000000000000000000d7e7c851d3ba4e42b00b50dcb9a40159ff", - "0x00000000000000000000000000000000002750be703cf6981c927c48de088588", - "0x00000000000000000000000000000048b23b4fb077032ac487b882dec8a8c38b", - "0x000000000000000000000000000000000017150b214b8aa285fed8a5b374a4f9", - "0x000000000000000000000000000000416e099bfce67a459c5a20a4311705f6c4", - "0x00000000000000000000000000000000002b684b94d2f1f96e86dfad7af6171d", - "0x000000000000000000000000000000651160cf941fb73a15062e12bfc9e35804", - "0x000000000000000000000000000000000007a1bb9d8533d71515e6e3b5e6866d", + "0x000000000000000000000000000000be3ef7df55faad770dd417b568b334bb61", + "0x0000000000000000000000000000000000020dbb5be28ee0dddbe361d4210575", + "0x0000000000000000000000000000002a9a30c0f428736335b3eb03271a7faa35", + "0x0000000000000000000000000000000000011eeab7deb21addfa7d56d1c588a1", + "0x000000000000000000000000000000cd7414d72fbdd24b1bad570941833708ea", + "0x0000000000000000000000000000000000125ab5466e467ad79893fe6fb71dac", + "0x000000000000000000000000000000275ffdc4a6a9c963cff9f4bfc97ff47ae5", + "0x000000000000000000000000000000000009b0fc1fdcf1eb4720e77df4bf579e", + "0x0000000000000000000000000000004b41b33ed09d6f2e0d1e2778bcc0a412bf", + "0x00000000000000000000000000000000002431de0fcb1f1e513962b6ddaff0cb", + "0x000000000000000000000000000000ceacbeb3107979529c12c1d0eee1557e98", + "0x000000000000000000000000000000000015157c061d1d61cf7dd3a7ce845922", + "0x0000000000000000000000000000003f7443a3cea90f0e6730b33675efbbda73", + "0x00000000000000000000000000000000002ca6b067638c1c24bbadd530a94798", + "0x000000000000000000000000000000f4d7b640687e4a07ea713f599fa766d14f", + "0x00000000000000000000000000000000001da3ebbf464dad0213d7cbb620146c", + "0x000000000000000000000000000000a5e9f66b74ff0bfcb7cb43d4ae9f154cf7", + "0x00000000000000000000000000000000001b50d6d924c13b8138405d313f1875", + "0x00000000000000000000000000000091dda1fdadf6e5bb631936d41c3e919572", + "0x0000000000000000000000000000000000218f9e93fa7efcdb8d89b8303acc50", + "0x000000000000000000000000000000f659c8815b22bacd330bee0c95d2a77cfd", + "0x00000000000000000000000000000000002aee8b729bc510e581461f3c3d3f20", + "0x000000000000000000000000000000d35405c664cefb21dd45302fa07ce6e1ae", + "0x0000000000000000000000000000000000168af130006e1ff22ea8737f0207e3", + "0x0000000000000000000000000000004b9beda85c743bfc49ac3aa711ccf95ca3", + "0x000000000000000000000000000000000028fb89c6da361c392f36475551e5c7", + "0x000000000000000000000000000000c5d8af9e91084202d30bd24e2ae1787dd1", + "0x00000000000000000000000000000000002ea1690f1652415522380675b4f298", + "0x00000000000000000000000000000004cc26069474a70fefc9e011a297d3659a", + "0x00000000000000000000000000000000002c4ca65f1f3ce11e955002f76823b7", + "0x000000000000000000000000000000caa9709b37a3f896da980148bd862f79ad", + "0x00000000000000000000000000000000001cdab1dc53ddf21433efb20a019aed", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bada1572761d2d57e5d206da78afa472c5", - "0x00000000000000000000000000000000000248453a876b49502a5a8259818f44", - "0x000000000000000000000000000000ec45f0511c4ef04800c3d31e152e9265de", - "0x00000000000000000000000000000000001fff1bef8afe963c3b78c3c2549ca4", + "0x00000000000000000000000000000091be1f8e738e8cf74c39dcff97e574049a", + "0x0000000000000000000000000000000000253b1d48e89dea2387345d1f190cf8", + "0x00000000000000000000000000000001f523e64316ec12df1d1fed701b1fc3ff", + "0x0000000000000000000000000000000000254e8bc817fd854d25dce4ca34bbb9", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -689,57 +727,340 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000e379faf5ffdd383be5ce0f1ee38f5e73fe", - "0x00000000000000000000000000000000001429616496865cd170bc83c40d415a", - "0x00000000000000000000000000000066e08b7ad48415290d2ff590e84057e60e", - "0x000000000000000000000000000000000023a625e90ae9701e33c52be8f0d396", - "0x000000000000000000000000000000774fc954a6adaa4e4db1da6228184e1354", - "0x000000000000000000000000000000000015ca4073735e39fd5dc55567dc1068", - "0x000000000000000000000000000000fd9e5f594db01e4b2625e1e3dcfd400f6e", - "0x00000000000000000000000000000000000f4a392bbee96bddd468b2c9a18896", - "0x000000000000000000000000000000d28954aef28e666d63ee0fb401ab7bc1b6", - "0x0000000000000000000000000000000000253b48f95132d1a3183e26dbd56884", - "0x00000000000000000000000000000022887784410bf17c157fc004401281c342", - "0x00000000000000000000000000000000000a249d88427c50df84670228613493", - "0x0000000000000000000000000000000f495c15c8a9098c779fef9227f1c5a897", - "0x000000000000000000000000000000000016d74e40a54fe1961a01c0a275941e", - "0x000000000000000000000000000000a968320348365b69bc59ded07a855fb88c", - "0x000000000000000000000000000000000010c9846c3754b0fb4b4c9ab8d68cd3", - "0x00000000000000000000000000000088ee0f0a54893f8b1e8b56a7fa7bee9d4f", - "0x000000000000000000000000000000000021d14db4aa9ae9f88641b9336d9dba", - "0x0000000000000000000000000000000f46a800020405196bda0c07afe5154eac", - "0x0000000000000000000000000000000000062e98c038c271784c9fb61136242f", - "0x00000000000000000000000000000024ed87f3417bd5bbaa53682680b1b915c8", - "0x000000000000000000000000000000000003beb3d385de2c0a7a40cebe01d34a", - "0x000000000000000000000000000000f85b812b32412267c5221f3600eaa3f3d2", - "0x00000000000000000000000000000000000289ace5de4f3e7a721b5a184d1e76", - "0x0000000000000000000000000000002e30085e1c74fe70d1d2ab68faf0984ca4", - "0x00000000000000000000000000000000001adb7660db50eb3c9d70b137871b2f", - "0x0000000000000000000000000000008e05ae370a270eeb6d282e3bc2b7889cc3", - "0x000000000000000000000000000000000020e76f33b00bccd1f97095bece663a", - "0x000000000000000000000000000000d71d8a40f7c9f1984d513aa7eb1a895e6e", - "0x0000000000000000000000000000000000021aee4d83119d0af331d5893af9fe", - "0x000000000000000000000000000000dec3abe29c9aa4bf73251a0c748d11e9dc", - "0x0000000000000000000000000000000000153c1ed58f5394ad372869f471ca8b", - "0x000000000000000000000000000000bf4d6e6ed9dad1b05bd3d5cb3b3740d3e2", - "0x000000000000000000000000000000000006803b1ef715809ab5085220b7c284", - "0x00000000000000000000000000000041efece86e20c4323fb08d7aad7345c79c", - "0x0000000000000000000000000000000000096fab6acc87fe26e0eefb5660a7db", - "0x0000000000000000000000000000002d550983acbdea743f381bf4d55b8c6110", - "0x0000000000000000000000000000000000107455727dcf49837ee29622f4e9ae", - "0x000000000000000000000000000000a07bfb26d2f33a45866564f6fb630fc1b3", - "0x000000000000000000000000000000000004b58a9a3d784d5857e224b300b97a", - "0x000000000000000000000000000000c0f8d7d2fa6eac6b45b736e838db02e437", - "0x0000000000000000000000000000000000012728fef15749f6355802ac76d166", - "0x000000000000000000000000000000caa9dd21f786e491093e94a42326c20c4b", - "0x0000000000000000000000000000000000181c00a5273565ed45cde6516b7267", - "0x000000000000000000000000000000f791b0a7d2376523eebf266bd58c615a72", - "0x00000000000000000000000000000000001658c7b51e5eb76e58124a4bf26d30", - "0x0000000000000000000000000000007ffefc9b69f9b9f766f98d9390ad49a8f6", - "0x00000000000000000000000000000000002700900f023bdb2524f5ce218af8a6", - "0x0000000000000000000000000000001d12e2e9feedc5df84ac9cb8e405fc64ea", - "0x00000000000000000000000000000000001645d7c72fd8844ddf0659d2b77656", - "0x00000000000000000000000000000098eaadb9c8f156e98d8dfde6f90be22a80", - "0x000000000000000000000000000000000028291c89dafd88dced57d87f6d8ab7" + "0x00000000000000000000000000000063a793166969e30306b1a33ee3140ab639", + "0x00000000000000000000000000000000000689ae6c5351a0c7d2bddd28760eba", + "0x000000000000000000000000000000e9e058e78b28069998e0b545635c751505", + "0x000000000000000000000000000000000029d041f64f9c7a4b574afdd84eb2bc", + "0x000000000000000000000000000000de0e873aad4dce9c296b5822c49119b396", + "0x00000000000000000000000000000000001e622a80763bdce9e84c5936947ea4", + "0x000000000000000000000000000000ff979afed880f8777a1d7edb65ce1450e3", + "0x000000000000000000000000000000000012be4428cf92f37d4329f288edd6d7", + "0x000000000000000000000000000000d68061ce1bad9ac1e54cdf86b65d18b89f", + "0x000000000000000000000000000000000020fdf737ed00586f6db007044965a8", + "0x000000000000000000000000000000946bb34bc2173c2659e824f5fd377a3cbf", + "0x000000000000000000000000000000000022da84ec41699f355efa9e9550e4e4", + "0x0000000000000000000000000000008b0f4ef158c13087ed0e80688fe8373342", + "0x00000000000000000000000000000000002a4cae8c1411ba84463b850ab1844a", + "0x00000000000000000000000000000081d9bb13936c0676b987efe4a7ccd38a7e", + "0x00000000000000000000000000000000001e527e0c58ebec97285f8d47471778", + "0x000000000000000000000000000000c17602371eddd69a1e0e5b82a51441f2d3", + "0x000000000000000000000000000000000010fd74deb218f4d0d58aee589c31a6", + "0x000000000000000000000000000000dc8cd28e055e13b175149f797af895f0f4", + "0x000000000000000000000000000000000014d50f3e5a64cc7500ed82e02796e5", + "0x000000000000000000000000000000c61024b9433cc9b608636d33133501734f", + "0x0000000000000000000000000000000000080ffdff074611822ac0029ae9ac87", + "0x000000000000000000000000000000251c0f33e1f84d4365571cd965fc9b951c", + "0x00000000000000000000000000000000002e7e699ac6cc777970c0d5dd410bc0", + "0x0000000000000000000000000000009e1f4030259589018ce84f6f1dd736ae5d", + "0x000000000000000000000000000000000006154a1e0fea69f24bf7ac004afb7a", + "0x000000000000000000000000000000189020ea1ed822257549ab99ac2b33647e", + "0x00000000000000000000000000000000002a384f4831d00b56c6219abcb3b785", + "0x00000000000000000000000000000035fb02b0d2e793607a238e08539424c438", + "0x00000000000000000000000000000000001d0e75eecc618b087887f7d14ddf24", + "0x000000000000000000000000000000eae70e5ed566bcad446daa8f1059119fb5", + "0x00000000000000000000000000000000001f16d342675b048447aec1d841ea6f", + "0x000000000000000000000000000000dec8287d2ca445b6611951692aceb93f09", + "0x00000000000000000000000000000000000d237ea339d430164ddcf07c98eebb", + "0x00000000000000000000000000000069bd0705898ec802324165e180c23cca88", + "0x00000000000000000000000000000000002b2487b0a0cad2ab8b703eda79048b", + "0x000000000000000000000000000000526f89287c9fa8d0869c89341b300cd057", + "0x00000000000000000000000000000000000da86b460feb2479d72b91bad3aa4e", + "0x000000000000000000000000000000aba6055db467fa492b870fccd9251c0cb4", + "0x000000000000000000000000000000000022e849a8f64faebc36288439518d4b", + "0x000000000000000000000000000000ab679268e81d4770ddc1861ac7485ac4e8", + "0x000000000000000000000000000000000009a186caa2f074b8b5d3d26afddfc5", + "0x000000000000000000000000000000694fbc055e1f0045837b2bcf0d60f82934", + "0x00000000000000000000000000000000000ffba7e4a28991553a68d277bf2aa3", + "0x000000000000000000000000000000de4a494414853cc677e6f0de0f19a070c8", + "0x000000000000000000000000000000000004485188f222785e8455584b3632e6", + "0x0000000000000000000000000000001e68682a2d646f241b36838e8627fe4258", + "0x00000000000000000000000000000000001cd86d75f808b92947367db49e99b3", + "0x000000000000000000000000000000a21f994888d69ad0e60ea74b527f54a7ed", + "0x00000000000000000000000000000000001bbdaa75acb6eb653db71e1666d066", + "0x000000000000000000000000000000eb0694220d1a490792b0165b98d9b8bf71", + "0x000000000000000000000000000000000025729291a976e4cbed01962ee0b0d0" +] + hash = "0x242e942739553143b651d041e96bc6bc5e09baa6142d959488ffa864ce063d69" + + [inputs.message_bundle] + messages = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.previous_l1_to_l2] + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.start_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" ] - hash = "0x016a3b94e0b04a9f99ca3c31a475b4b5b1854bb2f3cea14fc49177110c9d7142" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml index 84fd2564c7f3..32660fb207e3 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-block-root/Prover.toml @@ -1,7 +1,45 @@ [inputs] +l1_to_l2_message_frontier_hint = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x05ff2de82d97bb7924bc45b96cd828ffe002085bd7179c6283df4757fa07d3e7", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", + "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", + "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", + "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", + "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", + "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", + "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", + "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", + "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", + "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", + "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", + "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", + "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", + "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", + "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", + "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", + "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", + "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", + "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", + "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", + "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c", + "0x2403f18ba27f090c40c95fc6724d67b4b7d537b967ee15656c79e55284df9d6b", + "0x13404ebc0eed291ffb14cad19114bad8df35bae99793ea99e4dde966cb4e53ad", + "0x006a1008132293c19aafbe7130eda035bd1b90065032894071b1f390f4946844", + "0x03ff3b6c066342b657a8583acef6fadbc8e390be6e1fff8dc1526a05f16f2005", + "0x294aa2b063a035c26fe57d58d15931cdc79a6a94edf097d5347277f6e4b0f9da", + "0x0aced6fe68143f4c7acd16345a8c1bb50c51a0692b760eb48728feb923d90757" +] new_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x1f46c86bfadbdbf682291d06e0af66ce58d17ab72005b68b73fa4217e517024d", + "0x259ddf6e0d198731861a3aeebdf1b054d4115e13a7a0f57f91905a3b4df236bf", "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", @@ -517,23 +555,23 @@ new_archive_sibling_path = [ ] [inputs.previous_rollups.public_inputs] - num_txs = "0x0000000000000000000000000000000000000000000000000000000000000002" - out_hash = "0x00bd3da907cbb210cd100bd369f8dd7eb04b938c69dce277dc1efea8403ed88e" + num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" + out_hash = "0x00fab7a43a18caf54d1e3dd82cf6d3def175265507c701576b015603f4dd1b44" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x26c404240cb9d3965fdd677de1d4ea1d907e460403e304ed198e839901a4cebc" + root = "0x0bf231280528029b2b1a5edd82e73b5ae8b11264525dd8e90227c12b9e27de90" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" + root = "0x17108deb7a97c2ff200627cff40a2fe4cf6829aa004b567f9c7bc3b782b5ed54" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000005" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -553,126 +591,126 @@ new_archive_sibling_path = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x2590f2aab19dd791700b4a43d3f52bb88ef2409a3731da8e848663559202e4c6" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" +root = "0x144f9224dee4aac6eddc5d988e7c6965528d2e08db91cf58989655a68fbfcc52" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" +root = "0x191d19a6ad2b7bba03d122035938544f5e65de24aeaa436cd5e4d977bd014505" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000007" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a1f" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922", - "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454", - "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x1cf24640611b8c3ea83ce645fab1d515a5b0cf58739548f128ed62c908a998c0", + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" ] state = [ - "0x0f19f1d5a0d014c8f9cb5070b6a72c7efb81b4971bc364738cea68076cfc9128", - "0x1e62eaea4ad0390925cb2382c5f4dc22f4d23495e0890061050f08c37ca8c9cd", - "0x143fae3a86f2ed36eca31eccf44ce149d098395a86dd8c9d541a15c155870153", - "0x2643afd339189b520e780ca47df76348b0d58825939d38dd1b1b0df9e8239947" + "0x2efbca83c7575de34b9aa2de843b182024e51e4efa57a87613d06b815ff70eee", + "0x18931f67b07c31e6153b33e903d6572d44fd818ce438d1a3c564f9fc1c67a2a1", + "0x2d30489f9e9df1cc7a22c31ab9b140c5faf6fcbffb0a63a4e1e6b4f26778e80d", + "0x23d7dc79540a57d650bbbe119dfb6872ed952a1eca1b3417a831e467c41683aa" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a9d" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000eec" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", - "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", - "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" + "0x00000000000000000000000000000000000000000000000000000000b7f9d44e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44d" ] state = [ - "0x0b7c9bbfac21d3c59031a865ee1f7abea9012d898a238d0b9d545e7e15be4f9a", - "0x11e47e7e5a97cace7b8cb5c63eeaf7cb076e5e19a4e89c1d3f4c3fb1faddf0b3", - "0x03a1357263e162410b5a70343adea4b373f3006660d9b40c28425be41749a8f7", - "0x100bc00d33720748142a7cd2ab57c5c140b681cdeec9b6197841f983ed05a3e2" + "0x20919f1663ed9695ea49102584aab0d33393c1f0a3e71fb94d8379eac90bf504", + "0x00b14aa0f911d5f7c357bd29c8c9e4cd21316e34f5f999e2c1bc141c3b8d05b5", + "0x058d00874168957ee2bde39d66f8d866f28d89dd627b2e4a3b0fe29a63fbcb0d", + "0x0708d0c5b32da1b4e144f6dfa4ab7feb6bd96429b5f308487a0a58cc19bdd756" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" sibling_path = [ - "0x016a3b94e0b04a9f99ca3c31a475b4b5b1854bb2f3cea14fc49177110c9d7142", - "0x2a9ef81b082ec4212c08eba71c46e645efc1ae573e9cca5b480785be9dcc4d21", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x1fc39d0a428c8536dbca551ea79848acf67d89d090fd8c643c7d90f2e8f32340", + "0x12ce5a49a1ceca53ada7bee003f929bbd65abaa74e8072a81f304c2c96c44e31", + "0x276f60617ee2c3b406af56bfe9216a7d99be56ad316ff557cee0446f08e14135", + "0x1dab7bce1884db3c7fa09243adb445f93156a1a0546582123d8c1d6c89e7fe41", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000015", + "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000caa1598dca4e37d78572fa4a673fe48fcf", - "0x0000000000000000000000000000000000016ad6643bea8ee78b1a225f498d9e", - "0x0000000000000000000000000000003cbf301e1f115d44eb4a073858500d1f90", - "0x000000000000000000000000000000000021c73a326143da86ab5fc585cf4246", - "0x000000000000000000000000000000d7da14c2cab8ecde96bacd6d6f2430424f", - "0x00000000000000000000000000000000001e870057fcdfbadbaeeac10640a097", - "0x000000000000000000000000000000704a325b3d5a903c262c44348d7a86d0ec", - "0x00000000000000000000000000000000002de4239e3d91df4477e49132bb87b1", - "0x000000000000000000000000000000a27bf5a15e26f43aa820086e335f7ad09d", - "0x000000000000000000000000000000000002165a625977654e98dd9b723c14e8", - "0x000000000000000000000000000000c3637de63520e9d9372c17571b5e739c1b", - "0x000000000000000000000000000000000020e48513502d9c415ed9fe14629d15", - "0x00000000000000000000000000000012349c04470abdf58fb01a7d0fe24cdbf3", - "0x00000000000000000000000000000000001f239046e3013028e98434553690c4", - "0x00000000000000000000000000000095caedf215800fdd92feb9986cd1a88723", - "0x000000000000000000000000000000000009d26dcd344fe75c8f35c7479f511d", - "0x0000000000000000000000000000000111cfbbe08f8b821450d0b90c0f1070c8", - "0x00000000000000000000000000000000002558314b5fb8680380616e72d0c053", - "0x000000000000000000000000000000995f7ab83bc05dcda1afb1372e59cdfcc7", - "0x00000000000000000000000000000000001aeb91af1f30c02dbbd36a98cc2231", - "0x0000000000000000000000000000006221173072fa9551c663afb6209fdefa2e", - "0x00000000000000000000000000000000000e171ef3e60f887b0a7cb618e7711c", - "0x000000000000000000000000000000b3bbea9329a345198e3fdfe3505b99df4a", - "0x00000000000000000000000000000000000dbb8cbe2b75c09a2a82ef538290e5", - "0x0000000000000000000000000000004ded14c1b910011b99fd16df857fbc58c6", - "0x00000000000000000000000000000000001faa5965c5913bd455ce44b99914e5", - "0x0000000000000000000000000000003027abdd2d8b5ef2e2bc25fabdd211a6fa", - "0x0000000000000000000000000000000000034a596c8cadd90d73bf17fc3afffe", - "0x0000000000000000000000000000005518194ea9887921d16cc389a54bf3832b", - "0x00000000000000000000000000000000001ce989b3df90479090b78e92b638ab", - "0x00000000000000000000000000000080f0ccbf9cfb73dfb6b8873a2851742359", - "0x000000000000000000000000000000000003650108505c9b45bbf70c2d6b7378", + "0x00000000000000000000000000000002dae7e831ed78b9726034fdf56e583ace", + "0x00000000000000000000000000000000002b3f4d616e8027a20f8edc16cfbe3b", + "0x0000000000000000000000000000004c72b92cbd48ecea19ad5642f7d557f5a4", + "0x0000000000000000000000000000000000168654a45c7d8664e75623ab72ffab", + "0x00000000000000000000000000000083005b55cabaef097051546fbfd7685d43", + "0x0000000000000000000000000000000000085264859c243091d0290fee66961d", + "0x000000000000000000000000000000a3609a137f0c64e9af9d672c82bb879030", + "0x00000000000000000000000000000000002f2816311eb3afd6c30a91f05a906c", + "0x000000000000000000000000000000e4511cf49697e16a74e0d6730d364cd6e4", + "0x00000000000000000000000000000000000d9b15c1ab4aafa9870030fb1f01f1", + "0x0000000000000000000000000000006dde861e212bf26640ef1436d7bdc4f201", + "0x00000000000000000000000000000000001ffaf73c05b99d1722a697b54ea994", + "0x000000000000000000000000000000396ba274703ebf4a03e4339dbc26d099a0", + "0x0000000000000000000000000000000000022e3ee5ffc2dc0533c2bbeb9099ec", + "0x000000000000000000000000000000e6e227b60dc9057a88f8cb4471a9fea86a", + "0x0000000000000000000000000000000000246959db6c3a295438492d935eaacb", + "0x0000000000000000000000000000003191ffb83d7d42b1add187223d067540a7", + "0x00000000000000000000000000000000001c6597787b5ebaa53b48a9fecacda8", + "0x000000000000000000000000000000e9f6be3f78c38204280bc224a2fd27c65d", + "0x00000000000000000000000000000000001c3e420965e904cac372ef32dc7923", + "0x0000000000000000000000000000007da218400340a430b8cf011f7892173af8", + "0x00000000000000000000000000000000000a31a316504c8be7ae5701acb98ced", + "0x0000000000000000000000000000003cf75706f021e6a661df64ef16d9a42b55", + "0x0000000000000000000000000000000000177148b7da28c2bf2cfe5737c85963", + "0x000000000000000000000000000000e0bc19695db19d2b16f525fa63874ddd68", + "0x00000000000000000000000000000000000ad3d70c629c5446ac4b2065893923", + "0x0000000000000000000000000000001617d14d968bc2679b85973347963a6329", + "0x00000000000000000000000000000000002c77cb09381821d1d62a74c81bcafb", + "0x000000000000000000000000000000915addec4b02be7e5599bbb1f41fbb9e0f", + "0x000000000000000000000000000000000028bcf441b36723bf95e0be039533f0", + "0x000000000000000000000000000000954535ac3a2cb2b7ea19315aca8ffff3bd", + "0x00000000000000000000000000000000000473d4f91369383b78b9324f8d83a3", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x0000000000000000000000000000001256412563febc9d3d73639a002e1fc9b9", - "0x00000000000000000000000000000000000620a3d4eeb54142ca75e2dba2a4db", - "0x00000000000000000000000000000039917c91cc366fd4912cb7be248a35233c", - "0x0000000000000000000000000000000000092472bf677235f6956f2d093c008b", - "0x000000000000000000000000000000b1795305b34f2f47e00fefef8e3ff03117", - "0x0000000000000000000000000000000000219d203b492d7debf5d8e7df9d2059", - "0x000000000000000000000000000000bfa96395c8478bacb512c36590c5b7b901", - "0x00000000000000000000000000000000001088537efb9ccd4bbaf4c519fb15ef", + "0x000000000000000000000000000000a0309c5acf411dabd67697d4075710b60f", + "0x0000000000000000000000000000000000017125ed54d5f16d50c2be55f8d80b", + "0x000000000000000000000000000000c3884b62c59c37f43e8acad4f15afdba7a", + "0x00000000000000000000000000000000001a3bfaf919de7e9b9af2d6281c6374", + "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", + "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", + "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", + "0x00000000000000000000000000000000001b8936a0be628b58af9859c2a851d1", "0x00000000000000000000000000000016c08d152f9dc697daff20714fccf7a5ea", "0x000000000000000000000000000000000021414e160dd06b07bdc4cfc47e4e2c", "0x0000000000000000000000000000002a824f2fcf5190d78d4fc5975ad848a5d1", @@ -689,60 +727,60 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x00000000000000000000000000000061405ee59edb83d219a4493604d8df8073", - "0x000000000000000000000000000000000011a34f74e4e97e31cd231a1b171c5f", - "0x00000000000000000000000000000065b8a5a2da7d378115003ef097e0ec1b33", - "0x00000000000000000000000000000000000d958a9a530f6138807471b9f00dd3", - "0x00000000000000000000000000000076fd099960d4125a29c7341d193feaa0be", - "0x000000000000000000000000000000000016d6a9f7c51b91e2097bb9cf70ca99", - "0x0000000000000000000000000000000066878c25e24883918ee19236dedf8e7a", - "0x0000000000000000000000000000000000239dea1597e850ac7b8beeb2919d9b", - "0x0000000000000000000000000000009ac59b14d9350d9b422f319b3a0142a2ba", - "0x00000000000000000000000000000000001e91c8f0370d6d72378892ac071836", - "0x0000000000000000000000000000008a494943abd8f50dc5188d4b34bfc75a3f", - "0x00000000000000000000000000000000002bc55ee1a56f307dc6c11edf632e11", - "0x000000000000000000000000000000a3bbf9a024521bff63ac9ec84b2e102450", - "0x000000000000000000000000000000000026359bfd648ec54ad2a62ce0f56200", - "0x000000000000000000000000000000970c79863e1fe0ce9c7e5208046b8f7bc8", - "0x000000000000000000000000000000000011965004488f372d1c7ce8202eaa07", - "0x0000000000000000000000000000002c9193106d9b94c289d3cd6cf50b262a33", - "0x000000000000000000000000000000000025603e1f70d8b8958c93998d233876", - "0x0000000000000000000000000000009c11e9b5a22b4b61bfc97eba76026f4cd7", - "0x00000000000000000000000000000000002db5cd7ae62e323c72ec8c187a5aae", - "0x000000000000000000000000000000a93093ff27ad3f2d5cf1dd53ba2ee845a0", - "0x00000000000000000000000000000000001cec9ca40768a2cd1a17f6c7c9dbf9", - "0x0000000000000000000000000000003d900afb111be27899d10b78fc1ebbec91", - "0x00000000000000000000000000000000002dbc1ed8b7a9d47c0f41eb45ae9670", - "0x000000000000000000000000000000dc5cc2370e6ea2bd90453a121270b4e1c4", - "0x00000000000000000000000000000000001ee583c3be7e33fe5bb33c3c6607dc", - "0x0000000000000000000000000000005b8dbfac41f7f00686c9bea577999342db", - "0x000000000000000000000000000000000002dcdb63b4738aedce151a1a90ccbb", - "0x000000000000000000000000000000503652993795ebf9c48026d15d693a1d77", - "0x00000000000000000000000000000000000ade8b97f88d4fc37a5918ba95d655", - "0x000000000000000000000000000000f708293c9af0019712e8676e0f81532b9f", - "0x00000000000000000000000000000000000fac0307a594c5601eaad4b3a2ad05", - "0x0000000000000000000000000000006cf7268767d45ce8110619c21c9a214a2f", - "0x000000000000000000000000000000000012c49f22347c4caa3f2187e510e4ba", - "0x000000000000000000000000000000ee4d3060375318f5f489ff5a8f76135787", - "0x00000000000000000000000000000000000b248f2f9673f5135d11083ff4fce4", - "0x000000000000000000000000000000e239eb099884d7ca28e161a9aa1b91af81", - "0x00000000000000000000000000000000001b1973e513eed3e33431ef809a0e83", - "0x0000000000000000000000000000000c4e4edf6fb53a76bd35e4d7f3a15112db", - "0x0000000000000000000000000000000000145ba233c13b3914b4da7f9ec60fd5", - "0x000000000000000000000000000000ba214ccc13ebb1b9872f840d92212cb7fa", - "0x00000000000000000000000000000000000f318091b8546b6c346065a0421fae", - "0x0000000000000000000000000000001857cd22bc6e548e3a1326a38342380abc", - "0x0000000000000000000000000000000000258af1ecbdec237c4ca3e7c43e23be", - "0x000000000000000000000000000000ddcd935bfcbed61b2d5dfb467633cd065d", - "0x00000000000000000000000000000000001bdcff79947d7bf8717ff6af7eace4", - "0x0000000000000000000000000000002f0274569b50d632b7df62579a51700a78", - "0x0000000000000000000000000000000000110205f104c154f37db7ba03296738", - "0x0000000000000000000000000000001669ec30d62997299c6384897452e193cc", - "0x0000000000000000000000000000000000091f36af19ffa02534ed6c6a12bd77", - "0x0000000000000000000000000000000cc9c593f552b97588f6a252104231d75a", - "0x00000000000000000000000000000000002d0af598a89ca680fc9928f822506d" + "0x000000000000000000000000000000af74c853140d3b0cf48ac5426ad44e3a5c", + "0x00000000000000000000000000000000000cb504c2196f73934d76e059397164", + "0x000000000000000000000000000000684b219a630e4770c224f7391ce903b574", + "0x000000000000000000000000000000000003d04c0a020da0ff25d4d81a4d60cc", + "0x0000000000000000000000000000003a547a2ea7e16e11451dbbeff89a46927d", + "0x00000000000000000000000000000000000fe460a80b11f07f28d016ffcbbdd5", + "0x000000000000000000000000000000ef84584cfec94dd3c5125887edc8b15648", + "0x00000000000000000000000000000000002775675418cc4ce82c6c45ee105a60", + "0x000000000000000000000000000000a78629fdc8d0021839d214273a985802a3", + "0x000000000000000000000000000000000010a06e7102f85337eb4c8b60d97c25", + "0x000000000000000000000000000000518765c5253492c980ea80aac7e9986f75", + "0x00000000000000000000000000000000000a622d7d27836ced89d7a2c1ff2967", + "0x0000000000000000000000000000006460b6c05ba8ae4c71040cd807a630f6d8", + "0x00000000000000000000000000000000002879f62ac90caf8d067aa57f0a2cb6", + "0x00000000000000000000000000000071bf565e74a124d3587a0d63adc7f29b32", + "0x0000000000000000000000000000000000122c536450106d4844375b13d9ba2a", + "0x0000000000000000000000000000009133f308fcba6ba2e78c78f1540f56e805", + "0x00000000000000000000000000000000001cabb18101f26c315098c437934f63", + "0x0000000000000000000000000000002622d42a77800505a1cb7d4d76702cf100", + "0x000000000000000000000000000000000006b02f8ebd2ac84a9c6991c39dab4d", + "0x00000000000000000000000000000018d1dbeba31941616af05128326ec86ea5", + "0x000000000000000000000000000000000007c9f24379b75927ccb4d7ad3b8c82", + "0x00000000000000000000000000000092277632f048f820823839ad073172915a", + "0x00000000000000000000000000000000000a09bb921f8ca99cb19752b1bac91d", + "0x000000000000000000000000000000d91ca36caa7bd53f0c6da30743948a8639", + "0x000000000000000000000000000000000021e7290c49f78addda4ccd9eef9c8c", + "0x00000000000000000000000000000081b433648af06686217c238ce4b13cf535", + "0x00000000000000000000000000000000002047531ed8535e381cffae559b6bb0", + "0x0000000000000000000000000000007ffdec7092f6d520c0209c640bfadc695d", + "0x00000000000000000000000000000000000a26fbb3d9d87f4ab3dd718c3bb75e", + "0x000000000000000000000000000000c636bdd1555ebce8fb6a9751c48376b7dd", + "0x0000000000000000000000000000000000017cb50edda28183e752c7e00faa40", + "0x000000000000000000000000000000ec2af0c236db172d1e5c00f7de73ae4fef", + "0x0000000000000000000000000000000000053be81fcb74e5cbb36dc0f630a49a", + "0x000000000000000000000000000000080baf1731ad04c68e93e7045d03ef4fd3", + "0x00000000000000000000000000000000001e593590b8049fe6542e11d3606aa5", + "0x000000000000000000000000000000575f11519d26bc15d34402b3331befb097", + "0x00000000000000000000000000000000001b7eed68e0e1c24fbf77cbfa588283", + "0x000000000000000000000000000000e1cdf4c6808f1f53377d276a0214b9af54", + "0x000000000000000000000000000000000002c44f6a43320eb961560c6a40262b", + "0x0000000000000000000000000000009f48843445d33387ce0134c37a9b82037a", + "0x00000000000000000000000000000000000a2852b8f7464eefbba66e39124b2f", + "0x00000000000000000000000000000077e865b0eef6500d62b5ed5b71795e1fdd", + "0x00000000000000000000000000000000001bc28e177eaebca799a38f9b96bd41", + "0x0000000000000000000000000000008a3623ef604d2b654cbc7b6f898ab36fd2", + "0x0000000000000000000000000000000000239c355843996ddcf4f3330873dc58", + "0x0000000000000000000000000000001fd35d9c3df35c0ab05822a8a7672f307d", + "0x000000000000000000000000000000000008eff9c124dc7092426dbfef4f367f", + "0x000000000000000000000000000000045c0a8172f53ba9a5c8e00908c493018e", + "0x00000000000000000000000000000000002ca001cbe15bf21d7bc13cb56f8272", + "0x0000000000000000000000000000001842209bfe3ad1cfba506322320f9c1a8f", + "0x000000000000000000000000000000000005e47c6d153729d8788d2a9c9cd993" ] - hash = "0x20ab775da5bb45344ffe17866237142b9321b97b2e93ccfb1c299476a262e0b5" + hash = "0x035b62916d53f6a30d14dfd8245816108afd3d59028ddcf59607c26f190a855c" [[inputs.previous_rollups]] proof = [ @@ -1230,22 +1268,22 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" - out_hash = "0x009be21298b4428b38b9b314446eef3243121c400edd3780e34da475ea5f17c3" + out_hash = "0x00f329e671c45418c360ecaffc93fbda197fdbbb11c27c83ed0381ec4ff35ccb" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x26c404240cb9d3965fdd677de1d4ea1d907e460403e304ed198e839901a4cebc" + root = "0x0bf231280528029b2b1a5edd82e73b5ae8b11264525dd8e90227c12b9e27de90" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" + root = "0x17108deb7a97c2ff200627cff40a2fe4cf6829aa004b567f9c7bc3b782b5ed54" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000005" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1265,75 +1303,75 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" +root = "0x144f9224dee4aac6eddc5d988e7c6965528d2e08db91cf58989655a68fbfcc52" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" +root = "0x191d19a6ad2b7bba03d122035938544f5e65de24aeaa436cd5e4d977bd014505" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" +root = "0x12a2218e991bfcb4acb2e3e5a91d8424043c127125a1705c50f526b657f1522d" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" +root = "0x05006c16ae34df049241a32f199ec71b6e91f581b27e4ae8da8d8658a93f4d46" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x069ad5cd9f6b5ac53ec9533083d53fb0e3b8cc49b13211bd6d314c00493971c2" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000013d" +root = "0x18bab17c744c297c8a7ec8cac2c6f2f6c4b6b4041037f5e4dd97d04b37e2f026" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a9d" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000eec" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", - "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", - "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" + "0x00000000000000000000000000000000000000000000000000000000b7f9d44e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44d" ] state = [ - "0x0b7c9bbfac21d3c59031a865ee1f7abea9012d898a238d0b9d545e7e15be4f9a", - "0x11e47e7e5a97cace7b8cb5c63eeaf7cb076e5e19a4e89c1d3f4c3fb1faddf0b3", - "0x03a1357263e162410b5a70343adea4b373f3006660d9b40c28425be41749a8f7", - "0x100bc00d33720748142a7cd2ab57c5c140b681cdeec9b6197841f983ed05a3e2" + "0x20919f1663ed9695ea49102584aab0d33393c1f0a3e71fb94d8379eac90bf504", + "0x00b14aa0f911d5f7c357bd29c8c9e4cd21316e34f5f999e2c1bc141c3b8d05b5", + "0x058d00874168957ee2bde39d66f8d866f28d89dd627b2e4a3b0fe29a63fbcb0d", + "0x0708d0c5b32da1b4e144f6dfa4ab7feb6bd96429b5f308487a0a58cc19bdd756" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000fe8" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000001437" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7f9d34e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34d" + "0x00000000000000000000000000000000000000000000000000000000b80de34c", + "0x00000000000000000000000000000000000000000000000000000000b80de34d", + "0x00000000000000000000000000000000000000000000000000000000b80de34e" ] state = [ - "0x22b79dec2cc8832eb6f5b6f555e3f46df7cf49c430792401c0bd69d93acd5a9e", - "0x11f095e238c4fcaf03e98bd59bc4ced15d15c960672b7985f115d431b6465f28", - "0x2fffb57d55f42b18f76eeac271cb09237dee47004c2003d367dd7f783837dbbe", - "0x0350c82eeb6f621178086345c4170033e27dd8ca1fd9fec9277096ac2a409fee" + "0x024bf0c456550abd96a3c1861be85939128c1aad32828721b425d097eae85dba", + "0x09299ca2c473f03303182e83482024eed16ee3aa7485911a5cf4f4e3ad4280e5", + "0x2fb97c2674d963e3d3b0261162ae6a4e7f3d9f7cfdc2aeef7529a02210647357", + "0x290f80a555215650feb9df2675e0e2c3e8553c399b2b689de4def696ca59b3f6" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x20ab775da5bb45344ffe17866237142b9321b97b2e93ccfb1c299476a262e0b5", - "0x2a9ef81b082ec4212c08eba71c46e645efc1ae573e9cca5b480785be9dcc4d21", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x10b6730f1d1e9c6bf8d7c4b42b64b40d2603e3ae6ddbd464c3d8fcfb9e06e6d4", + "0x11017f6408ff020bf1556ed3f4d41fba9dfe9fe312cd5430ec7c1abf7e3a9bcc", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] @@ -1341,46 +1379,46 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001393476211d0127a80dce177bd2139b525", - "0x00000000000000000000000000000000000a64db7a774dad381e4034cb2457f3", - "0x000000000000000000000000000000d5fb425ef17d829bcbd2f2212397cc69ba", - "0x00000000000000000000000000000000002902ad5d5e880ce9d3ff8815ad1554", - "0x0000000000000000000000000000009b94b4b71ebf49ca1ccee622099eb37a96", - "0x0000000000000000000000000000000000217517f2a6d3c0ad2a63c69b28d392", - "0x00000000000000000000000000000038d8df60934ce84e0ed3e7f5ca09c1ee4d", - "0x000000000000000000000000000000000013384c8161e64209078ece69fcaa19", - "0x00000000000000000000000000000093c2a0c6ec49f39474bd6782c5cd6b01b2", - "0x000000000000000000000000000000000008ff5813561afc758759d27f19b55c", - "0x00000000000000000000000000000097291956465f3aa94d25b11bc567a6c287", - "0x000000000000000000000000000000000007f14a03af147b21368785d869ca98", - "0x0000000000000000000000000000006a811b91c5970c9c2acd7a754d7b7f9cb1", - "0x0000000000000000000000000000000000190a1ac15c24fdafc83b205b9a284b", - "0x000000000000000000000000000000b61bdc9c40c5c1e94e290d7b383b2ee122", - "0x00000000000000000000000000000000002f5117ca48de83b07881d30427d341", - "0x00000000000000000000000000000012095bbac1cead43059d0a230818a027b7", - "0x00000000000000000000000000000000001c7b3a018ad17b7cbb3752d56c6f80", - "0x00000000000000000000000000000018c18cff602c8434b90273cb1ff38dd751", - "0x000000000000000000000000000000000003bd5bfa0c05c005fcbde355422947", - "0x0000000000000000000000000000009dac7aa803151cb1966b812422755d8e9e", - "0x000000000000000000000000000000000010f818617b14b429abcd3acd46653c", - "0x0000000000000000000000000000007951c87d59a7b4319ddc32a19635675d94", - "0x000000000000000000000000000000000005be6b96d6eb897429b815388db99b", - "0x000000000000000000000000000000d7e7c851d3ba4e42b00b50dcb9a40159ff", - "0x00000000000000000000000000000000002750be703cf6981c927c48de088588", - "0x00000000000000000000000000000048b23b4fb077032ac487b882dec8a8c38b", - "0x000000000000000000000000000000000017150b214b8aa285fed8a5b374a4f9", - "0x000000000000000000000000000000416e099bfce67a459c5a20a4311705f6c4", - "0x00000000000000000000000000000000002b684b94d2f1f96e86dfad7af6171d", - "0x000000000000000000000000000000651160cf941fb73a15062e12bfc9e35804", - "0x000000000000000000000000000000000007a1bb9d8533d71515e6e3b5e6866d", + "0x000000000000000000000000000000be3ef7df55faad770dd417b568b334bb61", + "0x0000000000000000000000000000000000020dbb5be28ee0dddbe361d4210575", + "0x0000000000000000000000000000002a9a30c0f428736335b3eb03271a7faa35", + "0x0000000000000000000000000000000000011eeab7deb21addfa7d56d1c588a1", + "0x000000000000000000000000000000cd7414d72fbdd24b1bad570941833708ea", + "0x0000000000000000000000000000000000125ab5466e467ad79893fe6fb71dac", + "0x000000000000000000000000000000275ffdc4a6a9c963cff9f4bfc97ff47ae5", + "0x000000000000000000000000000000000009b0fc1fdcf1eb4720e77df4bf579e", + "0x0000000000000000000000000000004b41b33ed09d6f2e0d1e2778bcc0a412bf", + "0x00000000000000000000000000000000002431de0fcb1f1e513962b6ddaff0cb", + "0x000000000000000000000000000000ceacbeb3107979529c12c1d0eee1557e98", + "0x000000000000000000000000000000000015157c061d1d61cf7dd3a7ce845922", + "0x0000000000000000000000000000003f7443a3cea90f0e6730b33675efbbda73", + "0x00000000000000000000000000000000002ca6b067638c1c24bbadd530a94798", + "0x000000000000000000000000000000f4d7b640687e4a07ea713f599fa766d14f", + "0x00000000000000000000000000000000001da3ebbf464dad0213d7cbb620146c", + "0x000000000000000000000000000000a5e9f66b74ff0bfcb7cb43d4ae9f154cf7", + "0x00000000000000000000000000000000001b50d6d924c13b8138405d313f1875", + "0x00000000000000000000000000000091dda1fdadf6e5bb631936d41c3e919572", + "0x0000000000000000000000000000000000218f9e93fa7efcdb8d89b8303acc50", + "0x000000000000000000000000000000f659c8815b22bacd330bee0c95d2a77cfd", + "0x00000000000000000000000000000000002aee8b729bc510e581461f3c3d3f20", + "0x000000000000000000000000000000d35405c664cefb21dd45302fa07ce6e1ae", + "0x0000000000000000000000000000000000168af130006e1ff22ea8737f0207e3", + "0x0000000000000000000000000000004b9beda85c743bfc49ac3aa711ccf95ca3", + "0x000000000000000000000000000000000028fb89c6da361c392f36475551e5c7", + "0x000000000000000000000000000000c5d8af9e91084202d30bd24e2ae1787dd1", + "0x00000000000000000000000000000000002ea1690f1652415522380675b4f298", + "0x00000000000000000000000000000004cc26069474a70fefc9e011a297d3659a", + "0x00000000000000000000000000000000002c4ca65f1f3ce11e955002f76823b7", + "0x000000000000000000000000000000caa9709b37a3f896da980148bd862f79ad", + "0x00000000000000000000000000000000001cdab1dc53ddf21433efb20a019aed", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bada1572761d2d57e5d206da78afa472c5", - "0x00000000000000000000000000000000000248453a876b49502a5a8259818f44", - "0x000000000000000000000000000000ec45f0511c4ef04800c3d31e152e9265de", - "0x00000000000000000000000000000000001fff1bef8afe963c3b78c3c2549ca4", + "0x00000000000000000000000000000091be1f8e738e8cf74c39dcff97e574049a", + "0x0000000000000000000000000000000000253b1d48e89dea2387345d1f190cf8", + "0x00000000000000000000000000000001f523e64316ec12df1d1fed701b1fc3ff", + "0x0000000000000000000000000000000000254e8bc817fd854d25dce4ca34bbb9", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -1401,57 +1439,340 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000e379faf5ffdd383be5ce0f1ee38f5e73fe", - "0x00000000000000000000000000000000001429616496865cd170bc83c40d415a", - "0x00000000000000000000000000000066e08b7ad48415290d2ff590e84057e60e", - "0x000000000000000000000000000000000023a625e90ae9701e33c52be8f0d396", - "0x000000000000000000000000000000774fc954a6adaa4e4db1da6228184e1354", - "0x000000000000000000000000000000000015ca4073735e39fd5dc55567dc1068", - "0x000000000000000000000000000000fd9e5f594db01e4b2625e1e3dcfd400f6e", - "0x00000000000000000000000000000000000f4a392bbee96bddd468b2c9a18896", - "0x000000000000000000000000000000d28954aef28e666d63ee0fb401ab7bc1b6", - "0x0000000000000000000000000000000000253b48f95132d1a3183e26dbd56884", - "0x00000000000000000000000000000022887784410bf17c157fc004401281c342", - "0x00000000000000000000000000000000000a249d88427c50df84670228613493", - "0x0000000000000000000000000000000f495c15c8a9098c779fef9227f1c5a897", - "0x000000000000000000000000000000000016d74e40a54fe1961a01c0a275941e", - "0x000000000000000000000000000000a968320348365b69bc59ded07a855fb88c", - "0x000000000000000000000000000000000010c9846c3754b0fb4b4c9ab8d68cd3", - "0x00000000000000000000000000000088ee0f0a54893f8b1e8b56a7fa7bee9d4f", - "0x000000000000000000000000000000000021d14db4aa9ae9f88641b9336d9dba", - "0x0000000000000000000000000000000f46a800020405196bda0c07afe5154eac", - "0x0000000000000000000000000000000000062e98c038c271784c9fb61136242f", - "0x00000000000000000000000000000024ed87f3417bd5bbaa53682680b1b915c8", - "0x000000000000000000000000000000000003beb3d385de2c0a7a40cebe01d34a", - "0x000000000000000000000000000000f85b812b32412267c5221f3600eaa3f3d2", - "0x00000000000000000000000000000000000289ace5de4f3e7a721b5a184d1e76", - "0x0000000000000000000000000000002e30085e1c74fe70d1d2ab68faf0984ca4", - "0x00000000000000000000000000000000001adb7660db50eb3c9d70b137871b2f", - "0x0000000000000000000000000000008e05ae370a270eeb6d282e3bc2b7889cc3", - "0x000000000000000000000000000000000020e76f33b00bccd1f97095bece663a", - "0x000000000000000000000000000000d71d8a40f7c9f1984d513aa7eb1a895e6e", - "0x0000000000000000000000000000000000021aee4d83119d0af331d5893af9fe", - "0x000000000000000000000000000000dec3abe29c9aa4bf73251a0c748d11e9dc", - "0x0000000000000000000000000000000000153c1ed58f5394ad372869f471ca8b", - "0x000000000000000000000000000000bf4d6e6ed9dad1b05bd3d5cb3b3740d3e2", - "0x000000000000000000000000000000000006803b1ef715809ab5085220b7c284", - "0x00000000000000000000000000000041efece86e20c4323fb08d7aad7345c79c", - "0x0000000000000000000000000000000000096fab6acc87fe26e0eefb5660a7db", - "0x0000000000000000000000000000002d550983acbdea743f381bf4d55b8c6110", - "0x0000000000000000000000000000000000107455727dcf49837ee29622f4e9ae", - "0x000000000000000000000000000000a07bfb26d2f33a45866564f6fb630fc1b3", - "0x000000000000000000000000000000000004b58a9a3d784d5857e224b300b97a", - "0x000000000000000000000000000000c0f8d7d2fa6eac6b45b736e838db02e437", - "0x0000000000000000000000000000000000012728fef15749f6355802ac76d166", - "0x000000000000000000000000000000caa9dd21f786e491093e94a42326c20c4b", - "0x0000000000000000000000000000000000181c00a5273565ed45cde6516b7267", - "0x000000000000000000000000000000f791b0a7d2376523eebf266bd58c615a72", - "0x00000000000000000000000000000000001658c7b51e5eb76e58124a4bf26d30", - "0x0000000000000000000000000000007ffefc9b69f9b9f766f98d9390ad49a8f6", - "0x00000000000000000000000000000000002700900f023bdb2524f5ce218af8a6", - "0x0000000000000000000000000000001d12e2e9feedc5df84ac9cb8e405fc64ea", - "0x00000000000000000000000000000000001645d7c72fd8844ddf0659d2b77656", - "0x00000000000000000000000000000098eaadb9c8f156e98d8dfde6f90be22a80", - "0x000000000000000000000000000000000028291c89dafd88dced57d87f6d8ab7" + "0x00000000000000000000000000000063a793166969e30306b1a33ee3140ab639", + "0x00000000000000000000000000000000000689ae6c5351a0c7d2bddd28760eba", + "0x000000000000000000000000000000e9e058e78b28069998e0b545635c751505", + "0x000000000000000000000000000000000029d041f64f9c7a4b574afdd84eb2bc", + "0x000000000000000000000000000000de0e873aad4dce9c296b5822c49119b396", + "0x00000000000000000000000000000000001e622a80763bdce9e84c5936947ea4", + "0x000000000000000000000000000000ff979afed880f8777a1d7edb65ce1450e3", + "0x000000000000000000000000000000000012be4428cf92f37d4329f288edd6d7", + "0x000000000000000000000000000000d68061ce1bad9ac1e54cdf86b65d18b89f", + "0x000000000000000000000000000000000020fdf737ed00586f6db007044965a8", + "0x000000000000000000000000000000946bb34bc2173c2659e824f5fd377a3cbf", + "0x000000000000000000000000000000000022da84ec41699f355efa9e9550e4e4", + "0x0000000000000000000000000000008b0f4ef158c13087ed0e80688fe8373342", + "0x00000000000000000000000000000000002a4cae8c1411ba84463b850ab1844a", + "0x00000000000000000000000000000081d9bb13936c0676b987efe4a7ccd38a7e", + "0x00000000000000000000000000000000001e527e0c58ebec97285f8d47471778", + "0x000000000000000000000000000000c17602371eddd69a1e0e5b82a51441f2d3", + "0x000000000000000000000000000000000010fd74deb218f4d0d58aee589c31a6", + "0x000000000000000000000000000000dc8cd28e055e13b175149f797af895f0f4", + "0x000000000000000000000000000000000014d50f3e5a64cc7500ed82e02796e5", + "0x000000000000000000000000000000c61024b9433cc9b608636d33133501734f", + "0x0000000000000000000000000000000000080ffdff074611822ac0029ae9ac87", + "0x000000000000000000000000000000251c0f33e1f84d4365571cd965fc9b951c", + "0x00000000000000000000000000000000002e7e699ac6cc777970c0d5dd410bc0", + "0x0000000000000000000000000000009e1f4030259589018ce84f6f1dd736ae5d", + "0x000000000000000000000000000000000006154a1e0fea69f24bf7ac004afb7a", + "0x000000000000000000000000000000189020ea1ed822257549ab99ac2b33647e", + "0x00000000000000000000000000000000002a384f4831d00b56c6219abcb3b785", + "0x00000000000000000000000000000035fb02b0d2e793607a238e08539424c438", + "0x00000000000000000000000000000000001d0e75eecc618b087887f7d14ddf24", + "0x000000000000000000000000000000eae70e5ed566bcad446daa8f1059119fb5", + "0x00000000000000000000000000000000001f16d342675b048447aec1d841ea6f", + "0x000000000000000000000000000000dec8287d2ca445b6611951692aceb93f09", + "0x00000000000000000000000000000000000d237ea339d430164ddcf07c98eebb", + "0x00000000000000000000000000000069bd0705898ec802324165e180c23cca88", + "0x00000000000000000000000000000000002b2487b0a0cad2ab8b703eda79048b", + "0x000000000000000000000000000000526f89287c9fa8d0869c89341b300cd057", + "0x00000000000000000000000000000000000da86b460feb2479d72b91bad3aa4e", + "0x000000000000000000000000000000aba6055db467fa492b870fccd9251c0cb4", + "0x000000000000000000000000000000000022e849a8f64faebc36288439518d4b", + "0x000000000000000000000000000000ab679268e81d4770ddc1861ac7485ac4e8", + "0x000000000000000000000000000000000009a186caa2f074b8b5d3d26afddfc5", + "0x000000000000000000000000000000694fbc055e1f0045837b2bcf0d60f82934", + "0x00000000000000000000000000000000000ffba7e4a28991553a68d277bf2aa3", + "0x000000000000000000000000000000de4a494414853cc677e6f0de0f19a070c8", + "0x000000000000000000000000000000000004485188f222785e8455584b3632e6", + "0x0000000000000000000000000000001e68682a2d646f241b36838e8627fe4258", + "0x00000000000000000000000000000000001cd86d75f808b92947367db49e99b3", + "0x000000000000000000000000000000a21f994888d69ad0e60ea74b527f54a7ed", + "0x00000000000000000000000000000000001bbdaa75acb6eb653db71e1666d066", + "0x000000000000000000000000000000eb0694220d1a490792b0165b98d9b8bf71", + "0x000000000000000000000000000000000025729291a976e4cbed01962ee0b0d0" +] + hash = "0x242e942739553143b651d041e96bc6bc5e09baa6142d959488ffa864ce063d69" + + [inputs.message_bundle] + messages = [ + "0x0000000000000000000000000000000000000000000000000000000000000c00", + "0x0000000000000000000000000000000000000000000000000000000000000c01", + "0x0000000000000000000000000000000000000000000000000000000000000c02", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000003" + + [inputs.previous_l1_to_l2] + root = "0x1cf24640611b8c3ea83ce645fab1d515a5b0cf58739548f128ed62c908a998c0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000002" + + [inputs.start_msg_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000b00", + "0x0000000000000000000000000000000000000000000000000000000000000b01", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - hash = "0x016a3b94e0b04a9f99ca3c31a475b4b5b1854bb2f3cea14fc49177110c9d7142" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + squeeze_mode = false diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml index aed9ec3e1772..a5d165618cc5 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-merge/Prover.toml @@ -483,8 +483,10 @@ proof = [ ] [inputs.previous_rollups.public_inputs] + start_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" checkpoint_header_hashes = [ - "0x003f28245501cd83312b059b7469c9efcbd17cdf1b87748a6684380140e8b8f4", + "0x006420e6a81e8bf50b9175b1c7e3d0648de4d3d043cc4f9f406ff7a9a3add5b8", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -519,33 +521,33 @@ proof = [ ] [inputs.previous_rollups.public_inputs.constants] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x1842a814b068f699565f4df77ab9139f1cfab687ef959bf92ba0bb3adf93d8dd" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x1302274e4a6bea5811bcdf1a547430241566bcecab5eb026ced46711d8e78501" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x0950cbcd8c47c28e14da74cadc13fee3f308aff298ee1c0a545a290ee67ba418" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.new_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" + root = "0x0003e0e323f66d29e6a69f447a88e682190ce3e0a2546cb3e7f4a3ee4a31f1f8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000198e45581dc500" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -772,15 +774,15 @@ proof = [ ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00c7d69903605c24450d8cc4111d6b01e31f84cacd7a01402f0cef9f221f27f3" - z_acc = "0x1beeba27d94c66514c35883c6684bfdc767455041a16225205c326fd2e2cb7fc" - gamma_acc = "0x088bb68a165bc27058fd98272ebe5f98cb66378ebc3d5c2639d6f59a66e134ca" + blob_commitments_hash_acc = "0x004de360c1e1bab9d63f6505559f9ecfb12acfff9830bc3cdc88df8f45d32e23" + z_acc = "0x11fd751039476db14d33f5dfbedb4d01c950538ac3c0f71c7135728dc2d0907f" + gamma_acc = "0x25987b100d9bb31cf80bca1387bfc5ff9c21c6763a86257c1beb8d1b1e1280bb" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x523fafae630b01cb88597856ec2ecc", - "0xf3db7c5d601e16ac93c5bbe54e70b7", - "0x31dc" + "0x76d28b50bbf7f3ebc188d45cf44828", + "0x18c38f30e3b353d07f425dfd06be20", + "0x413b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,168 +790,168 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0xdc0744575b26b4c4b7ee41dc7bee5a", - "0xab24ae0f1c266615b22dc3e9ffeecf", - "0xb738f18d636a06615561d266fd2d4d", - "0x19668e" + "0x5ad17b7163c2297e255d79877b272e", + "0x27fdadfadf26cb9c14f34cbeba8d72", + "0x073c70fc72f7ee0bb6cefb5a8aae8c", + "0x096bf1" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0x713d223616e8efe8cd4821efdde4f2", - "0x9a9a221be261841a9296b4d1eefd77", - "0xdb1af24cb0ccdcba1a7900c4fc1ad5", - "0x15b665" + "0x6d077d2d4c01253ae851efee4a316e", + "0xb1db1450e1242aa42ba0920b3d9f20", + "0x55d39e7ab76ad40bc787b9940e81bf", + "0x0e69bf" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x7cada12fe37b447eedceda7fcd7261", + "0x9d8e4fe065452dc53f81f57e8078e7", + "0x1f1b" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" + z = "0x1efd2648c273ceeac65dcf274d8fa604d1e4e97bca33d88471d5f2359a2caf63" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x7cada12fe37b447eedceda7fcd7261", + "0x9d8e4fe065452dc53f81f57e8078e7", + "0x1f1b" ] [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000011" sibling_path = [ - "0x233055a6920a13764c09bad668c75e48f8165a1894c37152ede5c09640a63b15", - "0x2c74d12f23eca40b1748248d689d41cb7ac4771cecfe01c3ae67dab27f821949", - "0x035c573a1f2634405482213a2b805e186d6b81073e2b7a5bd3f64c2e4e8bc21e", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x25ece109d362b4b8dbb8966f2fe94ddb217a6c63f7ac83b96c4f385ab2d03cf5", + "0x151ec971d9b291d78b1d405b001fc9a60d1bc918252466d6a4774554135802ac", + "0x29c4f2a137ff5c5b54eb911f6add38eb5ec9d139f54d95a7db432abbae472256", + "0x02dfab3acbc7708b1b3654912e946fe846568b8cb0e8af8da6a1845278664e55", + "0x2a6f812baf5176557f2f41b40fa4cb962d52e2e0c8ff7bf6b1fd7fe3a4223ac2", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", - "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x00000000000000000000000000000000000000000000000000000000000000a5", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000744c51f21e3dd8540bccf510ecc1d766be", - "0x00000000000000000000000000000000001e95a14c474168aaa5c9372f7a0abf", - "0x000000000000000000000000000000879082cb89dbf870ad3aa0d5da2ee67125", - "0x0000000000000000000000000000000000192656445ad3e71909ee40b06deeaf", - "0x000000000000000000000000000000e1909fba28938423134c0d59b76683863d", - "0x0000000000000000000000000000000000003e26f42f57c6e694c1e7e40b17c6", - "0x0000000000000000000000000000002a188fa67065c4bcc359cb5fd771dabcb6", - "0x0000000000000000000000000000000000160ac0b054344bb77bac08ac568575", - "0x000000000000000000000000000000fc970af33d774376cf02d202aaef414ba5", - "0x000000000000000000000000000000000021c2bd629cd0a533238d0ab831f778", - "0x00000000000000000000000000000068db97499ceb5bc0ee7a25f7b9474f2b8d", - "0x0000000000000000000000000000000000177f1d3bcc53dc664aeffa8f221982", - "0x00000000000000000000000000000071bf5b67b8cc7197d679fb2c9b28eff994", - "0x000000000000000000000000000000000004d0af735c0dba71607923878247b9", - "0x000000000000000000000000000000f9dfca16db1889889cabadcb3c086a4f27", - "0x000000000000000000000000000000000000ab2307518eeb29981848b3d1ee07", - "0x000000000000000000000000000000d6bffac49573916cfa0c7fc812ecbba5b6", - "0x000000000000000000000000000000000009655ac19e9e344b05e4a2fdce84c7", - "0x000000000000000000000000000000f7755de133f87eac380cca4fb5d60afa6f", - "0x00000000000000000000000000000000001d7cff28580bdd7cfbc17f159c5620", - "0x0000000000000000000000000000007f26c16746a68d8270726a65373e58c426", - "0x00000000000000000000000000000000001bcc461c1faa451fd1a0ed4683c3c0", - "0x000000000000000000000000000000ae6f4726a6e0f83357befc61e67a9ca001", - "0x00000000000000000000000000000000001ef4f7456ae1908e7a90de3d05cff2", - "0x00000000000000000000000000000017d5cef864c8bae29b2bec7712603477e6", - "0x00000000000000000000000000000000000c2947db29055b93c4ab5b26120a74", - "0x0000000000000000000000000000003a28bc16570b9a581942c4f4a5978e6455", - "0x0000000000000000000000000000000000297af63688110e42582a51c7fce3a5", - "0x0000000000000000000000000000008de422f0c439a79c6fe60b90f08dfe1498", - "0x00000000000000000000000000000000001c56ba82c1f1910eb581559e94ae3c", - "0x0000000000000000000000000000006fa0127d67c2462bec9945343f82c18b62", - "0x00000000000000000000000000000000001ab9b001ba47aa775c9094ccff2543", + "0x00000000000000000000000000000036d2157369305013c8479b661e9bffe8ff", + "0x00000000000000000000000000000000002c0aec83bfae212c5618a01dc5032f", + "0x00000000000000000000000000000079637952a9432b6c04de26b960419c2406", + "0x000000000000000000000000000000000016f81bd583fca03c4d6921866b2f4e", + "0x000000000000000000000000000000605da43776fb998e8f5a8f8f59493d1bdf", + "0x0000000000000000000000000000000000054fa1fe31a30b843030aa85747cc3", + "0x000000000000000000000000000000430e08eab747886838a73b7eb93d6a7049", + "0x00000000000000000000000000000000000fc7c1272750c481ab3aa64f760871", + "0x0000000000000000000000000000007b6c487b081cd42381fc2c5f460756fabf", + "0x00000000000000000000000000000000001c13765984a1558018db6833e2c706", + "0x000000000000000000000000000000e006291b1d02535c4f3f8796a584e253a3", + "0x00000000000000000000000000000000001497cc705bbd9bfaa96f7211db87d3", + "0x000000000000000000000000000000610db7fe4bfe6171822260ba25cf7fd7e5", + "0x00000000000000000000000000000000002cf5b96da296aa3d0d33e0897a3671", + "0x000000000000000000000000000000dbe98ae829fef8e64f045d80ed2aa380c6", + "0x000000000000000000000000000000000008c6b12c1e28f07325f3bc43328181", + "0x000000000000000000000000000000e11a616a8bf2e45900cb16ef7a387547a1", + "0x00000000000000000000000000000000000899d4536ca132a3255187d4bdcd3a", + "0x000000000000000000000000000000d7409e9b99d91622a75f1936d63d13ce21", + "0x0000000000000000000000000000000000010eb0051652a1e12fd910841b7380", + "0x000000000000000000000000000000a4d763a025d63693086d5e42b4dd09c983", + "0x0000000000000000000000000000000000057f7ee27662a1a3a797e9d5be3b23", + "0x0000000000000000000000000000000c00705cf8d7cb905d5bbea77f847bb1a1", + "0x00000000000000000000000000000000000ad3c7dbc5a0d102219b06b5425fab", + "0x0000000000000000000000000000003b3d6b7d7dfa41a114fdd2bb06d47fd826", + "0x00000000000000000000000000000000002e64810b091045697d64d9cd1590c9", + "0x0000000000000000000000000000004d92a88e43bae24502d046bf0ed7fe0623", + "0x0000000000000000000000000000000000168ebacff5cdf9c2ece95c81807f81", + "0x000000000000000000000000000000af15f3f90f76892655ae5ea104ab710df0", + "0x000000000000000000000000000000000012c00b8679fb65c6261e29481d20e1", + "0x00000000000000000000000000000097d1e3059e77dbcb559ae7ec59f4f1799c", + "0x00000000000000000000000000000000001bdc813cfa0a8f0b5b5dce352bfa5c", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x0000000000000000000000000000001aafcb2e2c5b4ee357c3cf460fa8614ed8", - "0x00000000000000000000000000000000000d7a76e33e068c44cecba8c22ae8d7", - "0x000000000000000000000000000000492fb683c7e0e137bc4e2ea86c37740b5c", - "0x0000000000000000000000000000000000206f337fb8b6d365b941ba4a8d8a9c", - "0x000000000000000000000000000000577c33d5c10b485d8c213d16ac4664dd62", - "0x00000000000000000000000000000000001dbb32af825db919015b2f62ac527a", - "0x0000000000000000000000000000004089798ec9503f6d851e3f36c8134fffca", - "0x0000000000000000000000000000000000258c2a8625473699411a82c908b205", - "0x00000000000000000000000000000039e66e47fbf20c042e57bc7b20b446fef5", - "0x00000000000000000000000000000000001a7afcba66a6d1561b93bbc1af74f6", - "0x0000000000000000000000000000002455981c887b06eaa76d3e33d58c191122", - "0x00000000000000000000000000000000001de23e2477dda30d3d197f197ac419", - "0x000000000000000000000000000000b116578da6236d15e82788782d873df37f", - "0x0000000000000000000000000000000000269873dc9e65f74c789d8a58db0077", - "0x000000000000000000000000000000ee7cf9691c5ad6f6e90099bc5d04408a73", - "0x0000000000000000000000000000000000284704a1b995c3a251204d4c6c01a2", - "0x0000000000000000000000000000004d63dd4c7af54fcf2e481be7293211350b", - "0x000000000000000000000000000000000003805c1292ab954706ed7e0cca9281", - "0x0000000000000000000000000000006572fd92d3bf1845cceeef0a7f0d044f8b", - "0x00000000000000000000000000000000000641fb756d60be4b60f5c0a76f6930", - "0x0000000000000000000000000000003c9242ea4df53612f2943b641741fb9359", - "0x00000000000000000000000000000000002ebb3334e2b6b702d04d94e2c6a5c4", - "0x0000000000000000000000000000004be64b431a5a816b719da16e8e02535892", - "0x000000000000000000000000000000000001339afc1567176d3527faaf56c0a0", - "0x000000000000000000000000000000377b1426e1e1857f300907c39678bab9d2", - "0x00000000000000000000000000000000001f460fe6b26626b496ca4a53dc2103", - "0x000000000000000000000000000000093cc8cd227239606f069fb8b0d89be197", - "0x00000000000000000000000000000000001d6ddaa3a6362872d4ad6f6ffdf26d", - "0x000000000000000000000000000000aaca84b607b945c22f9380968dca37b3dc", - "0x000000000000000000000000000000000006e37c218b5ddd9fe30f2d074af3ac", - "0x00000000000000000000000000000050ac5a5bfb200bb882053095cb7707c6c4", - "0x00000000000000000000000000000000002f598bce6b07a71ea18c892626f896", - "0x0000000000000000000000000000005981f7adfea2cb4c98608311c60dea02c0", - "0x0000000000000000000000000000000000289d38f2a30b52ebcfcda8ef0e441f", - "0x0000000000000000000000000000001b49052b5e34aed999b8b52e9496cbcc97", - "0x00000000000000000000000000000000000deaff0903f20c3a8781e8f36aeb29", - "0x00000000000000000000000000000013595eda489c2581add81a3054c537cde8", - "0x000000000000000000000000000000000016c291915bad74124a1089dd4e4b1e", - "0x0000000000000000000000000000009f60b0b20e50c2b872bbc2eba64d13d4dd", - "0x00000000000000000000000000000000002126fb29255849ef1cadd1b85f4ca6", - "0x00000000000000000000000000000018aa24e4df9dd2e6b857b79eb65063f442", - "0x00000000000000000000000000000000002bb078b426453481a11b32c23b5f17", - "0x000000000000000000000000000000471c619f4de581893a418a64ae1edbbf33", - "0x00000000000000000000000000000000000d33fe66c2a1ab73aa83ef5f9d6c1e", - "0x00000000000000000000000000000003cef58ea44be7d8c5d8d1639f1546b9d3", - "0x00000000000000000000000000000000001a5ca4c297a12ec7cbd3567570c84b", - "0x00000000000000000000000000000012c623f77652847ff7f2c87290036e946c", - "0x0000000000000000000000000000000000032e99aff3cb68a95f2493b6103618", - "0x0000000000000000000000000000003cabab340137b323e877e56cef1f8dbed8", - "0x00000000000000000000000000000000002986530e89170feacfa3abf1dc2bb2", - "0x000000000000000000000000000000b1af0f91346433e1a924e81e36062d5b12", - "0x00000000000000000000000000000000000fd850761ae3567a47c5015f5a49db", - "0x000000000000000000000000000000e96960409cc77dc83c19eb6c4a65a443bd", - "0x00000000000000000000000000000000002bc73c5cbad6a06c445f8c13667a0a", - "0x000000000000000000000000000000251d1a42e82570c38d16a0acb91075ff6f", - "0x0000000000000000000000000000000000252ab69e8a5eb85a7f07767a0b4cbd", - "0x000000000000000000000000000000775b0cbb24a05ae474393667bb23cbff4c", - "0x000000000000000000000000000000000020f65bb075b316367c63e1a78fa27f", - "0x00000000000000000000000000000045b7ffafdcdf6888cc39d9dca42576a396", - "0x000000000000000000000000000000000013c3af9f7d3e8d077e8765d6138d0d", - "0x00000000000000000000000000000061e4e7505a7274b9b128765e285681b6da", - "0x00000000000000000000000000000000000f860b75cc5deb976b9b05b8746e6b", - "0x0000000000000000000000000000003df46a7142e10868dc5980f6d2e13da00e", - "0x000000000000000000000000000000000022668e231bb6db8db665c18b46974f", - "0x000000000000000000000000000000dbf91bf91f60763e0c56fe43a8add14ab3", - "0x00000000000000000000000000000000002b6652da5918a262675f7b0ee80f9b", - "0x00000000000000000000000000000064092190c017f3620d4d39dad54d2f659d", - "0x00000000000000000000000000000000001be569b3318816be8bfafaeb38a0fe", - "0x000000000000000000000000000000e3d69f89db31d9400f666e59726928ef4c", - "0x00000000000000000000000000000000002757caef4b3a637a9aa7b191b32627", - "0x00000000000000000000000000000019852bf5ca19b13351bddedbf4335cb53f", - "0x00000000000000000000000000000000000b3498c424d7206a9dc3b30bcf4f7c", - "0x0000000000000000000000000000008fb1973e9d508a1b5258225627b8ecbfb4", - "0x000000000000000000000000000000000026f9f578430377663d282fe858e493", - "0x000000000000000000000000000000655c16efe629ce3bbb6555bc125d328ea9", - "0x00000000000000000000000000000000002c6140875c92938e10d156a43b9a9b" + "0x000000000000000000000000000000a720f425c05a4825b46e027afd0a6fd671", + "0x00000000000000000000000000000000001fcf1da494426fbf2621511cbd70eb", + "0x00000000000000000000000000000018a2e7cbf823397368dc4b87db4c644619", + "0x0000000000000000000000000000000000052e92af9a02920e4e179c4f67214b", + "0x000000000000000000000000000000825a267e5cfd171426338e2d9b3b9838d1", + "0x0000000000000000000000000000000000171fc66ae3ce33b767fbab8d5fbbdd", + "0x000000000000000000000000000000d5c49f2d00924b287efe89dea6879ff77b", + "0x000000000000000000000000000000000011f85546a9cd87a6b2b635c4771b94", + "0x00000000000000000000000000000027f61f3b9d8cd56f2a70ca35c2ba7e31a8", + "0x0000000000000000000000000000000000025050331a4428aed5b520dca6bd63", + "0x000000000000000000000000000000a41247254c9c0a191ebf6b4b27818cc313", + "0x00000000000000000000000000000000000be606e57a400a3f8579ce40332a7a", + "0x000000000000000000000000000000ffccc8bdab452ad48ae9f3a068de887c8a", + "0x00000000000000000000000000000000000c2a7bdf80e4f60a5ac20e3b9c6544", + "0x000000000000000000000000000000b7c80a222c2a6ae46bc9f64e581bf7271e", + "0x0000000000000000000000000000000000205b8c3084d3f5bb5db7d9590acaec", + "0x0000000000000000000000000000002a609fcebe46daf0c552761c19228be9c5", + "0x00000000000000000000000000000000000947b7d62dd0fa528f93ad462244bb", + "0x0000000000000000000000000000009dff2728b1e8ece8f977dd5f17c2c78105", + "0x00000000000000000000000000000000002d440b35f618fde819e1506404b866", + "0x000000000000000000000000000000ac37642801b1ef63703d72c94a15203772", + "0x00000000000000000000000000000000001bbe645b815c8305a5626fd64ed05c", + "0x000000000000000000000000000000ca1770abe5384c224b2cb8623ef53a891f", + "0x00000000000000000000000000000000000ea2e1c7b5a6b648868a1fbda389d5", + "0x0000000000000000000000000000008d6c11553db2a55004627c023b0e249573", + "0x00000000000000000000000000000000001cd0294ac6bce284bfd5e7c2a052a4", + "0x000000000000000000000000000000452503cff155bfcdc7a19e5f332b377870", + "0x0000000000000000000000000000000000150185e04d84d9b6ffbd2bb9052295", + "0x000000000000000000000000000000f3d6ba952c2b5b06d98e0b38222a510fce", + "0x0000000000000000000000000000000000277241267c9a7ff692b8f4a91039a7", + "0x000000000000000000000000000000a6e09a49d41c587395657bf22bae9f860a", + "0x00000000000000000000000000000000001ccb77f5c0bfe18ce719db97108493", + "0x00000000000000000000000000000009e276023bea7cb392a3ff9f7e2ecf364e", + "0x00000000000000000000000000000000001eb222312f45556a06e2c1a09eff73", + "0x00000000000000000000000000000017439a8fd7a316e174faabb48101bbf30e", + "0x00000000000000000000000000000000001b50b9d5fe4c43d61fc72fb8667869", + "0x00000000000000000000000000000094d24031f5c3c0f952282a186f2b2771a0", + "0x0000000000000000000000000000000000114af0d951e8098442447c796dd53d", + "0x00000000000000000000000000000043ff61c245cfed1afca45f10338f26f398", + "0x000000000000000000000000000000000029d3ccaf2bb1347618eab89bd09dff", + "0x000000000000000000000000000000151aeefea0cabef34bc27be650b1ea310a", + "0x00000000000000000000000000000000000f2f9770fce59054a8f14ccc9cfc71", + "0x000000000000000000000000000000344430ca97860eec6bef9811cf0248309d", + "0x00000000000000000000000000000000002fc0aa17a61a27fb1695ec956e1762", + "0x000000000000000000000000000000ea7eab06aeb8bcdd1119cd6dc0c4d5a928", + "0x0000000000000000000000000000000000009802fdcab28040b969b68ab9304a", + "0x000000000000000000000000000000be464a1807845060ccd8ed02952dff3c42", + "0x00000000000000000000000000000000001261948934bec645944b279144c0c6", + "0x000000000000000000000000000000e939eb8746a3940d252f066182db1ebaea", + "0x00000000000000000000000000000000001893928a8f5c0b449cfedddc616208", + "0x000000000000000000000000000000b547fa88f4cbcf2cc699e010df114ef488", + "0x00000000000000000000000000000000001855c0805882b38a94f77c4954ee63", + "0x000000000000000000000000000000941b647c5ae6e7f56b546111c81c74d0ce", + "0x000000000000000000000000000000000008bf6ae4485da8f6b85da2294eb827", + "0x000000000000000000000000000000745670ce1763611988377f9ac6564eb5fd", + "0x00000000000000000000000000000000000301e521f41d74a9ecb4d01c0420a6", + "0x000000000000000000000000000000cecdcb68e1d824e8ff0e1141bbb7241469", + "0x000000000000000000000000000000000024268af5f26bc3f68c9e01f1bb5f8c", + "0x0000000000000000000000000000000f14a7eb43fb641f0df2376be3c3142503", + "0x00000000000000000000000000000000001b76722b102ed6e7047b2ae4e5e231", + "0x000000000000000000000000000000383ced98d5cec8a4402527be6f5e7051fe", + "0x000000000000000000000000000000000022bb60f3feb6266eb8162fa04f39f1", + "0x0000000000000000000000000000007bd40dd0a298fc81c05dd9fed45875e3c2", + "0x00000000000000000000000000000000001c15c8c22696761205c439f69d5901", + "0x000000000000000000000000000000ea1e1b77dbba23394273a0fcc91d2f0028", + "0x0000000000000000000000000000000000296071a24eb3b9fd36d48bde2d940b", + "0x0000000000000000000000000000004faa047a8080c62ba37675f1025770dd46", + "0x00000000000000000000000000000000002be549ad4ae6dd609c8d19d2eafcb2", + "0x000000000000000000000000000000474079f7ebdc0d8d3a9eb468fcca6ffc07", + "0x00000000000000000000000000000000002ec8274bbb27ccec0982e7a9a251e3", + "0x00000000000000000000000000000002fe71f79eed108e0a5d260e85a99a4421", + "0x0000000000000000000000000000000000141c12a891f86b645a5cd828da5765", + "0x0000000000000000000000000000002dc9a42df3d5364488b418d610251242b4", + "0x0000000000000000000000000000000000290e01132bc34d5e15b6e02b4a759e", + "0x000000000000000000000000000000c16b5a7cce01d055cf28364a3d018dd5d1", + "0x00000000000000000000000000000000001847d542cff1a613b4d76aa92254de" ] - hash = "0x04fbc459fb16d984f4019cc33c1eb7d791a57a8307d473858a0d5b44c202e230" + hash = "0x157b40a6fa6e0c8b1aa9182c66ce9c22deec7a7a1507dabb4c78f3a05cb67dee" [[inputs.previous_rollups]] proof = [ @@ -1436,8 +1438,10 @@ proof = [ ] [inputs.previous_rollups.public_inputs] + start_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" checkpoint_header_hashes = [ - "0x004395c583aa5d8b61d95de30020015595c6ff15a98a908376053c285e760047", + "0x008ba0dbe6cfe546b12ee6dc5a840291257d16ba12a16df60755487233a993fb", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1472,33 +1476,33 @@ proof = [ ] [inputs.previous_rollups.public_inputs.constants] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x1302274e4a6bea5811bcdf1a547430241566bcecab5eb026ced46711d8e78501" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x0950cbcd8c47c28e14da74cadc13fee3f308aff298ee1c0a545a290ee67ba418" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x119b91fb8888367eb1a374fd489be3f5b034be672409857b5921f06d85523269" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + root = "0x2e2154ae5f5de018141654b73b05b76c29aa75ce17a7afd18e332b9f4a68606f" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.previous_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" + root = "0x0003e0e323f66d29e6a69f447a88e682190ce3e0a2546cb3e7f4a3ee4a31f1f8" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" + root = "0x003b613be7a069f0b767725574398f44f0e974cf9710decbe80ad27194d6acaf" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000030e6f24b2fa80" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,15 +1691,15 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x00c7d69903605c24450d8cc4111d6b01e31f84cacd7a01402f0cef9f221f27f3" - z_acc = "0x1beeba27d94c66514c35883c6684bfdc767455041a16225205c326fd2e2cb7fc" - gamma_acc = "0x088bb68a165bc27058fd98272ebe5f98cb66378ebc3d5c2639d6f59a66e134ca" + blob_commitments_hash_acc = "0x004de360c1e1bab9d63f6505559f9ecfb12acfff9830bc3cdc88df8f45d32e23" + z_acc = "0x11fd751039476db14d33f5dfbedb4d01c950538ac3c0f71c7135728dc2d0907f" + gamma_acc = "0x25987b100d9bb31cf80bca1387bfc5ff9c21c6763a86257c1beb8d1b1e1280bb" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x523fafae630b01cb88597856ec2ecc", - "0xf3db7c5d601e16ac93c5bbe54e70b7", - "0x31dc" + "0x76d28b50bbf7f3ebc188d45cf44828", + "0x18c38f30e3b353d07f425dfd06be20", + "0x413b" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] @@ -1703,37 +1707,37 @@ proof = [ [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0xdc0744575b26b4c4b7ee41dc7bee5a", - "0xab24ae0f1c266615b22dc3e9ffeecf", - "0xb738f18d636a06615561d266fd2d4d", - "0x19668e" + "0x5ad17b7163c2297e255d79877b272e", + "0x27fdadfadf26cb9c14f34cbeba8d72", + "0x073c70fc72f7ee0bb6cefb5a8aae8c", + "0x096bf1" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0x713d223616e8efe8cd4821efdde4f2", - "0x9a9a221be261841a9296b4d1eefd77", - "0xdb1af24cb0ccdcba1a7900c4fc1ad5", - "0x15b665" + "0x6d077d2d4c01253ae851efee4a316e", + "0xb1db1450e1242aa42ba0920b3d9f20", + "0x55d39e7ab76ad40bc787b9940e81bf", + "0x0e69bf" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x7cada12fe37b447eedceda7fcd7261", + "0x9d8e4fe065452dc53f81f57e8078e7", + "0x1f1b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x00fbe8b1a1759d43e9105404b28cac4aecff4e95738d70e4cccaac168b420e22" - z_acc = "0x176add1054eec877e808c664abb8ebc1baff3b041ab083467209f38654f8753d" - gamma_acc = "0x0de90da6a38dfce59b8d0f833c1bfe3e16e0eb560794083f8b7cc496599b710f" + blob_commitments_hash_acc = "0x0054b0e60dd99251c79b345af0a650eb735e6395ee1ca5f5893ed2806feca42a" + z_acc = "0x112392bc3c11c12fa4ad8d356e88405885d6c5cad0a8deb6c5d327fec7ad879a" + gamma_acc = "0x29b22e353acb5c3f4c65bcaee36dc525586e6d4ec02b814238b185c036571961" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xdf0081c38d524980410d61db922503", - "0x62517b1dfbda85451c0439cc0806e0", - "0x4d17" + "0x9eeff1f9087f93984225661e061c35", + "0xe0108be561dcd373c0668b4ec5ef22", + "0x6d39" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -1741,165 +1745,165 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x03625c74c2be70b1c311884cc7e585", - "0x6f620dfe7adc0c51d6ee59c585191e", - "0x0bed8a0ba276719689b549269aef57", - "0x18eb5e" + "0x324ba024e83da2c15ad2020bbda5b7", + "0x38475c821b5ad56bdae24c22d7bf32", + "0x8fb7d80d54d5f6aca83f50343ea8e8", + "0x198d52" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0x4683126714b4a2600b4aeb2ba09cb1", - "0x39d8a2712f7099eac558d4cb10484b", - "0xc15888f6212e3918f05f094bae5012", - "0x16bebd" + "0xa7fb54844284b6d32cca7c95d35d0e", + "0xa3453916a698e0fc33728beca0151f", + "0xe1811f8fe4e19f57769a81bb3b57e6", + "0x10ac0e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xeb2cbe158831bbbac06ed1f495640a", - "0x1557369df375c0edf8fdd550186e8e", - "0x5598" + "0x5a6907f3a4f705401f6afcafb6aa04", + "0x9734a8e972a375297d01ef04b4e54c", + "0x1978" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" + z = "0x1efd2648c273ceeac65dcf274d8fa604d1e4e97bca33d88471d5f2359a2caf63" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x7cada12fe37b447eedceda7fcd7261", + "0x9d8e4fe065452dc53f81f57e8078e7", + "0x1f1b" ] [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000011" sibling_path = [ - "0x233055a6920a13764c09bad668c75e48f8165a1894c37152ede5c09640a63b15", - "0x2c74d12f23eca40b1748248d689d41cb7ac4771cecfe01c3ae67dab27f821949", - "0x035c573a1f2634405482213a2b805e186d6b81073e2b7a5bd3f64c2e4e8bc21e", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x25ece109d362b4b8dbb8966f2fe94ddb217a6c63f7ac83b96c4f385ab2d03cf5", + "0x151ec971d9b291d78b1d405b001fc9a60d1bc918252466d6a4774554135802ac", + "0x29c4f2a137ff5c5b54eb911f6add38eb5ec9d139f54d95a7db432abbae472256", + "0x02dfab3acbc7708b1b3654912e946fe846568b8cb0e8af8da6a1845278664e55", + "0x2a6f812baf5176557f2f41b40fa4cb962d52e2e0c8ff7bf6b1fd7fe3a4223ac2", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000017", - "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x00000000000000000000000000000000000000000000000000000000000000a5", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000744c51f21e3dd8540bccf510ecc1d766be", - "0x00000000000000000000000000000000001e95a14c474168aaa5c9372f7a0abf", - "0x000000000000000000000000000000879082cb89dbf870ad3aa0d5da2ee67125", - "0x0000000000000000000000000000000000192656445ad3e71909ee40b06deeaf", - "0x000000000000000000000000000000e1909fba28938423134c0d59b76683863d", - "0x0000000000000000000000000000000000003e26f42f57c6e694c1e7e40b17c6", - "0x0000000000000000000000000000002a188fa67065c4bcc359cb5fd771dabcb6", - "0x0000000000000000000000000000000000160ac0b054344bb77bac08ac568575", - "0x000000000000000000000000000000fc970af33d774376cf02d202aaef414ba5", - "0x000000000000000000000000000000000021c2bd629cd0a533238d0ab831f778", - "0x00000000000000000000000000000068db97499ceb5bc0ee7a25f7b9474f2b8d", - "0x0000000000000000000000000000000000177f1d3bcc53dc664aeffa8f221982", - "0x00000000000000000000000000000071bf5b67b8cc7197d679fb2c9b28eff994", - "0x000000000000000000000000000000000004d0af735c0dba71607923878247b9", - "0x000000000000000000000000000000f9dfca16db1889889cabadcb3c086a4f27", - "0x000000000000000000000000000000000000ab2307518eeb29981848b3d1ee07", - "0x000000000000000000000000000000d6bffac49573916cfa0c7fc812ecbba5b6", - "0x000000000000000000000000000000000009655ac19e9e344b05e4a2fdce84c7", - "0x000000000000000000000000000000f7755de133f87eac380cca4fb5d60afa6f", - "0x00000000000000000000000000000000001d7cff28580bdd7cfbc17f159c5620", - "0x0000000000000000000000000000007f26c16746a68d8270726a65373e58c426", - "0x00000000000000000000000000000000001bcc461c1faa451fd1a0ed4683c3c0", - "0x000000000000000000000000000000ae6f4726a6e0f83357befc61e67a9ca001", - "0x00000000000000000000000000000000001ef4f7456ae1908e7a90de3d05cff2", - "0x00000000000000000000000000000017d5cef864c8bae29b2bec7712603477e6", - "0x00000000000000000000000000000000000c2947db29055b93c4ab5b26120a74", - "0x0000000000000000000000000000003a28bc16570b9a581942c4f4a5978e6455", - "0x0000000000000000000000000000000000297af63688110e42582a51c7fce3a5", - "0x0000000000000000000000000000008de422f0c439a79c6fe60b90f08dfe1498", - "0x00000000000000000000000000000000001c56ba82c1f1910eb581559e94ae3c", - "0x0000000000000000000000000000006fa0127d67c2462bec9945343f82c18b62", - "0x00000000000000000000000000000000001ab9b001ba47aa775c9094ccff2543", + "0x00000000000000000000000000000036d2157369305013c8479b661e9bffe8ff", + "0x00000000000000000000000000000000002c0aec83bfae212c5618a01dc5032f", + "0x00000000000000000000000000000079637952a9432b6c04de26b960419c2406", + "0x000000000000000000000000000000000016f81bd583fca03c4d6921866b2f4e", + "0x000000000000000000000000000000605da43776fb998e8f5a8f8f59493d1bdf", + "0x0000000000000000000000000000000000054fa1fe31a30b843030aa85747cc3", + "0x000000000000000000000000000000430e08eab747886838a73b7eb93d6a7049", + "0x00000000000000000000000000000000000fc7c1272750c481ab3aa64f760871", + "0x0000000000000000000000000000007b6c487b081cd42381fc2c5f460756fabf", + "0x00000000000000000000000000000000001c13765984a1558018db6833e2c706", + "0x000000000000000000000000000000e006291b1d02535c4f3f8796a584e253a3", + "0x00000000000000000000000000000000001497cc705bbd9bfaa96f7211db87d3", + "0x000000000000000000000000000000610db7fe4bfe6171822260ba25cf7fd7e5", + "0x00000000000000000000000000000000002cf5b96da296aa3d0d33e0897a3671", + "0x000000000000000000000000000000dbe98ae829fef8e64f045d80ed2aa380c6", + "0x000000000000000000000000000000000008c6b12c1e28f07325f3bc43328181", + "0x000000000000000000000000000000e11a616a8bf2e45900cb16ef7a387547a1", + "0x00000000000000000000000000000000000899d4536ca132a3255187d4bdcd3a", + "0x000000000000000000000000000000d7409e9b99d91622a75f1936d63d13ce21", + "0x0000000000000000000000000000000000010eb0051652a1e12fd910841b7380", + "0x000000000000000000000000000000a4d763a025d63693086d5e42b4dd09c983", + "0x0000000000000000000000000000000000057f7ee27662a1a3a797e9d5be3b23", + "0x0000000000000000000000000000000c00705cf8d7cb905d5bbea77f847bb1a1", + "0x00000000000000000000000000000000000ad3c7dbc5a0d102219b06b5425fab", + "0x0000000000000000000000000000003b3d6b7d7dfa41a114fdd2bb06d47fd826", + "0x00000000000000000000000000000000002e64810b091045697d64d9cd1590c9", + "0x0000000000000000000000000000004d92a88e43bae24502d046bf0ed7fe0623", + "0x0000000000000000000000000000000000168ebacff5cdf9c2ece95c81807f81", + "0x000000000000000000000000000000af15f3f90f76892655ae5ea104ab710df0", + "0x000000000000000000000000000000000012c00b8679fb65c6261e29481d20e1", + "0x00000000000000000000000000000097d1e3059e77dbcb559ae7ec59f4f1799c", + "0x00000000000000000000000000000000001bdc813cfa0a8f0b5b5dce352bfa5c", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x0000000000000000000000000000001aafcb2e2c5b4ee357c3cf460fa8614ed8", - "0x00000000000000000000000000000000000d7a76e33e068c44cecba8c22ae8d7", - "0x000000000000000000000000000000492fb683c7e0e137bc4e2ea86c37740b5c", - "0x0000000000000000000000000000000000206f337fb8b6d365b941ba4a8d8a9c", - "0x000000000000000000000000000000577c33d5c10b485d8c213d16ac4664dd62", - "0x00000000000000000000000000000000001dbb32af825db919015b2f62ac527a", - "0x0000000000000000000000000000004089798ec9503f6d851e3f36c8134fffca", - "0x0000000000000000000000000000000000258c2a8625473699411a82c908b205", - "0x00000000000000000000000000000039e66e47fbf20c042e57bc7b20b446fef5", - "0x00000000000000000000000000000000001a7afcba66a6d1561b93bbc1af74f6", - "0x0000000000000000000000000000002455981c887b06eaa76d3e33d58c191122", - "0x00000000000000000000000000000000001de23e2477dda30d3d197f197ac419", - "0x000000000000000000000000000000b116578da6236d15e82788782d873df37f", - "0x0000000000000000000000000000000000269873dc9e65f74c789d8a58db0077", - "0x000000000000000000000000000000ee7cf9691c5ad6f6e90099bc5d04408a73", - "0x0000000000000000000000000000000000284704a1b995c3a251204d4c6c01a2", - "0x0000000000000000000000000000004d63dd4c7af54fcf2e481be7293211350b", - "0x000000000000000000000000000000000003805c1292ab954706ed7e0cca9281", - "0x0000000000000000000000000000006572fd92d3bf1845cceeef0a7f0d044f8b", - "0x00000000000000000000000000000000000641fb756d60be4b60f5c0a76f6930", - "0x0000000000000000000000000000003c9242ea4df53612f2943b641741fb9359", - "0x00000000000000000000000000000000002ebb3334e2b6b702d04d94e2c6a5c4", - "0x0000000000000000000000000000004be64b431a5a816b719da16e8e02535892", - "0x000000000000000000000000000000000001339afc1567176d3527faaf56c0a0", - "0x000000000000000000000000000000377b1426e1e1857f300907c39678bab9d2", - "0x00000000000000000000000000000000001f460fe6b26626b496ca4a53dc2103", - "0x000000000000000000000000000000093cc8cd227239606f069fb8b0d89be197", - "0x00000000000000000000000000000000001d6ddaa3a6362872d4ad6f6ffdf26d", - "0x000000000000000000000000000000aaca84b607b945c22f9380968dca37b3dc", - "0x000000000000000000000000000000000006e37c218b5ddd9fe30f2d074af3ac", - "0x00000000000000000000000000000050ac5a5bfb200bb882053095cb7707c6c4", - "0x00000000000000000000000000000000002f598bce6b07a71ea18c892626f896", - "0x0000000000000000000000000000005981f7adfea2cb4c98608311c60dea02c0", - "0x0000000000000000000000000000000000289d38f2a30b52ebcfcda8ef0e441f", - "0x0000000000000000000000000000001b49052b5e34aed999b8b52e9496cbcc97", - "0x00000000000000000000000000000000000deaff0903f20c3a8781e8f36aeb29", - "0x00000000000000000000000000000013595eda489c2581add81a3054c537cde8", - "0x000000000000000000000000000000000016c291915bad74124a1089dd4e4b1e", - "0x0000000000000000000000000000009f60b0b20e50c2b872bbc2eba64d13d4dd", - "0x00000000000000000000000000000000002126fb29255849ef1cadd1b85f4ca6", - "0x00000000000000000000000000000018aa24e4df9dd2e6b857b79eb65063f442", - "0x00000000000000000000000000000000002bb078b426453481a11b32c23b5f17", - "0x000000000000000000000000000000471c619f4de581893a418a64ae1edbbf33", - "0x00000000000000000000000000000000000d33fe66c2a1ab73aa83ef5f9d6c1e", - "0x00000000000000000000000000000003cef58ea44be7d8c5d8d1639f1546b9d3", - "0x00000000000000000000000000000000001a5ca4c297a12ec7cbd3567570c84b", - "0x00000000000000000000000000000012c623f77652847ff7f2c87290036e946c", - "0x0000000000000000000000000000000000032e99aff3cb68a95f2493b6103618", - "0x0000000000000000000000000000003cabab340137b323e877e56cef1f8dbed8", - "0x00000000000000000000000000000000002986530e89170feacfa3abf1dc2bb2", - "0x000000000000000000000000000000b1af0f91346433e1a924e81e36062d5b12", - "0x00000000000000000000000000000000000fd850761ae3567a47c5015f5a49db", - "0x000000000000000000000000000000e96960409cc77dc83c19eb6c4a65a443bd", - "0x00000000000000000000000000000000002bc73c5cbad6a06c445f8c13667a0a", - "0x000000000000000000000000000000251d1a42e82570c38d16a0acb91075ff6f", - "0x0000000000000000000000000000000000252ab69e8a5eb85a7f07767a0b4cbd", - "0x000000000000000000000000000000775b0cbb24a05ae474393667bb23cbff4c", - "0x000000000000000000000000000000000020f65bb075b316367c63e1a78fa27f", - "0x00000000000000000000000000000045b7ffafdcdf6888cc39d9dca42576a396", - "0x000000000000000000000000000000000013c3af9f7d3e8d077e8765d6138d0d", - "0x00000000000000000000000000000061e4e7505a7274b9b128765e285681b6da", - "0x00000000000000000000000000000000000f860b75cc5deb976b9b05b8746e6b", - "0x0000000000000000000000000000003df46a7142e10868dc5980f6d2e13da00e", - "0x000000000000000000000000000000000022668e231bb6db8db665c18b46974f", - "0x000000000000000000000000000000dbf91bf91f60763e0c56fe43a8add14ab3", - "0x00000000000000000000000000000000002b6652da5918a262675f7b0ee80f9b", - "0x00000000000000000000000000000064092190c017f3620d4d39dad54d2f659d", - "0x00000000000000000000000000000000001be569b3318816be8bfafaeb38a0fe", - "0x000000000000000000000000000000e3d69f89db31d9400f666e59726928ef4c", - "0x00000000000000000000000000000000002757caef4b3a637a9aa7b191b32627", - "0x00000000000000000000000000000019852bf5ca19b13351bddedbf4335cb53f", - "0x00000000000000000000000000000000000b3498c424d7206a9dc3b30bcf4f7c", - "0x0000000000000000000000000000008fb1973e9d508a1b5258225627b8ecbfb4", - "0x000000000000000000000000000000000026f9f578430377663d282fe858e493", - "0x000000000000000000000000000000655c16efe629ce3bbb6555bc125d328ea9", - "0x00000000000000000000000000000000002c6140875c92938e10d156a43b9a9b" + "0x000000000000000000000000000000a720f425c05a4825b46e027afd0a6fd671", + "0x00000000000000000000000000000000001fcf1da494426fbf2621511cbd70eb", + "0x00000000000000000000000000000018a2e7cbf823397368dc4b87db4c644619", + "0x0000000000000000000000000000000000052e92af9a02920e4e179c4f67214b", + "0x000000000000000000000000000000825a267e5cfd171426338e2d9b3b9838d1", + "0x0000000000000000000000000000000000171fc66ae3ce33b767fbab8d5fbbdd", + "0x000000000000000000000000000000d5c49f2d00924b287efe89dea6879ff77b", + "0x000000000000000000000000000000000011f85546a9cd87a6b2b635c4771b94", + "0x00000000000000000000000000000027f61f3b9d8cd56f2a70ca35c2ba7e31a8", + "0x0000000000000000000000000000000000025050331a4428aed5b520dca6bd63", + "0x000000000000000000000000000000a41247254c9c0a191ebf6b4b27818cc313", + "0x00000000000000000000000000000000000be606e57a400a3f8579ce40332a7a", + "0x000000000000000000000000000000ffccc8bdab452ad48ae9f3a068de887c8a", + "0x00000000000000000000000000000000000c2a7bdf80e4f60a5ac20e3b9c6544", + "0x000000000000000000000000000000b7c80a222c2a6ae46bc9f64e581bf7271e", + "0x0000000000000000000000000000000000205b8c3084d3f5bb5db7d9590acaec", + "0x0000000000000000000000000000002a609fcebe46daf0c552761c19228be9c5", + "0x00000000000000000000000000000000000947b7d62dd0fa528f93ad462244bb", + "0x0000000000000000000000000000009dff2728b1e8ece8f977dd5f17c2c78105", + "0x00000000000000000000000000000000002d440b35f618fde819e1506404b866", + "0x000000000000000000000000000000ac37642801b1ef63703d72c94a15203772", + "0x00000000000000000000000000000000001bbe645b815c8305a5626fd64ed05c", + "0x000000000000000000000000000000ca1770abe5384c224b2cb8623ef53a891f", + "0x00000000000000000000000000000000000ea2e1c7b5a6b648868a1fbda389d5", + "0x0000000000000000000000000000008d6c11553db2a55004627c023b0e249573", + "0x00000000000000000000000000000000001cd0294ac6bce284bfd5e7c2a052a4", + "0x000000000000000000000000000000452503cff155bfcdc7a19e5f332b377870", + "0x0000000000000000000000000000000000150185e04d84d9b6ffbd2bb9052295", + "0x000000000000000000000000000000f3d6ba952c2b5b06d98e0b38222a510fce", + "0x0000000000000000000000000000000000277241267c9a7ff692b8f4a91039a7", + "0x000000000000000000000000000000a6e09a49d41c587395657bf22bae9f860a", + "0x00000000000000000000000000000000001ccb77f5c0bfe18ce719db97108493", + "0x00000000000000000000000000000009e276023bea7cb392a3ff9f7e2ecf364e", + "0x00000000000000000000000000000000001eb222312f45556a06e2c1a09eff73", + "0x00000000000000000000000000000017439a8fd7a316e174faabb48101bbf30e", + "0x00000000000000000000000000000000001b50b9d5fe4c43d61fc72fb8667869", + "0x00000000000000000000000000000094d24031f5c3c0f952282a186f2b2771a0", + "0x0000000000000000000000000000000000114af0d951e8098442447c796dd53d", + "0x00000000000000000000000000000043ff61c245cfed1afca45f10338f26f398", + "0x000000000000000000000000000000000029d3ccaf2bb1347618eab89bd09dff", + "0x000000000000000000000000000000151aeefea0cabef34bc27be650b1ea310a", + "0x00000000000000000000000000000000000f2f9770fce59054a8f14ccc9cfc71", + "0x000000000000000000000000000000344430ca97860eec6bef9811cf0248309d", + "0x00000000000000000000000000000000002fc0aa17a61a27fb1695ec956e1762", + "0x000000000000000000000000000000ea7eab06aeb8bcdd1119cd6dc0c4d5a928", + "0x0000000000000000000000000000000000009802fdcab28040b969b68ab9304a", + "0x000000000000000000000000000000be464a1807845060ccd8ed02952dff3c42", + "0x00000000000000000000000000000000001261948934bec645944b279144c0c6", + "0x000000000000000000000000000000e939eb8746a3940d252f066182db1ebaea", + "0x00000000000000000000000000000000001893928a8f5c0b449cfedddc616208", + "0x000000000000000000000000000000b547fa88f4cbcf2cc699e010df114ef488", + "0x00000000000000000000000000000000001855c0805882b38a94f77c4954ee63", + "0x000000000000000000000000000000941b647c5ae6e7f56b546111c81c74d0ce", + "0x000000000000000000000000000000000008bf6ae4485da8f6b85da2294eb827", + "0x000000000000000000000000000000745670ce1763611988377f9ac6564eb5fd", + "0x00000000000000000000000000000000000301e521f41d74a9ecb4d01c0420a6", + "0x000000000000000000000000000000cecdcb68e1d824e8ff0e1141bbb7241469", + "0x000000000000000000000000000000000024268af5f26bc3f68c9e01f1bb5f8c", + "0x0000000000000000000000000000000f14a7eb43fb641f0df2376be3c3142503", + "0x00000000000000000000000000000000001b76722b102ed6e7047b2ae4e5e231", + "0x000000000000000000000000000000383ced98d5cec8a4402527be6f5e7051fe", + "0x000000000000000000000000000000000022bb60f3feb6266eb8162fa04f39f1", + "0x0000000000000000000000000000007bd40dd0a298fc81c05dd9fed45875e3c2", + "0x00000000000000000000000000000000001c15c8c22696761205c439f69d5901", + "0x000000000000000000000000000000ea1e1b77dbba23394273a0fcc91d2f0028", + "0x0000000000000000000000000000000000296071a24eb3b9fd36d48bde2d940b", + "0x0000000000000000000000000000004faa047a8080c62ba37675f1025770dd46", + "0x00000000000000000000000000000000002be549ad4ae6dd609c8d19d2eafcb2", + "0x000000000000000000000000000000474079f7ebdc0d8d3a9eb468fcca6ffc07", + "0x00000000000000000000000000000000002ec8274bbb27ccec0982e7a9a251e3", + "0x00000000000000000000000000000002fe71f79eed108e0a5d260e85a99a4421", + "0x0000000000000000000000000000000000141c12a891f86b645a5cd828da5765", + "0x0000000000000000000000000000002dc9a42df3d5364488b418d610251242b4", + "0x0000000000000000000000000000000000290e01132bc34d5e15b6e02b4a759e", + "0x000000000000000000000000000000c16b5a7cce01d055cf28364a3d018dd5d1", + "0x00000000000000000000000000000000001847d542cff1a613b4d76aa92254de" ] - hash = "0x04fbc459fb16d984f4019cc33c1eb7d791a57a8307d473858a0d5b44c202e230" + hash = "0x157b40a6fa6e0c8b1aa9182c66ce9c22deec7a7a1507dabb4c78f3a05cb67dee" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml index 72539e72bd18..ba381a8610e3 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root-single-block/Prover.toml @@ -483,70 +483,70 @@ proof = [ ] [inputs.previous_rollup.public_inputs] - timestamp = "0x000000000000000000000000000000000000000000000000000000006a4d22fd" - block_headers_hash = "0x2efa5fe41af017572583e705fc35f6b2eede2df0257526bbee6536817b583a11" - in_hash = "0x00de7b349d2306334734e4f58b1302a6ed5a6c796a706f6597a5641b6d468223" - out_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_fees = "0x00000000000000000000000000000000000000000000000000198e45581dc500" - accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000008992c" + timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" + block_headers_hash = "0x169bbf26eccce6074f9e6ff7f75dc601fbb2f50ad0911698e934690f81b386e2" + is_first_block = true + out_hash = "0x00746f2611b7b24448263e846ba73bf1861fc6e68dbc605414405a520957a902" + accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollup.public_inputs.constants] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000044" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" [inputs.previous_rollup.public_inputs.constants.coinbase] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.constants.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000002f8e08bc0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.previous_archive] - root = "0x1842a814b068f699565f4df77ab9139f1cfab687ef959bf92ba0bb3adf93d8dd" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollup.public_inputs.new_archive] - root = "0x1302274e4a6bea5811bcdf1a547430241566bcecab5eb026ced46711d8e78501" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" + root = "0x2273e2d62f8531ba33939e5dc5790c5e03aeaa738012eb9fb81c0b51c2b0f5b6" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollup.public_inputs.start_state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.start_state.partial.note_hash_tree] -root = "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" +root = "0x2590f2aab19dd791700b4a43d3f52bb88ef2409a3731da8e848663559202e4c6" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollup.public_inputs.start_state.partial.nullifier_tree] -root = "0x1c13b69ab508e560dc7c25e4f77aed48439749310a58609f31475734efe7287b" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" +root = "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.start_state.partial.public_data_tree] -root = "0x073b8408b98dbac4d5f0c84d47161ee954b8d8e7920e620bf14bc44cb50d07d5" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.end_state.l1_to_l2_message_tree] -root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001c00" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollup.public_inputs.end_state.partial.note_hash_tree] -root = "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000180" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollup.public_inputs.end_state.partial.nullifier_tree] -root = "0x00260be7577812f167b02eb1c2fa10efc5f169fe19845ada374d4c1518af35f4" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000200" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollup.public_inputs.end_state.partial.public_data_tree] -root = "0x2536a3212b711359308d274b8a92fa44465b6ce091dd9369c1331f1ffdeaa8ca" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollup.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -567,2788 +567,3413 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollup.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000087" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a1f" [inputs.previous_rollup.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00260be7577812f167b02eb1c2fa10efc5f169fe19845ada374d4c1518af35f4", - "0x2536a3212b711359308d274b8a92fa44465b6ce091dd9369c1331f1ffdeaa8ca", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c", + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" +] + state = [ + "0x1a60801c6e39494965d70acf32711082883e0977a0fdf6bb6eec7bca1de6d3c6", + "0x21c2eb4846d3c83a6f55d19456ce9cee977ece418aca61c7e10b71de2e9adfb8", + "0x0cffa534e50144052e7b439198499853b2f3cb163604a3dc4774716591692f7a", + "0x0222cb175cd623cb6b73e0126c9fbb1e6f7675be2750c0df99fb3e7ef902bcf4" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + squeeze_mode = false + + [inputs.previous_rollup.public_inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.previous_rollup.public_inputs.start_msg_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" + squeeze_mode = false + + [inputs.previous_rollup.public_inputs.end_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollup.public_inputs.end_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" ] state = [ - "0x09c5a5ce332193157aff3f33e91b102d9e4d89d1bc75f3b3f35c15671c59c0ed", - "0x12dec657347c4b34a75cd95ad1e3bc343bb7800797a8c0a4036f88793cf0e32f", - "0x187c15e04638cd020e01c721b80acbe5905daf8670de1219385cc7e6838b25b5", - "0x22b3946d4e314d5204db5a09eccd5fddfec86678582867a5bbda12432a2dd64f" + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollup.vk_data] - leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000b" + leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000a" sibling_path = [ - "0x02904385b9df599026d8b15d1015623ccc1b22881f9cdae1f57b519af5580631", - "0x0f63dbbd49436fb3261c320d539cfbec7d375147081e6787c7ae161d25a9581d", - "0x0a2818ba5dd5624d91f012822293d4135b8958ec1d8ab6cf952ee3de138bb8c4", - "0x0787c8cc4cfb80390c27cdc17cb24ae198faad7989508690070b3cf40a2ae4fd", - "0x2a17b9f268be22deec2941ce8de06f485f2d164710a5177d262a4ae86b7c351f", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x08aa7cad4ad4cc2aac0bc46bd25ebe810137ecf1cf2552e254cfb5906108d5e8", + "0x0fce3d763e56ccd931e3e9536681a7df5fe092534a25d45edf794268d3d86405", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollup.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x000000000000000000000000000000000000000000000000000000000000005a", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x00000000000000000000000000000024bc9db45b73e7fb4b2487a72e7a279fba", - "0x00000000000000000000000000000000002769a1528c44352e10b39f5bfea4a1", - "0x000000000000000000000000000000739f1925ed35ea2e2ca65ccb78e791f9ad", - "0x000000000000000000000000000000000018e6f35c3cb0460b3905f75ae7f4ae", - "0x00000000000000000000000000000060ddc6dad1ed0a6c59f22ebe8b844f6189", - "0x00000000000000000000000000000000001cd99394c4e85c1c915aa5beb9ce81", - "0x0000000000000000000000000000006dd43fb76256eb6d974b8f1ba8a8fa2f09", - "0x000000000000000000000000000000000016c881187c584a799be44d946986f9", - "0x0000000000000000000000000000008b0c7ba6da9f1d46c37b98cb132ddf095e", - "0x00000000000000000000000000000000002e5f96015a2d5b5e730b5a06838057", - "0x000000000000000000000000000000d3d571ca1486c4f824709e534f6391edf6", - "0x00000000000000000000000000000000000f3516049f253ca5bc12060df0f136", - "0x000000000000000000000000000000519d47be7b86bc7a814add890c8885f2ae", - "0x0000000000000000000000000000000000236167a2385bdd1c41518b152fa7ab", - "0x000000000000000000000000000000bfaf64390d931434b94523a713dcdcfd9b", - "0x00000000000000000000000000000000002ed601cb78e61cc724cf9de221fa9e", - "0x000000000000000000000000000000048d30fb3c70be3e6941f157cdd951b40c", - "0x0000000000000000000000000000000000134f003d3de1142df0709afe3a7e4c", - "0x0000000000000000000000000000001142be6efed3ac936ed3f1c413f464fc83", - "0x0000000000000000000000000000000000170c59933623a935ba06ef80525392", - "0x0000000000000000000000000000005286e1d6fe903602a25c2cb759ebe8c1d6", - "0x00000000000000000000000000000000001025946b613678c4c528cabfb3f67d", - "0x0000000000000000000000000000003d54230920d0431a760ef6d2d9decedf77", - "0x00000000000000000000000000000000000fe45d06cdb9e695183f54891c0818", - "0x000000000000000000000000000000c5f1918b891092e77d3f3e2e67ecebf5e8", - "0x000000000000000000000000000000000026d3f4339318924af66ebfdd5e577a", - "0x0000000000000000000000000000005cb2f39fb3bdaaeb130f34e1870346aacf", - "0x000000000000000000000000000000000013160f5368de16f01b817104643457", - "0x000000000000000000000000000000e8f2964ecb996ae83ee78e3d489a3f0ec2", - "0x00000000000000000000000000000000000de27bd975f399f37468aa9bdd3984", - "0x000000000000000000000000000000916a8213edb121f5c66404923cc32d26f4", - "0x00000000000000000000000000000000002adc79542e8feadf9aa61ba1bcf584", + "0x0000000000000000000000000000006f5cbaecea05451d444650bdea8e61b182", + "0x000000000000000000000000000000000003479107e567fe999d4bcf4d149f05", + "0x000000000000000000000000000000817a621003a78669fd4c5efe4ce9f48b20", + "0x00000000000000000000000000000000001f5d4fdd106cc0d5926f18488de249", + "0x0000000000000000000000000000004def8c8d386a5ddb15a409e0b8c3cb523c", + "0x00000000000000000000000000000000000d8ec653c6796515e55de423944bbe", + "0x0000000000000000000000000000001875441e4dc34a68aa9eb9710ea9a69a3d", + "0x000000000000000000000000000000000006501b36e5b221865b9f0bacdc6f48", + "0x0000000000000000000000000000007aeda376651cd10f81d9a1cb2d2f2de234", + "0x00000000000000000000000000000000000997d206556a889afa1f018aef9e7c", + "0x00000000000000000000000000000037b8490f198c527321c0233419a45f320b", + "0x0000000000000000000000000000000000235a1cde377b2a58a6a52db578c9aa", + "0x0000000000000000000000000000006ec8c579f44f99222d48c632ce454e6e5e", + "0x00000000000000000000000000000000000b62178f59ff76727395d2a236cea3", + "0x000000000000000000000000000000979cd8a67c3ca0b0eb914ab7c631d7bdaf", + "0x00000000000000000000000000000000002f87ff53ec36e4dd0c128a396d0552", + "0x0000000000000000000000000000003f7f93923d979d888ce6cd1ff18e379e08", + "0x0000000000000000000000000000000000044e6893438ebb4fcce14e54a3df8c", + "0x0000000000000000000000000000007c2624df9d910b29562a2da3af632368f4", + "0x000000000000000000000000000000000014ff364f21ccbb513e4477e53a0769", + "0x000000000000000000000000000000afec5e87c688b9da518285e1ca4cfe0eaf", + "0x0000000000000000000000000000000000260792a11fc74d7b7756b1ecd4696a", + "0x0000000000000000000000000000000dcea3833792fe8eaa9f710222b40e4881", + "0x00000000000000000000000000000000001a5af3368e40b4b1647906e3718cec", + "0x000000000000000000000000000000b5002fef832fc1b3823da41a254e6bab6e", + "0x00000000000000000000000000000000000a86f3d9a36ffb0685a79f5fbdc21d", + "0x000000000000000000000000000000efafe38b21882ca83d377a27b3ee30dddd", + "0x000000000000000000000000000000000013e5ccdec53d141060b17aced1827e", + "0x0000000000000000000000000000001fac526a022e4eadd6cb49cbfa849d0369", + "0x00000000000000000000000000000000002f7983c3cb5f516012989beb2c7093", + "0x000000000000000000000000000000d9a0d63cd9fda9fe542d87cb269caa3775", + "0x00000000000000000000000000000000000531d4888e80e70530ebd178ce6328", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000e6c6276dfc9b16e2931ef96898d84a82dd", - "0x00000000000000000000000000000000002e66f12a8a85fd18c91ca86c28060d", - "0x00000000000000000000000000000082a662ace0ebb2a55d6aa40a17c6b81e82", - "0x000000000000000000000000000000000003c7a450b7335348b6ce339f0b0cc6", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000b1adf6ee18274cb79bbaa249551703c604", - "0x00000000000000000000000000000000003018cc9a7ca8f8ef4023c27afbb616", - "0x00000000000000000000000000000006d726e31e712b8c8eb97fe520bb343a59", - "0x0000000000000000000000000000000000105db0db8ce9fbb93b3ee5cb90ad31", - "0x0000000000000000000000000000003a2e45fc6e2aa706adb32a0a64098e4e47", - "0x00000000000000000000000000000000002bc247d2a4cfdc6e7fea304220104e", - "0x000000000000000000000000000000093b7a0052b8f9d68df7e3dc5a4fb741fe", - "0x00000000000000000000000000000000002a7cee714ffd8e1ddf9ecddc5cf5e4", - "0x000000000000000000000000000000974c9ee433a23c20e6be26c38fe6a50f38", - "0x000000000000000000000000000000000000f384f19fec9dd45adf40cff33ea3", - "0x00000000000000000000000000000053b77cd88598168f8cbe8c18ee3662049b", - "0x00000000000000000000000000000000000177847cd2cc4ed48594f74560c178", - "0x0000000000000000000000000000001dcd9fc2d402b5463e3031c831b2b02bcd", - "0x000000000000000000000000000000000006d3280a20894689a5963e7efd000c", - "0x000000000000000000000000000000ef357aec8006ddb8396a3060f2af6f5757", - "0x00000000000000000000000000000000002203fe128291e0a96d5668c174f510", - "0x0000000000000000000000000000001d9eb9e9ca5c4749bedd1dc0db26e0b3e9", - "0x0000000000000000000000000000000000156f732f26d187f0af354881b02ff8", - "0x000000000000000000000000000000e0e35d86a2d0f68808a1f18320246dc3ca", - "0x00000000000000000000000000000000001b56dd24e59f145cfe958f31ee11ba", - "0x000000000000000000000000000000f6c162cdbd5e0907845b07814a38a5b70d", - "0x000000000000000000000000000000000006a9cc39e3832513e3db5ef5fe1356", - "0x000000000000000000000000000000449ce17638109f970b0f8b81d15ebb189f", - "0x000000000000000000000000000000000017eb50498175605c0fe7b80e445a04", - "0x00000000000000000000000000000002692c690e0806130ed7743f59ba8d5b57", - "0x000000000000000000000000000000000024885f0dad88c4e8ae637f7fa6e975", - "0x000000000000000000000000000000b79190581f9e7e22443deba5384fc79d42", - "0x00000000000000000000000000000000001c75f312d63b47dd4dded27cb0b01a", - "0x000000000000000000000000000000c73b713c18ab6d4a1427ccc6e416d6905f", - "0x000000000000000000000000000000000022b02f015c9b720cc74b56b0c0ad55", - "0x000000000000000000000000000000419241ffffa1f54d8f6399b195afc611a6", - "0x00000000000000000000000000000000001e96a8328d780d5b30c34f5778a16d", - "0x000000000000000000000000000000d256cc1d92056e3bf5e975cfe6449dbbe9", - "0x000000000000000000000000000000000006c6686cc48ddabf62c3bc1b0ffd22", - "0x000000000000000000000000000000e40d6630a0ae06492ec94b92103ad28108", - "0x000000000000000000000000000000000021d4f96cf23fe7998f35eacbf6bc76", - "0x00000000000000000000000000000055b3fb429246925b30fcee9ba51ff0d015", - "0x00000000000000000000000000000000000abbdd6aaead814196aa41542d15eb", - "0x00000000000000000000000000000069bac93130a7153ffd637bbc1696cb6cfe", - "0x000000000000000000000000000000000023a6843b4984921d6449c8c0861d99", - "0x000000000000000000000000000000255db62b6d7cdc3c9312a447d5bf2d49cb", - "0x00000000000000000000000000000000001a6be8b693df2c6ca087c4dc8286c7", - "0x00000000000000000000000000000000e11dc62dddeb3931735dc70559fa9938", - "0x00000000000000000000000000000000000fd5e82445a60979c1838f9d475ba9", - "0x00000000000000000000000000000086b491848efcba147344cf4623c5011e84", - "0x000000000000000000000000000000000024e299ae28d4f8e761778550a163ab", - "0x000000000000000000000000000000cdaf442fb6221a53909c441f5ae9a4e68c", - "0x00000000000000000000000000000000001bd8ab0913cac43548f2a8206f8d39", - "0x0000000000000000000000000000007af5cd832d815f050ff25d77bc7974ba7c", - "0x0000000000000000000000000000000000032946a4fc0df5dffe84eec2d5812c", - "0x000000000000000000000000000000d486e2809977417d0e65a6eab3df781940", - "0x0000000000000000000000000000000000286fa51b17dc4d47818fc47cc7790c" + "0x0000000000000000000000000000004825252ade380d19db46d6575217746594", + "0x000000000000000000000000000000000024731c0db92b493baabc40063c83c3", + "0x000000000000000000000000000000b9b9fe4557dedf94852907d3fa5b9b9696", + "0x000000000000000000000000000000000005ea5995e8d36af0353c578b75e099", + "0x00000000000000000000000000000013e4441cf7e4a6a389a39dc21c24275be2", + "0x0000000000000000000000000000000000017aab51c397a2d57778ebe5022782", + "0x00000000000000000000000000000009adaeede4203a41f991031ec50f09bb98", + "0x00000000000000000000000000000000002c9fa3c370cbb1f1bc9128d27307d8", + "0x00000000000000000000000000000086f83dd5fa9178c3c683137ef6a3018c50", + "0x00000000000000000000000000000000000af8d38dc8b77bda3980c013658848", + "0x0000000000000000000000000000007307ee1df3133617f2e5a4d2bbb01f449f", + "0x00000000000000000000000000000000002e27ed3b0658fb9d44ebdb9e459679", + "0x00000000000000000000000000000037ec6f22980fbc5a795d816788a7c7fd87", + "0x000000000000000000000000000000000022973f4a5a82fd556aad37856af147", + "0x000000000000000000000000000000f6f48a91dac1f229b2b35e0fe3ef98abfb", + "0x000000000000000000000000000000000011b923ec095c6746d167d68a4b20e8", + "0x0000000000000000000000000000002d4825c2a902a49bad97fcf3510dea717e", + "0x00000000000000000000000000000000000a00b7e38d47dba44d1fa8d9e462d8", + "0x000000000000000000000000000000f14f2adda7c6729037603c11f6df57543b", + "0x00000000000000000000000000000000000bd236e34f1859cda4709a1895cdab", + "0x000000000000000000000000000000d3678bafd3a8f024c9373604ff3b9445e5", + "0x00000000000000000000000000000000002e41d5db4cb0fc20648504962c7e38", + "0x0000000000000000000000000000004ea6f803bdb1c654c7a3e38c2fc5747710", + "0x000000000000000000000000000000000012b2e307e4788fa75f5058585d1ba3", + "0x000000000000000000000000000000566e9ecd91d1f1e63ba3ab3be205654c3b", + "0x0000000000000000000000000000000000270e58fd161f7a04e01d3f7b1b83dc", + "0x000000000000000000000000000000ff5d0e9d02a09664c7d93118ef929c0a47", + "0x0000000000000000000000000000000000236fa5dc0778c6de032a4732949c9d", + "0x000000000000000000000000000000ddd9e0852b28bcbaea93e277318504814e", + "0x000000000000000000000000000000000007d6bc603a469476d4efeb703c96f8", + "0x00000000000000000000000000000016c13eb7f20515c6b070eafb82c915e8fe", + "0x00000000000000000000000000000000002bdc3630610f06e06f8099b99f9e7a", + "0x000000000000000000000000000000241ddb92f8ae1e326c984a3c8f47a12db1", + "0x000000000000000000000000000000000002dbd010b0084559d801e4c2d2ffde", + "0x0000000000000000000000000000002b43564f5d9b01995c40e88b1c478cd214", + "0x000000000000000000000000000000000006ea5b76788e217c4ad6b5b4cb7a77", + "0x000000000000000000000000000000f2207989267e09dfdd21af3e6d3f7208a3", + "0x000000000000000000000000000000000012ed88b873a6415ebb5c336e1a156b", + "0x0000000000000000000000000000002e58db07b222abf8bbbd82745d4c5bd3e1", + "0x0000000000000000000000000000000000087a16711c6f13b933bb88dcc67e1e", + "0x00000000000000000000000000000098605c632e9e02acfc06bbc669aca20d14", + "0x000000000000000000000000000000000004781e9898ceecda5edb827e9cfecf", + "0x0000000000000000000000000000005713fa4f0b203f8c51ce30e3fc93a114c4", + "0x0000000000000000000000000000000000095c115cc3b5c56ecf1f921f8a77df", + "0x0000000000000000000000000000006cafe020b87be36043acfa0a4e2e0cbad0", + "0x000000000000000000000000000000000009ef0d12f9917c5f608fb46c9c966a", + "0x0000000000000000000000000000003e1da98baf20047b8bd089da008dc9eb42", + "0x0000000000000000000000000000000000249fd1bfd073d63427439be7fd32d4", + "0x0000000000000000000000000000005473f61603722398381bc3b9b76ceabf81", + "0x00000000000000000000000000000000000b2d3974e833f79e54cb3635735731", + "0x000000000000000000000000000000fa04f0e731560504b7e8cd6f98ed9030df", + "0x00000000000000000000000000000000000fad8fed1c64a24d0372f94e5fc848", + "0x000000000000000000000000000000c7555d7de39ff9e296bff643dbcbe6064c", + "0x00000000000000000000000000000000001b14295dc9d111239d74938f693816", + "0x0000000000000000000000000000009aa5b631c8f4a38c84fc951f342bf0b0c1", + "0x00000000000000000000000000000000000afce535ec4e8297e658a17bb2c10d", + "0x0000000000000000000000000000009d802e75ee04c8fb7f16c323d2429a753f", + "0x000000000000000000000000000000000004a349d8396da0cc771c60bc27aea4", + "0x000000000000000000000000000000726aca87cd8839b9f818cd3c2935eec8b4", + "0x00000000000000000000000000000000001a8ece7459ac674b0ddd7034f98eb9", + "0x000000000000000000000000000000f8536512901c785a7f5115c43342ddc6f8", + "0x00000000000000000000000000000000000072fd49b98bc6a5e12f19a71660e1", + "0x000000000000000000000000000000afd1beb8aa6678b745eda4ad15f2d15dfa", + "0x00000000000000000000000000000000002b77544ff12d0e2f47fce3a71554dc", + "0x000000000000000000000000000000711414c25448a023ed4c4e5fdb6e0e33c3", + "0x000000000000000000000000000000000028a646b752990587f8abf8c61fb786", + "0x000000000000000000000000000000aad5387ba3705168bd302697dc1e2642f6", + "0x0000000000000000000000000000000000092eb9577b43046f7383d7291397a0", + "0x0000000000000000000000000000001b1ed02eac6838d26a14d90f94db5530fd", + "0x00000000000000000000000000000000003012c7aa16e652fb75d00b7fa2efb8", + "0x00000000000000000000000000000021075698a70f24583676fd7c407804f7a9", + "0x000000000000000000000000000000000013128a0aa4c95211b93752f88e2b88", + "0x000000000000000000000000000000b642dc7435425bfe4a8da196b420fc3943", + "0x0000000000000000000000000000000000209710d543a64c24da3519333cf90b", + "0x0000000000000000000000000000001bb29c4382ed4d5d56bd2dda0e3a10fa94", + "0x00000000000000000000000000000000000ec2c8584b61af4dfbbe3a262b437b" ] - hash = "0x23038e9c150580495cc7acd85a02a273bf3431573ec9c266d6f2982af4e0dcf1" + hash = "0x0b5802278aa8eb5ab2fcbd2c97df88eaf72e224d2c9e2bd6677b39ff3560d1af" -[inputs.hints] -previous_archive_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", - "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", - "0x09308d0807f5aed64dd43d2014519a161c32f9a52ea75992cc18bec0bcde410e", - "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", - "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", - "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", - "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", - "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", - "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", - "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", - "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", - "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", - "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", - "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", - "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", - "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", - "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", - "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", - "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", - "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", - "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", - "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", - "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", - "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", - "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", - "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", - "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", - "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", - "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" -] -new_out_hash_sibling_path = [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb", - "0x0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c3", - "0x00efcbdb79553ae6863646bf36441755bc344a9a4af335fadc6659594faa4316", - "0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c" -] -blobs_fields = [ - "0x00000000009c70751800000003000000010001000f0000000000670000000080", - "0x1d5eca2c8752fa06d9d1ecd4578d2199986802a4fa302e01dee816659b53c8de", - "0x00000000000000000000000000000000000000000000000000198e45581dc500", - "0x12d1a8f339ac9b30aa47bf7c00ed478423d06e8a4e568bd827fc8104d901ca05", - "0x2e3af71b5fe34cd92094dd31931363f24ff8f759742d09a216d636de4c7e0323", - "0x277b1930c96a4771d7d1c33b7d19eff1b3a47fce3a328b55a2a4caadc7fc74bd", - "0x061ad0f0ed7065820b58cc64574e3bf863d19f7b368dc6d3594bc21208d48f6f", - "0x00000000000000000000000000000000000000000000021e0a6a3c99fb198000", - "0x000000000000000000000000000000000000000000000000000000000000000f", - "0x1a7e1badb79abdd38c684b3c8306ffe7ecb33c69e3380d9855730aaaa83a21a8", - "0x25f1be81a0ae9f7adc0506c721cfc092cececc837fd115cb16a60e8247d6312b", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x1e495537a58fe255952a20bc319ebbf9d5eb2bc2692addbee2f6f97f946eae28", - "0x1e492f3e5b963534b5812a7e1e704db89c5265ff507aee8ff96a27154525c44d", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x14fbaeaeddaa69be81d404c684e78e9f1a786d225faf8de2ce97c92f67d89a26", - "0x00c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c", - "0x1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb151", - "0x0e60ed663a4da5636e2e25a1f1f0c5b27c011c8eaed22bbe61e2a0fd875dd24b", - "0x082c6d164b0ba073c9dd911100248c8ecd80b03f82f38531856a3c16dadcbef0", - "0x14a5d4bde495b8c3a9ba4aed0d4870526e46fdff22d341a2f689ac5a50d10356", - "0x0f124f07811eebfaaa6d31316a2cc5bf255fa118f720e8ff1f2fc0d4aa46d496", - "0x2deebd90399de05cddcd37661b24bdb4acd97dfd9faccc3a82543732d8f33e93", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x20f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244", - "0x1e492f3e5b963534b5812a7e1e704db89c5265ff507aee8ff96a27154525c44d", +[inputs.inbox_parity] +proof = [ "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x1a46c5781598e4074ebb3bababaee59adf89f1c84cffe38a4e814818f1c2ad27", - "0x2501a258c0ca8b1e06c26e9949c9e935d5e3240d83fb04d725d2e9da233c2382", - "0x0000000000000000000000000000000000000000000000000000000000000bb8", - "0x0027000204012800000104804527000004452500000041270203040127020404", - "0x00001f0a0003000400442d084402250000004b270202044527020304003b0e00", - "0x000300022900004304ffffffff262902000300a5a0df610a2a02030427020304", - "0x0001240200040000006b230000012f2d08010427020504020008010501270304", - "0x00040100220402051f3a000300030005002a0403052d0b05051e020004001e02", - "0x000004001e02000403002a0504061e02000404002a0604051e020004051c0a04", - "0x000600002a0506041e020005061c0a050600002a040605270206040127020804", - "0x0003002a0608072d0801040008010701270304040100220402072d0e06070022", - "0x000702072d0e06072702070403002a0407062d0a06072d0e050700220402062d", - "0x000b06062702070403002a0407053b0e00060005230000012f2902000400eb1e", - "0x0033420a2a020405270206000127020700002702080402240200050000015923", - "0x00000002542d08010527020904020008010901270305040100220502091f3a00", - "0x000300030009002a0503092d0b09091e020005001e02000500300a0009000627", - "0x00020a040227020c0403002a0a0c0b2d0801050008010b012703050401002205", - "0x00020b2d0e0a0b00220b020b2d0e0a0b27020b0403002a050b0a2d0a0a0b2d0e", - "0x00070b00220b020b2d0e090b002205020b2d0b0b0b27020c0403002a050c0a37", - "0x000e000b000a27020a040127020c0403002a0a0c0b2d0801050008010b012703", - "0x00050401002205020b2d0e0a0b00220b020b2d0e0a0b27020b0403002a050b0a", - "0x002d0a0a0b2d0e090b002205020a2d0b0a0a27020b0403002a050b093b0e000a", - "0x0000092300000254290200050022538df70a2a020509240200090000026f2300", - "0x0000037c2d08010527020904020008010901270305040100220502091f3a0003", - "0x0000030009002a0503092d0b09091e020005001e020005001e020005002f2a00", - "0x00060005000a002a0a0905300a0005000627020a040227020c0403002a0a0c0b", - "0x002d0801050008010b012703050401002205020b2d0e0a0b00220b020b2d0e0a", - "0x000b27020b0403002a050b0a2d0a0a0b2d0e070b00220b020b2d0e090b002205", - "0x00020b2d0b0b0b27020c0403002a050c0a370e000b000a27020a040127020c04", - "0x0003002a0a0c0b2d0801050008010b012703050401002205020b2d0e0a0b0022", - "0x000b020b2d0e0a0b27020b0403002a050b0a2d0a0a0b2d0e090b002205020a2d", - "0x000b0a0a27020b0403002a050b093b0e000a0009230000037c2902000500f0a3", - "0x004f5f0a2a02050927020a001427020c040227020e0403002a0c0e0d2d08010b", - "0x000008010d0127030b040100220b020d2d0e0c0d00220d020d2d0e0c0d27020d", - "0x000403002a0b0d0c2d0a0c0d2d0e070d00220d020d2d0e0a0d27020c04002702", - "0x000e0403002a0c0e0d2d0801070008010d012703070401002207020d2d0e0c0d", - "0x0000220d020d2d0e0c0d27020d0403002a070d0c27020c000a2d08010d27020e", - "0x0004030008010e0127030d040100220d020e2d0a0e0f2d0e040f00220f020f2d", - "0x000e0c0f2702040400240200090000045223000005a91e020009001e02000c00", - "0x002d0b0d0c00220c020c2d0e0c0d00220d020c3903a00043004300090008000c", - "0x00200200092102000c2d08010f27020e040000220f02112d0b11112702120403", - "0x00002a0f1210223a000c000400102d0a0c1127030f040100220f02122d0e1112", - "0x0000221202122d0e11122702130403002a111312000801120127021204002d0a", - "0x00111306221302130a2a0e121424020014000004f52d0a0e0e23000004f92d0a", - "0x00130e24020014000005130a2a0e131524020015000005132500000b74240200", - "0x00090000053c230000052000220f020c2d0b0c0c2702100403002a0f10093c0e", - "0x000c09230000053c0a2a0e0309240200090000055227020c04003c060c01300a", - "0x00000a00062d0b0b0900220902092d0e090b00220b020c2d0b0c0c27020e0403", - "0x00002a0b0e09370e000c00092d0b070900220902092d0e0907002207020c2d0b", - "0x000c0c27020e0403002a070e093b0e000c000923000005a92902000900a5f91f", - "0x00690a2a02090c2402000c000005c4230000071b1e02000c001e02000e00300a", - "0x00000a00062d0b0b0e00220e020e2d0e0e0b00220b020f2d0b0f0f2702100403", - "0x00002a0b100e370e000f000e2d0b0d0e00220e020e2d0e0e0d00220d020e3903", - "0x00a000430043000c0008000e2002000c2102000d2d08010f27020e040000220f", - "0x0002112d0b11112702120403002a0f1210223a000d000400102d0a0d1127030f", - "0x00040100220f02122d0e111200221202122d0e11122702130403002a11131200", - "0x000801120127021204002d0a111306221302130a2a0e12142402001400000693", - "0x002d0a0e0e23000006972d0a130e24020014000006b10a2a0e13152402001500", - "0x000006b12500000b742402000c000006da23000006be00220f020d2d0b0d0d27", - "0x0002100403002a0f100c3c0e0d0c23000006da0a2a0e030c2402000c000006f0", - "0x0027020d04003c060d012d0b070c00220c020c2d0e0c07002207020d2d0b0d0d", - "0x0027020e0403002a070e0c3b0e000d000c230000071b2902000c008aec94960a", - "0x002a020c0d2402000d0000073623000009a91e02000c001e02000d002d08010d", - "0x0027020e04020008010e0127030d040100220d020e2d0a0e0f2d0e050f00220d", - "0x0002053903a000430043000c00030005200200052102000d2d08010f27020e04", - "0x000000220f02112d0b11112702120403002a0f1210223a000d000400102d0a0d", - "0x001127030f040100220f02122d0e111200221202122d0e11122702130403002a", - "0x00111312000801120127021204002d0a111306221302130a2a0e121424020014", - "0x00000007ec2d0a0e0e23000007f02d0a130e240200140000080a0a2a0e131524", - "0x000200150000080a2500000b742402000500000833230000081700220f020d2d", - "0x000b0d0d2702100403002a0f10053c0e0d0523000008330a2a0e040524020005", - "0x000000084927020d04003c060d012d08010527020d04020008010d0127030504", - "0x0001002205020d2d0a0d0e2d0e090e00220502093903a000430043000c000300", - "0x000920020003210200052d08010c270209040000220c020e2d0b0e0e27020f04", - "0x0003002a0c0f0d223a00050004000d2d0a050e27030c040100220c020f2d0e0e", - "0x000f00220f020f2d0e0e0f2702100403002a0e100f0008010f0127020f04002d", - "0x000a0e1006221002100a2a090f1124020011000008f52d0a090923000008f92d", - "0x000a100924020011000009130a2a09101224020012000009132500000b742402", - "0x0000030000093c230000092000220c02052d0b050527020d0403002a0c0d033c", - "0x000e0503230000093c0a2a090403240200030000095227020504003c06050130", - "0x000a000a00062d0b0b0300220302032d0e030b00220b02052d0b050527020904", - "0x0003002a0b0903370e000500032d0b070300220302032d0e030700220702052d", - "0x000b05052702080403002a0708033b0e0005000323000009a927020302552702", - "0x0004026e270205026b270207026f2702080277270209022027020a027327020b", - "0x00026527020c026c27020d026327020e027427020f0272270210027b27021102", - "0x007d2d080112270213041c0008011301270312040100221202132d0a13142d0e", - "0x00031400221402142d0e041400221402142d0e051400221402142d0e04140022", - "0x001402142d0e071400221402142d0e081400221402142d0e041400221402142d", - "0x000e091400221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400", - "0x00221402142d0e0b1400221402142d0e0d1400221402142d0e0e140022140214", - "0x002d0e071400221402142d0e0f1400221402142d0e091400221402142d0e1014", - "0x0000221402142d0e0a1400221402142d0e0b1400221402142d0e0c1400221402", - "0x00142d0e0b1400221402142d0e0d1400221402142d0e0e1400221402142d0e07", - "0x001400221402142d0e0f1400221402142d0e1114270203010127020401000a2a", - "0x000403052402000500000b74270207041e2d080108270209041e00080109012d", - "0x000a08092a030009059b5bbff74a5bff190022090209002212020a27020b041b", - "0x002d020a032d0209042d020b052500000b8627020a041b002a090a092d0e0609", - "0x0000220902092d0e020900220902093c0e07082a0100010575fef108377c8a4f", - "0x003c0402012600000305072d0003082d0004092300000baa2d0108062d040609", - "0x00000008020800000902090c0008070a2400000a00000b982600000000000000", - "0x0000000000000000000000000000eb8dcdbf000000006a4d22fd000000090001", - "0x000000000000000001c00000000006000000000200000000008b00000008992c", - "0x1842a814b068f699565f4df77ab9139f1cfab687ef959bf92ba0bb3adf93d8dd", - "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5", - "0x00260be7577812f167b02eb1c2fa10efc5f169fe19845ada374d4c1518af35f4", - "0x2536a3212b711359308d274b8a92fa44465b6ce091dd9369c1331f1ffdeaa8ca", - "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a", - "0x0000000000000000000000000000000000000000000000008c63744300000088", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000000000000000000000000000b", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x000000000000000000000000000000000000000000000000000000000000000e", + "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000000000000000000000000000013", + "0x0000000000000000000000000000000000000000000000000000000000000014", + "0x0000000000000000000000000000000000000000000000000000000000000015", + "0x0000000000000000000000000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000018", + "0x0000000000000000000000000000000000000000000000000000000000000019", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x000000000000000000000000000000000000000000000000000000000000001b", + "0x000000000000000000000000000000000000000000000000000000000000001c", + "0x000000000000000000000000000000000000000000000000000000000000001d", + "0x000000000000000000000000000000000000000000000000000000000000001e", + "0x000000000000000000000000000000000000000000000000000000000000001f", + "0x0000000000000000000000000000000000000000000000000000000000000020", + "0x0000000000000000000000000000000000000000000000000000000000000021", + "0x0000000000000000000000000000000000000000000000000000000000000022", + "0x0000000000000000000000000000000000000000000000000000000000000023", + "0x0000000000000000000000000000000000000000000000000000000000000024", + "0x0000000000000000000000000000000000000000000000000000000000000025", + "0x0000000000000000000000000000000000000000000000000000000000000026", + "0x0000000000000000000000000000000000000000000000000000000000000027", + "0x0000000000000000000000000000000000000000000000000000000000000028", + "0x0000000000000000000000000000000000000000000000000000000000000029", + "0x000000000000000000000000000000000000000000000000000000000000002a", + "0x000000000000000000000000000000000000000000000000000000000000002b", + "0x000000000000000000000000000000000000000000000000000000000000002c", + "0x000000000000000000000000000000000000000000000000000000000000002d", + "0x000000000000000000000000000000000000000000000000000000000000002e", + "0x000000000000000000000000000000000000000000000000000000000000002f", + "0x0000000000000000000000000000000000000000000000000000000000000030", + "0x0000000000000000000000000000000000000000000000000000000000000031", + "0x0000000000000000000000000000000000000000000000000000000000000032", + "0x0000000000000000000000000000000000000000000000000000000000000033", + "0x0000000000000000000000000000000000000000000000000000000000000034", + "0x0000000000000000000000000000000000000000000000000000000000000035", + "0x0000000000000000000000000000000000000000000000000000000000000036", + "0x0000000000000000000000000000000000000000000000000000000000000037", + "0x0000000000000000000000000000000000000000000000000000000000000038", + "0x0000000000000000000000000000000000000000000000000000000000000039", + "0x000000000000000000000000000000000000000000000000000000000000003a", + "0x000000000000000000000000000000000000000000000000000000000000003b", + "0x000000000000000000000000000000000000000000000000000000000000003c", + "0x000000000000000000000000000000000000000000000000000000000000003d", + "0x000000000000000000000000000000000000000000000000000000000000003e", + "0x000000000000000000000000000000000000000000000000000000000000003f", + "0x0000000000000000000000000000000000000000000000000000000000000040", + "0x0000000000000000000000000000000000000000000000000000000000000041", + "0x0000000000000000000000000000000000000000000000000000000000000042", + "0x0000000000000000000000000000000000000000000000000000000000000043", + "0x0000000000000000000000000000000000000000000000000000000000000044", + "0x0000000000000000000000000000000000000000000000000000000000000045", + "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x0000000000000000000000000000000000000000000000000000000000000047", + "0x0000000000000000000000000000000000000000000000000000000000000048", + "0x0000000000000000000000000000000000000000000000000000000000000049", + "0x000000000000000000000000000000000000000000000000000000000000004a", + "0x000000000000000000000000000000000000000000000000000000000000004b", + "0x000000000000000000000000000000000000000000000000000000000000004c", + "0x000000000000000000000000000000000000000000000000000000000000004d", + "0x000000000000000000000000000000000000000000000000000000000000004e", + "0x000000000000000000000000000000000000000000000000000000000000004f", + "0x0000000000000000000000000000000000000000000000000000000000000050", + "0x0000000000000000000000000000000000000000000000000000000000000051", + "0x0000000000000000000000000000000000000000000000000000000000000052", + "0x0000000000000000000000000000000000000000000000000000000000000053", + "0x0000000000000000000000000000000000000000000000000000000000000054", + "0x0000000000000000000000000000000000000000000000000000000000000055", + "0x0000000000000000000000000000000000000000000000000000000000000056", + "0x0000000000000000000000000000000000000000000000000000000000000057", + "0x0000000000000000000000000000000000000000000000000000000000000058", + "0x0000000000000000000000000000000000000000000000000000000000000059", + "0x000000000000000000000000000000000000000000000000000000000000005a", + "0x000000000000000000000000000000000000000000000000000000000000005b", + "0x000000000000000000000000000000000000000000000000000000000000005c", + "0x000000000000000000000000000000000000000000000000000000000000005d", + "0x000000000000000000000000000000000000000000000000000000000000005e", + "0x000000000000000000000000000000000000000000000000000000000000005f", + "0x0000000000000000000000000000000000000000000000000000000000000060", + "0x0000000000000000000000000000000000000000000000000000000000000061", + "0x0000000000000000000000000000000000000000000000000000000000000062", + "0x0000000000000000000000000000000000000000000000000000000000000063", + "0x0000000000000000000000000000000000000000000000000000000000000064", + "0x0000000000000000000000000000000000000000000000000000000000000065", + "0x0000000000000000000000000000000000000000000000000000000000000066", + "0x0000000000000000000000000000000000000000000000000000000000000067", + "0x0000000000000000000000000000000000000000000000000000000000000068", + "0x0000000000000000000000000000000000000000000000000000000000000069", + "0x000000000000000000000000000000000000000000000000000000000000006a", + "0x000000000000000000000000000000000000000000000000000000000000006b", + "0x000000000000000000000000000000000000000000000000000000000000006c", + "0x000000000000000000000000000000000000000000000000000000000000006d", + "0x000000000000000000000000000000000000000000000000000000000000006e", + "0x000000000000000000000000000000000000000000000000000000000000006f", + "0x0000000000000000000000000000000000000000000000000000000000000070", + "0x0000000000000000000000000000000000000000000000000000000000000071", + "0x0000000000000000000000000000000000000000000000000000000000000072", + "0x0000000000000000000000000000000000000000000000000000000000000073", + "0x0000000000000000000000000000000000000000000000000000000000000074", + "0x0000000000000000000000000000000000000000000000000000000000000075", + "0x0000000000000000000000000000000000000000000000000000000000000076", + "0x0000000000000000000000000000000000000000000000000000000000000077", + "0x0000000000000000000000000000000000000000000000000000000000000078", + "0x0000000000000000000000000000000000000000000000000000000000000079", + "0x000000000000000000000000000000000000000000000000000000000000007a", + "0x000000000000000000000000000000000000000000000000000000000000007b", + "0x000000000000000000000000000000000000000000000000000000000000007c", + "0x000000000000000000000000000000000000000000000000000000000000007d", + "0x000000000000000000000000000000000000000000000000000000000000007e", + "0x000000000000000000000000000000000000000000000000000000000000007f", + "0x0000000000000000000000000000000000000000000000000000000000000080", + "0x0000000000000000000000000000000000000000000000000000000000000081", + "0x0000000000000000000000000000000000000000000000000000000000000082", + "0x0000000000000000000000000000000000000000000000000000000000000083", + "0x0000000000000000000000000000000000000000000000000000000000000084", + "0x0000000000000000000000000000000000000000000000000000000000000085", + "0x0000000000000000000000000000000000000000000000000000000000000086", + "0x0000000000000000000000000000000000000000000000000000000000000087", + "0x0000000000000000000000000000000000000000000000000000000000000088", + "0x0000000000000000000000000000000000000000000000000000000000000089", + "0x000000000000000000000000000000000000000000000000000000000000008a", + "0x000000000000000000000000000000000000000000000000000000000000008b", + "0x000000000000000000000000000000000000000000000000000000000000008c", + "0x000000000000000000000000000000000000000000000000000000000000008d", + "0x000000000000000000000000000000000000000000000000000000000000008e", + "0x000000000000000000000000000000000000000000000000000000000000008f", + "0x0000000000000000000000000000000000000000000000000000000000000090", + "0x0000000000000000000000000000000000000000000000000000000000000091", + "0x0000000000000000000000000000000000000000000000000000000000000092", + "0x0000000000000000000000000000000000000000000000000000000000000093", + "0x0000000000000000000000000000000000000000000000000000000000000094", + "0x0000000000000000000000000000000000000000000000000000000000000095", + "0x0000000000000000000000000000000000000000000000000000000000000096", + "0x0000000000000000000000000000000000000000000000000000000000000097", + "0x0000000000000000000000000000000000000000000000000000000000000098", + "0x0000000000000000000000000000000000000000000000000000000000000099", + "0x000000000000000000000000000000000000000000000000000000000000009a", + "0x000000000000000000000000000000000000000000000000000000000000009b", + "0x000000000000000000000000000000000000000000000000000000000000009c", + "0x000000000000000000000000000000000000000000000000000000000000009d", + "0x000000000000000000000000000000000000000000000000000000000000009e", + "0x000000000000000000000000000000000000000000000000000000000000009f", + "0x00000000000000000000000000000000000000000000000000000000000000a0", + "0x00000000000000000000000000000000000000000000000000000000000000a1", + "0x00000000000000000000000000000000000000000000000000000000000000a2", + "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x00000000000000000000000000000000000000000000000000000000000000a4", + "0x00000000000000000000000000000000000000000000000000000000000000a5", + "0x00000000000000000000000000000000000000000000000000000000000000a6", + "0x00000000000000000000000000000000000000000000000000000000000000a7", + "0x00000000000000000000000000000000000000000000000000000000000000a8", + "0x00000000000000000000000000000000000000000000000000000000000000a9", + "0x00000000000000000000000000000000000000000000000000000000000000aa", + "0x00000000000000000000000000000000000000000000000000000000000000ab", + "0x00000000000000000000000000000000000000000000000000000000000000ac", + "0x00000000000000000000000000000000000000000000000000000000000000ad", + "0x00000000000000000000000000000000000000000000000000000000000000ae", + "0x00000000000000000000000000000000000000000000000000000000000000af", + "0x00000000000000000000000000000000000000000000000000000000000000b0", + "0x00000000000000000000000000000000000000000000000000000000000000b1", + "0x00000000000000000000000000000000000000000000000000000000000000b2", + "0x00000000000000000000000000000000000000000000000000000000000000b3", + "0x00000000000000000000000000000000000000000000000000000000000000b4", + "0x00000000000000000000000000000000000000000000000000000000000000b5", + "0x00000000000000000000000000000000000000000000000000000000000000b6", + "0x00000000000000000000000000000000000000000000000000000000000000b7", + "0x00000000000000000000000000000000000000000000000000000000000000b8", + "0x00000000000000000000000000000000000000000000000000000000000000b9", + "0x00000000000000000000000000000000000000000000000000000000000000ba", + "0x00000000000000000000000000000000000000000000000000000000000000bb", + "0x00000000000000000000000000000000000000000000000000000000000000bc", + "0x00000000000000000000000000000000000000000000000000000000000000bd", + "0x00000000000000000000000000000000000000000000000000000000000000be", + "0x00000000000000000000000000000000000000000000000000000000000000bf", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000c1", + "0x00000000000000000000000000000000000000000000000000000000000000c2", + "0x00000000000000000000000000000000000000000000000000000000000000c3", + "0x00000000000000000000000000000000000000000000000000000000000000c4", + "0x00000000000000000000000000000000000000000000000000000000000000c5", + "0x00000000000000000000000000000000000000000000000000000000000000c6", + "0x00000000000000000000000000000000000000000000000000000000000000c7", + "0x00000000000000000000000000000000000000000000000000000000000000c8", + "0x00000000000000000000000000000000000000000000000000000000000000c9", + "0x00000000000000000000000000000000000000000000000000000000000000ca", + "0x00000000000000000000000000000000000000000000000000000000000000cb", + "0x00000000000000000000000000000000000000000000000000000000000000cc", + "0x00000000000000000000000000000000000000000000000000000000000000cd", + "0x00000000000000000000000000000000000000000000000000000000000000ce", + "0x00000000000000000000000000000000000000000000000000000000000000cf", + "0x00000000000000000000000000000000000000000000000000000000000000d0", + "0x00000000000000000000000000000000000000000000000000000000000000d1", + "0x00000000000000000000000000000000000000000000000000000000000000d2", + "0x00000000000000000000000000000000000000000000000000000000000000d3", + "0x00000000000000000000000000000000000000000000000000000000000000d4", + "0x00000000000000000000000000000000000000000000000000000000000000d5", + "0x00000000000000000000000000000000000000000000000000000000000000d6", + "0x00000000000000000000000000000000000000000000000000000000000000d7", + "0x00000000000000000000000000000000000000000000000000000000000000d8", + "0x00000000000000000000000000000000000000000000000000000000000000d9", + "0x00000000000000000000000000000000000000000000000000000000000000da", + "0x00000000000000000000000000000000000000000000000000000000000000db", + "0x00000000000000000000000000000000000000000000000000000000000000dc", + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x00000000000000000000000000000000000000000000000000000000000000de", + "0x00000000000000000000000000000000000000000000000000000000000000df", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x00000000000000000000000000000000000000000000000000000000000000e1", + "0x00000000000000000000000000000000000000000000000000000000000000e2", + "0x00000000000000000000000000000000000000000000000000000000000000e3", + "0x00000000000000000000000000000000000000000000000000000000000000e4", + "0x00000000000000000000000000000000000000000000000000000000000000e5", + "0x00000000000000000000000000000000000000000000000000000000000000e6", + "0x00000000000000000000000000000000000000000000000000000000000000e7", + "0x00000000000000000000000000000000000000000000000000000000000000e8", + "0x00000000000000000000000000000000000000000000000000000000000000e9", + "0x00000000000000000000000000000000000000000000000000000000000000ea", + "0x00000000000000000000000000000000000000000000000000000000000000eb", + "0x00000000000000000000000000000000000000000000000000000000000000ec", + "0x00000000000000000000000000000000000000000000000000000000000000ed", + "0x00000000000000000000000000000000000000000000000000000000000000ee", + "0x00000000000000000000000000000000000000000000000000000000000000ef", + "0x00000000000000000000000000000000000000000000000000000000000000f0", + "0x00000000000000000000000000000000000000000000000000000000000000f1", + "0x00000000000000000000000000000000000000000000000000000000000000f2", + "0x00000000000000000000000000000000000000000000000000000000000000f3", + "0x00000000000000000000000000000000000000000000000000000000000000f4", + "0x00000000000000000000000000000000000000000000000000000000000000f5", + "0x00000000000000000000000000000000000000000000000000000000000000f6", + "0x00000000000000000000000000000000000000000000000000000000000000f7", + "0x00000000000000000000000000000000000000000000000000000000000000f8", + "0x00000000000000000000000000000000000000000000000000000000000000f9", + "0x00000000000000000000000000000000000000000000000000000000000000fa", + "0x00000000000000000000000000000000000000000000000000000000000000fb", + "0x00000000000000000000000000000000000000000000000000000000000000fc", + "0x00000000000000000000000000000000000000000000000000000000000000fd", + "0x00000000000000000000000000000000000000000000000000000000000000fe", + "0x00000000000000000000000000000000000000000000000000000000000000ff", + "0x0000000000000000000000000000000000000000000000000000000000000100", + "0x0000000000000000000000000000000000000000000000000000000000000101", + "0x0000000000000000000000000000000000000000000000000000000000000102", + "0x0000000000000000000000000000000000000000000000000000000000000103", + "0x0000000000000000000000000000000000000000000000000000000000000104", + "0x0000000000000000000000000000000000000000000000000000000000000105", + "0x0000000000000000000000000000000000000000000000000000000000000106", + "0x0000000000000000000000000000000000000000000000000000000000000107", + "0x0000000000000000000000000000000000000000000000000000000000000108", + "0x0000000000000000000000000000000000000000000000000000000000000109", + "0x000000000000000000000000000000000000000000000000000000000000010a", + "0x000000000000000000000000000000000000000000000000000000000000010b", + "0x000000000000000000000000000000000000000000000000000000000000010c", + "0x000000000000000000000000000000000000000000000000000000000000010d", + "0x000000000000000000000000000000000000000000000000000000000000010e", + "0x000000000000000000000000000000000000000000000000000000000000010f", + "0x0000000000000000000000000000000000000000000000000000000000000110", + "0x0000000000000000000000000000000000000000000000000000000000000111", + "0x0000000000000000000000000000000000000000000000000000000000000112", + "0x0000000000000000000000000000000000000000000000000000000000000113", + "0x0000000000000000000000000000000000000000000000000000000000000114", + "0x0000000000000000000000000000000000000000000000000000000000000115", + "0x0000000000000000000000000000000000000000000000000000000000000116", + "0x0000000000000000000000000000000000000000000000000000000000000117", + "0x0000000000000000000000000000000000000000000000000000000000000118", + "0x0000000000000000000000000000000000000000000000000000000000000119", + "0x000000000000000000000000000000000000000000000000000000000000011a", + "0x000000000000000000000000000000000000000000000000000000000000011b", + "0x000000000000000000000000000000000000000000000000000000000000011c", + "0x000000000000000000000000000000000000000000000000000000000000011d", + "0x000000000000000000000000000000000000000000000000000000000000011e", + "0x000000000000000000000000000000000000000000000000000000000000011f", + "0x0000000000000000000000000000000000000000000000000000000000000120", + "0x0000000000000000000000000000000000000000000000000000000000000121", + "0x0000000000000000000000000000000000000000000000000000000000000122", + "0x0000000000000000000000000000000000000000000000000000000000000123", + "0x0000000000000000000000000000000000000000000000000000000000000124", + "0x0000000000000000000000000000000000000000000000000000000000000125", + "0x0000000000000000000000000000000000000000000000000000000000000126", + "0x0000000000000000000000000000000000000000000000000000000000000127", + "0x0000000000000000000000000000000000000000000000000000000000000128", + "0x0000000000000000000000000000000000000000000000000000000000000129", + "0x000000000000000000000000000000000000000000000000000000000000012a", + "0x000000000000000000000000000000000000000000000000000000000000012b", + "0x000000000000000000000000000000000000000000000000000000000000012c", + "0x000000000000000000000000000000000000000000000000000000000000012d", + "0x000000000000000000000000000000000000000000000000000000000000012e", + "0x000000000000000000000000000000000000000000000000000000000000012f", + "0x0000000000000000000000000000000000000000000000000000000000000130", + "0x0000000000000000000000000000000000000000000000000000000000000131", + "0x0000000000000000000000000000000000000000000000000000000000000132", + "0x0000000000000000000000000000000000000000000000000000000000000133", + "0x0000000000000000000000000000000000000000000000000000000000000134", + "0x0000000000000000000000000000000000000000000000000000000000000135", + "0x0000000000000000000000000000000000000000000000000000000000000136", + "0x0000000000000000000000000000000000000000000000000000000000000137", + "0x0000000000000000000000000000000000000000000000000000000000000138", + "0x0000000000000000000000000000000000000000000000000000000000000139", + "0x000000000000000000000000000000000000000000000000000000000000013a", + "0x000000000000000000000000000000000000000000000000000000000000013b", + "0x000000000000000000000000000000000000000000000000000000000000013c", + "0x000000000000000000000000000000000000000000000000000000000000013d", + "0x000000000000000000000000000000000000000000000000000000000000013e", + "0x000000000000000000000000000000000000000000000000000000000000013f", + "0x0000000000000000000000000000000000000000000000000000000000000140", + "0x0000000000000000000000000000000000000000000000000000000000000141", + "0x0000000000000000000000000000000000000000000000000000000000000142", + "0x0000000000000000000000000000000000000000000000000000000000000143", + "0x0000000000000000000000000000000000000000000000000000000000000144", + "0x0000000000000000000000000000000000000000000000000000000000000145", + "0x0000000000000000000000000000000000000000000000000000000000000146", + "0x0000000000000000000000000000000000000000000000000000000000000147", + "0x0000000000000000000000000000000000000000000000000000000000000148", + "0x0000000000000000000000000000000000000000000000000000000000000149", + "0x000000000000000000000000000000000000000000000000000000000000014a", + "0x000000000000000000000000000000000000000000000000000000000000014b", + "0x000000000000000000000000000000000000000000000000000000000000014c", + "0x000000000000000000000000000000000000000000000000000000000000014d", + "0x000000000000000000000000000000000000000000000000000000000000014e", + "0x000000000000000000000000000000000000000000000000000000000000014f", + "0x0000000000000000000000000000000000000000000000000000000000000150", + "0x0000000000000000000000000000000000000000000000000000000000000151", + "0x0000000000000000000000000000000000000000000000000000000000000152", + "0x0000000000000000000000000000000000000000000000000000000000000153", + "0x0000000000000000000000000000000000000000000000000000000000000154", + "0x0000000000000000000000000000000000000000000000000000000000000155", + "0x0000000000000000000000000000000000000000000000000000000000000156", + "0x0000000000000000000000000000000000000000000000000000000000000157", + "0x0000000000000000000000000000000000000000000000000000000000000158", + "0x0000000000000000000000000000000000000000000000000000000000000159", + "0x000000000000000000000000000000000000000000000000000000000000015a", + "0x000000000000000000000000000000000000000000000000000000000000015b", + "0x000000000000000000000000000000000000000000000000000000000000015c", + "0x000000000000000000000000000000000000000000000000000000000000015d", + "0x000000000000000000000000000000000000000000000000000000000000015e", + "0x000000000000000000000000000000000000000000000000000000000000015f", + "0x0000000000000000000000000000000000000000000000000000000000000160", + "0x0000000000000000000000000000000000000000000000000000000000000161", + "0x0000000000000000000000000000000000000000000000000000000000000162", + "0x0000000000000000000000000000000000000000000000000000000000000163", + "0x0000000000000000000000000000000000000000000000000000000000000164", + "0x0000000000000000000000000000000000000000000000000000000000000165", + "0x0000000000000000000000000000000000000000000000000000000000000166", + "0x0000000000000000000000000000000000000000000000000000000000000167", + "0x0000000000000000000000000000000000000000000000000000000000000168", + "0x0000000000000000000000000000000000000000000000000000000000000169", + "0x000000000000000000000000000000000000000000000000000000000000016a", + "0x000000000000000000000000000000000000000000000000000000000000016b", + "0x000000000000000000000000000000000000000000000000000000000000016c", + "0x000000000000000000000000000000000000000000000000000000000000016d", + "0x000000000000000000000000000000000000000000000000000000000000016e", + "0x000000000000000000000000000000000000000000000000000000000000016f", + "0x0000000000000000000000000000000000000000000000000000000000000170", + "0x0000000000000000000000000000000000000000000000000000000000000171", + "0x0000000000000000000000000000000000000000000000000000000000000172", + "0x0000000000000000000000000000000000000000000000000000000000000173", + "0x0000000000000000000000000000000000000000000000000000000000000174", + "0x0000000000000000000000000000000000000000000000000000000000000175", + "0x0000000000000000000000000000000000000000000000000000000000000176", + "0x0000000000000000000000000000000000000000000000000000000000000177", + "0x0000000000000000000000000000000000000000000000000000000000000178", + "0x0000000000000000000000000000000000000000000000000000000000000179", + "0x000000000000000000000000000000000000000000000000000000000000017a", + "0x000000000000000000000000000000000000000000000000000000000000017b", + "0x000000000000000000000000000000000000000000000000000000000000017c", + "0x000000000000000000000000000000000000000000000000000000000000017d", + "0x000000000000000000000000000000000000000000000000000000000000017e", + "0x000000000000000000000000000000000000000000000000000000000000017f", + "0x0000000000000000000000000000000000000000000000000000000000000180", + "0x0000000000000000000000000000000000000000000000000000000000000181", + "0x0000000000000000000000000000000000000000000000000000000000000182", + "0x0000000000000000000000000000000000000000000000000000000000000183", + "0x0000000000000000000000000000000000000000000000000000000000000184", + "0x0000000000000000000000000000000000000000000000000000000000000185", + "0x0000000000000000000000000000000000000000000000000000000000000186", + "0x0000000000000000000000000000000000000000000000000000000000000187", + "0x0000000000000000000000000000000000000000000000000000000000000188", + "0x0000000000000000000000000000000000000000000000000000000000000189", + "0x000000000000000000000000000000000000000000000000000000000000018a", + "0x000000000000000000000000000000000000000000000000000000000000018b", + "0x000000000000000000000000000000000000000000000000000000000000018c", + "0x000000000000000000000000000000000000000000000000000000000000018d", + "0x000000000000000000000000000000000000000000000000000000000000018e", + "0x000000000000000000000000000000000000000000000000000000000000018f", + "0x0000000000000000000000000000000000000000000000000000000000000190", + "0x0000000000000000000000000000000000000000000000000000000000000191", + "0x0000000000000000000000000000000000000000000000000000000000000192", + "0x0000000000000000000000000000000000000000000000000000000000000193", + "0x0000000000000000000000000000000000000000000000000000000000000194", + "0x0000000000000000000000000000000000000000000000000000000000000195", + "0x0000000000000000000000000000000000000000000000000000000000000196", + "0x0000000000000000000000000000000000000000000000000000000000000197", + "0x0000000000000000000000000000000000000000000000000000000000000198", + "0x0000000000000000000000000000000000000000000000000000000000000199", + "0x000000000000000000000000000000000000000000000000000000000000019a" +] + + [inputs.inbox_parity.public_inputs] + start_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_rolling_hash = "0x00a48b67f417042d5231ac634d609fe03a3884c4757a2afe457a7d1c6ca063ba" + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000100" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.inbox_parity.public_inputs.start_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.inbox_parity.public_inputs.start_sponge.sponge] + cache = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" + squeeze_mode = false + + [inputs.inbox_parity.public_inputs.end_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.inbox_parity.public_inputs.end_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false + + [inputs.inbox_parity.vk_data] + leaf_index = "0x000000000000000000000000000000000000000000000000000000000000004b" + sibling_path = [ + "0x0ce57ef9658f5dcd6e252d942f93d5849c88741ff38e986a9c23698a78af34f8", + "0x1901849bbf00ef11f1b4d6813ff73db197ff3651540c8b7b8a35d4b73f802b53", + "0x0f5fb8e46928cbfb3f605126eaddf42b57788c66536d3d5d14c351dc53c57247", + "0x21ed90cd61698dc1e3dfc970eefcedc837dfedf46c2c4e594ce076ee8fba9386", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x24bf189628d199694f93e70205def14d96fb881b5a613b3e3ce2279c0e61d43f" +] + + [inputs.inbox_parity.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000021", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000c53f64dfc96470530db6ace16066e37a1d", + "0x00000000000000000000000000000000002a4aa09996ebfce8b72c9859d40a76", + "0x000000000000000000000000000000c021bf9d18ec75052cb06d0de9ec7f3c0b", + "0x00000000000000000000000000000000002ed3ec63df5dde157121ead0e3394a", + "0x0000000000000000000000000000008e52b43cea18affa0552239445532d3dfa", + "0x0000000000000000000000000000000000189b5cfaeda80ba752185e134d782d", + "0x000000000000000000000000000000d8ddd956deabfef7cf4e75b77e94087cde", + "0x000000000000000000000000000000000012088f809a0607c64af087559d7a1c", + "0x000000000000000000000000000000af3512e2b02ca8e3e5983edab46b37c124", + "0x00000000000000000000000000000000000bc4c64a908903352744013b92a706", + "0x0000000000000000000000000000005d2e8719a6bf28fc26170f43ebaf851e57", + "0x00000000000000000000000000000000002dd75b5a0ce761c1d1741b89bb3220", + "0x00000000000000000000000000000060ee4d844e88b11151822bc1006d6d14da", + "0x000000000000000000000000000000000003b9fc877fd36d9f71131076146822", + "0x000000000000000000000000000000cf6b45fc328a2092e1e5060198c6779001", + "0x00000000000000000000000000000000001e24603f0360820b8025e12ee90538", + "0x000000000000000000000000000000dca672efd630b28631070c23ac79894ffb", + "0x0000000000000000000000000000000000208ae5f11db8476d152143bd820324", + "0x000000000000000000000000000000037e45f0f351437ff9926de30c98fae12f", + "0x00000000000000000000000000000000001f11c3b9d9d82669b4d5a4e304a86a", + "0x00000000000000000000000000000082d43a15a593806829ef7b49017f9593eb", + "0x00000000000000000000000000000000002c18d89ed3fa58330a02d047d1006c", + "0x0000000000000000000000000000009ee5d086b44c67fd2845247551fec700ba", + "0x00000000000000000000000000000000000d61fca9f49c92cba01d09d84b590d", + "0x000000000000000000000000000000b79615e2c9c43e979c39e94b5aef77d17e", + "0x00000000000000000000000000000000001afadf5e9d48948e38bb57d3aa86b6", + "0x0000000000000000000000000000000f2455636bef5ab7d499950e2a477d6d01", + "0x00000000000000000000000000000000001d27f7fd12cb249a614d019632f596", + "0x00000000000000000000000000000097a669c1bcd8e9b70e0a4cefc0848a3e33", + "0x000000000000000000000000000000000024c7a70a53c5598868371c047927a1", + "0x000000000000000000000000000000602ad8a9486de199dd1de58f39a27acfcd", + "0x0000000000000000000000000000000000141fcf1e826474f1033dd405a5c227", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003a57c27b30e08f6c165ea04e1c12078d86", + "0x000000000000000000000000000000000008d8a0131f34de690ce72b0e8cc997", + "0x00000000000000000000000000000072db0dbafee7ebe37300f57d3b861a1ed4", + "0x000000000000000000000000000000000008b1f713f28097c7934c96300ff933", + "0x00000000000000000000000000000093335a2d7db2ecc73c2a0b7a648767b3fa", + "0x000000000000000000000000000000000023058389968593a9d699ac61081497", + "0x000000000000000000000000000000c6f184ddade0468849894d086897891dae", + "0x0000000000000000000000000000000000177c7fe17fb62bd5c589b997be2be8", + "0x0000000000000000000000000000009df947a1824dd3e4c25006e55148430193", + "0x000000000000000000000000000000000025fffc71b2d4c067937ffaa0cbf575", + "0x00000000000000000000000000000028995e133a2c13cc3db00acdd8aad170a8", + "0x000000000000000000000000000000000005aacaf7b06227aa09f4ac8e12b63e", + "0x000000000000000000000000000000fd6e7754395ee57e0c460549931360c099", + "0x00000000000000000000000000000000000be33e0029e81b7ac23442af699121", + "0x0000000000000000000000000000006d6d5e8519b2b49fcd677457f81f1cb57a", + "0x000000000000000000000000000000000013b5a13f5802a5e358bf0ba73a0284", + "0x000000000000000000000000000000bc328653111a2fe499ec1a1393005c9f97", + "0x00000000000000000000000000000000000aba9237199085bd00ff8a2d90a5a1", + "0x000000000000000000000000000000d30c8eb234c4be977ec50cdaa0c970e988", + "0x0000000000000000000000000000000000126b7b5d6b48d64ce1d81cab3360c7", + "0x0000000000000000000000000000006ded6c9275e8c5f114d2662b03a09a5e3b", + "0x00000000000000000000000000000000001d3926dda40de089a5c7a24d35399a", + "0x000000000000000000000000000000a99b31d8f0421291c246e9431b4db095c0", + "0x00000000000000000000000000000000002163cf3bef71ec3deb0befbe80562f", + "0x00000000000000000000000000000059d41d5bf8f2a34d8b5aacc9714e881793", + "0x0000000000000000000000000000000000044a8b9042c8f236b9fc6a4387e06d", + "0x0000000000000000000000000000002a48938569e265b24943cb1a59dca4ee0a", + "0x0000000000000000000000000000000000267c7099894e9c5b1cc22e6eef2272", + "0x0000000000000000000000000000009fcc79cda6b0a41e0bdaaf6bfb549978d9", + "0x00000000000000000000000000000000001b4c96c38c76d0ee07b7e58e702d0c", + "0x000000000000000000000000000000f4fa13d704275b8d7e997bdfda7121e226", + "0x00000000000000000000000000000000001f285950282a94f4788070c29ecd1a", + "0x000000000000000000000000000000f65d1d2d0072c13ac17f9dfe0505166bb6", + "0x00000000000000000000000000000000000ad3bff96526cff78d95911e972e92", + "0x000000000000000000000000000000b54b6db0ec422f52e358f8a3c7f32c2ae4", + "0x00000000000000000000000000000000001a420aee136484fd32d44c1ce11d5b", + "0x000000000000000000000000000000297330b41d0c706bd513951f52ceb1e016", + "0x00000000000000000000000000000000001f5c675aca3686dd867f7bd2b07dac", + "0x000000000000000000000000000000d30f505432d411dbd9b8adbec808b94502", + "0x00000000000000000000000000000000002ef8adb3cea16fc68c4bad3fe3746e", + "0x000000000000000000000000000000a74bd48db81ce1e576b260788dbbe3ae73", + "0x00000000000000000000000000000000002dbbdba5149c40257503f0599b20a0", + "0x000000000000000000000000000000210302c9d6a317610609231e2554634d6c", + "0x0000000000000000000000000000000000163bcdfc12dcd3e842ab5156e7d3c8", + "0x0000000000000000000000000000000372b1edab65c3200e90aded2403a7bbd9", + "0x0000000000000000000000000000000000167129f1c2377787f35a31bb3cbfcd", + "0x000000000000000000000000000000049565f4db812be49e05e942e1282a80d9", + "0x000000000000000000000000000000000005ff62f0112be0f68fbbacb61d496e", + "0x000000000000000000000000000000661e266983059d97c6a1235a84553e0542", + "0x000000000000000000000000000000000025a0c734e75b6aadfb38222a66ad70", + "0x0000000000000000000000000000001315cc4242cedcba5c3a13a95fc31db9df", + "0x000000000000000000000000000000000026dac182a98f8fc7f93f0a32564022", + "0x000000000000000000000000000000f75b56af4f4f1cdb4794a64607e229c8bb", + "0x000000000000000000000000000000000011d9a02f40267bff021da5653104e8", + "0x000000000000000000000000000000213970438635e5bc87217e0ef8cad56c03", + "0x00000000000000000000000000000000001f0b565ab39f8750bb6288f59d1d90", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000ce8d339e9525430229bc5c203dae8f7ce6", + "0x000000000000000000000000000000000012872d1a4ee10c27e560412918917b", + "0x000000000000000000000000000000eaff5d1045972910fa67c9d6139a2d8170", + "0x000000000000000000000000000000000023fd76f167813bfb90cd2c36676412", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003e3af00bf035f2b2595659a53fb5e36a25", + "0x00000000000000000000000000000000000be135e96f8061912e16dee4eeadc9", + "0x0000000000000000000000000000000f2730a470360be5041e25dfcb3170b79c", + "0x00000000000000000000000000000000002ef3cf8e2ef9ed0359a37694a30d5b", + "0x000000000000000000000000000000762b2f6a9947f0362b3e07ade872bd4ad0", + "0x000000000000000000000000000000000009330958b31fa64652a63b0290910c", + "0x0000000000000000000000000000008b43122ec9495e49f0dde9140e71b72eb0", + "0x000000000000000000000000000000000011577b0c4e6dbc35f57d754d00dfb7" +] + hash = "0x28e207116e573337e83d7ab38d918cba438149cbd188ae0fd2e0d2fa31aea01c" + +[inputs.hints] +previous_archive_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb", + "0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d", + "0x30105bad22ddcc508b739b7c9ad87a561c569ff5cb0098a853c1c4ac21b7a037", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f", + "0x221cf368938c74e4fced9dfb2a8e37cd8a6c57d21385c249f0b5c2412341287f", + "0x2c5214dfc4d70d2619fce2a7e02ddcf380576dca42b66c9215c7d8d1ec154116", + "0x13abc9bba431e6930c169f5daeb60aedbb27d7618c7ff88b3b4ec1c6de1d6bb8", + "0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f", + "0x042c72d0ca208f0631ed947050258333518c26059f0a2ef041e933b1b2a6d8ad", + "0x00c21235cdc5d4241fab782680421cdd99c088a3b48a740d8289d0e67b2ee5da", + "0x1077e8e59029b12e321c47a8a2a25283e50664b6ca1dd766a83828ddc6a22bb9", + "0x15b7bb46f75a6826da53df52c290eda3ddea8924becad6e9a3c08e4eb9a6f604", + "0x0f092097aaee3e41e55706add0701d0eff7a0c972a909dcbc915a478cbc8f122", + "0x2cf33c7d57e1ff8f3d98aabae3092befa8e92274da5e6d324ba0b8839889d27c", + "0x137e350aaf8bab893d768cb6e14bc5464877833efbb8c7091da9ecc7a96bc7b7", + "0x016505cc51b09b257b8c96b5fb20e90bd9e68416286a904d9f86b805e5a89e13", + "0x04d6e1009a70843f5bad89c59765d09421aad04e3276fc90f2a459565057978a", + "0x093a8215cd7e725a45949f4d6d4faec9d078221f09d26a27d61e4f0bf670a580", + "0x1704545cd66b0aa172d2c355fac161d17d7ea42f0132d24708762b544fa17357", + "0x2db6ed73abe6fc42bde50d4422c3e0c81def268d702b9256b7e67cafbbd0325c", + "0x21868e4f8cdcbcb9754d297edc2a361754517465c469017e784a4347f9eb6644", + "0x1adbb821ee5346b1979da8ddbb58789f5ef90c31ece8f0c543c221a3ef0f0aed", + "0x2058aa06a8e23bc53a625831ce1df1aa8d8f01924ad840607f33805aee179d90", + "0x1002be9f0852a234617c837e49555e328bb19a71fcea0ff34368901cee52c85e", + "0x2b238a0d25b834a061e45d817289ab221d13fd0e4cc7adf72d91d54c280f1aa0", + "0x15fada375c113bd526097e297b422ffb59f54a5451e5b70d4a4b028dc65208d1", + "0x2aad701e57c7069cb4e148d971c0eae9ac7429d7d833c51d87875ead0c5aca3c" +] +new_out_hash_sibling_path = [ "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb", + "0x0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c3", + "0x00efcbdb79553ae6863646bf36441755bc344a9a4af335fadc6659594faa4316", + "0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c" +] +blobs_fields = [ + "0x00000000009c70751800400040000800010040040000000000000000000004cd", + "0x2d96d0ca52ec6573821a795e7b92a54e6e5ab63ca317bbd137cee2b276abad58", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000b7d1b100", + "0x00000000000000000000000000000000000000000000000000000000b7d1b101", + "0x00000000000000000000000000000000000000000000000000000000b7d1b102", + "0x00000000000000000000000000000000000000000000000000000000b7d1b103", + "0x00000000000000000000000000000000000000000000000000000000b7d1b104", + "0x00000000000000000000000000000000000000000000000000000000b7d1b105", + "0x00000000000000000000000000000000000000000000000000000000b7d1b106", + "0x00000000000000000000000000000000000000000000000000000000b7d1b107", + "0x00000000000000000000000000000000000000000000000000000000b7d1b108", + "0x00000000000000000000000000000000000000000000000000000000b7d1b109", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b10f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b110", + "0x00000000000000000000000000000000000000000000000000000000b7d1b111", + "0x00000000000000000000000000000000000000000000000000000000b7d1b112", + "0x00000000000000000000000000000000000000000000000000000000b7d1b113", + "0x00000000000000000000000000000000000000000000000000000000b7d1b114", + "0x00000000000000000000000000000000000000000000000000000000b7d1b115", + "0x00000000000000000000000000000000000000000000000000000000b7d1b116", + "0x00000000000000000000000000000000000000000000000000000000b7d1b117", + "0x00000000000000000000000000000000000000000000000000000000b7d1b118", + "0x00000000000000000000000000000000000000000000000000000000b7d1b119", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b11f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b120", + "0x00000000000000000000000000000000000000000000000000000000b7d1b121", + "0x00000000000000000000000000000000000000000000000000000000b7d1b122", + "0x00000000000000000000000000000000000000000000000000000000b7d1b123", + "0x00000000000000000000000000000000000000000000000000000000b7d1b124", + "0x00000000000000000000000000000000000000000000000000000000b7d1b125", + "0x00000000000000000000000000000000000000000000000000000000b7d1b126", + "0x00000000000000000000000000000000000000000000000000000000b7d1b127", + "0x00000000000000000000000000000000000000000000000000000000b7d1b128", + "0x00000000000000000000000000000000000000000000000000000000b7d1b129", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b12f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b130", + "0x00000000000000000000000000000000000000000000000000000000b7d1b131", + "0x00000000000000000000000000000000000000000000000000000000b7d1b132", + "0x00000000000000000000000000000000000000000000000000000000b7d1b133", + "0x00000000000000000000000000000000000000000000000000000000b7d1b134", + "0x00000000000000000000000000000000000000000000000000000000b7d1b135", + "0x00000000000000000000000000000000000000000000000000000000b7d1b136", + "0x00000000000000000000000000000000000000000000000000000000b7d1b137", + "0x00000000000000000000000000000000000000000000000000000000b7d1b138", + "0x00000000000000000000000000000000000000000000000000000000b7d1b139", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b200", + "0x00000000000000000000000000000000000000000000000000000000b7d1b201", + "0x00000000000000000000000000000000000000000000000000000000b7d1b202", + "0x00000000000000000000000000000000000000000000000000000000b7d1b203", + "0x00000000000000000000000000000000000000000000000000000000b7d1b204", + "0x00000000000000000000000000000000000000000000000000000000b7d1b205", + "0x00000000000000000000000000000000000000000000000000000000b7d1b206", + "0x00000000000000000000000000000000000000000000000000000000b7d1b207", + "0x00000000000000000000000000000000000000000000000000000000b7d1b208", + "0x00000000000000000000000000000000000000000000000000000000b7d1b209", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b210", + "0x00000000000000000000000000000000000000000000000000000000b7d1b211", + "0x00000000000000000000000000000000000000000000000000000000b7d1b212", + "0x00000000000000000000000000000000000000000000000000000000b7d1b213", + "0x00000000000000000000000000000000000000000000000000000000b7d1b214", + "0x00000000000000000000000000000000000000000000000000000000b7d1b215", + "0x00000000000000000000000000000000000000000000000000000000b7d1b216", + "0x00000000000000000000000000000000000000000000000000000000b7d1b217", + "0x00000000000000000000000000000000000000000000000000000000b7d1b218", + "0x00000000000000000000000000000000000000000000000000000000b7d1b219", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b220", + "0x00000000000000000000000000000000000000000000000000000000b7d1b221", + "0x00000000000000000000000000000000000000000000000000000000b7d1b222", + "0x00000000000000000000000000000000000000000000000000000000b7d1b223", + "0x00000000000000000000000000000000000000000000000000000000b7d1b224", + "0x00000000000000000000000000000000000000000000000000000000b7d1b225", + "0x00000000000000000000000000000000000000000000000000000000b7d1b226", + "0x00000000000000000000000000000000000000000000000000000000b7d1b227", + "0x00000000000000000000000000000000000000000000000000000000b7d1b228", + "0x00000000000000000000000000000000000000000000000000000000b7d1b229", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b230", + "0x00000000000000000000000000000000000000000000000000000000b7d1b231", + "0x00000000000000000000000000000000000000000000000000000000b7d1b232", + "0x00000000000000000000000000000000000000000000000000000000b7d1b233", + "0x00000000000000000000000000000000000000000000000000000000b7d1b234", + "0x00000000000000000000000000000000000000000000000000000000b7d1b235", + "0x00000000000000000000000000000000000000000000000000000000b7d1b236", + "0x00000000000000000000000000000000000000000000000000000000b7d1b237", + "0x00000000000000000000000000000000000000000000000000000000b7d1b238", + "0x00000000000000000000000000000000000000000000000000000000b7d1b239", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23f", + "0x0014e392e48abf86fbcc646ebd535dcfadddf685f17cea1ad8692d84091fee6c", + "0x0081d7915f280fb0ab3bc1424d1f3b0afe8b13ca662631eb35d42d344b463ca5", + "0x00108dedfcd6e6ec14921619d606d4e274eb020bb1cceaecaabc10591905ccca", + "0x002d49d5a469f7a62cab3d2b266ed8f6bb38dacb2fb848e61cdbd6f174fa4473", + "0x00c9d057674688ddc5b9dce4037f7a173d54d42423831b1f17c7ad345ba12acb", + "0x00d65baedb6181e9f1d19c3e64ae63b26c0df768927d9654153a4312c0bfb8f9", + "0x00baf276002157aa3a0111d9547fd25bfbefd9d1841ffb292d2801e5354e7d05", + "0x002e2d381dbc44262bbafdf7e1645e1642daf94aa6175667bd69b3452c748e41", + "0x27d08044a627c19f19b7b033af1c9b13f99160a207c22534c11ce11f88ad6814", + "0x0000000000000000000000000000000000000000000000056bc75e2d63100000", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b400", + "0x00000000000000000000000000000000000000000000000000000000b7d1b401", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b401", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000009c707518004000400008004000400400000000000000000000054b", + "0x14e4f610b14fc23a28b68c8c8c63a18135a0acb54098b9e0536186d00a100e85", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000b7e5c000", + "0x00000000000000000000000000000000000000000000000000000000b7e5c001", + "0x00000000000000000000000000000000000000000000000000000000b7e5c002", + "0x00000000000000000000000000000000000000000000000000000000b7e5c003", + "0x00000000000000000000000000000000000000000000000000000000b7e5c004", + "0x00000000000000000000000000000000000000000000000000000000b7e5c005", + "0x00000000000000000000000000000000000000000000000000000000b7e5c006", + "0x00000000000000000000000000000000000000000000000000000000b7e5c007", + "0x00000000000000000000000000000000000000000000000000000000b7e5c008", + "0x00000000000000000000000000000000000000000000000000000000b7e5c009", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c00f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c011", + "0x00000000000000000000000000000000000000000000000000000000b7e5c012", + "0x00000000000000000000000000000000000000000000000000000000b7e5c013", + "0x00000000000000000000000000000000000000000000000000000000b7e5c014", + "0x00000000000000000000000000000000000000000000000000000000b7e5c015", + "0x00000000000000000000000000000000000000000000000000000000b7e5c016", + "0x00000000000000000000000000000000000000000000000000000000b7e5c017", + "0x00000000000000000000000000000000000000000000000000000000b7e5c018", + "0x00000000000000000000000000000000000000000000000000000000b7e5c019", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c01f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c020", + "0x00000000000000000000000000000000000000000000000000000000b7e5c021", + "0x00000000000000000000000000000000000000000000000000000000b7e5c022", + "0x00000000000000000000000000000000000000000000000000000000b7e5c023", + "0x00000000000000000000000000000000000000000000000000000000b7e5c024", + "0x00000000000000000000000000000000000000000000000000000000b7e5c025", + "0x00000000000000000000000000000000000000000000000000000000b7e5c026", + "0x00000000000000000000000000000000000000000000000000000000b7e5c027", + "0x00000000000000000000000000000000000000000000000000000000b7e5c028", + "0x00000000000000000000000000000000000000000000000000000000b7e5c029", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c02f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c030", + "0x00000000000000000000000000000000000000000000000000000000b7e5c031", + "0x00000000000000000000000000000000000000000000000000000000b7e5c032", + "0x00000000000000000000000000000000000000000000000000000000b7e5c033", + "0x00000000000000000000000000000000000000000000000000000000b7e5c034", + "0x00000000000000000000000000000000000000000000000000000000b7e5c035", + "0x00000000000000000000000000000000000000000000000000000000b7e5c036", + "0x00000000000000000000000000000000000000000000000000000000b7e5c037", + "0x00000000000000000000000000000000000000000000000000000000b7e5c038", + "0x00000000000000000000000000000000000000000000000000000000b7e5c039", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c03f", + "0x00000000000000000000000000000000000000000000000000000000b7e5b001", + "0x00000000000000000000000000000000000000000000000000000000b7e5c100", + "0x00000000000000000000000000000000000000000000000000000000b7e5c101", + "0x00000000000000000000000000000000000000000000000000000000b7e5c102", + "0x00000000000000000000000000000000000000000000000000000000b7e5c103", + "0x00000000000000000000000000000000000000000000000000000000b7e5c104", + "0x00000000000000000000000000000000000000000000000000000000b7e5c105", + "0x00000000000000000000000000000000000000000000000000000000b7e5c106", + "0x00000000000000000000000000000000000000000000000000000000b7e5c107", + "0x00000000000000000000000000000000000000000000000000000000b7e5c108", + "0x00000000000000000000000000000000000000000000000000000000b7e5c109", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c10f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c110", + "0x00000000000000000000000000000000000000000000000000000000b7e5c111", + "0x00000000000000000000000000000000000000000000000000000000b7e5c112", + "0x00000000000000000000000000000000000000000000000000000000b7e5c113", + "0x00000000000000000000000000000000000000000000000000000000b7e5c114", + "0x00000000000000000000000000000000000000000000000000000000b7e5c115", + "0x00000000000000000000000000000000000000000000000000000000b7e5c116", + "0x00000000000000000000000000000000000000000000000000000000b7e5c117", + "0x00000000000000000000000000000000000000000000000000000000b7e5c118", + "0x00000000000000000000000000000000000000000000000000000000b7e5c119", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c11f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c120", + "0x00000000000000000000000000000000000000000000000000000000b7e5c121", + "0x00000000000000000000000000000000000000000000000000000000b7e5c122", + "0x00000000000000000000000000000000000000000000000000000000b7e5c123", + "0x00000000000000000000000000000000000000000000000000000000b7e5c124", + "0x00000000000000000000000000000000000000000000000000000000b7e5c125", + "0x00000000000000000000000000000000000000000000000000000000b7e5c126", + "0x00000000000000000000000000000000000000000000000000000000b7e5c127", + "0x00000000000000000000000000000000000000000000000000000000b7e5c128", + "0x00000000000000000000000000000000000000000000000000000000b7e5c129", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c12f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c130", + "0x00000000000000000000000000000000000000000000000000000000b7e5c131", + "0x00000000000000000000000000000000000000000000000000000000b7e5c132", + "0x00000000000000000000000000000000000000000000000000000000b7e5c133", + "0x00000000000000000000000000000000000000000000000000000000b7e5c134", + "0x00000000000000000000000000000000000000000000000000000000b7e5c135", + "0x00000000000000000000000000000000000000000000000000000000b7e5c136", + "0x00000000000000000000000000000000000000000000000000000000b7e5c137", + "0x00000000000000000000000000000000000000000000000000000000b7e5c138", + "0x00000000000000000000000000000000000000000000000000000000b7e5c139", + "0x00000000000000000000000000000000000000000000000000000000b7e5c13a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c13b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c13c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c13d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c13e", + "0x00b127f3f010102ee75542c6d7ea6d5882e7684c5ee9356f5ad220c93d67d444", + "0x00dfda5cece61f6680ba771aab12cb53462fef041f2b4b66aa6c65ff0893de6a", + "0x00ce587edb8f2da34e9b79a46b0fd072e0e98a8ef4e0df3f6bf401962acbcf12", + "0x00089a1b3144bd5867811140210d4522e80d2d01aceef8773ca1438313caf3f8", + "0x00a3e975c4eb26d4144db7c1aeba0961560eb0c302c97f7c1658b14a7e153c6a", + "0x003bafff5667638196d10618edf8f2b14a4be1468f4bcf36fef5803c32fba293", + "0x00c9ad352ff74227247dfa18731985cbe86ca423cda60a3d7c5233d2f1b1e584", + "0x00e073f9722b050752a0c38bf2132ac5c9ab55682757cf267c1fe5f534579e2b", + "0x27d08044a627c19f19b7b033af1c9b13f99160a207c22534c11ce11f88ad6814", + "0x0000000000000000000000000000000000000000000000056bc75e2d63100000", + "0x00000000000000000000000000000000000000000000000000000000b7e5d001", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d002", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d003", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d004", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d005", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d006", + "0x00000000000000000000000000000000000000000000000000000000b7e5d010", + "0x00000000000000000000000000000000000000000000000000000000b7e5d007", + "0x00000000000000000000000000000000000000000000000000000000b7e5d011", + "0x00000000000000000000000000000000000000000000000000000000b7e5d008", + "0x00000000000000000000000000000000000000000000000000000000b7e5d012", + "0x00000000000000000000000000000000000000000000000000000000b7e5d009", + "0x00000000000000000000000000000000000000000000000000000000b7e5d013", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d014", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d015", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d016", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d017", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d018", + "0x00000000000000000000000000000000000000000000000000000000b7e5d00f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d019", + "0x00000000000000000000000000000000000000000000000000000000b7e5d010", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d011", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d012", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d013", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d014", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d015", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d016", + "0x00000000000000000000000000000000000000000000000000000000b7e5d020", + "0x00000000000000000000000000000000000000000000000000000000b7e5d017", + "0x00000000000000000000000000000000000000000000000000000000b7e5d021", + "0x00000000000000000000000000000000000000000000000000000000b7e5d018", + "0x00000000000000000000000000000000000000000000000000000000b7e5d022", + "0x00000000000000000000000000000000000000000000000000000000b7e5d019", + "0x00000000000000000000000000000000000000000000000000000000b7e5d023", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d024", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d025", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d026", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d027", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d028", + "0x00000000000000000000000000000000000000000000000000000000b7e5d01f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d029", + "0x00000000000000000000000000000000000000000000000000000000b7e5d020", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d021", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d022", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d023", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d024", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d025", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d026", + "0x00000000000000000000000000000000000000000000000000000000b7e5d030", + "0x00000000000000000000000000000000000000000000000000000000b7e5d027", + "0x00000000000000000000000000000000000000000000000000000000b7e5d031", + "0x00000000000000000000000000000000000000000000000000000000b7e5d028", + "0x00000000000000000000000000000000000000000000000000000000b7e5d032", + "0x00000000000000000000000000000000000000000000000000000000b7e5d029", + "0x00000000000000000000000000000000000000000000000000000000b7e5d033", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d034", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d035", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d036", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d037", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d038", + "0x00000000000000000000000000000000000000000000000000000000b7e5d02f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d039", + "0x00000000000000000000000000000000000000000000000000000000b7e5d030", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d031", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d032", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d033", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d034", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d035", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d036", + "0x00000000000000000000000000000000000000000000000000000000b7e5d040", + "0x00000000000000000000000000000000000000000000000000000000b7e5d037", + "0x00000000000000000000000000000000000000000000000000000000b7e5d041", + "0x00000000000000000000000000000000000000000000000000000000b7e5d038", + "0x00000000000000000000000000000000000000000000000000000000b7e5d042", + "0x00000000000000000000000000000000000000000000000000000000b7e5d039", + "0x00000000000000000000000000000000000000000000000000000000b7e5d043", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03a", + "0x00000000000000000000000000000000000000000000000000000000b7e5d044", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03b", + "0x00000000000000000000000000000000000000000000000000000000b7e5d045", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03c", + "0x00000000000000000000000000000000000000000000000000000000b7e5d046", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03d", + "0x00000000000000000000000000000000000000000000000000000000b7e5d047", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03e", + "0x00000000000000000000000000000000000000000000000000000000b7e5d048", + "0x00000000000000000000000000000000000000000000000000000000b7e5d03f", + "0x00000000000000000000000000000000000000000000000000000000b7e5d049", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c300", + "0x00000000000000000000000000000000000000000000000000000000b7e5c301", + "0x00000000000000000000000000000000000000000000000000000000b7e5c302", + "0x00000000000000000000000000000000000000000000000000000000b7e5c303", + "0x00000000000000000000000000000000000000000000000000000000b7e5c304", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c301", + "0x00000000000000000000000000000000000000000000000000000000b7e5c302", + "0x00000000000000000000000000000000000000000000000000000000b7e5c303", + "0x00000000000000000000000000000000000000000000000000000000b7e5c304", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c302", + "0x00000000000000000000000000000000000000000000000000000000b7e5c303", + "0x00000000000000000000000000000000000000000000000000000000b7e5c304", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c303", + "0x00000000000000000000000000000000000000000000000000000000b7e5c304", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c304", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c305", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c306", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c307", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c308", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c309", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c30f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c310", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c311", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c312", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c313", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c314", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c315", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c316", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c317", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c318", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c319", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c31f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c320", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c321", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c322", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c323", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c324", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c325", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c326", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c327", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c328", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c329", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c32f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c330", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c331", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c332", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c333", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c334", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c335", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c336", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c337", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c338", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c339", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34a", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34b", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34c", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33e", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000b7e5c33f", + "0x00000000000000000000000000000000000000000000000000000000b7e5c340", + "0x00000000000000000000000000000000000000000000000000000000b7e5c341", + "0x00000000000000000000000000000000000000000000000000000000b7e5c342", + "0x00000000000000000000000000000000000000000000000000000000b7e5c343", + "0x00000000000000000000000000000000000000000000000000000000b7e5c344", + "0x00000000000000000000000000000000000000000000000000000000b7e5c345", + "0x00000000000000000000000000000000000000000000000000000000b7e5c346", + "0x00000000000000000000000000000000000000000000000000000000b7e5c347", + "0x00000000000000000000000000000000000000000000000000000000b7e5c348", + "0x00000000000000000000000000000000000000000000000000000000b7e5c349", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34a", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34b", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", + "0x0000000000000000000000000000eb8dcdbf0000000000000186000000010002", + "0x00000000000000000010000000000200000000010000000000bf00000006b6c0", + "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0", + "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b", + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c", + "0x0000000000000000000000000000000000000000000000008c63744300000a20", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -25334,49 +25959,49 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x00f09841b6beb6ac35e2d402e872f1408b67f5c5c84e46dc3787b46156d7f84c" +blobs_hash = "0x004ba8de2f093feb7b89d9edf2efd648708ab7fdd7b25bee41ccb92f3e8b2b8b" [inputs.hints.previous_block_header] - sponge_blob_hash = "0x0b313f5b633f0a3900167237b8b327f56fd8a1b294008e6527004c920d1e0c06" - total_fees = "0x000000000000000000000000000000000000000000000000001e63b1d6a4b780" - total_mana_used = "0x00000000000000000000000000000000000000000000000000000000000a3982" + sponge_blob_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + total_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" + total_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.last_archive] - root = "0x16d512452fc6d3fe373224d568f89a90072bc29881297e1053501494ea43bb0c" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + root = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.state.l1_to_l2_message_tree] root = "0x0fef6d80d31109ddb56d6b3f607cbc9c0af0bff3ea0d43e8f278983c64c11f7a" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000001800" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.state.partial.note_hash_tree] -root = "0x034b30004686b0cbe57927eaa548af4a428eabee71f4e3e8a581a43084facde5" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" +root = "0x2590f2aab19dd791700b4a43d3f52bb88ef2409a3731da8e848663559202e4c6" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.state.partial.nullifier_tree] -root = "0x1c13b69ab508e560dc7c25e4f77aed48439749310a58609f31475734efe7287b" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000001c0" +root = "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.hints.previous_block_header.state.partial.public_data_tree] -root = "0x073b8408b98dbac4d5f0c84d47161ee954b8d8e7920e620bf14bc44cb50d07d5" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000008b" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.hints.previous_block_header.global_variables] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000008" - slot_number = "0x0000000000000000000000000000000000000000000000000000000000000025" - timestamp = "0x000000000000000000000000000000000000000000000000000000006a4d2189" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000000" + slot_number = "0x0000000000000000000000000000000000000000000000000000000000000000" + timestamp = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.global_variables.coinbase] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.global_variables.fee_recipient] inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_block_header.global_variables.gas_fees] fee_per_da_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" - fee_per_l2_gas = "0x00000000000000000000000000000000000000000000000000000002f8e08bc0" + fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.hints.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" @@ -25421,13 +26046,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.hints.final_blob_challenges] - z = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" + z = "0x0323ea98046e7dfb23bb8afa0e3b88cb5418dc5857c0660552ba8cfafc9d86a0" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x96bd142e5d415a97f10cda549bd108", + "0xa9a5bde904e677ea35648dbc58905b", + "0x262e" ] [[inputs.hints.blob_commitments]] @@ -25435,18 +26060,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0xdc0744575b26b4c4b7ee41dc7bee5a", - "0xab24ae0f1c266615b22dc3e9ffeecf", - "0xb738f18d636a06615561d266fd2d4d", - "0x19668e" + "0x4da4aae2c5530b730c9c5f26ffc9e8", + "0xe4c843f7701b89c766d5f201f3bd61", + "0xbd0346ed5ed1dbda59247d62c3fef7", + "0x00ba3b" ] [inputs.hints.blob_commitments.y] limbs = [ - "0x713d223616e8efe8cd4821efdde4f2", - "0x9a9a221be261841a9296b4d1eefd77", - "0xdb1af24cb0ccdcba1a7900c4fc1ad5", - "0x15b665" + "0x03d1aa5a043df52839c019d32d9f64", + "0x4724dffeb46756ed087769f4404d1e", + "0x736cf13e91bbeda8581787d66646c2", + "0x10c72e" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml index 365629ea0dba..57d41d09cc12 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-checkpoint-root/Prover.toml @@ -484,17 +484,17 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x17c4bb819a9cc0d99d5e3adbe3afc8004e565750767388207337e77c8a097f53" - in_hash = "0x00b0e02949c7c042e780651385688dcec114af3dbb3892bab1a9cd8e2bbafdc5" - out_hash = "0x00bd3da907cbb210cd100bd369f8dd7eb04b938c69dce277dc1efea8403ed88e" + block_headers_hash = "0x218eecc79215028c26f0d6b52af3fbc8b2072ebe5966398da7525094d0daed4d" + is_first_block = true + out_hash = "0x00746f2611b7b24448263e846ba73bf1861fc6e68dbc605414405a520957a902" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -513,7 +513,7 @@ proof = [ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x02c1e55021910a8552fe034bd1dad5769dec59fc837d88b03d9cf7a8bba0a348" + root = "0x29fde061771e275677f732d70886777109f0477a1215ce9c07480b1539d82335" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] @@ -533,20 +533,20 @@ root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_state.partial.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -567,154 +567,190 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000aa3" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a26" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", - "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f", - "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +] + state = [ + "0x0722b05c2b0f06abd176de7a071a9055ff39a497d4d63d6d2c39d5140ecb52f8", + "0x29ec3c21f8d02e220855f5c5b4a260a5090fe1f8f35f4769d3df98f1c7d34d5c", + "0x2185bd14d30b97a5c4276078635b7240e0d410a867a6b0852bcca7c9a10799fc", + "0x2512de60fc10d6e204b7bf99bfc72943582ad3610981748d0aa56b4c10dcd953" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.previous_rollups.public_inputs.start_msg_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] state = [ - "0x15da51316f6d05717039ebdac951746a67f2039305acba3dde6937f37537a3be", - "0x18d3719d0b48c48b53ca67a10f27a44337f426a5765bad3dacedaacfb6ccac97", - "0x14aff5482ea838000d13644e493656299d3e8d89a40030dbe5ca9bfc7ca80e9b", - "0x101f0785768c74cde83892e08bc25e14d7aff6304b2281bbcdee77377417c602" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.end_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.end_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000f" sibling_path = [ - "0x01343c2fd6c1ffb7f74e657666d03b4842aa647357eeafa82c9a740c7ab7c0f5", - "0x279cfadc25df7db3e8d0a15e10ff6e5f4bcb741888255ef55ded2c7e7f364ffe", - "0x1944964394682423d7fc879430c65da6feda679bf7aba3c1e99a6cbd464ada9a", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x1aef2e89b01e4e061677cac5349fec0eb6935d55d28eef632d06e59bf9063afd", + "0x0ab64a8ec7844b84698532feb08dd86e85cb6e4fec68c5b4161142c43c49ae83", + "0x20bf663f55e9d2ee08565dee96b424f44f3d6254d1f95848fd9bd35f34b6ed3f", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x000000000000000000000000000000000000000000000000000000000000005a", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000006a9667dccdd162d2ae42f4e052ab6feb00", - "0x0000000000000000000000000000000000063291bd0b843c87aff87dbeb8776f", - "0x0000000000000000000000000000004a3e0e4fadc23eda87a6e0b7e2770f97d0", - "0x000000000000000000000000000000000004231112238efcd5a8bbfdf02126af", - "0x00000000000000000000000000000057d27c9209ecd83d9d45357a73671b03ff", - "0x00000000000000000000000000000000000530da1a5fe1fa70f89a7b25183101", - "0x000000000000000000000000000000138ac4080e122ce141128960ac2c5cfd20", - "0x0000000000000000000000000000000000090980ae28917dd4a854759ba202ed", - "0x000000000000000000000000000000fd615c5e6be695bc3f08cb6fbc89726d3a", - "0x00000000000000000000000000000000002e4ee78c63f411c0f2731a1de4234f", - "0x000000000000000000000000000000f7ecdc73440e0f108dc4756df4bfedd84e", - "0x00000000000000000000000000000000002e1eda2438deabb21604f9b80842a4", - "0x0000000000000000000000000000001d3aef4dde892039943e1aeb0d978b20b6", - "0x000000000000000000000000000000000026f3aa754f63457a19998cd5a191d8", - "0x000000000000000000000000000000ac00b422a1ba12bc88fc941a3773b9b62b", - "0x00000000000000000000000000000000001777437ecae54c2781ba66be067d35", - "0x00000000000000000000000000000038481039363f02fcfc4ebd2da51e9d3cc9", - "0x0000000000000000000000000000000000182aba9f2da6e353b27eab1da98c66", - "0x0000000000000000000000000000008b49c75f3efe3ce830c093f883b7d81dc3", - "0x0000000000000000000000000000000000173b08f18df8f22f4051139253d804", - "0x000000000000000000000000000000524613a71ac75a0986d68582ceee6d47bd", - "0x00000000000000000000000000000000001f7e863054817fd349c1a60b6a1b4a", - "0x00000000000000000000000000000001752f62b903d26d79dd6a7398688b5631", - "0x000000000000000000000000000000000003021cb3a85e9463776084ae58a1bd", - "0x000000000000000000000000000000f32d72552e36ee057e56dee89bd470cf9c", - "0x00000000000000000000000000000000002446c410b40892fcef669e0da042a5", - "0x0000000000000000000000000000001c35a61d019a29ff6291b33a41206dd94b", - "0x0000000000000000000000000000000000182dc003198330d46ee04d2ce8829c", - "0x000000000000000000000000000000e97e2dd7dbadcc2995c1e0fcab49fd8f29", - "0x0000000000000000000000000000000000082a0d78185ebf44c412ee980086cc", - "0x000000000000000000000000000000f6d9120bd11108d12ebac08ee2a73a4ee2", - "0x000000000000000000000000000000000016c73e09ea4a37f39f4ae7ebadad6b", + "0x000000000000000000000000000000f1e7ddcc14d1a5d954b81215388a0d348d", + "0x00000000000000000000000000000000000a5caa9ffe2cd5d44288655960fbb9", + "0x00000000000000000000000000000039722eedf301c4f0a8efd6f2a5b349af4c", + "0x000000000000000000000000000000000002fc484866ff4729771b06d59730d3", + "0x0000000000000000000000000000000a13bcac0492974dedf395a6af8eea80d3", + "0x00000000000000000000000000000000002addf6796f866bdc0ed3be86404372", + "0x0000000000000000000000000000005eb92f69d61631d10b47a8e07e15ba655f", + "0x00000000000000000000000000000000001443b0b67361085f625a568644b015", + "0x000000000000000000000000000000a74214365af1b6d41319c9dd8382e9a8f0", + "0x00000000000000000000000000000000002f76e511e2c969dbc5eecb7f670071", + "0x0000000000000000000000000000000001504b38af9f0066a9d2bfbfa02b3b08", + "0x00000000000000000000000000000000000d73b83290e156de6a240fd3ae1b2b", + "0x0000000000000000000000000000006abfb3e6bd55642eb7ed0c7197cfa7a3dd", + "0x0000000000000000000000000000000000076f4d5cfa5c8088106a0c7a9cfa90", + "0x0000000000000000000000000000000709f2356dab09214b4171d4f1d3323326", + "0x00000000000000000000000000000000000b14f0f3f64d7e357a45f0276a1ea9", + "0x0000000000000000000000000000003babe5a95fdd4610840a724bd2ed3828e1", + "0x0000000000000000000000000000000000201cdfdb5a5bc4703457f89df55f98", + "0x000000000000000000000000000000b3fac9da70ad5fa3860ec0ce960f8981d9", + "0x000000000000000000000000000000000010b10135960c565c5349d5f789b5b1", + "0x000000000000000000000000000000c305056fc5f0a60230121d87f8a5d5cb8a", + "0x000000000000000000000000000000000029325cbe3d90e4f70ea17d72e0c4fd", + "0x0000000000000000000000000000009083c259c2a18982a69f48b80acd80bcc4", + "0x00000000000000000000000000000000000218a1611680626e6a316d0b789c69", + "0x0000000000000000000000000000001e8f0c3e04a78ba2ed7ab06f3bbc7715f5", + "0x000000000000000000000000000000000027cbd768f12d7c17b58c80509d62f5", + "0x0000000000000000000000000000003923892efe2dc2fa020857749ce62d5439", + "0x000000000000000000000000000000000014395b407fc85c60a3250accf76758", + "0x0000000000000000000000000000006edff51b3196ff338accb863e273712472", + "0x0000000000000000000000000000000000179cd05231571e8a1f63d1c48674d1", + "0x000000000000000000000000000000195985990189ea39cf9537a33353284b57", + "0x000000000000000000000000000000000005b499926e55583ec9d33533a4293e", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000274ddacf8e96776fe797a1569ab9b79085", - "0x00000000000000000000000000000000002866896852c4af3959a75cacc3a632", - "0x000000000000000000000000000000f88ab574d4ca30564608764a8253c59d75", - "0x000000000000000000000000000000000022427337a713b58d3d8fde1a1235c1", - "0x0000000000000000000000000000004724cde9ce06e5411caabd7dd4fe2dcf89", - "0x0000000000000000000000000000000000267e7e5f0e6e2991964e87475f961b", - "0x0000000000000000000000000000001f11b31d10d889999d1f1349f99703a55f", - "0x00000000000000000000000000000000001ca2da1bd75c23c6533fc450360e0a", - "0x000000000000000000000000000000afbed629fb5fa26fc41e8a923b9ee70fa5", - "0x00000000000000000000000000000000002dbe4a15a76cab43f9be075522c4f7", - "0x000000000000000000000000000000f872acaefe3c6d6ce10c87d61b829fbbec", - "0x00000000000000000000000000000000000da796b562c87f2895396300fea539", - "0x000000000000000000000000000000c9f0341494ab58f3e1e930a49a555b3530", - "0x0000000000000000000000000000000000209512993e91e87bb1d8858c75ece1", - "0x0000000000000000000000000000006909e9ae72e572edc17af4fdf7b4e755eb", - "0x00000000000000000000000000000000001ec0e3b93e01c67030c1aa756fcb40", - "0x0000000000000000000000000000008ce19cfbcd9d36b4d6c2b1c8b00c7ac4ed", - "0x00000000000000000000000000000000002b8384ee941d9da9a54abd43f2277e", - "0x000000000000000000000000000000e0655aece8058e01830ab3c2fccfaf43d4", - "0x00000000000000000000000000000000002129825ddff055bff8da3ac65f9d97", - "0x00000000000000000000000000000072446655f6fbebd858814689ee8d77f733", - "0x00000000000000000000000000000000000fbd2b0c165ae278d54a9f26a77ddb", - "0x00000000000000000000000000000002774107a304abf72ed2ebe7e179274c53", - "0x000000000000000000000000000000000012e445ab5de7b8fd0c6fb507c66a79", - "0x000000000000000000000000000000d14ce80691e789f2d6eef88c0e19739224", - "0x000000000000000000000000000000000015a7d8d72ac0cd46dece1ed45d9cf0", - "0x000000000000000000000000000000dfde16ba0db9360fb86ea22c03a4b0ba15", - "0x00000000000000000000000000000000002557f14c86a34be75255705fe08561", - "0x00000000000000000000000000000019d8b84ecc1a26c797ca5539f68cec2d42", - "0x000000000000000000000000000000000007189c147cd9a5129667b6012c4f5d", - "0x00000000000000000000000000000041054d81036e294b6d2365cc52d68deff4", - "0x00000000000000000000000000000000003047192f88bb7ca1a719faed1a2e0a", - "0x0000000000000000000000000000008f046cbba2c9c3a6a62634c8e14548dd79", - "0x00000000000000000000000000000000000f06ee1ef78193dc70df4c96a85909", - "0x000000000000000000000000000000f3b850e16e232b15077c8ae63bb780225e", - "0x00000000000000000000000000000000000c27b5763ba877829c5ea2028b62e9", - "0x00000000000000000000000000000034a75eaa6b329f2f9ba326bd197b09141e", - "0x0000000000000000000000000000000000202dfa08500a2e8f25017df19adf25", - "0x0000000000000000000000000000008afad1cc67ef6859e2e69f0e109aa60e53", - "0x0000000000000000000000000000000000202651c9cbf4f7bdc4c09481a7183e", - "0x0000000000000000000000000000004ad0e61ee6d136fec3cb6245c23a9d7fa4", - "0x00000000000000000000000000000000001ba6a85f42e9b747bdeb9ec693903d", - "0x000000000000000000000000000000f9167bc703d3994f127e4405ace11cd370", - "0x0000000000000000000000000000000000179429037ebb68f9eaab32e6b0fd95", - "0x00000000000000000000000000000067eef44d6bcc8c84c816c23e48fff9ef1a", - "0x00000000000000000000000000000000000dfaa11abdeec9d4d439ea513fe1bb", - "0x00000000000000000000000000000037299bad92af61aa5b7b7420e2136acd46", - "0x00000000000000000000000000000000001fcbf38a01e3cdf02d1366e71fe833", - "0x0000000000000000000000000000002d8da352b8f27deadac5e960d6e9cb277e", - "0x0000000000000000000000000000000000017bc6f28e4bc9a0ac3ef7569f355b", - "0x0000000000000000000000000000000fcc89a859300fc26d1b6e20c3f1f0aa69", - "0x00000000000000000000000000000000000db738295e84091db3b486a35f79af", - "0x00000000000000000000000000000098974828efb9f8c5313d1990a314808072", - "0x0000000000000000000000000000000000105acf3c77cd5b34b03c6ced8374e8", - "0x000000000000000000000000000000e41f37e5a17c5783f1366590879f3571c3", - "0x00000000000000000000000000000000002567eeabaff2b5808d012d63a8eca4", - "0x000000000000000000000000000000cbefc522c75dca6006c0eec85fb7cf2895", - "0x000000000000000000000000000000000008b1474a3d82ba5e951d3bc1190c54", - "0x000000000000000000000000000000658b1f0d08a6a2f6416bb93ba41bab1f65", - "0x000000000000000000000000000000000010cfb1307729684fd09a393e65859f", - "0x000000000000000000000000000000af595242eb57b0c44971b382c747414407", - "0x00000000000000000000000000000000001533ad4cd0ccb5f880d623c15193ac", - "0x0000000000000000000000000000002e715a02801c283d94e775da9677c3768e", - "0x000000000000000000000000000000000003a5eb9c1337e402b217b9c77fbd90", - "0x000000000000000000000000000000c41740632c841c230a98008525df0a1755", - "0x0000000000000000000000000000000000032858262782b159d5555f8b2e1da7", - "0x0000000000000000000000000000003e61e55d2d51e902fc1c1ca115e973d267", - "0x000000000000000000000000000000000017b56ae8be5f5dc134757ff9487968", - "0x00000000000000000000000000000069aa6cf9ffa5d5ac54c3db14701b8f8145", - "0x0000000000000000000000000000000000125f0b462cd93e4790785c1736a2ae", - "0x000000000000000000000000000000b8f6d5cf38acbf0f3256d9741eafc99913", - "0x00000000000000000000000000000000002cb43f5142fc186556989821e0285f", - "0x000000000000000000000000000000c2958e062d6920c6e2d8b2608c3d5ef552", - "0x0000000000000000000000000000000000064323312ffe1e7332a7400d475bd6", - "0x000000000000000000000000000000a3354f4bc1b37dde35b3cd6a6d8512c79b", - "0x00000000000000000000000000000000001dd4d808f01886425ccca7cb48ca2f" + "0x0000000000000000000000000000002972a9e49d9e5f60a10ee805ff2615663d", + "0x00000000000000000000000000000000002970fe8086600390dee3b98f7d940c", + "0x000000000000000000000000000000bfb1312cbda593e8f4c5473b47d35e3ff2", + "0x00000000000000000000000000000000000766be596296788b2e61417586c808", + "0x00000000000000000000000000000013e4441cf7e4a6a389a39dc21c24275be2", + "0x0000000000000000000000000000000000017aab51c397a2d57778ebe5022782", + "0x00000000000000000000000000000009adaeede4203a41f991031ec50f09bb98", + "0x00000000000000000000000000000000002c9fa3c370cbb1f1bc9128d27307d8", + "0x00000000000000000000000000000086f83dd5fa9178c3c683137ef6a3018c50", + "0x00000000000000000000000000000000000af8d38dc8b77bda3980c013658848", + "0x0000000000000000000000000000007307ee1df3133617f2e5a4d2bbb01f449f", + "0x00000000000000000000000000000000002e27ed3b0658fb9d44ebdb9e459679", + "0x00000000000000000000000000000037ec6f22980fbc5a795d816788a7c7fd87", + "0x000000000000000000000000000000000022973f4a5a82fd556aad37856af147", + "0x000000000000000000000000000000f6f48a91dac1f229b2b35e0fe3ef98abfb", + "0x000000000000000000000000000000000011b923ec095c6746d167d68a4b20e8", + "0x0000000000000000000000000000002d4825c2a902a49bad97fcf3510dea717e", + "0x00000000000000000000000000000000000a00b7e38d47dba44d1fa8d9e462d8", + "0x000000000000000000000000000000f14f2adda7c6729037603c11f6df57543b", + "0x00000000000000000000000000000000000bd236e34f1859cda4709a1895cdab", + "0x000000000000000000000000000000d3678bafd3a8f024c9373604ff3b9445e5", + "0x00000000000000000000000000000000002e41d5db4cb0fc20648504962c7e38", + "0x0000000000000000000000000000004ea6f803bdb1c654c7a3e38c2fc5747710", + "0x000000000000000000000000000000000012b2e307e4788fa75f5058585d1ba3", + "0x00000000000000000000000000000040e8f553b98122828b8a5bb679e7deb97a", + "0x00000000000000000000000000000000000a216b89977ad13bdff479764a27ca", + "0x000000000000000000000000000000933e4f2e04d2cded7e8cd136f18fcc4091", + "0x000000000000000000000000000000000015fcaee6b450c9e8fe7c6f82f7935e", + "0x00000000000000000000000000000000fef9ed223e1c4b1878f1382bb011d550", + "0x00000000000000000000000000000000002375a63f44311595e11cb13f5283f1", + "0x000000000000000000000000000000a7c977ccaf50e4d717c7ae36304af0dc66", + "0x0000000000000000000000000000000000010920abd2eae86f85d82ad9f88492", + "0x000000000000000000000000000000ef0a0674e70bb44ff728d53f5dbfabf7c1", + "0x00000000000000000000000000000000000d68a4ddf4aec05a29640ad1d40ee4", + "0x0000000000000000000000000000007123314f83f27f4833a0048b091d5d62b6", + "0x00000000000000000000000000000000000a8fd7bbc8ee63940f2baf92b53fd5", + "0x000000000000000000000000000000be04b6d97a1a16de66c8bae98cf95e37cc", + "0x000000000000000000000000000000000006849ce9eea56fb180865427034d54", + "0x0000000000000000000000000000002af94cb2b8ffa891913cb9840112bf0418", + "0x000000000000000000000000000000000021996f6ad0f8bb920691927dbcd592", + "0x000000000000000000000000000000fa6286fbf6c493e14b6486f0cb3b76251a", + "0x0000000000000000000000000000000000152c8222ea71be700b89cff2af9bcd", + "0x00000000000000000000000000000067aa0c105df79de2b889a044ecbf3d8d79", + "0x0000000000000000000000000000000000038fb4352d33ac89eeb1cfc441a140", + "0x000000000000000000000000000000b7cc4690c5191469ed4ce6ff94de732ec3", + "0x00000000000000000000000000000000001f533df11d1b8dd79d8af4331d0e65", + "0x000000000000000000000000000000ed3b9d0cc168e1dfdad7343c19a8ca5151", + "0x0000000000000000000000000000000000102355cb5d373d6ad337357a29a49d", + "0x000000000000000000000000000000f72372e068b952b940f0bed9060022b6be", + "0x00000000000000000000000000000000002baec2a144a6d761036c92a80f2b7d", + "0x000000000000000000000000000000cbb74d3007ba42781996344e39eed8ca92", + "0x00000000000000000000000000000000002ead419fd4671a2c55d8e213322757", + "0x0000000000000000000000000000004f1f9b46d63bb7d3f29fef23cdee865eb0", + "0x000000000000000000000000000000000015d453b35cb523095da1bdd087d788", + "0x000000000000000000000000000000f0038d9a9acf1b4f08fd384f73555d992a", + "0x00000000000000000000000000000000002a5916ff6f77368f00e27ffae348a2", + "0x0000000000000000000000000000001fbc7da3e43c92cd5c222c0a5110b583b5", + "0x000000000000000000000000000000000030227502aa8cdfa15452130b05f9e2", + "0x000000000000000000000000000000fbdfd671d0c02ccc7810114ab1d8df3aef", + "0x00000000000000000000000000000000000fee77f7a266bf78678dfb0fb1e9e1", + "0x000000000000000000000000000000e5bd9eec079f9b0c23a7104b5bc61ea63e", + "0x0000000000000000000000000000000000109cd00aae63694c002f41acbb96d7", + "0x0000000000000000000000000000003ee0abb01d4fa17976ba3efe665d72a2e1", + "0x000000000000000000000000000000000000ac0ec029786d7f8944e44270ef4d", + "0x0000000000000000000000000000009a3ae255b2f19a6238782945786d4028ce", + "0x00000000000000000000000000000000002cc7abdf9c27d92fc1ee2cda14a9ba", + "0x00000000000000000000000000000022460d28d93b778fbaf0e4387b1d4671e0", + "0x000000000000000000000000000000000019a8a6bb2563af3217ece000438b61", + "0x000000000000000000000000000000f6684177813b0420369158fb008ca9ed1c", + "0x00000000000000000000000000000000000335080eeedd367f988668e4788b54", + "0x0000000000000000000000000000003545c0cf9e10b59daab4c71d89c37d978b", + "0x00000000000000000000000000000000002106dfd562685db66b6fe3c5e9573b", + "0x000000000000000000000000000000eb65d6937a511f480f7f5d7ac805a2f7e2", + "0x0000000000000000000000000000000000069c9fe9f50c777128416ab06b27eb", + "0x000000000000000000000000000000577ea815b0fdf5fc38c60443f1010ea404", + "0x00000000000000000000000000000000000721a9a9517860e45c200bc7b5656b" ] - hash = "0x06b2006cb3575a42771e0becfe866fcfcef2d52af8bc19f613cabdb3122f2dc7" + hash = "0x227ea6d4336f178d19a6c3a96a9c67886365943c547eba8bc3264352c58d49b5" [[inputs.previous_rollups]] proof = [ @@ -1202,17 +1238,17 @@ proof = [ [inputs.previous_rollups.public_inputs] timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" - block_headers_hash = "0x1edf89104e7d3c14c92c5789cd10e293b3cb0e2f812e155b8277de808ec600ac" - in_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" - out_hash = "0x009be21298b4428b38b9b314446eef3243121c400edd3780e34da475ea5f17c3" + block_headers_hash = "0x2caf799ca4b73c74e7636d845f5ec0c49aad6a0f98753b80c539cd9edb41bd2e" + is_first_block = false + out_hash = "0x00fab7a43a18caf54d1e3dd82cf6d3def175265507c701576b015603f4dd1b44" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" @@ -1227,77 +1263,113 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x02c1e55021910a8552fe034bd1dad5769dec59fc837d88b03d9cf7a8bba0a348" + root = "0x29fde061771e275677f732d70886777109f0477a1215ce9c07480b1539d82335" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000003" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x1c2e04bddbe15b7083e383373e684a691f0687736114926f9500d315a5ea25e0" + root = "0x037cc93bc498d93e6f22ed343cfc0d0a907739b6a26687b43f0d310c49587713" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" [inputs.previous_rollups.public_inputs.start_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.start_state.partial.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_state.partial.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.start_state.partial.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.end_state.l1_to_l2_message_tree] -root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" -next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" +root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_state.partial.note_hash_tree] -root = "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e" +root = "0x144f9224dee4aac6eddc5d988e7c6965528d2e08db91cf58989655a68fbfcc52" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.end_state.partial.nullifier_tree] -root = "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e" +root = "0x191d19a6ad2b7bba03d122035938544f5e65de24aeaa436cd5e4d977bd014505" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000140" [inputs.previous_rollups.public_inputs.end_state.partial.public_data_tree] -root = "0x069ad5cd9f6b5ac53ec9533083d53fb0e3b8cc49b13211bd6d314c00493971c2" -next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000013d" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000aa3" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a26" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", - "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f", - "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" ] state = [ - "0x15da51316f6d05717039ebdac951746a67f2039305acba3dde6937f37537a3be", - "0x18d3719d0b48c48b53ca67a10f27a44337f426a5765bad3dacedaacfb6ccac97", - "0x14aff5482ea838000d13644e493656299d3e8d89a40030dbe5ca9bfc7ca80e9b", - "0x101f0785768c74cde83892e08bc25e14d7aff6304b2281bbcdee77377417c602" + "0x0722b05c2b0f06abd176de7a071a9055ff39a497d4d63d6d2c39d5140ecb52f8", + "0x29ec3c21f8d02e220855f5c5b4a260a5090fe1f8f35f4769d3df98f1c7d34d5c", + "0x2185bd14d30b97a5c4276078635b7240e0d410a867a6b0852bcca7c9a10799fc", + "0x2512de60fc10d6e204b7bf99bfc72943582ad3610981748d0aa56b4c10dcd953" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000ff4" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000efa" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x069ad5cd9f6b5ac53ec9533083d53fb0e3b8cc49b13211bd6d314c00493971c2", - "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e", - "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e" + "0x191d19a6ad2b7bba03d122035938544f5e65de24aeaa436cd5e4d977bd014505", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" +] + state = [ + "0x0ae600d3fc3b4f57ab248c26ab85d8324a16a2b213c111dd286f5b99a07559b7", + "0x1841b2a198b0ef30030e1db7c62945d4436b3ec1dea4996183ad65dcb3588ac0", + "0x2edf6bdcb0d72c1c2e0ce36d43fa346cc88141d25c2378064186b47874cfd695", + "0x1bf03a8ffd50424cadfabd493ddeab35372820df8583a9263db13334932b6871" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.start_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.start_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false + + [inputs.previous_rollups.public_inputs.end_msg_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.previous_rollups.public_inputs.end_msg_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" ] state = [ - "0x0409fd0cb5e0dd58444dad20a67900c2695b87d8f5e2d34be195b93bb7bf673e", - "0x2031bb478bec714f835ec97bb9667f9693b45aa727a624108a69a733d7167b12", - "0x10704cd8a3f1cf73d4d1db112c9d7ead399f9e9ff45f555829c80df54f8048d4", - "0x23f69a4ac36e7f859000638fcf61bb6aeda575453ae3995fae7cc2236b7cbd01" + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" ] cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false @@ -1305,60 +1377,60 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.previous_rollups.vk_data] leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000e" sibling_path = [ - "0x06b2006cb3575a42771e0becfe866fcfcef2d52af8bc19f613cabdb3122f2dc7", - "0x279cfadc25df7db3e8d0a15e10ff6e5f4bcb741888255ef55ded2c7e7f364ffe", - "0x1944964394682423d7fc879430c65da6feda679bf7aba3c1e99a6cbd464ada9a", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x227ea6d4336f178d19a6c3a96a9c67886365943c547eba8bc3264352c58d49b5", + "0x0ab64a8ec7844b84698532feb08dd86e85cb6e4fec68c5b4161142c43c49ae83", + "0x20bf663f55e9d2ee08565dee96b424f44f3d6254d1f95848fd9bd35f34b6ed3f", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ "0x0000000000000000000000000000000000000000000000000000000000000014", - "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x000000000000000000000000000000000000000000000000000000000000005a", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000f68447ed8472d9f9aecf573652a9d9a928", - "0x0000000000000000000000000000000000130b78833f316a05f0ac3ebb960dd6", - "0x000000000000000000000000000000b1b7566b1bdad938d7329c4055a9d3b44b", - "0x00000000000000000000000000000000000f95bf795c56af943937121ccabb11", - "0x0000000000000000000000000000007e871cbdb15c3280bb41589af6d4bf4600", - "0x0000000000000000000000000000000000005841a06f458a5220f323f6e67389", - "0x00000000000000000000000000000037a8be1964e1c1bf15fa90bbade2ae533e", - "0x00000000000000000000000000000000002fd8adf54cbe47073d8c68ab7231c7", - "0x0000000000000000000000000000007e2dfa58dd9e40bb6ee06db57e6892ad8e", - "0x0000000000000000000000000000000000228189c3a773ff5454da3c52426f43", - "0x000000000000000000000000000000ce262d6729da8006583c8f4a499313308d", - "0x0000000000000000000000000000000000121dc58a8b11eda0e11e988dc148f3", - "0x000000000000000000000000000000d483c67a2dd422d558a2bc6a0dc65c5441", - "0x00000000000000000000000000000000001436c8685ec282c19bacd9671e3424", - "0x000000000000000000000000000000505cfbf25a6b529a79d93da8a67a535226", - "0x0000000000000000000000000000000000277d585acb24a736a24c1c8715e0aa", - "0x0000000000000000000000000000000f71609653b0671afa25e611656d7024e2", - "0x000000000000000000000000000000000026075d31cd834975ea2ca0b120b383", - "0x000000000000000000000000000000307b6f68e4b5f4b0b1f1c7bf03a5442d7c", - "0x00000000000000000000000000000000001ef258df94844ef33b6ebc66098df9", - "0x000000000000000000000000000000366ab50465812874d088c1c47734295381", - "0x0000000000000000000000000000000000065332753549245a04b0f54d60d47d", - "0x00000000000000000000000000000016902f2c8fd7591bd62d52226e951c25b0", - "0x00000000000000000000000000000000002c90216fa88bb7b51a01c3ef4a320e", - "0x000000000000000000000000000000bbb432c76b363d49388741cd8557e22106", - "0x00000000000000000000000000000000002565b0ddbf8d6afaa067b84cb1f12e", - "0x000000000000000000000000000000974b3ad2190f2582dda8748859d47859a0", - "0x00000000000000000000000000000000000b31cf0fb5ec5e6d8541057aa4e2f2", - "0x000000000000000000000000000000025960f9968c5bbf83d3f7a484672b98d8", - "0x000000000000000000000000000000000013026001fd1b1981ad17e862f15a34", - "0x0000000000000000000000000000006e292910e9382851ed4de1b3ee3474c02c", - "0x00000000000000000000000000000000000c2fb93933722953cc5775728b35ec", + "0x000000000000000000000000000000171745e04bf3b398c7f018d6c6ae85b3ef", + "0x00000000000000000000000000000000002d29010b4f67617c7fa29ecf4da7bd", + "0x0000000000000000000000000000007e142d358ce3025e203266340fadcb38c0", + "0x00000000000000000000000000000000001acb070656c346e11208f8dca55fae", + "0x000000000000000000000000000000e3e90c58fa5859e2d0aa0fb6b90ae9d265", + "0x000000000000000000000000000000000022783a0a9afc9c35031a0b19c7252e", + "0x000000000000000000000000000000c3a8425b7dcf2974de08a6bea90bfb0e1d", + "0x00000000000000000000000000000000002bd5d0e482013f36dda8eccbf7a069", + "0x0000000000000000000000000000002c67a6a29b02e9d70e2d9c2a7c96ba325e", + "0x000000000000000000000000000000000006313947f257232e74af2725539a51", + "0x000000000000000000000000000000f96f7f92eb52e2421e05bf6726e5f7e46b", + "0x0000000000000000000000000000000000124964611e1e45432d534a938db40a", + "0x00000000000000000000000000000086b5767bea5905c98b657e7d7c5df5be52", + "0x00000000000000000000000000000000000b5d55777d6fbbbfedb0ab4159fe8e", + "0x000000000000000000000000000000f6cb975fc5e09435cab1575065181c9c2c", + "0x00000000000000000000000000000000001f582f62643dea4ddeff66741e8701", + "0x000000000000000000000000000000c1cc0960b5deade01b39fb1f622cae521a", + "0x00000000000000000000000000000000001580775480fdb3833934a90121e165", + "0x000000000000000000000000000000774ea1c3c41ff817e476e5530bca26eaab", + "0x000000000000000000000000000000000006bda2f1bb3dc2cbc0d79d978af377", + "0x000000000000000000000000000000419449bd1437352776172dd6816ce01dd2", + "0x00000000000000000000000000000000002e348f228b7408ea46fe5e1e025505", + "0x0000000000000000000000000000007ce1205f647113997b2de73126f283392e", + "0x00000000000000000000000000000000002d5e513e28ac080651a3520945c0dd", + "0x000000000000000000000000000000ad4992f90698806c2026a963d6c03b5db0", + "0x00000000000000000000000000000000001299de9aa8babae826bf90a96c3cbd", + "0x0000000000000000000000000000005baecf5414ff1c3aa1e099c5c2895f939f", + "0x00000000000000000000000000000000000c43f1a9a1c99f5f121a8672e1ad98", + "0x000000000000000000000000000000053cf0a6319726d0a4e166968e5b693d5d", + "0x000000000000000000000000000000000013003ee93f6bba3ca2dc482d747dd8", + "0x000000000000000000000000000000caa294c2200f26ea3353353f2abbab015a", + "0x0000000000000000000000000000000000174b38a5ed5ae78a18ca17193a5d66", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000239e2f11ea91c867d7080a159fc15e5711", - "0x000000000000000000000000000000000020983a3f65fd98715524f3be6a4d48", - "0x0000000000000000000000000000006251dee2124c8e8689c942362741d1b770", - "0x00000000000000000000000000000000002990e25ef65b37a0c14b2a53e370aa", + "0x000000000000000000000000000000811ba385bb8164bb5124cb1ae0b3ccb0c8", + "0x000000000000000000000000000000000014a46f70f1518de5fada5f535fab0d", + "0x000000000000000000000000000000cd91281c2f45667dcbe30858ef08312a30", + "0x00000000000000000000000000000000000ed382566771a880cc4467c7948f6b", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1379,60 +1451,649 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000005202c34600815583df0c2d0e0b711d9da9", - "0x000000000000000000000000000000000013c8db79f7fdf811172fde1144dee9", - "0x00000000000000000000000000000052109b26b144a2cdc1af4e5e60c04be21a", - "0x00000000000000000000000000000000002393c00b1515c1404d7d61513a265f", - "0x0000000000000000000000000000007241727fbbf4010a2c843195cdbeafd157", - "0x00000000000000000000000000000000000a795ef6998b55f779b66ac9d12933", - "0x0000000000000000000000000000001aee6f0314cb405e0bb90e540c1d4b5825", - "0x0000000000000000000000000000000000224ad4b3d1292b0599b3a2d611f162", - "0x000000000000000000000000000000f91ff5901f79ce2e9d2658719987ab0623", - "0x00000000000000000000000000000000001805237be733c97c8936141b767f20", - "0x000000000000000000000000000000a463dafbf5544b77b523e6d0b2e184f1b7", - "0x00000000000000000000000000000000000dd5ca5243a5f9287374bfe50d7231", - "0x000000000000000000000000000000d9d38a9ffb02c68fde1512e5bd4c4c14a1", - "0x00000000000000000000000000000000001feb05f2a116d8eb36aa9d0d39a059", - "0x00000000000000000000000000000036722e643e3ae6ed827a7a3545cb08d7af", - "0x00000000000000000000000000000000002a3543973beaa6206a0c0a81bc4d00", - "0x000000000000000000000000000000df116db890832c4330270e033c9c5b4672", - "0x000000000000000000000000000000000023249bec10f97d4e917ac37cd51f84", - "0x0000000000000000000000000000008c2ac8784c4c7231ef13cf8a40238cde28", - "0x00000000000000000000000000000000001a796365a3f5248fe27f83bbdfc204", - "0x0000000000000000000000000000004d37afbe9da8f90b8baf6fc91e16d8d686", - "0x0000000000000000000000000000000000239d7a93793b18511f1718afa60011", - "0x0000000000000000000000000000006553c4d22e787acd03956f3b68568d5af6", - "0x000000000000000000000000000000000019f0fa65aacb4f914e73a29b12ff95", - "0x00000000000000000000000000000021f7c2075b834340682cd55e057cd40797", - "0x000000000000000000000000000000000020cf3ed909b8b916f364f3e092d695", - "0x000000000000000000000000000000560c871bf2b8a17f94e0ee25d928b95ba5", - "0x000000000000000000000000000000000024ae77e31b4f17dd55e0eec865690d", - "0x00000000000000000000000000000084690b7ac3d1dddfcaa97b06bda3931daf", - "0x00000000000000000000000000000000002e5eea7caf51d4bf55b60a155b924a", - "0x0000000000000000000000000000004739db956c4c8cadd30b1ddf710b76bef3", - "0x00000000000000000000000000000000000c167a87058b33567470ed345dd62c", + "0x000000000000000000000000000000d08dc4216b73b18e4c3ed59f21747b058f", + "0x00000000000000000000000000000000000f066d4a5afea9a9b17ac7a4a7cc99", + "0x000000000000000000000000000000ae5a45c00369f87fd89e22ed8e9ae1b26c", + "0x00000000000000000000000000000000001772032f7513bfb4ec87cb3c381466", + "0x000000000000000000000000000000e844445263c1d09569b0a208a43dac22b0", + "0x0000000000000000000000000000000000200746d0ebd31e3100e54785e10a4e", + "0x000000000000000000000000000000e3abbce6e85aa82777100e42a403024f3b", + "0x00000000000000000000000000000000000edcdda7c859a9d532c0ecfb8ae20d", + "0x00000000000000000000000000000077654349e6de2d9f54eecec593fad39688", + "0x00000000000000000000000000000000001858d1181a4a332e734715b230cc59", + "0x000000000000000000000000000000175f205fe38af64c31f7109fe199ec1900", + "0x00000000000000000000000000000000001dc0769cc520d9832a85f6fc6ad2f0", + "0x000000000000000000000000000000b21544115e91a3e87e82672d838b37ba80", + "0x0000000000000000000000000000000000304b97f5ba72167a15c0b833fc6e8d", + "0x00000000000000000000000000000000a28a8d6a681bfedafbb78c8f05565163", + "0x00000000000000000000000000000000002617676042a6adddc34ef4325149de", + "0x00000000000000000000000000000087ed1863d8e1416fb7158da65866e4905c", + "0x0000000000000000000000000000000000297bf50f0815ed89b57efede14c221", + "0x000000000000000000000000000000ae75086dec67f3335af3eb56b5b59b46a8", + "0x00000000000000000000000000000000002f0ba91e3b0790f289a7a77033e944", + "0x0000000000000000000000000000008f1dc7ef52a66f9709b8276541459e5095", + "0x00000000000000000000000000000000001b8b733300f4a04e62e2b50cc13537", + "0x000000000000000000000000000000120c29128fdee9cac819e27d5e59b62c29", + "0x000000000000000000000000000000000007f266f7b45c332f902e07fdd930bb", + "0x000000000000000000000000000000673453fb2c427268658bd000eeff115cb1", + "0x00000000000000000000000000000000000bc9ee806b99e82569edbb5f01728f", + "0x00000000000000000000000000000060ede2f231b1961d20baa0c6b4195e45bf", + "0x00000000000000000000000000000000001a9ea1cc089db77b86d97e1b446b29", + "0x000000000000000000000000000000a240272a1d5cf9035d901f1e883f40dd04", + "0x00000000000000000000000000000000000d1d8059a04690c9ff079bc8e360ab", + "0x0000000000000000000000000000001ed32f48f420b19033840fedaab24a3671", + "0x00000000000000000000000000000000002a73ca315ef97290b6770ea6777586", + "0x0000000000000000000000000000005e496c48f730a346769ce8bc2fa408dd59", + "0x00000000000000000000000000000000001f44c5be9e8cb3632b163f9dce5b20", + "0x0000000000000000000000000000009a00247b355a24abf0fb6c6c38110e74ea", + "0x0000000000000000000000000000000000186011779c1a4f37f6ab96ec86ba1a", + "0x0000000000000000000000000000002c0ae96c1361972ddb673c19f868179414", + "0x000000000000000000000000000000000029aaace5fe8f52e2ffdb68539bf235", + "0x0000000000000000000000000000006d052b1eff6e35a175c1929237f54f145b", + "0x00000000000000000000000000000000000f79b8aa3c77ea22fec93ed13cc5db", + "0x0000000000000000000000000000008052b188ebeacba7640c39ca287fb43e02", + "0x00000000000000000000000000000000002c779c488a957ccbecd16bc0cef28f", + "0x0000000000000000000000000000003f0e4e60d839ab664210af647497054ec0", + "0x000000000000000000000000000000000017ac139d9ed663f80bc8f3bf9186eb", + "0x000000000000000000000000000000cd1b57f96c184006a7673bf67a70da6652", + "0x000000000000000000000000000000000008708c2dfc9b753226ad22fe6c36b3", + "0x0000000000000000000000000000006bcef5e19dcef445d5a8db81b6d9045df9", + "0x0000000000000000000000000000000000249f0fa7bf3615dc480813e351a6fc", + "0x000000000000000000000000000000edcc29049f239f4a6a6713f3d83c690c5c", + "0x000000000000000000000000000000000021e16eb6b2964938cc952d8f835ae7", + "0x00000000000000000000000000000065b062c409079f27e1fbcaa3227ce4c2f7", + "0x00000000000000000000000000000000001ef55120570e943466eefd433a3ebf" +] + hash = "0x1aef2e89b01e4e061677cac5349fec0eb6935d55d28eef632d06e59bf9063afd" + +[inputs.inbox_parity] +proof = [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000000000000000000000000000b", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x000000000000000000000000000000000000000000000000000000000000000e", + "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x0000000000000000000000000000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000000000000000000000000000013", + "0x0000000000000000000000000000000000000000000000000000000000000014", + "0x0000000000000000000000000000000000000000000000000000000000000015", + "0x0000000000000000000000000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000018", + "0x0000000000000000000000000000000000000000000000000000000000000019", + "0x000000000000000000000000000000000000000000000000000000000000001a", + "0x000000000000000000000000000000000000000000000000000000000000001b", + "0x000000000000000000000000000000000000000000000000000000000000001c", + "0x000000000000000000000000000000000000000000000000000000000000001d", + "0x000000000000000000000000000000000000000000000000000000000000001e", + "0x000000000000000000000000000000000000000000000000000000000000001f", + "0x0000000000000000000000000000000000000000000000000000000000000020", + "0x0000000000000000000000000000000000000000000000000000000000000021", + "0x0000000000000000000000000000000000000000000000000000000000000022", + "0x0000000000000000000000000000000000000000000000000000000000000023", + "0x0000000000000000000000000000000000000000000000000000000000000024", + "0x0000000000000000000000000000000000000000000000000000000000000025", + "0x0000000000000000000000000000000000000000000000000000000000000026", + "0x0000000000000000000000000000000000000000000000000000000000000027", + "0x0000000000000000000000000000000000000000000000000000000000000028", + "0x0000000000000000000000000000000000000000000000000000000000000029", + "0x000000000000000000000000000000000000000000000000000000000000002a", + "0x000000000000000000000000000000000000000000000000000000000000002b", + "0x000000000000000000000000000000000000000000000000000000000000002c", + "0x000000000000000000000000000000000000000000000000000000000000002d", + "0x000000000000000000000000000000000000000000000000000000000000002e", + "0x000000000000000000000000000000000000000000000000000000000000002f", + "0x0000000000000000000000000000000000000000000000000000000000000030", + "0x0000000000000000000000000000000000000000000000000000000000000031", + "0x0000000000000000000000000000000000000000000000000000000000000032", + "0x0000000000000000000000000000000000000000000000000000000000000033", + "0x0000000000000000000000000000000000000000000000000000000000000034", + "0x0000000000000000000000000000000000000000000000000000000000000035", + "0x0000000000000000000000000000000000000000000000000000000000000036", + "0x0000000000000000000000000000000000000000000000000000000000000037", + "0x0000000000000000000000000000000000000000000000000000000000000038", + "0x0000000000000000000000000000000000000000000000000000000000000039", + "0x000000000000000000000000000000000000000000000000000000000000003a", + "0x000000000000000000000000000000000000000000000000000000000000003b", + "0x000000000000000000000000000000000000000000000000000000000000003c", + "0x000000000000000000000000000000000000000000000000000000000000003d", + "0x000000000000000000000000000000000000000000000000000000000000003e", + "0x000000000000000000000000000000000000000000000000000000000000003f", + "0x0000000000000000000000000000000000000000000000000000000000000040", + "0x0000000000000000000000000000000000000000000000000000000000000041", + "0x0000000000000000000000000000000000000000000000000000000000000042", + "0x0000000000000000000000000000000000000000000000000000000000000043", + "0x0000000000000000000000000000000000000000000000000000000000000044", + "0x0000000000000000000000000000000000000000000000000000000000000045", + "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x0000000000000000000000000000000000000000000000000000000000000047", + "0x0000000000000000000000000000000000000000000000000000000000000048", + "0x0000000000000000000000000000000000000000000000000000000000000049", + "0x000000000000000000000000000000000000000000000000000000000000004a", + "0x000000000000000000000000000000000000000000000000000000000000004b", + "0x000000000000000000000000000000000000000000000000000000000000004c", + "0x000000000000000000000000000000000000000000000000000000000000004d", + "0x000000000000000000000000000000000000000000000000000000000000004e", + "0x000000000000000000000000000000000000000000000000000000000000004f", + "0x0000000000000000000000000000000000000000000000000000000000000050", + "0x0000000000000000000000000000000000000000000000000000000000000051", + "0x0000000000000000000000000000000000000000000000000000000000000052", + "0x0000000000000000000000000000000000000000000000000000000000000053", + "0x0000000000000000000000000000000000000000000000000000000000000054", + "0x0000000000000000000000000000000000000000000000000000000000000055", + "0x0000000000000000000000000000000000000000000000000000000000000056", + "0x0000000000000000000000000000000000000000000000000000000000000057", + "0x0000000000000000000000000000000000000000000000000000000000000058", + "0x0000000000000000000000000000000000000000000000000000000000000059", + "0x000000000000000000000000000000000000000000000000000000000000005a", + "0x000000000000000000000000000000000000000000000000000000000000005b", + "0x000000000000000000000000000000000000000000000000000000000000005c", + "0x000000000000000000000000000000000000000000000000000000000000005d", + "0x000000000000000000000000000000000000000000000000000000000000005e", + "0x000000000000000000000000000000000000000000000000000000000000005f", + "0x0000000000000000000000000000000000000000000000000000000000000060", + "0x0000000000000000000000000000000000000000000000000000000000000061", + "0x0000000000000000000000000000000000000000000000000000000000000062", + "0x0000000000000000000000000000000000000000000000000000000000000063", + "0x0000000000000000000000000000000000000000000000000000000000000064", + "0x0000000000000000000000000000000000000000000000000000000000000065", + "0x0000000000000000000000000000000000000000000000000000000000000066", + "0x0000000000000000000000000000000000000000000000000000000000000067", + "0x0000000000000000000000000000000000000000000000000000000000000068", + "0x0000000000000000000000000000000000000000000000000000000000000069", + "0x000000000000000000000000000000000000000000000000000000000000006a", + "0x000000000000000000000000000000000000000000000000000000000000006b", + "0x000000000000000000000000000000000000000000000000000000000000006c", + "0x000000000000000000000000000000000000000000000000000000000000006d", + "0x000000000000000000000000000000000000000000000000000000000000006e", + "0x000000000000000000000000000000000000000000000000000000000000006f", + "0x0000000000000000000000000000000000000000000000000000000000000070", + "0x0000000000000000000000000000000000000000000000000000000000000071", + "0x0000000000000000000000000000000000000000000000000000000000000072", + "0x0000000000000000000000000000000000000000000000000000000000000073", + "0x0000000000000000000000000000000000000000000000000000000000000074", + "0x0000000000000000000000000000000000000000000000000000000000000075", + "0x0000000000000000000000000000000000000000000000000000000000000076", + "0x0000000000000000000000000000000000000000000000000000000000000077", + "0x0000000000000000000000000000000000000000000000000000000000000078", + "0x0000000000000000000000000000000000000000000000000000000000000079", + "0x000000000000000000000000000000000000000000000000000000000000007a", + "0x000000000000000000000000000000000000000000000000000000000000007b", + "0x000000000000000000000000000000000000000000000000000000000000007c", + "0x000000000000000000000000000000000000000000000000000000000000007d", + "0x000000000000000000000000000000000000000000000000000000000000007e", + "0x000000000000000000000000000000000000000000000000000000000000007f", + "0x0000000000000000000000000000000000000000000000000000000000000080", + "0x0000000000000000000000000000000000000000000000000000000000000081", + "0x0000000000000000000000000000000000000000000000000000000000000082", + "0x0000000000000000000000000000000000000000000000000000000000000083", + "0x0000000000000000000000000000000000000000000000000000000000000084", + "0x0000000000000000000000000000000000000000000000000000000000000085", + "0x0000000000000000000000000000000000000000000000000000000000000086", + "0x0000000000000000000000000000000000000000000000000000000000000087", + "0x0000000000000000000000000000000000000000000000000000000000000088", + "0x0000000000000000000000000000000000000000000000000000000000000089", + "0x000000000000000000000000000000000000000000000000000000000000008a", + "0x000000000000000000000000000000000000000000000000000000000000008b", + "0x000000000000000000000000000000000000000000000000000000000000008c", + "0x000000000000000000000000000000000000000000000000000000000000008d", + "0x000000000000000000000000000000000000000000000000000000000000008e", + "0x000000000000000000000000000000000000000000000000000000000000008f", + "0x0000000000000000000000000000000000000000000000000000000000000090", + "0x0000000000000000000000000000000000000000000000000000000000000091", + "0x0000000000000000000000000000000000000000000000000000000000000092", + "0x0000000000000000000000000000000000000000000000000000000000000093", + "0x0000000000000000000000000000000000000000000000000000000000000094", + "0x0000000000000000000000000000000000000000000000000000000000000095", + "0x0000000000000000000000000000000000000000000000000000000000000096", + "0x0000000000000000000000000000000000000000000000000000000000000097", + "0x0000000000000000000000000000000000000000000000000000000000000098", + "0x0000000000000000000000000000000000000000000000000000000000000099", + "0x000000000000000000000000000000000000000000000000000000000000009a", + "0x000000000000000000000000000000000000000000000000000000000000009b", + "0x000000000000000000000000000000000000000000000000000000000000009c", + "0x000000000000000000000000000000000000000000000000000000000000009d", + "0x000000000000000000000000000000000000000000000000000000000000009e", + "0x000000000000000000000000000000000000000000000000000000000000009f", + "0x00000000000000000000000000000000000000000000000000000000000000a0", + "0x00000000000000000000000000000000000000000000000000000000000000a1", + "0x00000000000000000000000000000000000000000000000000000000000000a2", + "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x00000000000000000000000000000000000000000000000000000000000000a4", + "0x00000000000000000000000000000000000000000000000000000000000000a5", + "0x00000000000000000000000000000000000000000000000000000000000000a6", + "0x00000000000000000000000000000000000000000000000000000000000000a7", + "0x00000000000000000000000000000000000000000000000000000000000000a8", + "0x00000000000000000000000000000000000000000000000000000000000000a9", + "0x00000000000000000000000000000000000000000000000000000000000000aa", + "0x00000000000000000000000000000000000000000000000000000000000000ab", + "0x00000000000000000000000000000000000000000000000000000000000000ac", + "0x00000000000000000000000000000000000000000000000000000000000000ad", + "0x00000000000000000000000000000000000000000000000000000000000000ae", + "0x00000000000000000000000000000000000000000000000000000000000000af", + "0x00000000000000000000000000000000000000000000000000000000000000b0", + "0x00000000000000000000000000000000000000000000000000000000000000b1", + "0x00000000000000000000000000000000000000000000000000000000000000b2", + "0x00000000000000000000000000000000000000000000000000000000000000b3", + "0x00000000000000000000000000000000000000000000000000000000000000b4", + "0x00000000000000000000000000000000000000000000000000000000000000b5", + "0x00000000000000000000000000000000000000000000000000000000000000b6", + "0x00000000000000000000000000000000000000000000000000000000000000b7", + "0x00000000000000000000000000000000000000000000000000000000000000b8", + "0x00000000000000000000000000000000000000000000000000000000000000b9", + "0x00000000000000000000000000000000000000000000000000000000000000ba", + "0x00000000000000000000000000000000000000000000000000000000000000bb", + "0x00000000000000000000000000000000000000000000000000000000000000bc", + "0x00000000000000000000000000000000000000000000000000000000000000bd", + "0x00000000000000000000000000000000000000000000000000000000000000be", + "0x00000000000000000000000000000000000000000000000000000000000000bf", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000c1", + "0x00000000000000000000000000000000000000000000000000000000000000c2", + "0x00000000000000000000000000000000000000000000000000000000000000c3", + "0x00000000000000000000000000000000000000000000000000000000000000c4", + "0x00000000000000000000000000000000000000000000000000000000000000c5", + "0x00000000000000000000000000000000000000000000000000000000000000c6", + "0x00000000000000000000000000000000000000000000000000000000000000c7", + "0x00000000000000000000000000000000000000000000000000000000000000c8", + "0x00000000000000000000000000000000000000000000000000000000000000c9", + "0x00000000000000000000000000000000000000000000000000000000000000ca", + "0x00000000000000000000000000000000000000000000000000000000000000cb", + "0x00000000000000000000000000000000000000000000000000000000000000cc", + "0x00000000000000000000000000000000000000000000000000000000000000cd", + "0x00000000000000000000000000000000000000000000000000000000000000ce", + "0x00000000000000000000000000000000000000000000000000000000000000cf", + "0x00000000000000000000000000000000000000000000000000000000000000d0", + "0x00000000000000000000000000000000000000000000000000000000000000d1", + "0x00000000000000000000000000000000000000000000000000000000000000d2", + "0x00000000000000000000000000000000000000000000000000000000000000d3", + "0x00000000000000000000000000000000000000000000000000000000000000d4", + "0x00000000000000000000000000000000000000000000000000000000000000d5", + "0x00000000000000000000000000000000000000000000000000000000000000d6", + "0x00000000000000000000000000000000000000000000000000000000000000d7", + "0x00000000000000000000000000000000000000000000000000000000000000d8", + "0x00000000000000000000000000000000000000000000000000000000000000d9", + "0x00000000000000000000000000000000000000000000000000000000000000da", + "0x00000000000000000000000000000000000000000000000000000000000000db", + "0x00000000000000000000000000000000000000000000000000000000000000dc", + "0x00000000000000000000000000000000000000000000000000000000000000dd", + "0x00000000000000000000000000000000000000000000000000000000000000de", + "0x00000000000000000000000000000000000000000000000000000000000000df", + "0x00000000000000000000000000000000000000000000000000000000000000e0", + "0x00000000000000000000000000000000000000000000000000000000000000e1", + "0x00000000000000000000000000000000000000000000000000000000000000e2", + "0x00000000000000000000000000000000000000000000000000000000000000e3", + "0x00000000000000000000000000000000000000000000000000000000000000e4", + "0x00000000000000000000000000000000000000000000000000000000000000e5", + "0x00000000000000000000000000000000000000000000000000000000000000e6", + "0x00000000000000000000000000000000000000000000000000000000000000e7", + "0x00000000000000000000000000000000000000000000000000000000000000e8", + "0x00000000000000000000000000000000000000000000000000000000000000e9", + "0x00000000000000000000000000000000000000000000000000000000000000ea", + "0x00000000000000000000000000000000000000000000000000000000000000eb", + "0x00000000000000000000000000000000000000000000000000000000000000ec", + "0x00000000000000000000000000000000000000000000000000000000000000ed", + "0x00000000000000000000000000000000000000000000000000000000000000ee", + "0x00000000000000000000000000000000000000000000000000000000000000ef", + "0x00000000000000000000000000000000000000000000000000000000000000f0", + "0x00000000000000000000000000000000000000000000000000000000000000f1", + "0x00000000000000000000000000000000000000000000000000000000000000f2", + "0x00000000000000000000000000000000000000000000000000000000000000f3", + "0x00000000000000000000000000000000000000000000000000000000000000f4", + "0x00000000000000000000000000000000000000000000000000000000000000f5", + "0x00000000000000000000000000000000000000000000000000000000000000f6", + "0x00000000000000000000000000000000000000000000000000000000000000f7", + "0x00000000000000000000000000000000000000000000000000000000000000f8", + "0x00000000000000000000000000000000000000000000000000000000000000f9", + "0x00000000000000000000000000000000000000000000000000000000000000fa", + "0x00000000000000000000000000000000000000000000000000000000000000fb", + "0x00000000000000000000000000000000000000000000000000000000000000fc", + "0x00000000000000000000000000000000000000000000000000000000000000fd", + "0x00000000000000000000000000000000000000000000000000000000000000fe", + "0x00000000000000000000000000000000000000000000000000000000000000ff", + "0x0000000000000000000000000000000000000000000000000000000000000100", + "0x0000000000000000000000000000000000000000000000000000000000000101", + "0x0000000000000000000000000000000000000000000000000000000000000102", + "0x0000000000000000000000000000000000000000000000000000000000000103", + "0x0000000000000000000000000000000000000000000000000000000000000104", + "0x0000000000000000000000000000000000000000000000000000000000000105", + "0x0000000000000000000000000000000000000000000000000000000000000106", + "0x0000000000000000000000000000000000000000000000000000000000000107", + "0x0000000000000000000000000000000000000000000000000000000000000108", + "0x0000000000000000000000000000000000000000000000000000000000000109", + "0x000000000000000000000000000000000000000000000000000000000000010a", + "0x000000000000000000000000000000000000000000000000000000000000010b", + "0x000000000000000000000000000000000000000000000000000000000000010c", + "0x000000000000000000000000000000000000000000000000000000000000010d", + "0x000000000000000000000000000000000000000000000000000000000000010e", + "0x000000000000000000000000000000000000000000000000000000000000010f", + "0x0000000000000000000000000000000000000000000000000000000000000110", + "0x0000000000000000000000000000000000000000000000000000000000000111", + "0x0000000000000000000000000000000000000000000000000000000000000112", + "0x0000000000000000000000000000000000000000000000000000000000000113", + "0x0000000000000000000000000000000000000000000000000000000000000114", + "0x0000000000000000000000000000000000000000000000000000000000000115", + "0x0000000000000000000000000000000000000000000000000000000000000116", + "0x0000000000000000000000000000000000000000000000000000000000000117", + "0x0000000000000000000000000000000000000000000000000000000000000118", + "0x0000000000000000000000000000000000000000000000000000000000000119", + "0x000000000000000000000000000000000000000000000000000000000000011a", + "0x000000000000000000000000000000000000000000000000000000000000011b", + "0x000000000000000000000000000000000000000000000000000000000000011c", + "0x000000000000000000000000000000000000000000000000000000000000011d", + "0x000000000000000000000000000000000000000000000000000000000000011e", + "0x000000000000000000000000000000000000000000000000000000000000011f", + "0x0000000000000000000000000000000000000000000000000000000000000120", + "0x0000000000000000000000000000000000000000000000000000000000000121", + "0x0000000000000000000000000000000000000000000000000000000000000122", + "0x0000000000000000000000000000000000000000000000000000000000000123", + "0x0000000000000000000000000000000000000000000000000000000000000124", + "0x0000000000000000000000000000000000000000000000000000000000000125", + "0x0000000000000000000000000000000000000000000000000000000000000126", + "0x0000000000000000000000000000000000000000000000000000000000000127", + "0x0000000000000000000000000000000000000000000000000000000000000128", + "0x0000000000000000000000000000000000000000000000000000000000000129", + "0x000000000000000000000000000000000000000000000000000000000000012a", + "0x000000000000000000000000000000000000000000000000000000000000012b", + "0x000000000000000000000000000000000000000000000000000000000000012c", + "0x000000000000000000000000000000000000000000000000000000000000012d", + "0x000000000000000000000000000000000000000000000000000000000000012e", + "0x000000000000000000000000000000000000000000000000000000000000012f", + "0x0000000000000000000000000000000000000000000000000000000000000130", + "0x0000000000000000000000000000000000000000000000000000000000000131", + "0x0000000000000000000000000000000000000000000000000000000000000132", + "0x0000000000000000000000000000000000000000000000000000000000000133", + "0x0000000000000000000000000000000000000000000000000000000000000134", + "0x0000000000000000000000000000000000000000000000000000000000000135", + "0x0000000000000000000000000000000000000000000000000000000000000136", + "0x0000000000000000000000000000000000000000000000000000000000000137", + "0x0000000000000000000000000000000000000000000000000000000000000138", + "0x0000000000000000000000000000000000000000000000000000000000000139", + "0x000000000000000000000000000000000000000000000000000000000000013a", + "0x000000000000000000000000000000000000000000000000000000000000013b", + "0x000000000000000000000000000000000000000000000000000000000000013c", + "0x000000000000000000000000000000000000000000000000000000000000013d", + "0x000000000000000000000000000000000000000000000000000000000000013e", + "0x000000000000000000000000000000000000000000000000000000000000013f", + "0x0000000000000000000000000000000000000000000000000000000000000140", + "0x0000000000000000000000000000000000000000000000000000000000000141", + "0x0000000000000000000000000000000000000000000000000000000000000142", + "0x0000000000000000000000000000000000000000000000000000000000000143", + "0x0000000000000000000000000000000000000000000000000000000000000144", + "0x0000000000000000000000000000000000000000000000000000000000000145", + "0x0000000000000000000000000000000000000000000000000000000000000146", + "0x0000000000000000000000000000000000000000000000000000000000000147", + "0x0000000000000000000000000000000000000000000000000000000000000148", + "0x0000000000000000000000000000000000000000000000000000000000000149", + "0x000000000000000000000000000000000000000000000000000000000000014a", + "0x000000000000000000000000000000000000000000000000000000000000014b", + "0x000000000000000000000000000000000000000000000000000000000000014c", + "0x000000000000000000000000000000000000000000000000000000000000014d", + "0x000000000000000000000000000000000000000000000000000000000000014e", + "0x000000000000000000000000000000000000000000000000000000000000014f", + "0x0000000000000000000000000000000000000000000000000000000000000150", + "0x0000000000000000000000000000000000000000000000000000000000000151", + "0x0000000000000000000000000000000000000000000000000000000000000152", + "0x0000000000000000000000000000000000000000000000000000000000000153", + "0x0000000000000000000000000000000000000000000000000000000000000154", + "0x0000000000000000000000000000000000000000000000000000000000000155", + "0x0000000000000000000000000000000000000000000000000000000000000156", + "0x0000000000000000000000000000000000000000000000000000000000000157", + "0x0000000000000000000000000000000000000000000000000000000000000158", + "0x0000000000000000000000000000000000000000000000000000000000000159", + "0x000000000000000000000000000000000000000000000000000000000000015a", + "0x000000000000000000000000000000000000000000000000000000000000015b", + "0x000000000000000000000000000000000000000000000000000000000000015c", + "0x000000000000000000000000000000000000000000000000000000000000015d", + "0x000000000000000000000000000000000000000000000000000000000000015e", + "0x000000000000000000000000000000000000000000000000000000000000015f", + "0x0000000000000000000000000000000000000000000000000000000000000160", + "0x0000000000000000000000000000000000000000000000000000000000000161", + "0x0000000000000000000000000000000000000000000000000000000000000162", + "0x0000000000000000000000000000000000000000000000000000000000000163", + "0x0000000000000000000000000000000000000000000000000000000000000164", + "0x0000000000000000000000000000000000000000000000000000000000000165", + "0x0000000000000000000000000000000000000000000000000000000000000166", + "0x0000000000000000000000000000000000000000000000000000000000000167", + "0x0000000000000000000000000000000000000000000000000000000000000168", + "0x0000000000000000000000000000000000000000000000000000000000000169", + "0x000000000000000000000000000000000000000000000000000000000000016a", + "0x000000000000000000000000000000000000000000000000000000000000016b", + "0x000000000000000000000000000000000000000000000000000000000000016c", + "0x000000000000000000000000000000000000000000000000000000000000016d", + "0x000000000000000000000000000000000000000000000000000000000000016e", + "0x000000000000000000000000000000000000000000000000000000000000016f", + "0x0000000000000000000000000000000000000000000000000000000000000170", + "0x0000000000000000000000000000000000000000000000000000000000000171", + "0x0000000000000000000000000000000000000000000000000000000000000172", + "0x0000000000000000000000000000000000000000000000000000000000000173", + "0x0000000000000000000000000000000000000000000000000000000000000174", + "0x0000000000000000000000000000000000000000000000000000000000000175", + "0x0000000000000000000000000000000000000000000000000000000000000176", + "0x0000000000000000000000000000000000000000000000000000000000000177", + "0x0000000000000000000000000000000000000000000000000000000000000178", + "0x0000000000000000000000000000000000000000000000000000000000000179", + "0x000000000000000000000000000000000000000000000000000000000000017a", + "0x000000000000000000000000000000000000000000000000000000000000017b", + "0x000000000000000000000000000000000000000000000000000000000000017c", + "0x000000000000000000000000000000000000000000000000000000000000017d", + "0x000000000000000000000000000000000000000000000000000000000000017e", + "0x000000000000000000000000000000000000000000000000000000000000017f", + "0x0000000000000000000000000000000000000000000000000000000000000180", + "0x0000000000000000000000000000000000000000000000000000000000000181", + "0x0000000000000000000000000000000000000000000000000000000000000182", + "0x0000000000000000000000000000000000000000000000000000000000000183", + "0x0000000000000000000000000000000000000000000000000000000000000184", + "0x0000000000000000000000000000000000000000000000000000000000000185", + "0x0000000000000000000000000000000000000000000000000000000000000186", + "0x0000000000000000000000000000000000000000000000000000000000000187", + "0x0000000000000000000000000000000000000000000000000000000000000188", + "0x0000000000000000000000000000000000000000000000000000000000000189", + "0x000000000000000000000000000000000000000000000000000000000000018a", + "0x000000000000000000000000000000000000000000000000000000000000018b", + "0x000000000000000000000000000000000000000000000000000000000000018c", + "0x000000000000000000000000000000000000000000000000000000000000018d", + "0x000000000000000000000000000000000000000000000000000000000000018e", + "0x000000000000000000000000000000000000000000000000000000000000018f", + "0x0000000000000000000000000000000000000000000000000000000000000190", + "0x0000000000000000000000000000000000000000000000000000000000000191", + "0x0000000000000000000000000000000000000000000000000000000000000192", + "0x0000000000000000000000000000000000000000000000000000000000000193", + "0x0000000000000000000000000000000000000000000000000000000000000194", + "0x0000000000000000000000000000000000000000000000000000000000000195", + "0x0000000000000000000000000000000000000000000000000000000000000196", + "0x0000000000000000000000000000000000000000000000000000000000000197", + "0x0000000000000000000000000000000000000000000000000000000000000198", + "0x0000000000000000000000000000000000000000000000000000000000000199", + "0x000000000000000000000000000000000000000000000000000000000000019a" +] + + [inputs.inbox_parity.public_inputs] + start_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_rolling_hash = "0x00a48b67f417042d5231ac634d609fe03a3884c4757a2afe457a7d1c6ca063ba" + num_msgs = "0x0000000000000000000000000000000000000000000000000000000000000100" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.inbox_parity.public_inputs.start_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000000" + + [inputs.inbox_parity.public_inputs.start_sponge.sponge] + cache = [ + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + state = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000f358d0d158178b8c1c5d1ab306fc824c6e", - "0x00000000000000000000000000000000001bfd8927e824b9139109755ac78ae8", - "0x0000000000000000000000000000009f633351b5460cd99ae56aa83c0a509e80", - "0x000000000000000000000000000000000007a02b5dd7f155aba055ff7b97cefc", - "0x000000000000000000000000000000b4411838e9bff24af3fd0a5d83f0c11530", - "0x0000000000000000000000000000000000151208bcc3e48a87e85b4589c38db6", - "0x000000000000000000000000000000c97cd77b3a0e92086255723ecaf28d7e38", - "0x00000000000000000000000000000000000200b49f18b0213dd44e92f80d6c8f", - "0x000000000000000000000000000000ca55dc2b5233494a2fec946463b3580977", - "0x000000000000000000000000000000000002f0544254905ba4070d96e3cad8f5", - "0x000000000000000000000000000000a64246255e19fd5bfda22d42dfa6f33a06", - "0x00000000000000000000000000000000000f00cca836c24c894ef5b80652121b", - "0x00000000000000000000000000000064af99efc74cc9f94032445418dfe0ca63", - "0x00000000000000000000000000000000002ccbc5204c523afd51ef21b0d7297a", - "0x000000000000000000000000000000d3014926288a126140b79c57f8a1e3adf4", - "0x00000000000000000000000000000000002ea5f5bf7c4bbd05edf988f1b9319d" + "0x0000000000000000000000000000000000000000000000000000000000000000" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" + squeeze_mode = false + + [inputs.inbox_parity.public_inputs.end_sponge] + num_absorbed = "0x0000000000000000000000000000000000000000000000000000000000000100" + + [inputs.inbox_parity.public_inputs.end_sponge.sponge] + cache = [ + "0x00000000000000000000000000000000000000000000000000000000000006db", + "0x00000000000000000000000000000000000000000000000000000000000006d9", + "0x00000000000000000000000000000000000000000000000000000000000006da" +] + state = [ + "0x0a0aa9eae5277bc3a8414be4a1a279d69f89d765ed17a0123ac83a2547a9cf99", + "0x22e19d5ba8ed0525429b7ac6b29abd221ed25181a9a2085507125e57ad7c3514", + "0x29f22a3e1d331fa7d7d47f6f0f139d765279266c338b405db43ecd66b5ef328c", + "0x1235e52a8b15fc46edb612d48c23715f76bba8eb563b9e29e2519f16612f0faa" +] + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + squeeze_mode = false + + [inputs.inbox_parity.vk_data] + leaf_index = "0x000000000000000000000000000000000000000000000000000000000000004b" + sibling_path = [ + "0x0ce57ef9658f5dcd6e252d942f93d5849c88741ff38e986a9c23698a78af34f8", + "0x1901849bbf00ef11f1b4d6813ff73db197ff3651540c8b7b8a35d4b73f802b53", + "0x0f5fb8e46928cbfb3f605126eaddf42b57788c66536d3d5d14c351dc53c57247", + "0x21ed90cd61698dc1e3dfc970eefcedc837dfedf46c2c4e594ce076ee8fba9386", + "0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da", + "0x1434e6e2d5db1053ab8a3be58704509c799ee17e109c77f441f7bf1755400249", + "0x24bf189628d199694f93e70205def14d96fb881b5a613b3e3ce2279c0e61d43f" +] + + [inputs.inbox_parity.vk_data.vk] + key = [ + "0x0000000000000000000000000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000021", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x000000000000000000000000000000c53f64dfc96470530db6ace16066e37a1d", + "0x00000000000000000000000000000000002a4aa09996ebfce8b72c9859d40a76", + "0x000000000000000000000000000000c021bf9d18ec75052cb06d0de9ec7f3c0b", + "0x00000000000000000000000000000000002ed3ec63df5dde157121ead0e3394a", + "0x0000000000000000000000000000008e52b43cea18affa0552239445532d3dfa", + "0x0000000000000000000000000000000000189b5cfaeda80ba752185e134d782d", + "0x000000000000000000000000000000d8ddd956deabfef7cf4e75b77e94087cde", + "0x000000000000000000000000000000000012088f809a0607c64af087559d7a1c", + "0x000000000000000000000000000000af3512e2b02ca8e3e5983edab46b37c124", + "0x00000000000000000000000000000000000bc4c64a908903352744013b92a706", + "0x0000000000000000000000000000005d2e8719a6bf28fc26170f43ebaf851e57", + "0x00000000000000000000000000000000002dd75b5a0ce761c1d1741b89bb3220", + "0x00000000000000000000000000000060ee4d844e88b11151822bc1006d6d14da", + "0x000000000000000000000000000000000003b9fc877fd36d9f71131076146822", + "0x000000000000000000000000000000cf6b45fc328a2092e1e5060198c6779001", + "0x00000000000000000000000000000000001e24603f0360820b8025e12ee90538", + "0x000000000000000000000000000000dca672efd630b28631070c23ac79894ffb", + "0x0000000000000000000000000000000000208ae5f11db8476d152143bd820324", + "0x000000000000000000000000000000037e45f0f351437ff9926de30c98fae12f", + "0x00000000000000000000000000000000001f11c3b9d9d82669b4d5a4e304a86a", + "0x00000000000000000000000000000082d43a15a593806829ef7b49017f9593eb", + "0x00000000000000000000000000000000002c18d89ed3fa58330a02d047d1006c", + "0x0000000000000000000000000000009ee5d086b44c67fd2845247551fec700ba", + "0x00000000000000000000000000000000000d61fca9f49c92cba01d09d84b590d", + "0x000000000000000000000000000000b79615e2c9c43e979c39e94b5aef77d17e", + "0x00000000000000000000000000000000001afadf5e9d48948e38bb57d3aa86b6", + "0x0000000000000000000000000000000f2455636bef5ab7d499950e2a477d6d01", + "0x00000000000000000000000000000000001d27f7fd12cb249a614d019632f596", + "0x00000000000000000000000000000097a669c1bcd8e9b70e0a4cefc0848a3e33", + "0x000000000000000000000000000000000024c7a70a53c5598868371c047927a1", + "0x000000000000000000000000000000602ad8a9486de199dd1de58f39a27acfcd", + "0x0000000000000000000000000000000000141fcf1e826474f1033dd405a5c227", + "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", + "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", + "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", + "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", + "0x0000000000000000000000000000003a57c27b30e08f6c165ea04e1c12078d86", + "0x000000000000000000000000000000000008d8a0131f34de690ce72b0e8cc997", + "0x00000000000000000000000000000072db0dbafee7ebe37300f57d3b861a1ed4", + "0x000000000000000000000000000000000008b1f713f28097c7934c96300ff933", + "0x00000000000000000000000000000093335a2d7db2ecc73c2a0b7a648767b3fa", + "0x000000000000000000000000000000000023058389968593a9d699ac61081497", + "0x000000000000000000000000000000c6f184ddade0468849894d086897891dae", + "0x0000000000000000000000000000000000177c7fe17fb62bd5c589b997be2be8", + "0x0000000000000000000000000000009df947a1824dd3e4c25006e55148430193", + "0x000000000000000000000000000000000025fffc71b2d4c067937ffaa0cbf575", + "0x00000000000000000000000000000028995e133a2c13cc3db00acdd8aad170a8", + "0x000000000000000000000000000000000005aacaf7b06227aa09f4ac8e12b63e", + "0x000000000000000000000000000000fd6e7754395ee57e0c460549931360c099", + "0x00000000000000000000000000000000000be33e0029e81b7ac23442af699121", + "0x0000000000000000000000000000006d6d5e8519b2b49fcd677457f81f1cb57a", + "0x000000000000000000000000000000000013b5a13f5802a5e358bf0ba73a0284", + "0x000000000000000000000000000000bc328653111a2fe499ec1a1393005c9f97", + "0x00000000000000000000000000000000000aba9237199085bd00ff8a2d90a5a1", + "0x000000000000000000000000000000d30c8eb234c4be977ec50cdaa0c970e988", + "0x0000000000000000000000000000000000126b7b5d6b48d64ce1d81cab3360c7", + "0x0000000000000000000000000000006ded6c9275e8c5f114d2662b03a09a5e3b", + "0x00000000000000000000000000000000001d3926dda40de089a5c7a24d35399a", + "0x000000000000000000000000000000a99b31d8f0421291c246e9431b4db095c0", + "0x00000000000000000000000000000000002163cf3bef71ec3deb0befbe80562f", + "0x00000000000000000000000000000059d41d5bf8f2a34d8b5aacc9714e881793", + "0x0000000000000000000000000000000000044a8b9042c8f236b9fc6a4387e06d", + "0x0000000000000000000000000000002a48938569e265b24943cb1a59dca4ee0a", + "0x0000000000000000000000000000000000267c7099894e9c5b1cc22e6eef2272", + "0x0000000000000000000000000000009fcc79cda6b0a41e0bdaaf6bfb549978d9", + "0x00000000000000000000000000000000001b4c96c38c76d0ee07b7e58e702d0c", + "0x000000000000000000000000000000f4fa13d704275b8d7e997bdfda7121e226", + "0x00000000000000000000000000000000001f285950282a94f4788070c29ecd1a", + "0x000000000000000000000000000000f65d1d2d0072c13ac17f9dfe0505166bb6", + "0x00000000000000000000000000000000000ad3bff96526cff78d95911e972e92", + "0x000000000000000000000000000000b54b6db0ec422f52e358f8a3c7f32c2ae4", + "0x00000000000000000000000000000000001a420aee136484fd32d44c1ce11d5b", + "0x000000000000000000000000000000297330b41d0c706bd513951f52ceb1e016", + "0x00000000000000000000000000000000001f5c675aca3686dd867f7bd2b07dac", + "0x000000000000000000000000000000d30f505432d411dbd9b8adbec808b94502", + "0x00000000000000000000000000000000002ef8adb3cea16fc68c4bad3fe3746e", + "0x000000000000000000000000000000a74bd48db81ce1e576b260788dbbe3ae73", + "0x00000000000000000000000000000000002dbbdba5149c40257503f0599b20a0", + "0x000000000000000000000000000000210302c9d6a317610609231e2554634d6c", + "0x0000000000000000000000000000000000163bcdfc12dcd3e842ab5156e7d3c8", + "0x0000000000000000000000000000000372b1edab65c3200e90aded2403a7bbd9", + "0x0000000000000000000000000000000000167129f1c2377787f35a31bb3cbfcd", + "0x000000000000000000000000000000049565f4db812be49e05e942e1282a80d9", + "0x000000000000000000000000000000000005ff62f0112be0f68fbbacb61d496e", + "0x000000000000000000000000000000661e266983059d97c6a1235a84553e0542", + "0x000000000000000000000000000000000025a0c734e75b6aadfb38222a66ad70", + "0x0000000000000000000000000000001315cc4242cedcba5c3a13a95fc31db9df", + "0x000000000000000000000000000000000026dac182a98f8fc7f93f0a32564022", + "0x000000000000000000000000000000f75b56af4f4f1cdb4794a64607e229c8bb", + "0x000000000000000000000000000000000011d9a02f40267bff021da5653104e8", + "0x000000000000000000000000000000213970438635e5bc87217e0ef8cad56c03", + "0x00000000000000000000000000000000001f0b565ab39f8750bb6288f59d1d90", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000ce8d339e9525430229bc5c203dae8f7ce6", + "0x000000000000000000000000000000000012872d1a4ee10c27e560412918917b", + "0x000000000000000000000000000000eaff5d1045972910fa67c9d6139a2d8170", + "0x000000000000000000000000000000000023fd76f167813bfb90cd2c36676412", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000003e3af00bf035f2b2595659a53fb5e36a25", + "0x00000000000000000000000000000000000be135e96f8061912e16dee4eeadc9", + "0x0000000000000000000000000000000f2730a470360be5041e25dfcb3170b79c", + "0x00000000000000000000000000000000002ef3cf8e2ef9ed0359a37694a30d5b", + "0x000000000000000000000000000000762b2f6a9947f0362b3e07ade872bd4ad0", + "0x000000000000000000000000000000000009330958b31fa64652a63b0290910c", + "0x0000000000000000000000000000008b43122ec9495e49f0dde9140e71b72eb0", + "0x000000000000000000000000000000000011577b0c4e6dbc35f57d754d00dfb7" ] - hash = "0x01343c2fd6c1ffb7f74e657666d03b4842aa647357eeafa82c9a740c7ab7c0f5" + hash = "0x28e207116e573337e83d7ab38d918cba438149cbd188ae0fd2e0d2fa31aea01c" [inputs.hints] previous_archive_sibling_path = [ @@ -1475,74 +2136,9 @@ new_out_hash_sibling_path = [ "0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c" ] blobs_fields = [ - "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x2cc074b1c577bf415eedcc3b2f3d7d9b6748d020a20bdea1eb8c5eade8ebb81a", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000b7d1b000", - "0x00000000000000000000000000000000000000000000000000000000b7d1b001", - "0x00000000000000000000000000000000000000000000000000000000b7d1b002", - "0x00000000000000000000000000000000000000000000000000000000b7d1b003", - "0x00000000000000000000000000000000000000000000000000000000b7d1b004", - "0x00000000000000000000000000000000000000000000000000000000b7d1b005", - "0x00000000000000000000000000000000000000000000000000000000b7d1b006", - "0x00000000000000000000000000000000000000000000000000000000b7d1b007", - "0x00000000000000000000000000000000000000000000000000000000b7d1b008", - "0x00000000000000000000000000000000000000000000000000000000b7d1b009", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b00f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b011", - "0x00000000000000000000000000000000000000000000000000000000b7d1b012", - "0x00000000000000000000000000000000000000000000000000000000b7d1b013", - "0x00000000000000000000000000000000000000000000000000000000b7d1b014", - "0x00000000000000000000000000000000000000000000000000000000b7d1b015", - "0x00000000000000000000000000000000000000000000000000000000b7d1b016", - "0x00000000000000000000000000000000000000000000000000000000b7d1b017", - "0x00000000000000000000000000000000000000000000000000000000b7d1b018", - "0x00000000000000000000000000000000000000000000000000000000b7d1b019", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b01f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b020", - "0x00000000000000000000000000000000000000000000000000000000b7d1b021", - "0x00000000000000000000000000000000000000000000000000000000b7d1b022", - "0x00000000000000000000000000000000000000000000000000000000b7d1b023", - "0x00000000000000000000000000000000000000000000000000000000b7d1b024", - "0x00000000000000000000000000000000000000000000000000000000b7d1b025", - "0x00000000000000000000000000000000000000000000000000000000b7d1b026", - "0x00000000000000000000000000000000000000000000000000000000b7d1b027", - "0x00000000000000000000000000000000000000000000000000000000b7d1b028", - "0x00000000000000000000000000000000000000000000000000000000b7d1b029", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b02f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b030", - "0x00000000000000000000000000000000000000000000000000000000b7d1b031", - "0x00000000000000000000000000000000000000000000000000000000b7d1b032", - "0x00000000000000000000000000000000000000000000000000000000b7d1b033", - "0x00000000000000000000000000000000000000000000000000000000b7d1b034", - "0x00000000000000000000000000000000000000000000000000000000b7d1b035", - "0x00000000000000000000000000000000000000000000000000000000b7d1b036", - "0x00000000000000000000000000000000000000000000000000000000b7d1b037", - "0x00000000000000000000000000000000000000000000000000000000b7d1b038", - "0x00000000000000000000000000000000000000000000000000000000b7d1b039", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b03f", - "0x00000000000000000000000000000000000000000000000000000000b7d1a001", + "0x00000000009c70751800400040000800010040040000000000000000000004cd", + "0x19eb87169c44e5500d14439ba2d8dce68988c04baf474aec058255563f37f706", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7d1b100", "0x00000000000000000000000000000000000000000000000000000000b7d1b101", "0x00000000000000000000000000000000000000000000000000000000b7d1b102", @@ -1606,1239 +2202,1178 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7d1b13c", "0x00000000000000000000000000000000000000000000000000000000b7d1b13d", "0x00000000000000000000000000000000000000000000000000000000b7d1b13e", - "0x0032e4d4113845639d851c5eb5a42ad9c3d52322bb37b3931c8e1ebb3e8a6b46", - "0x00fbaab4742e01eef1ac0cc0967ba5186f340121d12ca20ab259bc8469e99300", - "0x001502388e1f106a5273074e7f4ed005b3c04c60c16ac65e039274cfb6db3e34", - "0x0023e6fb97bf6dfb2c127fe30b4cc41fab85965f0da8e20671ba14552f4a9c87", - "0x0031553957913988a49af5a4f3f1a508138dc04495e87769b8d44894fae7c4c7", - "0x00dd5b03d5cb9b9da10cfe0949a77ac0422768a68df447d27834a63302ccac16", - "0x00fe787083a3043eae580b1dcc72c132e7005cb32ecae7ba24f1570758258839", - "0x0014919077fbdf50ec823e2fd61c2c2d7be9486ae036fef5ef10f4b090d9f130", + "0x00000000000000000000000000000000000000000000000000000000b7d1b13f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b200", + "0x00000000000000000000000000000000000000000000000000000000b7d1b201", + "0x00000000000000000000000000000000000000000000000000000000b7d1b202", + "0x00000000000000000000000000000000000000000000000000000000b7d1b203", + "0x00000000000000000000000000000000000000000000000000000000b7d1b204", + "0x00000000000000000000000000000000000000000000000000000000b7d1b205", + "0x00000000000000000000000000000000000000000000000000000000b7d1b206", + "0x00000000000000000000000000000000000000000000000000000000b7d1b207", + "0x00000000000000000000000000000000000000000000000000000000b7d1b208", + "0x00000000000000000000000000000000000000000000000000000000b7d1b209", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b20f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b210", + "0x00000000000000000000000000000000000000000000000000000000b7d1b211", + "0x00000000000000000000000000000000000000000000000000000000b7d1b212", + "0x00000000000000000000000000000000000000000000000000000000b7d1b213", + "0x00000000000000000000000000000000000000000000000000000000b7d1b214", + "0x00000000000000000000000000000000000000000000000000000000b7d1b215", + "0x00000000000000000000000000000000000000000000000000000000b7d1b216", + "0x00000000000000000000000000000000000000000000000000000000b7d1b217", + "0x00000000000000000000000000000000000000000000000000000000b7d1b218", + "0x00000000000000000000000000000000000000000000000000000000b7d1b219", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b21f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b220", + "0x00000000000000000000000000000000000000000000000000000000b7d1b221", + "0x00000000000000000000000000000000000000000000000000000000b7d1b222", + "0x00000000000000000000000000000000000000000000000000000000b7d1b223", + "0x00000000000000000000000000000000000000000000000000000000b7d1b224", + "0x00000000000000000000000000000000000000000000000000000000b7d1b225", + "0x00000000000000000000000000000000000000000000000000000000b7d1b226", + "0x00000000000000000000000000000000000000000000000000000000b7d1b227", + "0x00000000000000000000000000000000000000000000000000000000b7d1b228", + "0x00000000000000000000000000000000000000000000000000000000b7d1b229", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b22f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b230", + "0x00000000000000000000000000000000000000000000000000000000b7d1b231", + "0x00000000000000000000000000000000000000000000000000000000b7d1b232", + "0x00000000000000000000000000000000000000000000000000000000b7d1b233", + "0x00000000000000000000000000000000000000000000000000000000b7d1b234", + "0x00000000000000000000000000000000000000000000000000000000b7d1b235", + "0x00000000000000000000000000000000000000000000000000000000b7d1b236", + "0x00000000000000000000000000000000000000000000000000000000b7d1b237", + "0x00000000000000000000000000000000000000000000000000000000b7d1b238", + "0x00000000000000000000000000000000000000000000000000000000b7d1b239", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b23f", + "0x0014e392e48abf86fbcc646ebd535dcfadddf685f17cea1ad8692d84091fee6c", + "0x0081d7915f280fb0ab3bc1424d1f3b0afe8b13ca662631eb35d42d344b463ca5", + "0x00108dedfcd6e6ec14921619d606d4e274eb020bb1cceaecaabc10591905ccca", + "0x002d49d5a469f7a62cab3d2b266ed8f6bb38dacb2fb848e61cdbd6f174fa4473", + "0x00c9d057674688ddc5b9dce4037f7a173d54d42423831b1f17c7ad345ba12acb", + "0x00d65baedb6181e9f1d19c3e64ae63b26c0df768927d9654153a4312c0bfb8f9", + "0x00baf276002157aa3a0111d9547fd25bfbefd9d1841ffb292d2801e5354e7d05", + "0x002e2d381dbc44262bbafdf7e1645e1642daf94aa6175667bd69b3452c748e41", "0x27d08044a627c19f19b7b033af1c9b13f99160a207c22534c11ce11f88ad6814", "0x0000000000000000000000000000000000000000000000056bc75e2d63100000", - "0x00000000000000000000000000000000000000000000000000000000b7d1c001", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c002", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c003", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c004", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c005", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c006", - "0x00000000000000000000000000000000000000000000000000000000b7d1c010", - "0x00000000000000000000000000000000000000000000000000000000b7d1c007", - "0x00000000000000000000000000000000000000000000000000000000b7d1c011", - "0x00000000000000000000000000000000000000000000000000000000b7d1c008", - "0x00000000000000000000000000000000000000000000000000000000b7d1c012", - "0x00000000000000000000000000000000000000000000000000000000b7d1c009", - "0x00000000000000000000000000000000000000000000000000000000b7d1c013", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c014", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c015", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c016", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c017", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c018", - "0x00000000000000000000000000000000000000000000000000000000b7d1c00f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c019", - "0x00000000000000000000000000000000000000000000000000000000b7d1c010", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c011", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c012", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c013", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c014", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c015", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c016", - "0x00000000000000000000000000000000000000000000000000000000b7d1c020", - "0x00000000000000000000000000000000000000000000000000000000b7d1c017", - "0x00000000000000000000000000000000000000000000000000000000b7d1c021", - "0x00000000000000000000000000000000000000000000000000000000b7d1c018", - "0x00000000000000000000000000000000000000000000000000000000b7d1c022", - "0x00000000000000000000000000000000000000000000000000000000b7d1c019", - "0x00000000000000000000000000000000000000000000000000000000b7d1c023", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c024", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c025", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c026", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c027", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c028", - "0x00000000000000000000000000000000000000000000000000000000b7d1c01f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c029", - "0x00000000000000000000000000000000000000000000000000000000b7d1c020", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c021", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c022", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c023", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c024", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c025", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c026", - "0x00000000000000000000000000000000000000000000000000000000b7d1c030", - "0x00000000000000000000000000000000000000000000000000000000b7d1c027", - "0x00000000000000000000000000000000000000000000000000000000b7d1c031", - "0x00000000000000000000000000000000000000000000000000000000b7d1c028", - "0x00000000000000000000000000000000000000000000000000000000b7d1c032", - "0x00000000000000000000000000000000000000000000000000000000b7d1c029", - "0x00000000000000000000000000000000000000000000000000000000b7d1c033", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c034", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c035", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c036", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c037", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c038", - "0x00000000000000000000000000000000000000000000000000000000b7d1c02f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c039", - "0x00000000000000000000000000000000000000000000000000000000b7d1c030", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c031", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c032", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c033", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c034", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c035", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c036", - "0x00000000000000000000000000000000000000000000000000000000b7d1c040", - "0x00000000000000000000000000000000000000000000000000000000b7d1c037", - "0x00000000000000000000000000000000000000000000000000000000b7d1c041", - "0x00000000000000000000000000000000000000000000000000000000b7d1c038", - "0x00000000000000000000000000000000000000000000000000000000b7d1c042", - "0x00000000000000000000000000000000000000000000000000000000b7d1c039", - "0x00000000000000000000000000000000000000000000000000000000b7d1c043", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03a", - "0x00000000000000000000000000000000000000000000000000000000b7d1c044", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03b", - "0x00000000000000000000000000000000000000000000000000000000b7d1c045", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03c", - "0x00000000000000000000000000000000000000000000000000000000b7d1c046", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03d", - "0x00000000000000000000000000000000000000000000000000000000b7d1c047", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03e", - "0x00000000000000000000000000000000000000000000000000000000b7d1c048", - "0x00000000000000000000000000000000000000000000000000000000b7d1c03f", - "0x00000000000000000000000000000000000000000000000000000000b7d1c049", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b300", - "0x00000000000000000000000000000000000000000000000000000000b7d1b301", - "0x00000000000000000000000000000000000000000000000000000000b7d1b302", - "0x00000000000000000000000000000000000000000000000000000000b7d1b303", - "0x00000000000000000000000000000000000000000000000000000000b7d1b304", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b400", + "0x00000000000000000000000000000000000000000000000000000000b7d1b401", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b301", - "0x00000000000000000000000000000000000000000000000000000000b7d1b302", - "0x00000000000000000000000000000000000000000000000000000000b7d1b303", - "0x00000000000000000000000000000000000000000000000000000000b7d1b304", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", + "0x00000000000000000000000000000000000000000000000000000000b7d1b401", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b302", - "0x00000000000000000000000000000000000000000000000000000000b7d1b303", - "0x00000000000000000000000000000000000000000000000000000000b7d1b304", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", + "0x00000000000000000000000000000000000000000000000000000000b7d1b402", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b303", - "0x00000000000000000000000000000000000000000000000000000000b7d1b304", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", + "0x00000000000000000000000000000000000000000000000000000000b7d1b403", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b304", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", + "0x00000000000000000000000000000000000000000000000000000000b7d1b404", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b305", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", + "0x00000000000000000000000000000000000000000000000000000000b7d1b405", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b306", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", + "0x00000000000000000000000000000000000000000000000000000000b7d1b406", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b307", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", + "0x00000000000000000000000000000000000000000000000000000000b7d1b407", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b308", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", + "0x00000000000000000000000000000000000000000000000000000000b7d1b408", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b309", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", + "0x00000000000000000000000000000000000000000000000000000000b7d1b409", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b30f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b40f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b310", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b410", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b311", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", + "0x00000000000000000000000000000000000000000000000000000000b7d1b411", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b312", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", + "0x00000000000000000000000000000000000000000000000000000000b7d1b412", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b313", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", + "0x00000000000000000000000000000000000000000000000000000000b7d1b413", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b314", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", + "0x00000000000000000000000000000000000000000000000000000000b7d1b414", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b315", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", + "0x00000000000000000000000000000000000000000000000000000000b7d1b415", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b316", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", + "0x00000000000000000000000000000000000000000000000000000000b7d1b416", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b317", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", + "0x00000000000000000000000000000000000000000000000000000000b7d1b417", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b318", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", + "0x00000000000000000000000000000000000000000000000000000000b7d1b418", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b319", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", + "0x00000000000000000000000000000000000000000000000000000000b7d1b419", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b31f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b41f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b320", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b420", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b321", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", + "0x00000000000000000000000000000000000000000000000000000000b7d1b421", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b322", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", + "0x00000000000000000000000000000000000000000000000000000000b7d1b422", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b323", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", + "0x00000000000000000000000000000000000000000000000000000000b7d1b423", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b324", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", + "0x00000000000000000000000000000000000000000000000000000000b7d1b424", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b325", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", + "0x00000000000000000000000000000000000000000000000000000000b7d1b425", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b326", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", + "0x00000000000000000000000000000000000000000000000000000000b7d1b426", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b327", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", + "0x00000000000000000000000000000000000000000000000000000000b7d1b427", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b328", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", + "0x00000000000000000000000000000000000000000000000000000000b7d1b428", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b329", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", + "0x00000000000000000000000000000000000000000000000000000000b7d1b429", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b32f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b42f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b330", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b430", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b331", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", + "0x00000000000000000000000000000000000000000000000000000000b7d1b431", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b332", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", + "0x00000000000000000000000000000000000000000000000000000000b7d1b432", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b333", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", + "0x00000000000000000000000000000000000000000000000000000000b7d1b433", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b334", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", + "0x00000000000000000000000000000000000000000000000000000000b7d1b434", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b335", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", + "0x00000000000000000000000000000000000000000000000000000000b7d1b435", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b336", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", + "0x00000000000000000000000000000000000000000000000000000000b7d1b436", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b337", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", + "0x00000000000000000000000000000000000000000000000000000000b7d1b437", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b338", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", + "0x00000000000000000000000000000000000000000000000000000000b7d1b438", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b339", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", + "0x00000000000000000000000000000000000000000000000000000000b7d1b439", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33e", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7d1b33f", - "0x00000000000000000000000000000000000000000000000000000000b7d1b340", - "0x00000000000000000000000000000000000000000000000000000000b7d1b341", - "0x00000000000000000000000000000000000000000000000000000000b7d1b342", - "0x00000000000000000000000000000000000000000000000000000000b7d1b343", - "0x00000000000000000000000000000000000000000000000000000000b7d1b344", - "0x00000000000000000000000000000000000000000000000000000000b7d1b345", - "0x00000000000000000000000000000000000000000000000000000000b7d1b346", - "0x00000000000000000000000000000000000000000000000000000000b7d1b347", - "0x00000000000000000000000000000000000000000000000000000000b7d1b348", - "0x00000000000000000000000000000000000000000000000000000000b7d1b349", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34a", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34b", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b43f", + "0x00000000000000000000000000000000000000000000000000000000b7d1b440", + "0x00000000000000000000000000000000000000000000000000000000b7d1b441", + "0x00000000000000000000000000000000000000000000000000000000b7d1b442", + "0x00000000000000000000000000000000000000000000000000000000b7d1b443", + "0x00000000000000000000000000000000000000000000000000000000b7d1b444", + "0x00000000000000000000000000000000000000000000000000000000b7d1b445", + "0x00000000000000000000000000000000000000000000000000000000b7d1b446", + "0x00000000000000000000000000000000000000000000000000000000b7d1b447", + "0x00000000000000000000000000000000000000000000000000000000b7d1b448", + "0x00000000000000000000000000000000000000000000000000000000b7d1b449", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44a", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44b", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000010001", - "0x0000000000000000004000000000010000000000c000000000bf000000000000", + "0x0000000000000000001000000000010000000000c0000000008000000006b6c0", "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0", - "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576", - "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d", - "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9", - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922", + "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7", + "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684", + "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c", "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x2a2bb254a295eb5a145c1723eaec08f9a0e64bfb83a166be67ea270421a4dba3", + "0x26e0dcc66a2a69e307671389e40ff8e757c64544cb1e90cd1abdc80592e55255", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7e5c000", "0x00000000000000000000000000000000000000000000000000000000b7e5c001", @@ -4193,79 +4728,15 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000020001", - "0x00000000000000000040000000000200000000010000000000fe000000000000", - "0x2ec9fc22ae7001e2ada488cbd0ea07e1cf7f54e151dc2bb766e561636b02eece", - "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449", - "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8", - "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f", - "0x00000000009c707518004000400008004000400400000000000000000000054b", - "0x208bf0543b34224ef7f865f1493a705f2b08d91ff98fd5e410d2d864c34a6e9d", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000b7f9d000", - "0x00000000000000000000000000000000000000000000000000000000b7f9d001", - "0x00000000000000000000000000000000000000000000000000000000b7f9d002", - "0x00000000000000000000000000000000000000000000000000000000b7f9d003", - "0x00000000000000000000000000000000000000000000000000000000b7f9d004", - "0x00000000000000000000000000000000000000000000000000000000b7f9d005", - "0x00000000000000000000000000000000000000000000000000000000b7f9d006", - "0x00000000000000000000000000000000000000000000000000000000b7f9d007", - "0x00000000000000000000000000000000000000000000000000000000b7f9d008", - "0x00000000000000000000000000000000000000000000000000000000b7f9d009", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d00f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d011", - "0x00000000000000000000000000000000000000000000000000000000b7f9d012", - "0x00000000000000000000000000000000000000000000000000000000b7f9d013", - "0x00000000000000000000000000000000000000000000000000000000b7f9d014", - "0x00000000000000000000000000000000000000000000000000000000b7f9d015", - "0x00000000000000000000000000000000000000000000000000000000b7f9d016", - "0x00000000000000000000000000000000000000000000000000000000b7f9d017", - "0x00000000000000000000000000000000000000000000000000000000b7f9d018", - "0x00000000000000000000000000000000000000000000000000000000b7f9d019", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d01f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d020", - "0x00000000000000000000000000000000000000000000000000000000b7f9d021", - "0x00000000000000000000000000000000000000000000000000000000b7f9d022", - "0x00000000000000000000000000000000000000000000000000000000b7f9d023", - "0x00000000000000000000000000000000000000000000000000000000b7f9d024", - "0x00000000000000000000000000000000000000000000000000000000b7f9d025", - "0x00000000000000000000000000000000000000000000000000000000b7f9d026", - "0x00000000000000000000000000000000000000000000000000000000b7f9d027", - "0x00000000000000000000000000000000000000000000000000000000b7f9d028", - "0x00000000000000000000000000000000000000000000000000000000b7f9d029", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d02f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d030", - "0x00000000000000000000000000000000000000000000000000000000b7f9d031", - "0x00000000000000000000000000000000000000000000000000000000b7f9d032", - "0x00000000000000000000000000000000000000000000000000000000b7f9d033", - "0x00000000000000000000000000000000000000000000000000000000b7f9d034", - "0x00000000000000000000000000000000000000000000000000000000b7f9d035", - "0x00000000000000000000000000000000000000000000000000000000b7f9d036", - "0x00000000000000000000000000000000000000000000000000000000b7f9d037", - "0x00000000000000000000000000000000000000000000000000000000b7f9d038", - "0x00000000000000000000000000000000000000000000000000000000b7f9d039", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d03f", - "0x00000000000000000000000000000000000000000000000000000000b7f9c001", + "0x00000000000000000010000000000200000000010000000000bf000000000000", + "0x0eab3e829cc7fe4fad08d43de98c4d400e7349bca7558dce0e7aebe7df63680b", + "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b", + "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c", + "0x00000000009c70751800400040000800010040040000000000000000000004cd", + "0x2c6f7adfa401b25364a49d41e1b5c6ebeb89f1bd50bd52da30a887ef009ce74b", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000000000000000000000000000000000000b7f9d100", "0x00000000000000000000000000000000000000000000000000000000b7f9d101", "0x00000000000000000000000000000000000000000000000000000000b7f9d102", @@ -4329,1237 +4800,1427 @@ blobs_fields = [ "0x00000000000000000000000000000000000000000000000000000000b7f9d13c", "0x00000000000000000000000000000000000000000000000000000000b7f9d13d", "0x00000000000000000000000000000000000000000000000000000000b7f9d13e", - "0x0014741a44b9f74c2b2a5fd138fd19009e7dfbd6346ef79b8a60ec9ff4a3468c", - "0x00e32fd1dab01ceab175f831ba5d34f008598114ab96bb397eef7daca929e33f", - "0x00561bb437fbc8557398d7e944021b1d8efcf9e54ffec1918c08ccbb1f8e725e", - "0x00352433020e3d49f61eca2b1ef6927d9211c1e42e59152f0a5077edd6b90387", - "0x00786401d7b4bb5f2fe168e6e52a8b664caf8cd1ab4fabb7234e7baee1012e94", - "0x00849e2f73059be0bad79266101e9fed574a9064c7b53aaf7339b1579a96a766", - "0x0052dc5caca760b8f9db01df301bbb8124ed5b5498e7d6a74e86ad80c65deca6", - "0x002f21c2dc506d0e24f4ec325962166c3dbcce10c8b088396832cf6e5cbf37b2", + "0x00000000000000000000000000000000000000000000000000000000b7f9d13f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d200", + "0x00000000000000000000000000000000000000000000000000000000b7f9d201", + "0x00000000000000000000000000000000000000000000000000000000b7f9d202", + "0x00000000000000000000000000000000000000000000000000000000b7f9d203", + "0x00000000000000000000000000000000000000000000000000000000b7f9d204", + "0x00000000000000000000000000000000000000000000000000000000b7f9d205", + "0x00000000000000000000000000000000000000000000000000000000b7f9d206", + "0x00000000000000000000000000000000000000000000000000000000b7f9d207", + "0x00000000000000000000000000000000000000000000000000000000b7f9d208", + "0x00000000000000000000000000000000000000000000000000000000b7f9d209", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d20f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d210", + "0x00000000000000000000000000000000000000000000000000000000b7f9d211", + "0x00000000000000000000000000000000000000000000000000000000b7f9d212", + "0x00000000000000000000000000000000000000000000000000000000b7f9d213", + "0x00000000000000000000000000000000000000000000000000000000b7f9d214", + "0x00000000000000000000000000000000000000000000000000000000b7f9d215", + "0x00000000000000000000000000000000000000000000000000000000b7f9d216", + "0x00000000000000000000000000000000000000000000000000000000b7f9d217", + "0x00000000000000000000000000000000000000000000000000000000b7f9d218", + "0x00000000000000000000000000000000000000000000000000000000b7f9d219", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d21f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d220", + "0x00000000000000000000000000000000000000000000000000000000b7f9d221", + "0x00000000000000000000000000000000000000000000000000000000b7f9d222", + "0x00000000000000000000000000000000000000000000000000000000b7f9d223", + "0x00000000000000000000000000000000000000000000000000000000b7f9d224", + "0x00000000000000000000000000000000000000000000000000000000b7f9d225", + "0x00000000000000000000000000000000000000000000000000000000b7f9d226", + "0x00000000000000000000000000000000000000000000000000000000b7f9d227", + "0x00000000000000000000000000000000000000000000000000000000b7f9d228", + "0x00000000000000000000000000000000000000000000000000000000b7f9d229", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d22f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d230", + "0x00000000000000000000000000000000000000000000000000000000b7f9d231", + "0x00000000000000000000000000000000000000000000000000000000b7f9d232", + "0x00000000000000000000000000000000000000000000000000000000b7f9d233", + "0x00000000000000000000000000000000000000000000000000000000b7f9d234", + "0x00000000000000000000000000000000000000000000000000000000b7f9d235", + "0x00000000000000000000000000000000000000000000000000000000b7f9d236", + "0x00000000000000000000000000000000000000000000000000000000b7f9d237", + "0x00000000000000000000000000000000000000000000000000000000b7f9d238", + "0x00000000000000000000000000000000000000000000000000000000b7f9d239", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d23f", + "0x0084b68f1635bb4387ad6e0a541458ef06c58c624beb729e208699a1580e8aff", + "0x00cfbe26e3d91220e6444179aafdf21e55ed65a45b9ad6eb3e6204697ebecc38", + "0x006194c01064b216dd159f35c086f972bc217050523a3dcad69db89da2c4b16f", + "0x00d1c527d86109d0bec77b091f384bbc71c295936c72fd57304467c25fa344f6", + "0x00a4e5dc95137053dce3a4e833b68ad65d456f13b61fcce41d2206361d0eb64f", + "0x00b7134c2169cbe7866c2455d5957de65e4ac9d0385041cfe3de74b76c326784", + "0x00568275f4816e273c40bc5217a99a4542db301dea198dde0fbd05afe6fda499", + "0x00cdd42ab3e5dca7b4e52a74e99bde6e9db5d425c792d9a5e0987fc66d0fb45a", "0x27d08044a627c19f19b7b033af1c9b13f99160a207c22534c11ce11f88ad6814", "0x0000000000000000000000000000000000000000000000056bc75e2d63100000", - "0x00000000000000000000000000000000000000000000000000000000b7f9e001", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e002", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e003", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e004", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e005", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e006", - "0x00000000000000000000000000000000000000000000000000000000b7f9e010", - "0x00000000000000000000000000000000000000000000000000000000b7f9e007", - "0x00000000000000000000000000000000000000000000000000000000b7f9e011", - "0x00000000000000000000000000000000000000000000000000000000b7f9e008", - "0x00000000000000000000000000000000000000000000000000000000b7f9e012", - "0x00000000000000000000000000000000000000000000000000000000b7f9e009", - "0x00000000000000000000000000000000000000000000000000000000b7f9e013", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e014", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e015", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e016", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e017", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e018", - "0x00000000000000000000000000000000000000000000000000000000b7f9e00f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e019", - "0x00000000000000000000000000000000000000000000000000000000b7f9e010", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e011", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e012", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e013", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e014", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e015", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e016", - "0x00000000000000000000000000000000000000000000000000000000b7f9e020", - "0x00000000000000000000000000000000000000000000000000000000b7f9e017", - "0x00000000000000000000000000000000000000000000000000000000b7f9e021", - "0x00000000000000000000000000000000000000000000000000000000b7f9e018", - "0x00000000000000000000000000000000000000000000000000000000b7f9e022", - "0x00000000000000000000000000000000000000000000000000000000b7f9e019", - "0x00000000000000000000000000000000000000000000000000000000b7f9e023", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e024", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e025", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e026", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e027", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e028", - "0x00000000000000000000000000000000000000000000000000000000b7f9e01f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e029", - "0x00000000000000000000000000000000000000000000000000000000b7f9e020", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e021", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e022", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e023", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e024", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e025", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e026", - "0x00000000000000000000000000000000000000000000000000000000b7f9e030", - "0x00000000000000000000000000000000000000000000000000000000b7f9e027", - "0x00000000000000000000000000000000000000000000000000000000b7f9e031", - "0x00000000000000000000000000000000000000000000000000000000b7f9e028", - "0x00000000000000000000000000000000000000000000000000000000b7f9e032", - "0x00000000000000000000000000000000000000000000000000000000b7f9e029", - "0x00000000000000000000000000000000000000000000000000000000b7f9e033", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e034", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e035", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e036", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e037", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e038", - "0x00000000000000000000000000000000000000000000000000000000b7f9e02f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e039", - "0x00000000000000000000000000000000000000000000000000000000b7f9e030", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e031", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e032", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e033", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e034", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e035", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e036", - "0x00000000000000000000000000000000000000000000000000000000b7f9e040", - "0x00000000000000000000000000000000000000000000000000000000b7f9e037", - "0x00000000000000000000000000000000000000000000000000000000b7f9e041", - "0x00000000000000000000000000000000000000000000000000000000b7f9e038", - "0x00000000000000000000000000000000000000000000000000000000b7f9e042", - "0x00000000000000000000000000000000000000000000000000000000b7f9e039", - "0x00000000000000000000000000000000000000000000000000000000b7f9e043", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03a", - "0x00000000000000000000000000000000000000000000000000000000b7f9e044", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03b", - "0x00000000000000000000000000000000000000000000000000000000b7f9e045", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03c", - "0x00000000000000000000000000000000000000000000000000000000b7f9e046", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03d", - "0x00000000000000000000000000000000000000000000000000000000b7f9e047", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03e", - "0x00000000000000000000000000000000000000000000000000000000b7f9e048", - "0x00000000000000000000000000000000000000000000000000000000b7f9e03f", - "0x00000000000000000000000000000000000000000000000000000000b7f9e049", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d300", - "0x00000000000000000000000000000000000000000000000000000000b7f9d301", - "0x00000000000000000000000000000000000000000000000000000000b7f9d302", - "0x00000000000000000000000000000000000000000000000000000000b7f9d303", - "0x00000000000000000000000000000000000000000000000000000000b7f9d304", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d400", + "0x00000000000000000000000000000000000000000000000000000000b7f9d401", + "0x00000000000000000000000000000000000000000000000000000000b7f9d402", + "0x00000000000000000000000000000000000000000000000000000000b7f9d403", + "0x00000000000000000000000000000000000000000000000000000000b7f9d404", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d301", - "0x00000000000000000000000000000000000000000000000000000000b7f9d302", - "0x00000000000000000000000000000000000000000000000000000000b7f9d303", - "0x00000000000000000000000000000000000000000000000000000000b7f9d304", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", + "0x00000000000000000000000000000000000000000000000000000000b7f9d401", + "0x00000000000000000000000000000000000000000000000000000000b7f9d402", + "0x00000000000000000000000000000000000000000000000000000000b7f9d403", + "0x00000000000000000000000000000000000000000000000000000000b7f9d404", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d302", - "0x00000000000000000000000000000000000000000000000000000000b7f9d303", - "0x00000000000000000000000000000000000000000000000000000000b7f9d304", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", + "0x00000000000000000000000000000000000000000000000000000000b7f9d402", + "0x00000000000000000000000000000000000000000000000000000000b7f9d403", + "0x00000000000000000000000000000000000000000000000000000000b7f9d404", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d303", - "0x00000000000000000000000000000000000000000000000000000000b7f9d304", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", + "0x00000000000000000000000000000000000000000000000000000000b7f9d403", + "0x00000000000000000000000000000000000000000000000000000000b7f9d404", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d304", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", + "0x00000000000000000000000000000000000000000000000000000000b7f9d404", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d305", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", + "0x00000000000000000000000000000000000000000000000000000000b7f9d405", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d306", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", + "0x00000000000000000000000000000000000000000000000000000000b7f9d406", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d307", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", + "0x00000000000000000000000000000000000000000000000000000000b7f9d407", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d308", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", + "0x00000000000000000000000000000000000000000000000000000000b7f9d408", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d309", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", + "0x00000000000000000000000000000000000000000000000000000000b7f9d409", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d30f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d40f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d310", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d410", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d311", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", + "0x00000000000000000000000000000000000000000000000000000000b7f9d411", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d312", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", + "0x00000000000000000000000000000000000000000000000000000000b7f9d412", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d313", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", + "0x00000000000000000000000000000000000000000000000000000000b7f9d413", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d314", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", + "0x00000000000000000000000000000000000000000000000000000000b7f9d414", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d315", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", + "0x00000000000000000000000000000000000000000000000000000000b7f9d415", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d316", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", + "0x00000000000000000000000000000000000000000000000000000000b7f9d416", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d317", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", + "0x00000000000000000000000000000000000000000000000000000000b7f9d417", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d318", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", + "0x00000000000000000000000000000000000000000000000000000000b7f9d418", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d319", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", + "0x00000000000000000000000000000000000000000000000000000000b7f9d419", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d31f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d41f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d320", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d420", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d321", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", + "0x00000000000000000000000000000000000000000000000000000000b7f9d421", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d322", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", + "0x00000000000000000000000000000000000000000000000000000000b7f9d422", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d323", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", + "0x00000000000000000000000000000000000000000000000000000000b7f9d423", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d324", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", + "0x00000000000000000000000000000000000000000000000000000000b7f9d424", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d325", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", + "0x00000000000000000000000000000000000000000000000000000000b7f9d425", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d326", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", + "0x00000000000000000000000000000000000000000000000000000000b7f9d426", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d327", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", + "0x00000000000000000000000000000000000000000000000000000000b7f9d427", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d328", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", + "0x00000000000000000000000000000000000000000000000000000000b7f9d428", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d329", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", + "0x00000000000000000000000000000000000000000000000000000000b7f9d429", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d32f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d42f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d330", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d430", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d331", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", + "0x00000000000000000000000000000000000000000000000000000000b7f9d431", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d332", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", + "0x00000000000000000000000000000000000000000000000000000000b7f9d432", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d333", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", + "0x00000000000000000000000000000000000000000000000000000000b7f9d433", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d334", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", + "0x00000000000000000000000000000000000000000000000000000000b7f9d434", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d335", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", + "0x00000000000000000000000000000000000000000000000000000000b7f9d435", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d336", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", + "0x00000000000000000000000000000000000000000000000000000000b7f9d436", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d337", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", + "0x00000000000000000000000000000000000000000000000000000000b7f9d437", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d338", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", + "0x00000000000000000000000000000000000000000000000000000000b7f9d438", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d339", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", + "0x00000000000000000000000000000000000000000000000000000000b7f9d439", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44a", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44b", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44c", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33e", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44d", "0x0000000000000000000000000000000000000000000000000000000000000010", - "0x00000000000000000000000000000000000000000000000000000000b7f9d33f", - "0x00000000000000000000000000000000000000000000000000000000b7f9d340", - "0x00000000000000000000000000000000000000000000000000000000b7f9d341", - "0x00000000000000000000000000000000000000000000000000000000b7f9d342", - "0x00000000000000000000000000000000000000000000000000000000b7f9d343", - "0x00000000000000000000000000000000000000000000000000000000b7f9d344", - "0x00000000000000000000000000000000000000000000000000000000b7f9d345", - "0x00000000000000000000000000000000000000000000000000000000b7f9d346", - "0x00000000000000000000000000000000000000000000000000000000b7f9d347", - "0x00000000000000000000000000000000000000000000000000000000b7f9d348", - "0x00000000000000000000000000000000000000000000000000000000b7f9d349", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34a", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34b", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34c", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34d", - "0x00000000000000000000000000000000000000000000000000000000b7f9d34e", + "0x00000000000000000000000000000000000000000000000000000000b7f9d43f", + "0x00000000000000000000000000000000000000000000000000000000b7f9d440", + "0x00000000000000000000000000000000000000000000000000000000b7f9d441", + "0x00000000000000000000000000000000000000000000000000000000b7f9d442", + "0x00000000000000000000000000000000000000000000000000000000b7f9d443", + "0x00000000000000000000000000000000000000000000000000000000b7f9d444", + "0x00000000000000000000000000000000000000000000000000000000b7f9d445", + "0x00000000000000000000000000000000000000000000000000000000b7f9d446", + "0x00000000000000000000000000000000000000000000000000000000b7f9d447", + "0x00000000000000000000000000000000000000000000000000000000b7f9d448", + "0x00000000000000000000000000000000000000000000000000000000b7f9d449", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44a", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44b", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44c", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44d", + "0x00000000000000000000000000000000000000000000000000000000b7f9d44e", "0x0000000000000000000000000000eb8dcdbf0000000000000186000000030001", - "0x000000000000000000400000000003000000000140000000013d000000000000", - "0x02c1e55021910a8552fe034bd1dad5769dec59fc837d88b03d9cf7a8bba0a348", - "0x0058e56291a20ba5208dec6c4e6f93513a7e475709e9292d09b7ca1c7147703e", - "0x06d941e09284387689272aef891ff6ec71993e808f3a832c4d1fd74955b1901e", - "0x069ad5cd9f6b5ac53ec9533083d53fb0e3b8cc49b13211bd6d314c00493971c2", - "0x0000000000000000000000000000000000000000000000008c63744300000ff5", + "0x00000000000000000010000000000300000000014000000000bf00000006b6c0", + "0x29fde061771e275677f732d70886777109f0477a1215ce9c07480b1539d82335", + "0x144f9224dee4aac6eddc5d988e7c6965528d2e08db91cf58989655a68fbfcc52", + "0x191d19a6ad2b7bba03d122035938544f5e65de24aeaa436cd5e4d977bd014505", + "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759", + "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c", + "0x0000000000000000000000000000000000000000000000008c63744300000efb", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -26052,7 +26713,7 @@ blobs_fields = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000" ] -blobs_hash = "0x00e3f7d54fd4b29292ce7b9ad9435a91f859ca73b7c6353f5efb8c808bb90404" +blobs_hash = "0x00aeffe018151cb0e55833ef4979644494a6a6a90ca8f04d873219c5331dd00c" [inputs.hints.previous_block_header] sponge_blob_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -26139,13 +26800,13 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 ] [inputs.hints.final_blob_challenges] - z = "0x143247d83cc93ed12dcfe7dd29b2e6f7066bf75ed8cce06313d7fbc22a453f57" + z = "0x24c2b04d22668cf1ed92f4aa4a8c4786895a62dd520116855023d9f7173dd325" [inputs.hints.final_blob_challenges.gamma] limbs = [ - "0x7fa40cbbd0c308a3a0455a0dfa22ed", - "0xbcacdb8ffef53c81a217a72a0433b6", - "0x1123" + "0xf622c6e72e668c1ce1cb885e05bb80", + "0x8ae40ae963f279550445c49d142303", + "0x0e9c" ] [[inputs.hints.blob_commitments]] @@ -26153,18 +26814,18 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 [inputs.hints.blob_commitments.x] limbs = [ - "0xe674754db6e1e252aa3b3d59647753", - "0xc21574d13d87a865e121540f84f4f3", - "0x342975dc6aefdefbc9a9b7054e834e", - "0x0c417c" + "0xaffc18140e08021375bc9e69339998", + "0x1010cd9a562cf4e0a453802271aeba", + "0x225f392508ed93621b14117b6df1c0", + "0x0f9191" ] [inputs.hints.blob_commitments.y] limbs = [ - "0xefae75ee8dd8ddcaa286e932412b87", - "0xded824efa66ae456595d5b3016dffd", - "0xfe63db91c1e88a22b3b8a9ee439f7e", - "0x0f399f" + "0x4d68d05a8bc96191762a9c4e40c71e", + "0xe53f26f8dc3bbaec8a49b249a973f5", + "0x0f2ed28d6e5d4b525470b11d8c06a2", + "0x18a389" ] [[inputs.hints.blob_commitments]] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_rollup_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_rollup_public_inputs.nr index 9600adda08ed..e014d61946b2 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_rollup_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_rollup_public_inputs.nr @@ -1,3 +1,4 @@ +use crate::abis::L1ToL2MessageSponge; use protocol_test_utils::make_fixture; use types::{ abis::{ @@ -39,9 +40,21 @@ pub struct BlockRollupPublicInputs { // stored in the checkpoint header, enabling validation of the blocks included in a checkpoint given their headers. pub block_headers_hash: Field, - // Root of the `l1_to_l2` message subtree, set in the first block root and propagated to the checkpoint root. - // Block root rollups that are not the first in a checkpoint will have an `in_hash` value of 0. - pub in_hash: Field, + // Whether this block range starts at the first block of its checkpoint. Only the first block root variants set it + // true; merges propagate it from the left rollup (`merge_block_rollups`), and + // `validate_consecutive_block_rollups` asserts the right rollup of every merge is not a first block. The flag is + // therefore a proof that the range's leftmost leaf is a first-variant block root, which is what lets the + // checkpoint root assert its leftmost block is one (`checkpoint_root_inputs_validator`) even though it cannot see + // the leaf VK indices. Since only first variants may be fully empty (no txs and no messages), that also confines + // a fully-empty filler block to the first position of a checkpoint. + pub is_first_block: bool, + + // Poseidon2 message-bundle sponge threaded across the blocks of the checkpoint. The leftmost block starts from the + // empty sponge and each block absorbs its bundle's leaves; `validate_consecutive_block_rollups` asserts + // `right.start_msg_sponge == left.end_msg_sponge`, and merges take `start` from the left and `end` from the right. + // The checkpoint root asserts the merged end equals the parity root's sponge over the same (padded) leaf list. + pub start_msg_sponge: L1ToL2MessageSponge, + pub end_msg_sponge: L1ToL2MessageSponge, // Root of the *wonky* tree composed of all tx out hashes in this block. It will be combined with the `out_hash` // values from other blocks within the same checkpoint to form a *wonky* tree. diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/checkpoint_rollup_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/checkpoint_rollup_public_inputs.nr index 9be134f81a4f..9c990d82cba9 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/checkpoint_rollup_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/checkpoint_rollup_public_inputs.nr @@ -29,6 +29,12 @@ pub struct CheckpointRollupPublicInputs { // final epoch out hash inserted into the Outbox on L1. pub new_out_hash: AppendOnlyTreeSnapshot, + // Inbox rolling-hash chain segment consumed by this checkpoint range. `start_inbox_rolling_hash` is the chain value + // before the first checkpoint's messages, `end_inbox_rolling_hash` is the value after the last checkpoint's. The end + // value is what lands in the checkpoint header. Checkpoint merges assert `right.start == left.end` for continuity. + pub start_inbox_rolling_hash: Field, + pub end_inbox_rolling_hash: Field, + // Hashes of checkpoint headers for this checkpoint range. pub checkpoint_header_hashes: [Field; MAX_CHECKPOINTS_PER_EPOCH], @@ -61,6 +67,8 @@ impl Empty for CheckpointRollupPublicInputs { new_archive: AppendOnlyTreeSnapshot::empty(), previous_out_hash: AppendOnlyTreeSnapshot::empty(), new_out_hash: AppendOnlyTreeSnapshot::empty(), + start_inbox_rolling_hash: 0, + end_inbox_rolling_hash: 0, checkpoint_header_hashes: [0; MAX_CHECKPOINTS_PER_EPOCH], fees: [FeeRecipient::empty(); MAX_CHECKPOINTS_PER_EPOCH], start_blob_accumulator: BlobAccumulator::empty(), diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_bundle.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_bundle.nr new file mode 100644 index 000000000000..338d5106509e --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_bundle.nr @@ -0,0 +1,20 @@ +use std::meta::derive; +use types::{constants::MAX_L1_TO_L2_MSGS_PER_BLOCK, traits::{Deserialize, Empty, Serialize}}; + +/// A block's L1-to-L2 message bundle: the real message leaves it inserts into the L1-to-L2 message tree, and the +/// count a block root needs to append them and absorb them into the message sponge. +/// +/// The `num_msgs` real messages occupy the leading lanes; the same count drives both the compact (unpadded) tree +/// append and the message-sponge absorb, matching the checkpoint's variable-size `InboxParity` proof. Lanes past +/// `num_msgs` are zero padding. +#[derive(Deserialize, Eq, Serialize)] +pub struct L1ToL2MessageBundle { + pub messages: [Field; MAX_L1_TO_L2_MSGS_PER_BLOCK], + pub num_msgs: u32, +} + +impl Empty for L1ToL2MessageBundle { + fn empty() -> Self { + L1ToL2MessageBundle { messages: [0; MAX_L1_TO_L2_MSGS_PER_BLOCK], num_msgs: 0 } + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_sponge.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_sponge.nr new file mode 100644 index 000000000000..9f4af934cce7 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_sponge.nr @@ -0,0 +1,116 @@ +use std::meta::derive; +use types::{ + hash::poseidon2_absorb_in_chunks_existing_sponge, + poseidon2::Poseidon2Sponge, + traits::{Deserialize, Empty, Serialize}, +}; + +/// An absorb-only Poseidon2 sponge over L1-to-L2 message leaves. +/// +/// It threads across the blocks of a checkpoint the way `SpongeBlob` threads tx effects: each block absorbs its message +/// bundle into the sponge it inherited from the previous block, and the checkpoint root recomputes the sponge over the +/// flat concatenation of every block's messages and asserts the final states are equal. There are no block separators +/// or markers in the absorbed stream, so the recomputation is identical regardless of how messages were split across +/// blocks. The sponge is never squeezed on the block path — equality of the accumulated state is the only check. +#[derive(Deserialize, Eq, Serialize)] +pub struct L1ToL2MessageSponge { + pub sponge: Poseidon2Sponge, + /// The number of message leaves absorbed so far. + pub num_absorbed: u32, +} + +impl L1ToL2MessageSponge { + pub fn new() -> Self { + Self { sponge: Poseidon2Sponge::new(0), num_absorbed: 0 } + } + + /// Absorb the first `num` leaves of `leaves` in order. Lanes beyond `num` are ignored. + pub fn absorb(&mut self, leaves: [Field; N], num: u32) { + self.sponge = poseidon2_absorb_in_chunks_existing_sponge(self.sponge, leaves, num); + self.num_absorbed += num; + } + + /// Finalize the sponge and output the (non-standard) Poseidon2 hash of all absorbed leaves. + pub fn squeeze(&mut self) -> Field { + self.sponge.squeeze() + } +} + +impl Empty for L1ToL2MessageSponge { + fn empty() -> Self { + Self { sponge: Poseidon2Sponge::new(0), num_absorbed: 0 } + } +} + +mod tests { + use super::L1ToL2MessageSponge; + use types::{poseidon2::Poseidon2Sponge, traits::Empty}; + + #[test] + fn new_equals_empty() { + assert_eq(L1ToL2MessageSponge::new(), L1ToL2MessageSponge::empty()); + assert_eq(L1ToL2MessageSponge::new().num_absorbed, 0); + } + + #[test] + fn absorb_tracks_count() { + let mut sponge = L1ToL2MessageSponge::new(); + sponge.absorb([11, 22, 33, 0, 0], 3); + assert_eq(sponge.num_absorbed, 3); + sponge.absorb([44, 55], 2); + assert_eq(sponge.num_absorbed, 5); + } + + #[test] + fn absorb_ignores_lanes_past_count() { + // Lanes beyond `num` must not affect the accumulated state. + let mut with_padding = L1ToL2MessageSponge::new(); + with_padding.absorb([11, 22, 33, 999, 888], 3); + + let mut exact = L1ToL2MessageSponge::new(); + exact.absorb([11, 22, 33], 3); + + assert_eq(with_padding, exact); + } + + #[test] + fn absorb_equality_across_split_boundaries() { + // Absorbing [11,22,33,44,55] in one call equals absorbing [11,22,33] then [44,55] across two threaded sponges. + let mut single = L1ToL2MessageSponge::new(); + single.absorb([11, 22, 33, 44, 55], 5); + + let mut threaded = L1ToL2MessageSponge::new(); + threaded.absorb([11, 22, 33, 44, 55], 3); + threaded.absorb([44, 55, 0, 0, 0], 2); + + assert_eq(threaded, single); + assert_eq(threaded.num_absorbed, 5); + + let mut single_squeeze = single; + let mut threaded_squeeze = threaded; + assert_eq(threaded_squeeze.squeeze(), single_squeeze.squeeze()); + } + + #[test] + fn empty_bundle_is_noop() { + let mut sponge = L1ToL2MessageSponge::new(); + sponge.absorb([0; 5], 0); + assert_eq(sponge, L1ToL2MessageSponge::empty()); + } + + #[test] + fn matches_raw_poseidon2_sponge() { + // The accumulated state must be a plain absorb-only Poseidon2 sponge with iv = 0. + let mut sponge = L1ToL2MessageSponge::new(); + sponge.absorb([11, 22, 33, 44, 55], 5); + + let mut expected = Poseidon2Sponge::new(0); + expected.absorb(11); + expected.absorb(22); + expected.absorb(33); + expected.absorb(44); + expected.absorb(55); + + assert_eq(sponge.sponge, expected); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/mod.nr index 1ee35685bc37..3a8609d4be2f 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/mod.nr @@ -1,4 +1,8 @@ // TODO: Move to types/src/abis/rollup/ +// `l1_to_l2_message_sponge` is declared first because the `#[derive(Serialize, Deserialize)]` macros require a field +// type's module to be declared before any struct that embeds it (see the ordering note in `types/src/lib.nr`). +mod l1_to_l2_message_sponge; +mod l1_to_l2_message_bundle; mod public_chonk_verifier_public_inputs; mod tx_rollup_public_inputs; mod block_rollup_public_inputs; @@ -8,6 +12,8 @@ mod root_rollup_public_inputs; pub use block_rollup_public_inputs::BlockRollupPublicInputs; pub use checkpoint_rollup_public_inputs::CheckpointRollupPublicInputs; +pub use l1_to_l2_message_bundle::L1ToL2MessageBundle; +pub use l1_to_l2_message_sponge::L1ToL2MessageSponge; pub use parity_public_inputs::ParityPublicInputs; pub use public_chonk_verifier_public_inputs::PublicChonkVerifierPublicInputs; pub use root_rollup_public_inputs::RootRollupPublicInputs; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/parity_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/parity_public_inputs.nr index 71fe26cdff17..1914ae700516 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/parity_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/parity_public_inputs.nr @@ -1,15 +1,35 @@ +use crate::abis::L1ToL2MessageSponge; use types::traits::{Deserialize, Empty, Serialize}; #[derive(Deserialize, Eq, Serialize)] pub struct ParityPublicInputs { - pub sha_root: Field, - pub converted_root: Field, + // Rolling hash of the Inbox message chain before absorbing this checkpoint's messages. + pub start_rolling_hash: Field, + // Rolling hash of the Inbox message chain after absorbing the `num_msgs` real messages. Each link is + // `sha256ToField(prev || msg)`, matching the truncated-to-field sha256 the L1 Inbox accumulates. + pub end_rolling_hash: Field, + // Poseidon2 message-bundle sponge before this checkpoint's messages (empty at checkpoint start). + pub start_sponge: L1ToL2MessageSponge, + // Message-bundle sponge after absorbing the `num_msgs` real messages. The checkpoint root asserts this equals the + // sponge accumulated across the checkpoint's block roots, tying the parity-committed message list to the leaves + // the blocks inserted into the L1-to-L2 tree. + pub end_sponge: L1ToL2MessageSponge, + // Number of real (non-padding) messages absorbed into the rolling hash and the sponge. + pub num_msgs: u32, pub vk_tree_root: Field, pub prover_id: Field, } impl Empty for ParityPublicInputs { fn empty() -> Self { - ParityPublicInputs { sha_root: 0, converted_root: 0, vk_tree_root: 0, prover_id: 0 } + ParityPublicInputs { + start_rolling_hash: 0, + end_rolling_hash: 0, + start_sponge: L1ToL2MessageSponge::empty(), + end_sponge: L1ToL2MessageSponge::empty(), + num_msgs: 0, + vk_tree_root: 0, + prover_id: 0, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/root_rollup_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/root_rollup_public_inputs.nr index 33f5e0d2c3c8..925ef68c24dc 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/root_rollup_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/root_rollup_public_inputs.nr @@ -17,6 +17,10 @@ pub struct RootRollupPublicInputs { // Root of the epoch out hash *balanced* tree. // The out hash of the first checkpoint in the epoch is inserted at index 0, the second at index 1, and so on. pub out_hash: Field, + // Inbox rolling-hash chain segment consumed across the epoch: the chain value before the first checkpoint's + // messages and after the last checkpoint's. Continuity within the range is enforced by the checkpoint merges. + pub previous_inbox_rolling_hash: Field, + pub end_inbox_rolling_hash: Field, // Checkpoint header hashes for each checkpoint in this epoch. // The header hash of the first checkpoint in the epoch is at index 0, the second at index 1, and so on. pub checkpoint_header_hashes: [Field; MAX_CHECKPOINTS_PER_EPOCH], diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup.nr index 249fb16561cd..83563c6e8825 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup.nr @@ -8,17 +8,23 @@ use crate::{ use types::{ constants::{ BLOCK_MERGE_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, - BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, }, proof::proof_data::RollupHonkProofData, }; // Note: see `rollup_structure_tests.nr` for valid combinations of left and right vks. -global ALLOWED_RIGHT_ROLLUP_VK_INDICES: [u32; 3] = - [BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, BLOCK_MERGE_ROLLUP_VK_INDEX]; +// The message-only block root is a non-first variant, so it appears alongside the other non-first block roots. +global ALLOWED_RIGHT_ROLLUP_VK_INDICES: [u32; 4] = [ + BLOCK_ROOT_ROLLUP_VK_INDEX, + BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + BLOCK_MERGE_ROLLUP_VK_INDEX, +]; -global ALLOWED_LEFT_ROLLUP_VK_INDICES: [u32; 6] = ALLOWED_RIGHT_ROLLUP_VK_INDICES.concat([ +global ALLOWED_LEFT_ROLLUP_VK_INDICES: [u32; 7] = ALLOWED_RIGHT_ROLLUP_VK_INDICES.concat([ // The first block roots may only appear as the left child of the block merge rollup. // However, this doesn't prevent having 2 first block roots in the same checkpoint. We rely on the checks in // `validate_consecutive_block_rollups` and `checkpoint_root_inputs_validator` to enforce this. @@ -41,7 +47,7 @@ pub struct BlockMergeRollupPrivateInputs { /// - Merges the state references (left's start with right's end) /// - Merges the sponge blobs (left's start with right's end) /// - Accumulates the block_headers_hash, out_hash, fees, and mana used -/// - Propagates the in_hash from the left rollup (which must be a first block) +/// - Propagates `is_first_block` from the left rollup and threads the message sponge (left's start, right's end) /// /// The output feeds into another Block Merge circuit to continue building the tree, /// or into a Checkpoint Root circuit once all blocks in the checkpoint are combined. diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/consecutive_block_rollups_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/consecutive_block_rollups_tests.nr index 8ac5eba688cc..892f72bdb8dd 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/consecutive_block_rollups_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/consecutive_block_rollups_tests.nr @@ -1,5 +1,5 @@ use super::TestBuilder; -use types::{address::EthAddress, hash::accumulate_sha256}; +use types::{address::EthAddress, constants::BLOCK_ROOT_ROLLUP_VK_INDEX, hash::accumulate_sha256}; #[test] fn accumulated_out_hash_correctly() { @@ -54,45 +54,53 @@ fn output_zero_when_both_out_hashes_are_zero() { } #[test] -fn non_zero_in_hash_in_left_rollup() { +fn first_block_in_left_rollup() { + // The default builder has a first block root on the left and a non-first block on the right. let mut builder = TestBuilder::default(); - builder.left_rollup.in_hash = 123; - let pi = builder.execute(); builder.assert_expected_public_inputs(pi); - assert_eq(pi.in_hash, 123); + assert(pi.is_first_block); } #[test] -fn zero_in_hash_in_both_rollups() { - let mut builder = TestBuilder::default(); - - builder.left_rollup.in_hash = 0; - builder.right_rollup.in_hash = 0; +fn no_first_block_in_either_rollup() { + // A merge of two non-first blocks in the middle of a checkpoint carries no first block. + let mut builder = + TestBuilder::new(BLOCK_ROOT_ROLLUP_VK_INDEX, 1, BLOCK_ROOT_ROLLUP_VK_INDEX, 1); let pi = builder.execute(); builder.assert_expected_public_inputs(pi); - assert_eq(pi.in_hash, 0); + assert(!pi.is_first_block); +} + +#[test(should_fail_with = "Right rollup must not be a first block")] +fn first_block_in_right_rollup() { + let mut builder = TestBuilder::default(); + + builder.right_rollup.is_first_block = true; + + builder.execute_and_fail(); } -#[test(should_fail_with = "Right rollup must not carry in_hash")] -fn non_zero_in_hash_in_right_rollup() { +#[test(should_fail_with = "Right rollup must not be a first block")] +fn first_block_in_both_rollups() { let mut builder = TestBuilder::default(); - builder.right_rollup.in_hash = 123; + builder.left_rollup.is_first_block = true; + builder.right_rollup.is_first_block = true; builder.execute_and_fail(); } -#[test(should_fail_with = "Right rollup must not carry in_hash")] -fn non_zero_in_hash_in_both_rollups() { +#[test(should_fail_with = "Mismatched message sponge: expected right.start_msg_sponge to match left.end_msg_sponge")] +fn mismatched_message_sponge_fails() { let mut builder = TestBuilder::default(); - builder.left_rollup.in_hash = 123; - builder.right_rollup.in_hash = 123; + // Break the sponge continuity between the left and right rollups. + builder.right_rollup.start_msg_sponge.num_absorbed += 1; builder.execute_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/mod.nr index 52d7d174f36e..d1e88b148729 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/mod.nr @@ -1,5 +1,6 @@ mod child_proof_vk_tests; mod consecutive_block_rollups_tests; +mod msgs_only_tests; mod rollup_structure_tests; use crate::{ @@ -13,8 +14,9 @@ use crate::{ use types::{ constants::{ BLOCK_MERGE_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, - BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, }, hash::accumulate_sha256, }; @@ -58,8 +60,8 @@ impl TestBuilder { if !is_first_block(left_rollup_vk_index) & (left_rollup_vk_index != BLOCK_MERGE_ROLLUP_VK_INDEX) { - // Change the start_block_number to be smaller than the left rollup's start_block_number so that the in_hash - // won't be set on the left rollup. + // Change the start_block_number to be smaller than the left rollup's start_block_number so that + // `is_first_block` won't be set on the left rollup. fixture_builder.start_block_number = start_block_number - 1; } let left_rollup = fixture_builder.get_merged_block_rollup_public_inputs( @@ -68,8 +70,8 @@ impl TestBuilder { ); if is_first_block(right_rollup_vk_index) { - // Change the start_block_number to be the right rollup's start_block_number so that the in_hash will be set - // on the right rollup. + // Change the start_block_number to be the right rollup's start_block_number so that `is_first_block` will be + // set on the right rollup. fixture_builder.start_block_number = start_block_number + num_left_blocks as u32; } let right_rollup = fixture_builder.get_merged_block_rollup_public_inputs( @@ -96,7 +98,8 @@ impl TestBuilder { | (vk_index == BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX) | (vk_index == BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX) | (vk_index == BLOCK_ROOT_ROLLUP_VK_INDEX) - | (vk_index == BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX), + | (vk_index == BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX) + | (vk_index == BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX), ); } } @@ -143,7 +146,11 @@ impl TestBuilder { accumulate_block_headers_hash(left.block_headers_hash, right.block_headers_hash); assert_eq(pi.block_headers_hash, expected_block_headers_hash); - assert_eq(pi.in_hash, left.in_hash); + // `is_first_block` and the start of the message sponge come from the left rollup; the sponge end comes from the + // right rollup. + assert_eq(pi.is_first_block, left.is_first_block); + assert_eq(pi.start_msg_sponge, left.start_msg_sponge); + assert_eq(pi.end_msg_sponge, right.end_msg_sponge); let expected_out_hash = if (left.out_hash != 0) & (right.out_hash != 0) { accumulate_sha256(left.out_hash, right.out_hash) diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/msgs_only_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/msgs_only_tests.nr new file mode 100644 index 000000000000..686ac28c31f7 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/tests/msgs_only_tests.nr @@ -0,0 +1,107 @@ +use crate::{ + abis::BlockRollupPublicInputs, + block_merge::block_merge_rollup::{self, BlockMergeRollupPrivateInputs}, + tests::RollupFixtureBuilder, +}; +use types::constants::{ + BLOCK_MERGE_ROLLUP_VK_INDEX, BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, +}; + +// Merges two consecutive single-block rollups into one. +fn merge( + left: BlockRollupPublicInputs, + left_vk_index: u32, + right: BlockRollupPublicInputs, + right_vk_index: u32, +) -> BlockRollupPublicInputs { + block_merge_rollup::execute( + BlockMergeRollupPrivateInputs { + previous_rollups: [ + RollupFixtureBuilder::make_proof_data(left, left_vk_index), + RollupFixtureBuilder::make_proof_data(right, right_vk_index), + ], + }, + ) +} + +// The roadmap's done-when: a checkpoint made of [first block, message-only block, normal block] proves. The +// message-only block sits in the middle, so the merge circuits must accept it as a non-first child and thread the state, +// archive and sponges through it. +#[test] +fn checkpoint_with_mid_checkpoint_msgs_only_block() { + let fixture_builder = RollupFixtureBuilder::new(); + let start_block_number = fixture_builder.start_block_number; + + // The consecutive single-block fixtures chain naturally by block number (archives, states and sponges line up). + let first = fixture_builder.get_block_rollup_public_inputs(start_block_number); + let msgs_only = fixture_builder.get_block_rollup_public_inputs(start_block_number + 1); + let normal = fixture_builder.get_block_rollup_public_inputs(start_block_number + 2); + + assert(first.is_first_block); + assert(!msgs_only.is_first_block); + assert(!normal.is_first_block); + + // ((first, msgs_only), normal) + let left = merge( + first, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, + msgs_only, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + ); + let merged = merge( + left, + BLOCK_MERGE_ROLLUP_VK_INDEX, + normal, + BLOCK_ROOT_ROLLUP_VK_INDEX, + ); + + assert_eq(merged.num_blocks(), 3); + // `is_first_block` propagates from the leftmost (first) block only. + assert(merged.is_first_block); + assert_eq(merged.previous_archive, first.previous_archive); + assert_eq(merged.new_archive, normal.new_archive); + assert_eq(merged.start_msg_sponge, first.start_msg_sponge); + assert_eq(merged.end_msg_sponge, normal.end_msg_sponge); +} + +// A message-only block is a valid right (non-first) child of a block merge. +#[test] +fn msgs_only_block_accepted_as_right_child() { + let fixture_builder = RollupFixtureBuilder::new(); + let start_block_number = fixture_builder.start_block_number; + + let first = fixture_builder.get_block_rollup_public_inputs(start_block_number); + let msgs_only = fixture_builder.get_block_rollup_public_inputs(start_block_number + 1); + + let merged = merge( + first, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, + msgs_only, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + ); + + assert_eq(merged.num_blocks(), 2); + assert(merged.is_first_block); +} + +// The message-only block's `start_msg_sponge` is a free input; the merge continuity check must catch it if it does not +// follow on from the previous block's `end_msg_sponge`. +#[test(should_fail_with = "Mismatched message sponge: expected right.start_msg_sponge to match left.end_msg_sponge")] +fn msgs_only_block_bad_start_msg_sponge_fails() { + let fixture_builder = RollupFixtureBuilder::new(); + let start_block_number = fixture_builder.start_block_number; + + let first = fixture_builder.get_block_rollup_public_inputs(start_block_number); + let mut msgs_only = fixture_builder.get_block_rollup_public_inputs(start_block_number + 1); + + // Break the sponge continuity with the previous (first) block. + msgs_only.start_msg_sponge.num_absorbed += 1; + + let _ = merge( + first, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, + msgs_only, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + ); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/merge_block_rollups.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/merge_block_rollups.nr index 8adf08cb1ba3..44cf8b2be5e7 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/merge_block_rollups.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/merge_block_rollups.nr @@ -16,9 +16,15 @@ pub fn merge_block_rollups( let block_headers_hash = accumulate_block_headers_hash(left.block_headers_hash, right.block_headers_hash); - // `in_hash` originates from the first block root and must propagate through all merge steps via the left rollup - // only. It's checked in `validate_consecutive_block_rollups` to make sure only the left rollup carries it. - let in_hash = left.in_hash; + // `is_first_block` originates from the first block root and must propagate through all merge steps via the left + // rollup only. `validate_consecutive_block_rollups` asserts the right rollup's is false, so only the leftmost leaf + // can carry it up to the checkpoint root. + let is_first_block = left.is_first_block; + + // The message sponge threads across the checkpoint's blocks: the range spans left's start through right's end. + // `validate_consecutive_block_rollups` asserts `right.start_msg_sponge == left.end_msg_sponge` for continuity. + let start_msg_sponge = left.start_msg_sponge; + let end_msg_sponge = right.end_msg_sponge; let out_hash = accumulate_out_hash(left.out_hash, right.out_hash); @@ -36,7 +42,9 @@ pub fn merge_block_rollups( end_sponge_blob: right.end_sponge_blob, timestamp: left.timestamp, // Both blocks have the same timestamp. block_headers_hash, - in_hash, + is_first_block, + start_msg_sponge, + end_msg_sponge, out_hash, accumulated_fees, accumulated_mana_used, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/validate_consecutive_block_rollups.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/validate_consecutive_block_rollups.nr index d01d67845e02..e3e9221d5f8c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/validate_consecutive_block_rollups.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/utils/validate_consecutive_block_rollups.nr @@ -42,11 +42,17 @@ fn assert_prev_block_rollups_follow_on_from_each_other( "Mismatched timestamps: expected right.timestamp to match left.timestamp", ); - // TODO: Consider extracting into its own function: - - // A non-empty `in_hash` originates from the first block root only, and is propagated through all merge - // steps via the left rollup only (see merge_block_rollups.nr). - // We prevent the right rollup from propagating a nonzero `in_hash`, so it's impossible for any - // block but the first to propagate a nonzero `in_hash` up to the checkpoint root. - assert_eq(right.in_hash, 0, "Right rollup must not carry in_hash"); + // `is_first_block` originates from the first block root only, and is propagated through all merge steps via the + // left rollup only (see merge_block_rollups.nr). We prevent the right rollup from carrying it, so it's impossible + // for any block but the first to propagate `is_first_block == true` up to the checkpoint root. + assert(!right.is_first_block, "Right rollup must not be a first block"); + + // The message sponge threads across the checkpoint's blocks: the right rollup must start from where the left rollup + // ended. Combined with the checkpoint root asserting the leftmost start is empty and the merged end matches the + // parity root's sponge, this pins the blocks to insert exactly the parity-committed message list, in order. + assert_eq( + right.start_msg_sponge, + left.end_msg_sponge, + "Mismatched message sponge: expected right.start_msg_sponge to match left.end_msg_sponge", + ); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_empty_tx_first_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_empty_tx_first_rollup.nr index a4ecb261edff..4e0ba02a4ee9 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_empty_tx_first_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_empty_tx_first_rollup.nr @@ -1,19 +1,16 @@ use crate::{ - abis::{BlockRollupPublicInputs, ParityPublicInputs}, - block_root::components::{BlockRollupPublicInputsComposer, validate_parity_root}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge}, + block_root::components::BlockRollupPublicInputsComposer, }; use types::{ abis::{ append_only_tree_snapshot::AppendOnlyTreeSnapshot, checkpoint_constant_data::CheckpointConstantData, state_reference::StateReference, }, - constants::{ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH}, - proof::proof_data::UltraHonkProofData, + constants::{ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT}, }; pub struct BlockRootEmptyTxFirstRollupPrivateInputs { - pub(crate) parity_root: UltraHonkProofData, - pub(crate) previous_archive: AppendOnlyTreeSnapshot, pub(crate) previous_state: StateReference, // The previous block is not in the same checkpoint as the current block. So we need to provide the constants for @@ -23,19 +20,20 @@ pub struct BlockRootEmptyTxFirstRollupPrivateInputs { // timestamp in the checkpoint root. pub(crate) timestamp: u64, - // Hint for inserting the new l1 to l2 message subtree. - pub(crate) new_l1_to_l2_message_subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_state`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], // Hint for inserting the new block hash to the last archive. pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], } /// The Block Root Empty Tx First Rollup circuit creates the first empty block of a checkpoint. -/// It processes L1-to-L2 messages and creates the block header. +/// It inserts the block's L1-to-L2 message bundle and creates the block header. /// This variant is used for the first block in a checkpoint that contains no transactions. /// /// This circuit: -/// - Verifies the parity root proof containing L1-to-L2 messages for the checkpoint -/// - Inserts the L1-to-L2 message subtree into the L1-to-L2 message tree +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge /// - Initializes an empty sponge blob (since it's the first block in a checkpoint) /// - Computes the block header hash and inserts it into the archive tree /// @@ -44,21 +42,18 @@ pub struct BlockRootEmptyTxFirstRollupPrivateInputs { /// /// VkIndex: BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX pub fn execute(inputs: BlockRootEmptyTxFirstRollupPrivateInputs) -> BlockRollupPublicInputs { - validate_parity_root( - inputs.parity_root, - inputs.constants.vk_tree_root, - inputs.constants.prover_id, - ); - BlockRollupPublicInputsComposer::new_from_no_rollups( inputs.previous_archive, inputs.previous_state, inputs.constants, inputs.timestamp, ) - .with_new_l1_to_l2_messages( - inputs.parity_root.public_inputs, - inputs.new_l1_to_l2_message_subtree_root_sibling_path, + .with_message_bundle( + true, + inputs.previous_state.l1_to_l2_message_tree, + L1ToL2MessageSponge::new(), + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, ) .finish(inputs.new_archive_sibling_path) } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_first_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_first_rollup.nr index 62485020c117..665f3cb37c5b 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_first_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_first_rollup.nr @@ -1,43 +1,43 @@ use crate::{ - abis::{BlockRollupPublicInputs, ParityPublicInputs, TxRollupPublicInputs}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, block_root::components::{ BlockRollupPublicInputsComposer, validate_l1_to_l2_tree_snapshot_in_constants, - validate_parity_root, validate_previous_rollups, + validate_previous_rollups, }, }; use types::{ abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::{ - ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX, TX_MERGE_ROLLUP_VK_INDEX, + ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, TX_MERGE_ROLLUP_VK_INDEX, }, - proof::proof_data::{RollupHonkProofData, UltraHonkProofData}, + proof::proof_data::RollupHonkProofData, }; global ALLOWED_PREVIOUS_VK_INDICES: [u32; 3] = [TX_MERGE_ROLLUP_VK_INDEX, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX]; pub struct BlockRootFirstRollupPrivateInputs { - pub(crate) parity_root: UltraHonkProofData, pub(crate) previous_rollups: [RollupHonkProofData; 2], - // Hinted value to insert the new l1-to-l2 message subtree to. + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // Hinted value the bundle is appended to. // This will be set to the `start_state` in the public inputs and validated in the checkpoint root circuit to // ensure it matches the l1-to-l2 tree snapshot in the header of the last block from the previous checkpoint. pub(crate) previous_l1_to_l2: AppendOnlyTreeSnapshot, - // Hint for inserting the new l1-to-l2 message subtree. - pub(crate) new_l1_to_l2_message_subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_l1_to_l2`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], // Hint for inserting the new block hash to the last archive. pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], } /// The Block Root First Rollup circuit finalizes the first block of a checkpoint. -/// It processes L1-to-L2 messages and creates the block header. +/// It inserts the block's L1-to-L2 message bundle and creates the block header. /// This variant is used for the first block with multiple transactions. /// /// This circuit: -/// - Verifies the parity root proof containing L1-to-L2 messages for the checkpoint /// - Verifies the proofs from two child tx rollups (Tx Base or Tx Merge circuits) -/// - Inserts the L1-to-L2 message subtree into the L1-to-L2 message tree +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge /// - Validates that the two child rollups are consecutive (end state of left matches start state of right) /// - Computes the block header hash and inserts it into the archive tree /// @@ -48,17 +48,16 @@ pub struct BlockRootFirstRollupPrivateInputs { pub fn execute(inputs: BlockRootFirstRollupPrivateInputs) -> BlockRollupPublicInputs { let previous_rollups = inputs.previous_rollups.map(|rollup| rollup.public_inputs); let mut composer = BlockRollupPublicInputsComposer::new_from_two_rollups(previous_rollups); - let new_l1_to_l2 = composer.update_l1_to_l2_tree_snapshots( - inputs.parity_root.public_inputs, - inputs.previous_l1_to_l2, - inputs.new_l1_to_l2_message_subtree_root_sibling_path, - ); - - validate_parity_root( - inputs.parity_root, - inputs.previous_rollups[0].public_inputs.constants.vk_tree_root, - inputs.previous_rollups[0].public_inputs.constants.prover_id, - ); + // The leftmost block of a checkpoint starts the message sponge from empty. + let new_l1_to_l2 = composer + .with_message_bundle( + true, + inputs.previous_l1_to_l2, + L1ToL2MessageSponge::new(), + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, + ) + .get_new_l1_to_l2(); validate_previous_rollups(inputs.previous_rollups, ALLOWED_PREVIOUS_VK_INDICES); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_msgs_only_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_msgs_only_rollup.nr new file mode 100644 index 000000000000..6f05226552ed --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_msgs_only_rollup.nr @@ -0,0 +1,81 @@ +use crate::{ + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge}, + block_root::components::BlockRollupPublicInputsComposer, +}; +use types::{ + abis::{ + append_only_tree_snapshot::AppendOnlyTreeSnapshot, + checkpoint_constant_data::CheckpointConstantData, state_reference::StateReference, + }, + blob_data::SpongeBlob, + constants::{ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT}, +}; + +pub struct BlockRootMsgsOnlyRollupPrivateInputs { + pub(crate) previous_archive: AppendOnlyTreeSnapshot, + pub(crate) previous_state: StateReference, + // The previous block is in the same checkpoint as this block, but this block has no txs, so there are no tx + // constants to carry them. The checkpoint constants are given as a free value here and pinned by the checkpoint + // root's previous-header check via the merge continuity of the states below. + pub(crate) constants: CheckpointConstantData, + // The timestamp of this block. It's given as a free value here, but will be checked against the previous block's + // timestamp in the block merge or checkpoint root. + pub(crate) timestamp: u64, + // Sponge blob inherited from the previous block. Checked against the previous block's `end_sponge_blob` in the + // block merge or checkpoint root circuit. + pub(crate) start_sponge_blob: SpongeBlob, + // Message sponge inherited from the previous block. Checked against the previous block's `end_msg_sponge` in the + // block merge or checkpoint root circuit. + pub(crate) start_msg_sponge: L1ToL2MessageSponge, + + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_state`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], + // Hint for inserting the new block hash to the last archive. + pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], +} + +/// The Block Root Msgs Only Rollup circuit creates a non-first, transaction-less block that inserts an L1-to-L2 message +/// bundle. It lets a proposer keep draining the Inbox into a checkpoint when the tx pool is empty. +/// +/// Unlike the first-empty variant, this block sits in the middle of a checkpoint: it inherits the sponge blob and +/// message sponge from the previous block (rather than starting them from empty) and sets `is_first_block = false`. It +/// is deliberately unable to be the leftmost block of a checkpoint: the checkpoint root asserts the leftmost rollup's +/// `is_first_block` is true, so a checkpoint made only of this variant cannot prove. +/// +/// This circuit: +/// - Requires the bundle to be non-empty (`num_msgs > 0`); an empty non-first block carries no reason to exist and +/// would otherwise be a provable filler block +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge +/// - Threads the (non-empty) start sponge blob through unchanged, since there are no tx effects +/// - Computes the block header hash and inserts it into the archive tree +/// +/// The output feeds into a Block Merge circuit if more blocks need to be combined, or directly into a Checkpoint Root +/// circuit. +/// +/// VkIndex: BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX +pub fn execute(inputs: BlockRootMsgsOnlyRollupPrivateInputs) -> BlockRollupPublicInputs { + // A message-only block exists solely to insert L1-to-L2 messages, so it must carry at least one real message. This + // prevents a provable, fully-empty non-first filler block. + assert( + inputs.message_bundle.num_msgs != 0, + "A message-only block must insert at least one L1-to-L2 message", + ); + + BlockRollupPublicInputsComposer::new_from_no_rollups_with_start_sponge_blob( + inputs.previous_archive, + inputs.previous_state, + inputs.constants, + inputs.timestamp, + inputs.start_sponge_blob, + ) + .with_message_bundle( + false, + inputs.previous_state.l1_to_l2_message_tree, + inputs.start_msg_sponge, + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, + ) + .finish(inputs.new_archive_sibling_path) +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup.nr index 4f971634aec0..b0a3119e00a1 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup.nr @@ -1,11 +1,15 @@ use crate::{ - abis::{BlockRollupPublicInputs, TxRollupPublicInputs}, - block_root::components::{BlockRollupPublicInputsComposer, validate_previous_rollups}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, + block_root::components::{ + BlockRollupPublicInputsComposer, validate_l1_to_l2_tree_snapshot_in_constants, + validate_previous_rollups, + }, }; use types::{ + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::{ - ARCHIVE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX, - TX_MERGE_ROLLUP_VK_INDEX, + ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, TX_MERGE_ROLLUP_VK_INDEX, }, proof::proof_data::RollupHonkProofData, }; @@ -15,16 +19,29 @@ global ALLOWED_PREVIOUS_VK_INDICES: [u32; 3] = pub struct BlockRootRollupPrivateInputs { pub(crate) previous_rollups: [RollupHonkProofData; 2], + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // The l1-to-l2 tree snapshot this block builds on (the previous block's post-insertion snapshot). It is a witnessed + // value, pinned by block-merge continuity (`right.start_state == left.end_state`) to the previous block's end + // state; since the checkpoint root forces the leftmost block to be a first-block variant, every non-first block + // has a left neighbour that pins it. + pub(crate) previous_l1_to_l2: AppendOnlyTreeSnapshot, + // Message sponge inherited from the previous block. Checked against the previous block's `end_msg_sponge` in the + // block merge or checkpoint root circuit. + pub(crate) start_msg_sponge: L1ToL2MessageSponge, + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_l1_to_l2`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], // Hint for inserting the new block hash to the last archive. pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], } /// The Block Root Rollup circuit finalizes a block by combining two transaction rollup proofs. -/// It creates the block header and does not process L1-to-L2 messages. +/// It inserts the block's L1-to-L2 message bundle and creates the block header. /// This variant is used for non-first blocks with multiple transactions. /// /// This circuit: /// - Verifies the proofs from two child tx rollups (Tx Base or Tx Merge circuits) +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge /// - Validates that the two child rollups are consecutive (end state of left matches start state of right) /// - Computes the block header hash and inserts it into the archive tree /// @@ -34,10 +51,29 @@ pub struct BlockRootRollupPrivateInputs { /// /// VkIndex: BLOCK_ROOT_ROLLUP_VK_INDEX pub fn execute(inputs: BlockRootRollupPrivateInputs) -> BlockRollupPublicInputs { + let previous_rollups = inputs.previous_rollups.map(|rollup| rollup.public_inputs); + // Non-first blocks build on a witnessed start snapshot (pinned by block-merge continuity to the previous block's + // end state) rather than the constants value, so this block can append its own bundle and still assert the tx + // constants carry the post-bundle snapshot. + let mut composer = BlockRollupPublicInputsComposer::new_from_two_rollups(previous_rollups); + let new_l1_to_l2 = composer + .with_message_bundle( + false, + inputs.previous_l1_to_l2, + inputs.start_msg_sponge, + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, + ) + .get_new_l1_to_l2(); + validate_previous_rollups(inputs.previous_rollups, ALLOWED_PREVIOUS_VK_INDICES); - let previous_rollups = inputs.previous_rollups.map(|rollup| rollup.public_inputs); - BlockRollupPublicInputsComposer::new_from_two_rollups(previous_rollups).finish( - inputs.new_archive_sibling_path, - ) + // The tx constants pin the l1-to-l2 snapshot the AVM validates message reads against; asserting it equals this + // block's post-bundle root lets this block's txs read the messages this block inserts (same-block consumption). + validate_l1_to_l2_tree_snapshot_in_constants( + inputs.previous_rollups[0].public_inputs.constants, + new_l1_to_l2, + ); + + composer.finish(inputs.new_archive_sibling_path) } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_first_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_first_rollup.nr index 5f9fb37a2597..ff318e4b2eb5 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_first_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_first_rollup.nr @@ -1,17 +1,17 @@ use crate::{ - abis::{BlockRollupPublicInputs, ParityPublicInputs, TxRollupPublicInputs}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, block_root::components::{ BlockRollupPublicInputsComposer, validate_l1_to_l2_tree_snapshot_in_constants, - validate_parity_root, validate_previous_rollups, + validate_previous_rollups, }, }; use types::{ abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::{ - ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX, + ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, }, - proof::proof_data::{RollupHonkProofData, UltraHonkProofData}, + proof::proof_data::RollupHonkProofData, }; // TX_MERGE_ROLLUP_VK_INDEX is not allowed if there is only one previous rollup. @@ -19,26 +19,26 @@ global ALLOWED_PREVIOUS_VK_INDICES: [u32; 2] = [PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX]; pub struct BlockRootSingleTxFirstRollupPrivateInputs { - pub(crate) parity_root: UltraHonkProofData, pub(crate) previous_rollup: RollupHonkProofData, - // Hinted value to insert the new l1-to-l2 message subtree to. + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // Hinted value the bundle is appended to. // This will be set to the `start_state` in the public inputs and validated in the checkpoint root circuit to // ensure it matches the l1-to-l2 tree snapshot in the header of the last block from the previous checkpoint. pub(crate) previous_l1_to_l2: AppendOnlyTreeSnapshot, - // Hint for inserting the new l1 to l2 message subtree. - pub(crate) new_l1_to_l2_message_subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_l1_to_l2`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], // Hint for inserting the new block hash to the last archive. pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], } /// The Block Root Single Tx First Rollup circuit finalizes the first block of a checkpoint. -/// It processes L1-to-L2 messages and creates the block header. +/// It inserts the block's L1-to-L2 message bundle and creates the block header. /// This variant is used for the first block with only one transaction. /// /// This circuit: -/// - Verifies the parity root proof containing L1-to-L2 messages for the checkpoint /// - Verifies the proof from a single tx rollup (Private Tx Base or Public Tx Base circuit) -/// - Inserts the L1-to-L2 message subtree into the L1-to-L2 message tree +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge /// - Computes the block header hash and inserts it into the archive tree /// /// The output feeds into a Block Merge circuit if more blocks need to be combined, @@ -49,17 +49,16 @@ pub fn execute(inputs: BlockRootSingleTxFirstRollupPrivateInputs) -> BlockRollup let mut composer = BlockRollupPublicInputsComposer::new_from_single_rollup( inputs.previous_rollup.public_inputs, ); - let new_l1_to_l2 = composer.update_l1_to_l2_tree_snapshots( - inputs.parity_root.public_inputs, - inputs.previous_l1_to_l2, - inputs.new_l1_to_l2_message_subtree_root_sibling_path, - ); - - validate_parity_root( - inputs.parity_root, - inputs.previous_rollup.public_inputs.constants.vk_tree_root, - inputs.previous_rollup.public_inputs.constants.prover_id, - ); + // The leftmost block of a checkpoint starts the message sponge from empty. + let new_l1_to_l2 = composer + .with_message_bundle( + true, + inputs.previous_l1_to_l2, + L1ToL2MessageSponge::new(), + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, + ) + .get_new_l1_to_l2(); validate_previous_rollups([inputs.previous_rollup], ALLOWED_PREVIOUS_VK_INDICES); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_rollup.nr index 00c7fd012803..3c3cacbdaea8 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_single_tx_rollup.nr @@ -1,9 +1,16 @@ use crate::{ - abis::{BlockRollupPublicInputs, TxRollupPublicInputs}, - block_root::components::{BlockRollupPublicInputsComposer, validate_previous_rollups}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, + block_root::components::{ + BlockRollupPublicInputsComposer, validate_l1_to_l2_tree_snapshot_in_constants, + validate_previous_rollups, + }, }; use types::{ - constants::{ARCHIVE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX}, + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, + constants::{ + ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, + }, proof::proof_data::RollupHonkProofData, }; @@ -13,16 +20,29 @@ global ALLOWED_PREVIOUS_VK_INDICES: [u32; 2] = pub struct BlockRootSingleTxRollupPrivateInputs { pub(crate) previous_rollup: RollupHonkProofData, + // L1-to-L2 message bundle inserted by this block. + pub(crate) message_bundle: L1ToL2MessageBundle, + // The l1-to-l2 tree snapshot this block builds on (the previous block's post-insertion snapshot). It is a witnessed + // value, pinned by block-merge continuity (`right.start_state == left.end_state`) to the previous block's end + // state; since the checkpoint root forces the leftmost block to be a first-block variant, every non-first block + // has a left neighbour that pins it. + pub(crate) previous_l1_to_l2: AppendOnlyTreeSnapshot, + // Message sponge inherited from the previous block. Checked against the previous block's `end_msg_sponge` in the + // block merge or checkpoint root circuit. + pub(crate) start_msg_sponge: L1ToL2MessageSponge, + // Frontier hint for appending the bundle to the l1-to-l2 message tree (validated against `previous_l1_to_l2`). + pub(crate) l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], // Hint for inserting the new block hash to the last archive. pub(crate) new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], } /// The Block Root Single Tx Rollup circuit finalizes a block containing exactly one transaction. -/// It creates the block header and does not process L1-to-L2 messages. +/// It inserts the block's L1-to-L2 message bundle and creates the block header. /// This variant is used for non-first blocks with only one transaction. /// /// This circuit: /// - Verifies the proof from a single tx rollup (Private Tx Base or Public Tx Base circuit) +/// - Appends the block's L1-to-L2 message bundle to the L1-to-L2 message tree and absorbs it into the message sponge /// - Computes the block header hash and inserts it into the archive tree /// /// The output feeds into a Block Merge circuit if more blocks need to be combined, @@ -31,8 +51,30 @@ pub struct BlockRootSingleTxRollupPrivateInputs { /// /// VkIndex: BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX pub fn execute(inputs: BlockRootSingleTxRollupPrivateInputs) -> BlockRollupPublicInputs { + // Non-first blocks build on a witnessed start snapshot (pinned by block-merge continuity to the previous block's + // end state) rather than the constants value, so this block can append its own bundle and still assert the tx + // constants carry the post-bundle snapshot. + let mut composer = BlockRollupPublicInputsComposer::new_from_single_rollup( + inputs.previous_rollup.public_inputs, + ); + let new_l1_to_l2 = composer + .with_message_bundle( + false, + inputs.previous_l1_to_l2, + inputs.start_msg_sponge, + inputs.message_bundle, + inputs.l1_to_l2_message_frontier_hint, + ) + .get_new_l1_to_l2(); + validate_previous_rollups([inputs.previous_rollup], ALLOWED_PREVIOUS_VK_INDICES); - BlockRollupPublicInputsComposer::new_from_single_rollup(inputs.previous_rollup.public_inputs) - .finish(inputs.new_archive_sibling_path) + // The tx constants pin the l1-to-l2 snapshot the AVM validates message reads against; asserting it equals this + // block's post-bundle root lets this block's txs read the messages this block inserts (same-block consumption). + validate_l1_to_l2_tree_snapshot_in_constants( + inputs.previous_rollup.public_inputs.constants, + new_l1_to_l2, + ); + + composer.finish(inputs.new_archive_sibling_path) } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_rollup_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_rollup_public_inputs_composer.nr index 2d11d861b95e..65a5c38e9bbe 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_rollup_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_rollup_public_inputs_composer.nr @@ -1,5 +1,5 @@ use crate::{ - abis::{BlockRollupPublicInputs, ParityPublicInputs, TxRollupPublicInputs}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, tx_merge::merge_tx_rollups, }; use types::{ @@ -9,12 +9,10 @@ use types::{ partial_state_reference::PartialStateReference, state_reference::StateReference, }, blob_data::SpongeBlob, - constants::{ - ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - L1_TO_L2_MSG_TREE_HEIGHT, - }, + constants::{ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT}, merkle_tree::append_only_tree, traits::Hash, + utils::arrays::assert_trailing_zeros, }; pub struct BlockRollupPublicInputsComposer { @@ -31,9 +29,15 @@ pub struct BlockRollupPublicInputsComposer { accumulated_fees: Field, accumulated_mana_used: Field, num_txs: u16, - // The followings are set by calling `with_new_l1_to_l2_messages` explicitly. - in_hash: Field, + // The followings are set by calling `with_message_bundle` explicitly. + is_first_block: bool, + start_msg_sponge: L1ToL2MessageSponge, + end_msg_sponge: L1ToL2MessageSponge, new_l1_to_l2: AppendOnlyTreeSnapshot, + // Set by `with_message_bundle` and asserted by `finish`. Without it, a variant that forgot to apply its bundle + // would emit `previous_l1_to_l2 == new_l1_to_l2 == constants.l1_to_l2_tree_snapshot`: a silent no-op append that + // still satisfies the snapshot check against the constants. + bundle_applied: bool, } impl BlockRollupPublicInputsComposer { @@ -43,8 +47,27 @@ impl BlockRollupPublicInputsComposer { constants: CheckpointConstantData, timestamp: u64, ) -> Self { - let empty_sponge_blob = SpongeBlob::init(); + // The first block of a checkpoint starts from an empty sponge blob. + Self::new_from_no_rollups_with_start_sponge_blob( + previous_archive, + previous_state, + constants, + timestamp, + SpongeBlob::init(), + ) + } + /// Same as `new_from_no_rollups` but for a non-first block, which inherits a (non-empty) sponge blob from the + /// previous block instead of starting from empty. The `start_sponge_blob` is threaded unchanged as the end sponge + /// blob (before this block's end data is absorbed in `finish`), since a block with no txs adds no tx effects. It is + /// pinned against the previous block's `end_sponge_blob` at the block merge or checkpoint root. + pub fn new_from_no_rollups_with_start_sponge_blob( + previous_archive: AppendOnlyTreeSnapshot, + previous_state: StateReference, + constants: CheckpointConstantData, + timestamp: u64, + start_sponge_blob: SpongeBlob, + ) -> Self { Self { constants, previous_archive, @@ -52,18 +75,20 @@ impl BlockRollupPublicInputsComposer { // The state remains the same since there are no tx effects in this block. start_tree_snapshots: previous_state.partial, end_tree_snapshots: previous_state.partial, - // Since it's the first block in a checkpoint, the start sponge blob is empty. - start_sponge_blob: empty_sponge_blob, - end_sponge_blob: empty_sponge_blob, + start_sponge_blob, + end_sponge_blob: start_sponge_blob, timestamp, // The followings are 0 since there are no tx effects in this block. out_hash: 0, accumulated_fees: 0, accumulated_mana_used: 0, num_txs: 0, - // The followings are updated by calling `with_new_l1_to_l2_messages` explicitly. - in_hash: 0, + // The followings are updated by calling `with_message_bundle` explicitly. + is_first_block: false, + start_msg_sponge: L1ToL2MessageSponge::new(), + end_msg_sponge: L1ToL2MessageSponge::new(), new_l1_to_l2: previous_state.l1_to_l2_message_tree, + bundle_applied: false, } } @@ -96,10 +121,13 @@ impl BlockRollupPublicInputsComposer { accumulated_fees: rollup.accumulated_fees, accumulated_mana_used: rollup.accumulated_mana_used, num_txs: rollup.num_txs, - // The followings are updated by calling `update_l1_to_l2_tree_snapshots` explicitly. + // The followings are updated by calling `with_message_bundle` explicitly. previous_l1_to_l2: rollup.constants.l1_to_l2_tree_snapshot, - in_hash: 0, + is_first_block: false, + start_msg_sponge: L1ToL2MessageSponge::new(), + end_msg_sponge: L1ToL2MessageSponge::new(), new_l1_to_l2: rollup.constants.l1_to_l2_tree_snapshot, + bundle_applied: false, } } @@ -108,40 +136,66 @@ impl BlockRollupPublicInputsComposer { Self::new_from_single_rollup(merged_rollup) } - pub fn with_new_l1_to_l2_messages( + /// Appends this block's L1-to-L2 message bundle to the tree and absorbs its real messages into the message sponge. + /// + /// `previous_l1_to_l2` is the tree snapshot this block builds on: for the first block it is the pre-insertion + /// snapshot (hinted, and later checked against the previous checkpoint), for subsequent blocks it is a witnessed + /// snapshot pinned by block-merge continuity to the previous block's end state. Either way, the caller asserts the + /// tx constants carry the resulting post-bundle snapshot. `start_msg_sponge` is the sponge inherited from the + /// previous block (empty for the first block). + /// + /// A single `bundle.num_msgs` count drives both the compact (unpadded) tree append and the message-sponge absorb, + /// so the sponge matches the checkpoint's variable-size `InboxParity` proof. The lanes past + /// `num_msgs` must be zero. + pub fn with_message_bundle( &mut self, - parity: ParityPublicInputs, - subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], + is_first_block: bool, + previous_l1_to_l2: AppendOnlyTreeSnapshot, + start_msg_sponge: L1ToL2MessageSponge, + bundle: L1ToL2MessageBundle, + frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], ) -> Self { - self.in_hash = parity.sha_root; + self.is_first_block = is_first_block; + self.previous_l1_to_l2 = previous_l1_to_l2; + self.bundle_applied = true; + + // Real messages occupy the leading lanes; everything past `num_msgs` is zero padding. + assert_trailing_zeros(bundle.messages, bundle.num_msgs); - // Insert subtree into the l1-to-l2 message tree. - self.new_l1_to_l2 = append_only_tree::insert_subtree_root_to_snapshot::( - self.previous_l1_to_l2, - subtree_root_sibling_path, - parity.converted_root, + // Append the real leaves to the l1-to-l2 message tree at its current (compact, unaligned) next-available index. + self.new_l1_to_l2 = append_only_tree::append_leaves_to_snapshot::( + previous_l1_to_l2, + bundle.messages, + bundle.num_msgs, + frontier_hint, ); + // Absorb the same real leaves into the message sponge, threading it from the previous block. + self.start_msg_sponge = start_msg_sponge; + let mut end_msg_sponge = start_msg_sponge; + end_msg_sponge.absorb(bundle.messages, bundle.num_msgs); + self.end_msg_sponge = end_msg_sponge; + *self } - pub fn update_l1_to_l2_tree_snapshots( - &mut self, - parity: ParityPublicInputs, - previous_l1_to_l2: AppendOnlyTreeSnapshot, - subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], - ) -> AppendOnlyTreeSnapshot { - // Update the previous l1-to-l2 tree snapshot to build the new snapshot with. - self.previous_l1_to_l2 = previous_l1_to_l2; - - // Update the new l1-to-l2 tree snapshot and return it. - self.with_new_l1_to_l2_messages(parity, subtree_root_sibling_path).new_l1_to_l2 + /// The l1-to-l2 tree snapshot after appending this block's bundle. Tx-carrying variants (first and non-first) + /// check this against the snapshot in the tx constants (consumed by the AVM to read new messages). + pub fn get_new_l1_to_l2(self) -> AppendOnlyTreeSnapshot { + self.new_l1_to_l2 } pub fn finish( self, new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], ) -> BlockRollupPublicInputs { + // Every block transitions the l1-to-l2 message tree, even when its bundle is empty, so the append is not + // optional: skipping it would leave the start and end snapshots trivially equal. + assert( + self.bundle_applied, + "with_message_bundle must be called before finishing the block rollup", + ); + // Build the header of this block and then insert its hash to the archive tree. let (block_header, end_sponge_blob) = self.create_block_header_and_end_sponge_blob(); let block_header_hash = block_header.hash(); @@ -166,7 +220,9 @@ impl BlockRollupPublicInputsComposer { end_sponge_blob, timestamp: self.timestamp, block_headers_hash: block_header_hash, - in_hash: self.in_hash, + is_first_block: self.is_first_block, + start_msg_sponge: self.start_msg_sponge, + end_msg_sponge: self.end_msg_sponge, out_hash: self.out_hash, accumulated_fees: self.accumulated_fees, accumulated_mana_used: self.accumulated_mana_used, @@ -213,23 +269,17 @@ impl BlockRollupPublicInputsComposer { gas_fees: self.constants.gas_fees, }; - // Absorb data for this block into the end sponge blob. + // Absorb data for this block into the end sponge blob. The l1-to-l2 message tree root is absorbed for every + // block: any block can insert its own bundle, so the root is per-block, not + // checkpoint-constant. let mut block_end_sponge_blob = self.end_sponge_blob; - // `in_hash` is not 0 if and only if it's the first block in the checkpoint. - // Note: the `in_hash` of the first block in the checkpoint is asserted to be nonzero - // by the Checkpoint Root circuit. - // Note: the `in_hash` of subsequent blocks in the checkpoint is asserted to be 0 - // within `validate_consecutive_block_rollups.nr`, by asserting that the `in_hash` of all - // "right" rollups is `0`. - let is_first_block_in_checkpoint = self.in_hash != 0; block_end_sponge_blob.absorb_block_end_data( global_variables, last_archive, state, self.num_txs, self.accumulated_mana_used, - is_first_block_in_checkpoint, ); // Duplicate the `block_end_sponge_blob` so that we can squeeze it. diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_root_rollup_inputs_validator.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_root_rollup_inputs_validator.nr index 53599b0017c4..35abb99345e0 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_root_rollup_inputs_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/block_root_rollup_inputs_validator.nr @@ -1,13 +1,12 @@ use crate::{ - abis::{ParityPublicInputs, TxRollupPublicInputs}, + abis::TxRollupPublicInputs, tx_merge::utils::validate_consecutive_tx_rollups::validate_consecutive_tx_rollups, }; use types::{ abis::{ append_only_tree_snapshot::AppendOnlyTreeSnapshot, block_constant_data::BlockConstantData, }, - constants::PARITY_ROOT_VK_INDEX, - proof::proof_data::{RollupHonkProofData, UltraHonkProofData}, + proof::proof_data::RollupHonkProofData, }; pub fn validate_previous_rollups( @@ -51,11 +50,11 @@ pub fn validate_previous_rollups, - vk_tree_root: Field, - prover_id: Field, -) { - if !::std::runtime::is_unconstrained() { - data.verify_proof(); - } - - assert_eq(data.vk_data.leaf_index, PARITY_ROOT_VK_INDEX, "Incorrect vk index for parity root"); - - // Check that the `vk_tree_root` in the public inputs matches the one in the rollup's constants, as it was used - // to verify the vk of the base parity proofs. - assert_eq( - data.public_inputs.vk_tree_root, - vk_tree_root, - "The vk tree root of the parity root does not match the rollup's vk tree root", - ); - - // Check that the `prover_id` in the public inputs matches the one in the rollup's constants, preventing sybil - // attacks where the same prover submits a parity root proof under different identities. - assert_eq( - data.public_inputs.prover_id, - prover_id, - "The prover id of the parity root does not match the rollup's prover id", - ); - - data.vk_data.validate_in_vk_tree(vk_tree_root); -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/mod.nr index 205550e6b6fe..62ea8f9b152d 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/components/mod.nr @@ -3,5 +3,5 @@ mod block_rollup_public_inputs_composer; pub use block_rollup_public_inputs_composer::BlockRollupPublicInputsComposer; pub use block_root_rollup_inputs_validator::{ - validate_l1_to_l2_tree_snapshot_in_constants, validate_parity_root, validate_previous_rollups, + validate_l1_to_l2_tree_snapshot_in_constants, validate_previous_rollups, }; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr index 6443dd58f68a..5a72b9bd3da2 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr @@ -4,12 +4,14 @@ pub mod block_root_single_tx_first_rollup; pub mod block_root_empty_tx_first_rollup; pub mod block_root_rollup; pub mod block_root_single_tx_rollup; +pub mod block_root_msgs_only_rollup; mod tests; // Re-exports pub use crate::abis::BlockRollupPublicInputs; pub use block_root_empty_tx_first_rollup::BlockRootEmptyTxFirstRollupPrivateInputs; pub use block_root_first_rollup::BlockRootFirstRollupPrivateInputs; +pub use block_root_msgs_only_rollup::BlockRootMsgsOnlyRollupPrivateInputs; pub use block_root_rollup::BlockRootRollupPrivateInputs; pub use block_root_single_tx_first_rollup::BlockRootSingleTxFirstRollupPrivateInputs; pub use block_root_single_tx_rollup::BlockRootSingleTxRollupPrivateInputs; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/child_proof_vk_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/child_proof_vk_tests.nr index fda5d9f605f0..3c72cab9126c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/child_proof_vk_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/child_proof_vk_tests.nr @@ -1,8 +1,8 @@ use super::TestBuilder; use protocol_test_utils::fixtures::vk_tree::{update_vk_hash, VK_MERKLE_TREE}; use types::constants::{ - BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, PARITY_BASE_VK_INDEX, - PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX, + BLOCK_ROOT_ROLLUP_VK_INDEX, INBOX_PARITY_64_VK_INDEX, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, }; #[test(should_fail_with = "Vk index not in allowed list")] @@ -27,7 +27,7 @@ fn disallowed_right_rollup_vk_index__first_block() { fn disallowed_rollup_vk_index__first_single_tx_block() { let mut builder = TestBuilder::default(true, true); - builder.left_rollup_vk_index = PARITY_BASE_VK_INDEX; + builder.left_rollup_vk_index = INBOX_PARITY_64_VK_INDEX; builder.execute_and_fail(); } @@ -73,7 +73,6 @@ fn left_rollup_vk_not_in_vk_tree__first_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.left_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); @@ -93,7 +92,6 @@ fn right_rollup_vk_not_in_vk_tree__first_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.right_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); @@ -107,7 +105,6 @@ fn left_rollup_vk_not_in_vk_tree__first_single_tx_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.left_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); @@ -127,7 +124,6 @@ fn left_rollup_vk_not_in_vk_tree__non_first_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.left_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); @@ -147,7 +143,6 @@ fn right_rollup_vk_not_in_vk_tree__non_first_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.right_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); @@ -161,82 +156,7 @@ fn left_rollup_vk_not_in_vk_tree__non_first_single_tx_block() { let mut new_vk_tree = VK_MERKLE_TREE; update_vk_hash(&mut new_vk_tree, builder.left_rollup_vk_index, 999); - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); builder.execute_and_fail(); } - -// --- Parity root --- - -#[test(should_fail_with = "Incorrect vk index for parity root")] -fn incorrect_parity_root_vk_index__first_block() { - let mut builder = TestBuilder::default(true, false); - - // Change the vk index of the parity root to something else. - builder.parity_root_vk_index = BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX; - - builder.execute_and_fail(); -} - -#[test(should_fail_with = "Incorrect vk index for parity root")] -fn incorrect_parity_root_vk_index__first_single_tx_block() { - let mut builder = TestBuilder::default(true, true); - - // Change the vk index of the parity root to something else. - builder.parity_root_vk_index = PARITY_BASE_VK_INDEX; - - builder.execute_and_fail(); -} - -#[test(should_fail_with = "Incorrect vk index for parity root")] -fn incorrect_parity_root_vk_index__first_empty_block() { - let mut builder = TestBuilder::new_empty(); - - // Change the vk index of the parity root to something else. - builder.parity_root_vk_index = PARITY_BASE_VK_INDEX; - - builder.execute_and_fail(); -} - -#[test(should_fail_with = "Membership check failed: vk hash not found in vk tree")] -fn parity_root_vk_not_in_vk_tree__first_block() { - let mut builder = TestBuilder::default(true, false); - - // Update the vk hash so that the old vk hash in the proof data is no longer in the vk tree. - let mut new_vk_tree = VK_MERKLE_TREE; - update_vk_hash(&mut new_vk_tree, builder.parity_root_vk_index, 999); - - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); - builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); - - builder.execute_and_fail(); -} - -#[test(should_fail_with = "Membership check failed: vk hash not found in vk tree")] -fn parity_root_vk_not_in_vk_tree__first_single_tx_block() { - let mut builder = TestBuilder::default(true, true); - - // Update the vk hash so that the old vk hash in the proof data is no longer in the vk tree. - let mut new_vk_tree = VK_MERKLE_TREE; - update_vk_hash(&mut new_vk_tree, builder.parity_root_vk_index, 999); - - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); - builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); - - builder.execute_and_fail(); -} - -#[test(should_fail_with = "Membership check failed: vk hash not found in vk tree")] -fn parity_root_vk_not_in_vk_tree__first_empty_block() { - let mut builder = TestBuilder::new_empty(); - - // Update the vk hash so that the old vk hash in the proof data is no longer in the vk tree. - let mut new_vk_tree = VK_MERKLE_TREE; - update_vk_hash(&mut new_vk_tree, builder.parity_root_vk_index, 999); - - builder.parity_root.vk_tree_root = new_vk_tree.get_root(); - builder.checkpoint_constants.vk_tree_root = new_vk_tree.get_root(); - - builder.execute_and_fail(); -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/failures_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/failures_tests.nr index dd65d2ba8243..4338380796f5 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/failures_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/failures_tests.nr @@ -161,32 +161,48 @@ fn incorrect_l1_to_l2_tree_next_available_leaf_index__first_single_tx_block() { builder.execute_and_fail(); } -#[test(should_fail_with = "The vk tree root of the parity root does not match the rollup's vk tree root")] -fn mismatched_vk_tree_root_from_parity__first_block() { - let mut builder = TestBuilder::default(true, false); +// Non-first blocks also insert their own bundle and must pin the post-bundle snapshot in their tx constants, so a +// non-first block whose constants snapshot differs from its computed post-bundle root must fail (same-block +// consumption). Both child rollups are tweaked together so the mismatch surfaces here rather than as unequal +// constants between the two tx rollups. +#[test(should_fail_with = "l1_to_l2 tree snapshot in constants does not match the computed value")] +fn incorrect_l1_to_l2_tree_root__non_first_block() { + let mut builder = TestBuilder::default(false, false); - // Tweak the vk tree root of the parity root. - builder.parity_root.vk_tree_root += 1; + // Tweak the root of the l1_to_l2_tree_snapshot in the rollups' constants. + builder.left_rollup.constants.l1_to_l2_tree_snapshot.root += 1; + builder.right_rollup.constants.l1_to_l2_tree_snapshot.root += 1; builder.execute_and_fail(); } -#[test(should_fail_with = "The vk tree root of the parity root does not match the rollup's vk tree root")] -fn mismatched_vk_tree_root_from_parity__first_single_tx_block() { - let mut builder = TestBuilder::default(true, true); +#[test(should_fail_with = "l1_to_l2 tree snapshot in constants does not match the computed value")] +fn incorrect_l1_to_l2_tree_next_available_leaf_index__non_first_block() { + let mut builder = TestBuilder::default(false, false); - // Tweak the vk tree root of the parity root. - builder.parity_root.vk_tree_root += 1; + // Tweak the next_available_leaf_index of the l1_to_l2_tree_snapshot in the rollups' constants. + builder.left_rollup.constants.l1_to_l2_tree_snapshot.next_available_leaf_index += 1; + builder.right_rollup.constants.l1_to_l2_tree_snapshot.next_available_leaf_index += 1; builder.execute_and_fail(); } -#[test(should_fail_with = "The vk tree root of the parity root does not match the rollup's vk tree root")] -fn mismatched_vk_tree_root_from_parity__first_empty_block() { - let mut builder = TestBuilder::new_empty(); +#[test(should_fail_with = "l1_to_l2 tree snapshot in constants does not match the computed value")] +fn incorrect_l1_to_l2_tree_root__non_first_single_tx_block() { + let mut builder = TestBuilder::default(false, true); - // Tweak the vk tree root of the parity root. - builder.parity_root.vk_tree_root += 1; + // Tweak the root of the l1_to_l2_tree_snapshot in the rollup's constants. + builder.left_rollup.constants.l1_to_l2_tree_snapshot.root += 1; + + builder.execute_and_fail(); +} + +#[test(should_fail_with = "l1_to_l2 tree snapshot in constants does not match the computed value")] +fn incorrect_l1_to_l2_tree_next_available_leaf_index__non_first_single_tx_block() { + let mut builder = TestBuilder::default(false, true); + + // Tweak the next_available_leaf_index of the l1_to_l2_tree_snapshot in the rollup's constants. + builder.left_rollup.constants.l1_to_l2_tree_snapshot.next_available_leaf_index += 1; builder.execute_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/message_bundle_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/message_bundle_tests.nr new file mode 100644 index 000000000000..7c17032f3c45 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/message_bundle_tests.nr @@ -0,0 +1,54 @@ +use super::TestBuilder; +use types::constants::{PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX}; + +global IS_FIRST_BLOCK_ROOT: bool = true; + +// A start index that is a right child at some levels and a left child at others, so the append has to merge the batch +// into a real frontier rather than drop an aligned subtree into an empty slot. +global NON_ALIGNED_START_INDEX: u32 = 5; + +fn builder_at_non_aligned_index(is_first_block_root: bool) -> TestBuilder { + TestBuilder::new_at_l1_to_l2_index( + PRIVATE_TX_BASE_ROLLUP_VK_INDEX, + 1, + PUBLIC_TX_BASE_ROLLUP_VK_INDEX, + 1, + is_first_block_root, + NON_ALIGNED_START_INDEX, + ) +} + +#[test] +fn first_block_appends_at_non_aligned_index() { + let builder = builder_at_non_aligned_index(IS_FIRST_BLOCK_ROOT); + let pi = builder.execute(); + builder.assert_expected_public_inputs(pi); +} + +#[test] +fn non_first_block_appends_at_non_aligned_index() { + let builder = builder_at_non_aligned_index(!IS_FIRST_BLOCK_ROOT); + let pi = builder.execute(); + builder.assert_expected_public_inputs(pi); +} + +#[test] +fn unpinned_frontier_hint_lane_is_ignored() { + // Index 5 is a left child at level 1, so the snapshot root cannot pin that hint lane. The append overwrites it + // with the batch's own node before anything reads it, so a wrong value there must not change the result. + let mut builder = builder_at_non_aligned_index(!IS_FIRST_BLOCK_ROOT); + builder.l1_to_l2_message_frontier_hint[1] += 1; + + let pi = builder.execute(); + builder.assert_expected_public_inputs(pi); +} + +#[test(should_fail_with = "Frontier hint does not match the snapshot root")] +fn corrupted_pinned_frontier_hint_lane_fails() { + // Index 5 is a right child at level 0, so that hint lane is pinned by the snapshot root and cannot be tampered + // with. Note this is only testable at a non-zero start index: appending into an empty tree pins no lane at all. + let mut builder = builder_at_non_aligned_index(!IS_FIRST_BLOCK_ROOT); + builder.l1_to_l2_message_frontier_hint[0] += 1; + + builder.execute_and_fail(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/mod.nr index 03e04d24b07f..802a8d9ce380 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/mod.nr @@ -1,10 +1,12 @@ mod child_proof_vk_tests; mod consecutive_rollups_tests; mod failures_tests; +mod message_bundle_tests; +mod msgs_only_tests; mod rollup_structure_tests; use crate::{ - abis::{BlockRollupPublicInputs, ParityPublicInputs, TxRollupPublicInputs}, + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge, TxRollupPublicInputs}, block_root::{ block_root_empty_tx_first_rollup::{self, BlockRootEmptyTxFirstRollupPrivateInputs}, block_root_first_rollup::{self, BlockRootFirstRollupPrivateInputs}, @@ -21,14 +23,17 @@ use types::{ }, blob_data::SpongeBlob, constants::{ - ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, PARITY_ROOT_VK_INDEX, + ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSGS_PER_BLOCK, PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PUBLIC_TX_BASE_ROLLUP_VK_INDEX, TX_MERGE_ROLLUP_VK_INDEX, }, hash::accumulate_sha256, merkle_tree::root_from_sibling_path, - traits::Hash, + traits::{Empty, Hash}, }; +// Default number of real L1-to-L2 messages in the block's bundle. Chosen non-zero so the tree and sponge both move. +global TEST_NUM_MSGS: u32 = 5; + struct TestBuilder { left_rollup: TxRollupPublicInputs, left_rollup_vk_index: u32, @@ -37,10 +42,14 @@ struct TestBuilder { right_rollup_vk_index: u32, num_right_txs: u16, is_first_block_root: bool, - parity_root: ParityPublicInputs, - parity_root_vk_index: u32, + // Message bundle appended by this block. + l1_to_l2_messages: [Field; MAX_L1_TO_L2_MSGS_PER_BLOCK], + num_msgs: u32, + l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], previous_l1_to_l2: AppendOnlyTreeSnapshot, - new_l1_to_l2_message_subtree_root_sibling_path: [Field; L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH], + new_l1_to_l2: AppendOnlyTreeSnapshot, + // Message sponge inherited from the previous block (empty for first blocks). + start_msg_sponge: L1ToL2MessageSponge, new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], checkpoint_constants: CheckpointConstantData, } @@ -78,6 +87,26 @@ impl TestBuilder { right_rollup_vk_index: u32, num_right_txs: u16, is_first_block_root: bool, + ) -> Self { + Self::new_at_l1_to_l2_index( + left_rollup_vk_index, + num_left_txs, + right_rollup_vk_index, + num_right_txs, + is_first_block_root, + 0, + ) + } + + /// Same as `new`, but the block's bundle is appended into an l1-to-l2 tree that already holds + /// `l1_to_l2_start_index` leaves instead of into an empty one. + pub fn new_at_l1_to_l2_index( + left_rollup_vk_index: u32, + num_left_txs: u16, + right_rollup_vk_index: u32, + num_right_txs: u16, + is_first_block_root: bool, + l1_to_l2_start_index: u32, ) -> Self { Self::validate_input_vk_index(left_rollup_vk_index, num_left_txs); Self::validate_input_vk_index(right_rollup_vk_index, num_right_txs); @@ -95,13 +124,23 @@ impl TestBuilder { ); let slot_number = fixture_builder.start_slot_number; - let parity_root = fixture_builder.get_parity_public_inputs(slot_number); - let (previous_l1_to_l2, new_l1_to_l2_message_subtree_root_sibling_path, new_l1_to_l2) = - fixture_builder.build_l1_to_l2_message_subtree_for_insertion(slot_number); + // Build the block's message bundle appended at the l1-to-l2 tree's next available index. + let (previous_l1_to_l2, l1_to_l2_messages, l1_to_l2_message_frontier_hint, new_l1_to_l2) = fixture_builder + .build_l1_to_l2_message_bundle_at_index(TEST_NUM_MSGS, l1_to_l2_start_index); + + // Every tx-carrying block-root variant (first and non-first) asserts the l1-to-l2 tree snapshot carried in the + // tx constants equals the post-append snapshot, so its txs read the messages this block inserts. left_rollup.constants.l1_to_l2_tree_snapshot = new_l1_to_l2; right_rollup.constants.l1_to_l2_tree_snapshot = new_l1_to_l2; + // First blocks start the message sponge from empty; non-first blocks inherit a (non-empty) sponge. + let start_msg_sponge = if is_first_block_root { + L1ToL2MessageSponge::empty() + } else { + fixture_builder.get_msg_sponge(slot_number) + }; + let block_number = fixture_builder.start_block_number; let (previous_archive, new_archive_sibling_path) = fixture_builder.build_archive_tree_for_insertion(block_number); @@ -118,10 +157,12 @@ impl TestBuilder { right_rollup_vk_index, num_right_txs, is_first_block_root, - parity_root, - parity_root_vk_index: PARITY_ROOT_VK_INDEX, + l1_to_l2_messages, + num_msgs: TEST_NUM_MSGS, + l1_to_l2_message_frontier_hint, previous_l1_to_l2, - new_l1_to_l2_message_subtree_root_sibling_path, + new_l1_to_l2, + start_msg_sponge, new_archive_sibling_path, checkpoint_constants, } @@ -154,16 +195,13 @@ impl TestBuilder { } fn execute_first_block_root(self) -> BlockRollupPublicInputs { - let parity_root = - RollupFixtureBuilder::make_proof_data(self.parity_root, self.parity_root_vk_index); - let previous_rollups = [ RollupFixtureBuilder::make_proof_data(self.left_rollup, self.left_rollup_vk_index), RollupFixtureBuilder::make_proof_data(self.right_rollup, self.right_rollup_vk_index), ]; - let new_l1_to_l2_message_subtree_root_sibling_path = - self.new_l1_to_l2_message_subtree_root_sibling_path; + let message_bundle = self.message_bundle(); + let l1_to_l2_message_frontier_hint = self.l1_to_l2_message_frontier_hint; let new_archive_sibling_path = self.new_archive_sibling_path; if self.num_left_txs == 0 { @@ -174,32 +212,32 @@ impl TestBuilder { }; block_root_empty_tx_first_rollup::execute( BlockRootEmptyTxFirstRollupPrivateInputs { - parity_root, previous_archive: left.constants.last_archive, previous_state, constants: self.checkpoint_constants, timestamp: left.constants.global_variables.timestamp, - new_l1_to_l2_message_subtree_root_sibling_path, + message_bundle, + l1_to_l2_message_frontier_hint, new_archive_sibling_path, }, ) } else if self.num_right_txs == 0 { block_root_single_tx_first_rollup::execute( BlockRootSingleTxFirstRollupPrivateInputs { - parity_root, previous_rollup: previous_rollups[0], + message_bundle, previous_l1_to_l2: self.previous_l1_to_l2, - new_l1_to_l2_message_subtree_root_sibling_path, + l1_to_l2_message_frontier_hint, new_archive_sibling_path, }, ) } else { block_root_first_rollup::execute( BlockRootFirstRollupPrivateInputs { - parity_root, previous_rollups, + message_bundle, previous_l1_to_l2: self.previous_l1_to_l2, - new_l1_to_l2_message_subtree_root_sibling_path, + l1_to_l2_message_frontier_hint, new_archive_sibling_path, }, ) @@ -212,22 +250,42 @@ impl TestBuilder { RollupFixtureBuilder::make_proof_data(self.right_rollup, self.right_rollup_vk_index), ]; + let message_bundle = self.message_bundle(); + let l1_to_l2_message_frontier_hint = self.l1_to_l2_message_frontier_hint; + let start_msg_sponge = self.start_msg_sponge; let new_archive_sibling_path = self.new_archive_sibling_path; if self.num_right_txs == 0 { block_root_single_tx_rollup::execute( BlockRootSingleTxRollupPrivateInputs { previous_rollup: previous_rollups[0], + message_bundle, + previous_l1_to_l2: self.previous_l1_to_l2, + start_msg_sponge, + l1_to_l2_message_frontier_hint, new_archive_sibling_path, }, ) } else { block_root_rollup::execute( - BlockRootRollupPrivateInputs { previous_rollups, new_archive_sibling_path }, + BlockRootRollupPrivateInputs { + previous_rollups, + message_bundle, + previous_l1_to_l2: self.previous_l1_to_l2, + start_msg_sponge, + l1_to_l2_message_frontier_hint, + new_archive_sibling_path, + }, ) } } + // The block's message bundle: exactly `num_msgs` real leaves, appended compactly to the tree and absorbed into the + // message sponge. + fn message_bundle(self) -> L1ToL2MessageBundle { + L1ToL2MessageBundle { messages: self.l1_to_l2_messages, num_msgs: self.num_msgs } + } + pub fn assert_expected_public_inputs(self, pi: BlockRollupPublicInputs) { // The private inputs of the empty block root are also constructed from the left rollup. let left = self.left_rollup; @@ -280,7 +338,6 @@ impl TestBuilder { pi.end_state, self.num_left_txs + self.num_right_txs, pi.accumulated_mana_used, - self.is_first_block_root, ); assert_eq(pi.end_sponge_blob, expected_end_sponge_blob); @@ -327,30 +384,30 @@ impl TestBuilder { // --- L1 to L2 message tree --- - let expected_previous_l1_to_l2 = if self.is_first_block_root { - self.previous_l1_to_l2 - } else { - self.left_rollup.constants.l1_to_l2_tree_snapshot - }; - assert_eq(pi.start_state.l1_to_l2_message_tree, expected_previous_l1_to_l2); - - assert_eq( - pi.end_state.l1_to_l2_message_tree, - self.left_rollup.constants.l1_to_l2_tree_snapshot, - ); + // Every block appends its bundle, so the state ref moves from the pre-append snapshot to the post-append one. + assert_eq(pi.start_state.l1_to_l2_message_tree, self.previous_l1_to_l2); + assert_eq(pi.end_state.l1_to_l2_message_tree, self.new_l1_to_l2); // --- Timestamps --- assert_eq(pi.timestamp, left.constants.global_variables.timestamp); - // --- In hash --- + // --- is_first_block --- - let expected_in_hash = if self.is_first_block_root { - self.parity_root.sha_root + assert_eq(pi.is_first_block, self.is_first_block_root); + + // --- Message sponge --- + + let expected_start_msg_sponge = if self.is_first_block_root { + L1ToL2MessageSponge::empty() } else { - 0 + self.start_msg_sponge }; - assert_eq(pi.in_hash, expected_in_hash); + assert_eq(pi.start_msg_sponge, expected_start_msg_sponge); + + let mut expected_end_msg_sponge = expected_start_msg_sponge; + expected_end_msg_sponge.absorb(self.l1_to_l2_messages, self.num_msgs); + assert_eq(pi.end_msg_sponge, expected_end_msg_sponge); // --- Out hash -- diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/msgs_only_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/msgs_only_tests.nr new file mode 100644 index 000000000000..904310fa0c94 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/tests/msgs_only_tests.nr @@ -0,0 +1,184 @@ +use crate::{ + abis::{BlockRollupPublicInputs, L1ToL2MessageBundle, L1ToL2MessageSponge}, + block_root::block_root_msgs_only_rollup::{self, BlockRootMsgsOnlyRollupPrivateInputs}, + tests::RollupFixtureBuilder, +}; +use types::{ + abis::{ + append_only_tree_snapshot::AppendOnlyTreeSnapshot, block_header::BlockHeader, + checkpoint_constant_data::CheckpointConstantData, global_variables::GlobalVariables, + partial_state_reference::PartialStateReference, state_reference::StateReference, + }, + blob_data::SpongeBlob, + constants::{ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSGS_PER_BLOCK}, + merkle_tree::root_from_sibling_path, + traits::Hash, +}; + +global TEST_NUM_MSGS: u32 = 5; + +// Builds the inputs for a non-first, transaction-less block that inserts an L1-to-L2 message bundle. +struct TestBuilder { + previous_archive: AppendOnlyTreeSnapshot, + previous_state: StateReference, + constants: CheckpointConstantData, + timestamp: u64, + start_sponge_blob: SpongeBlob, + start_msg_sponge: L1ToL2MessageSponge, + l1_to_l2_messages: [Field; MAX_L1_TO_L2_MSGS_PER_BLOCK], + num_msgs: u32, + l1_to_l2_message_frontier_hint: [Field; L1_TO_L2_MSG_TREE_HEIGHT], + new_archive_sibling_path: [Field; ARCHIVE_HEIGHT], + // Retained for assertions. + new_l1_to_l2: AppendOnlyTreeSnapshot, + partial: PartialStateReference, +} + +impl TestBuilder { + pub fn new() -> Self { + let fixture_builder = RollupFixtureBuilder::new(); + let slot_number = fixture_builder.start_slot_number; + let block_number = fixture_builder.start_block_number; + + let (previous_l1_to_l2, l1_to_l2_messages, l1_to_l2_message_frontier_hint, new_l1_to_l2) = + fixture_builder.build_l1_to_l2_message_bundle(TEST_NUM_MSGS); + + let (previous_archive, new_archive_sibling_path) = + fixture_builder.build_archive_tree_for_insertion(block_number); + + // Borrow a partial state from a tx rollup fixture; it is simply propagated to the start and end states. + let partial = fixture_builder.get_tx_rollup_public_inputs(6).start_tree_snapshots; + let previous_state = StateReference { l1_to_l2_message_tree: previous_l1_to_l2, partial }; + + Self { + previous_archive, + previous_state, + constants: fixture_builder.get_checkpoint_constant_data(slot_number), + timestamp: fixture_builder.get_global_variables(block_number).timestamp, + // A non-first block inherits a non-empty sponge blob and message sponge from the previous block. + start_sponge_blob: fixture_builder.get_sponge_blob(block_number), + start_msg_sponge: fixture_builder.get_msg_sponge(slot_number), + l1_to_l2_messages, + num_msgs: TEST_NUM_MSGS, + l1_to_l2_message_frontier_hint, + new_archive_sibling_path, + new_l1_to_l2, + partial, + } + } + + fn to_inputs(self) -> BlockRootMsgsOnlyRollupPrivateInputs { + BlockRootMsgsOnlyRollupPrivateInputs { + previous_archive: self.previous_archive, + previous_state: self.previous_state, + constants: self.constants, + timestamp: self.timestamp, + start_sponge_blob: self.start_sponge_blob, + start_msg_sponge: self.start_msg_sponge, + message_bundle: L1ToL2MessageBundle { + messages: self.l1_to_l2_messages, + num_msgs: self.num_msgs, + }, + l1_to_l2_message_frontier_hint: self.l1_to_l2_message_frontier_hint, + new_archive_sibling_path: self.new_archive_sibling_path, + } + } + + pub fn execute(self) -> BlockRollupPublicInputs { + block_root_msgs_only_rollup::execute(self.to_inputs()) + } + + pub fn execute_and_fail(self) { + let _ = self.execute(); + } + + pub fn assert_expected_public_inputs(self, pi: BlockRollupPublicInputs) { + // A message-only block is a single, non-first block. + assert_eq(pi.num_blocks(), 1); + assert_eq(pi.constants, self.constants); + assert(!pi.is_first_block); + + // --- Sponge blobs: threaded from the (non-empty) provided start, with the block end data absorbed. --- + assert_eq(pi.start_sponge_blob, self.start_sponge_blob); + let mut expected_end_sponge_blob = self.start_sponge_blob; + expected_end_sponge_blob.absorb_block_end_data( + self.constants_as_global_variables(), + pi.previous_archive, + pi.end_state, + 0, // num_txs + 0, // total_mana_used + ); + assert_eq(pi.end_sponge_blob, expected_end_sponge_blob); + + // --- Message sponge: threaded from the provided start, absorbing this block's bundle. --- + assert_eq(pi.start_msg_sponge, self.start_msg_sponge); + let mut expected_end_msg_sponge = self.start_msg_sponge; + expected_end_msg_sponge.absorb(self.l1_to_l2_messages, self.num_msgs); + assert_eq(pi.end_msg_sponge, expected_end_msg_sponge); + + // --- Archive: the block header hash is inserted at the next available index. --- + assert_eq(pi.previous_archive, self.previous_archive); + let sponge_blob_hash = expected_end_sponge_blob.squeeze(); + let block_header = BlockHeader { + last_archive: pi.previous_archive, + state: pi.end_state, + sponge_blob_hash, + global_variables: self.constants_as_global_variables(), + total_fees: pi.accumulated_fees, + total_mana_used: pi.accumulated_mana_used, + }; + let expected_archive_root = root_from_sibling_path( + block_header.hash(), + pi.previous_archive.next_available_leaf_index, + self.new_archive_sibling_path, + ); + assert_eq(pi.new_archive.root, expected_archive_root); + assert_eq( + pi.new_archive.next_available_leaf_index, + pi.previous_archive.next_available_leaf_index + 1, + ); + + // --- State: partial unchanged (no tx effects), l1-to-l2 tree moves by the appended bundle. --- + assert_eq(pi.start_state.partial, self.partial); + assert_eq(pi.end_state.partial, self.partial); + assert_eq(pi.start_state.l1_to_l2_message_tree, self.previous_state.l1_to_l2_message_tree); + assert_eq(pi.end_state.l1_to_l2_message_tree, self.new_l1_to_l2); + + // --- Timestamp / no tx effects. --- + assert_eq(pi.timestamp, self.timestamp); + assert_eq(pi.out_hash, 0); + assert_eq(pi.accumulated_fees, 0); + assert_eq(pi.accumulated_mana_used, 0); + } + + fn constants_as_global_variables(self) -> GlobalVariables { + GlobalVariables { + chain_id: self.constants.chain_id, + version: self.constants.version, + block_number: self.previous_archive.next_available_leaf_index as u32, + slot_number: self.constants.slot_number, + timestamp: self.timestamp, + coinbase: self.constants.coinbase, + fee_recipient: self.constants.fee_recipient, + gas_fees: self.constants.gas_fees, + } + } +} + +#[test] +fn msgs_only_block_root_success() { + let builder = TestBuilder::new(); + let pi = builder.execute(); + builder.assert_expected_public_inputs(pi); +} + +#[test(should_fail_with = "A message-only block must insert at least one L1-to-L2 message")] +fn msgs_only_block_root_rejects_empty_bundle() { + let mut builder = TestBuilder::new(); + + // A non-first empty block with no messages has no reason to exist and must be rejected. + builder.num_msgs = 0; + builder.l1_to_l2_messages = [0; MAX_L1_TO_L2_MSGS_PER_BLOCK]; + + builder.execute_and_fail(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/consecutive_checkpoint_rollups_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/consecutive_checkpoint_rollups_tests.nr index 060d9a2d4e28..a6f865298ba1 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/consecutive_checkpoint_rollups_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/consecutive_checkpoint_rollups_tests.nr @@ -238,6 +238,18 @@ fn non_consecutive_out_hash_next_available_leaf_indices() { builder.execute_and_fail(); } +// --- inbox rolling hash --- + +#[test(should_fail_with = "Mismatched inbox rolling hash: expected right.start to match left.end")] +fn non_consecutive_inbox_rolling_hash() { + let mut builder = TestBuilder::default(); + + // Break the continuity of the rolling-hash chain between the two checkpoints. + builder.right_rollup.start_inbox_rolling_hash += 1; + + builder.execute_and_fail(); +} + // --- blob accumulators --- #[test(should_fail_with = "Mismatched blob accumulators: expected right.start_blob_accumulator to match left.end_blob_accumulator")] diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/mod.nr index 96f8a16da3ee..c4e7c8eb6f44 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/tests/mod.nr @@ -107,6 +107,11 @@ impl TestBuilder { assert_eq(pi.new_out_hash, right.new_out_hash); assert(pi.previous_out_hash != pi.new_out_hash); + // The merged range spans from the left checkpoint's start to the right checkpoint's end; continuity across the + // two ranges is enforced in `validate_consecutive_checkpoint_rollups`. + assert_eq(pi.start_inbox_rolling_hash, left.start_inbox_rolling_hash); + assert_eq(pi.end_inbox_rolling_hash, right.end_inbox_rolling_hash); + let mut expected_header_hashes = [0; MAX_CHECKPOINTS_PER_EPOCH]; let mut expected_fees = [FeeRecipient::empty(); MAX_CHECKPOINTS_PER_EPOCH]; for i in 0..self.num_left_checkpoints as u32 { diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/merge_checkpoint_rollups.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/merge_checkpoint_rollups.nr index 0470e80e0c17..68a28c843fe0 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/merge_checkpoint_rollups.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/merge_checkpoint_rollups.nr @@ -55,6 +55,10 @@ pub fn merge_checkpoint_rollups( new_archive: right.new_archive, previous_out_hash: left.previous_out_hash, new_out_hash: right.new_out_hash, + // The rolling-hash chain spans both checkpoint ranges: start from the left, end at the right. Continuity + // (`right.start == left.end`) is asserted in `validate_consecutive_checkpoint_rollups`. + start_inbox_rolling_hash: left.start_inbox_rolling_hash, + end_inbox_rolling_hash: right.end_inbox_rolling_hash, checkpoint_header_hashes, fees, start_blob_accumulator: left.start_blob_accumulator, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/validate_consecutive_checkpoint_rollups.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/validate_consecutive_checkpoint_rollups.nr index 8d4fd24bd73b..7d00876625e2 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/validate_consecutive_checkpoint_rollups.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_merge/utils/validate_consecutive_checkpoint_rollups.nr @@ -29,6 +29,15 @@ fn assert_rollups_follow_on_from_each_other( "Mismatched out hashes: expected right.previous_out_hash to match left.new_out_hash", ); + // The inbox rolling-hash chain must be continuous across consecutive checkpoints: the right checkpoint's chain must + // start where the left checkpoint's chain ended. An end-only anchor would let a prover restart the chain from an + // earlier bucket and re-insert already-consumed messages, so continuity is enforced here. + assert_eq( + left.end_inbox_rolling_hash, + right.start_inbox_rolling_hash, + "Mismatched inbox rolling hash: expected right.start to match left.end", + ); + assert_eq( left.end_blob_accumulator, right.start_blob_accumulator, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_rollup.nr index 4b7c73a8e7b9..dd200d96ca43 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_rollup.nr @@ -1,7 +1,7 @@ use crate::{ - abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs}, + abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs, ParityPublicInputs}, checkpoint_root::components::{ - CheckpointRollupPublicInputsComposer, CheckpointRootInputsValidator, + CheckpointRollupPublicInputsComposer, CheckpointRootInputsValidator, validate_inbox_parity, }, }; use blob::abis::{BlobAccumulator, BLSPoint, FinalBlobBatchingChallenges}; @@ -10,23 +10,28 @@ use types::{ constants::{ ARCHIVE_HEIGHT, BLOBS_PER_CHECKPOINT, BLOCK_MERGE_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, FIELDS_PER_BLOB, OUT_HASH_TREE_HEIGHT, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, + BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + FIELDS_PER_BLOB, OUT_HASH_TREE_HEIGHT, }, - proof::proof_data::RollupHonkProofData, + proof::proof_data::{RollupHonkProofData, UltraHonkProofData}, }; -global ALLOWED_PREVIOUS_VK_INDICES: [u32; 6] = [ +global ALLOWED_PREVIOUS_VK_INDICES: [u32; 7] = [ BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, BLOCK_MERGE_ROLLUP_VK_INDEX, ]; pub struct CheckpointRootRollupPrivateInputs { pub(crate) previous_rollups: [RollupHonkProofData; 2], + // Inbox parity proof over the checkpoint's L1-to-L2 messages. One variable-size proof per checkpoint: the + // checkpoint root is the only circuit that sees the whole checkpoint's message commitments. + pub(crate) inbox_parity: UltraHonkProofData, pub(crate) hints: CheckpointRootRollupHints, } @@ -94,8 +99,17 @@ pub fn execute(inputs: CheckpointRootRollupPrivateInputs) -> CheckpointRollupPub .validate(); let previous_rollups = inputs.previous_rollups.map(|rollup| rollup.public_inputs); + + let constants = previous_rollups[0].constants; + validate_inbox_parity( + inputs.inbox_parity, + constants.vk_tree_root, + constants.prover_id, + ); + CheckpointRollupPublicInputsComposer::new( previous_rollups, + inputs.inbox_parity.public_inputs, hints.previous_out_hash, hints.new_out_hash_sibling_path, hints.start_blob_accumulator, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_single_block_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_single_block_rollup.nr index b01107e7557e..467a4ce58c97 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_single_block_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/checkpoint_root_single_block_rollup.nr @@ -1,27 +1,43 @@ use crate::{ - abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs}, + abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs, ParityPublicInputs}, checkpoint_root::{ checkpoint_root_rollup::CheckpointRootRollupHints, - components::{CheckpointRollupPublicInputsComposer, CheckpointRootInputsValidator}, + components::{ + CheckpointRollupPublicInputsComposer, CheckpointRootInputsValidator, + validate_inbox_parity, + }, }, }; use types::{ constants::{ BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, }, - proof::proof_data::RollupHonkProofData, + proof::proof_data::{RollupHonkProofData, UltraHonkProofData}, }; -// If there's only one previous rollup (i.e., one block in the checkpoint), it must be the first block root rollup. -global ALLOWED_PREVIOUS_VK_INDICES: [u32; 3] = [ +// If there's only one previous rollup (i.e., one block in the checkpoint), it must be a first block root: the inputs +// validator asserts the leftmost rollup's `is_first_block`. The message-only block root sets `is_first_block = false`, +// so it is listed here (for symmetry with the multi-block variant) but can never actually pass as the sole block. +// +// That `is_first_block` assertion is the only thing keeping a message-only block from standing as a checkpoint's sole +// block. If it is ever relaxed (e.g. replaced by a "leftmost block's start_msg_sponge is empty" check), this entry +// must be dropped in the same change, because barring the message-only variant from standing alone is what keeps +// each checkpoint shape to a single valid encoding: a sole transaction-less block carrying a message bundle is +// already provable as an empty-tx-first block, which accepts a non-empty bundle. It is also what keeps the rule +// confining fully-empty blocks to the first position enforceable. +global ALLOWED_PREVIOUS_VK_INDICES: [u32; 4] = [ BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, ]; pub struct CheckpointRootSingleBlockRollupPrivateInputs { pub(crate) previous_rollup: RollupHonkProofData, + // Inbox parity proof over the checkpoint's L1-to-L2 messages. One variable-size proof per checkpoint: the + // checkpoint root is the only circuit that sees the whole checkpoint's message commitments. + pub(crate) inbox_parity: UltraHonkProofData, pub(crate) hints: CheckpointRootRollupHints, } @@ -55,8 +71,16 @@ pub fn execute( ) .validate(); + let constants = inputs.previous_rollup.public_inputs.constants; + validate_inbox_parity( + inputs.inbox_parity, + constants.vk_tree_root, + constants.prover_id, + ); + CheckpointRollupPublicInputsComposer::new( [inputs.previous_rollup.public_inputs], + inputs.inbox_parity.public_inputs, hints.previous_out_hash, hints.new_out_hash_sibling_path, hints.start_blob_accumulator, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_rollup_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_rollup_public_inputs_composer.nr index c9f52a742e63..701a0b6a87a6 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_rollup_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_rollup_public_inputs_composer.nr @@ -1,5 +1,8 @@ use crate::{ - abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs}, + abis::{ + BlockRollupPublicInputs, CheckpointRollupPublicInputs, L1ToL2MessageSponge, + ParityPublicInputs, + }, block_merge::merge_block_rollups, }; use bignum::BLS12_381_Fr; @@ -21,6 +24,9 @@ use types::{ pub struct CheckpointRollupPublicInputsComposer { merged_rollup: BlockRollupPublicInputs, + // Public inputs of the inbox parity proof (verified by the caller). The checkpoint's `inbox_rolling_hash` is + // sourced from it, and its message sponge is checked against the blocks' accumulated one. + parity: ParityPublicInputs, // The below are all hints: previous_out_hash: AppendOnlyTreeSnapshot, new_out_hash_sibling_path: [Field; OUT_HASH_TREE_HEIGHT], @@ -34,6 +40,7 @@ pub struct CheckpointRollupPublicInputsComposer { impl CheckpointRollupPublicInputsComposer { pub fn new( previous_rollups: [BlockRollupPublicInputs; NumPreviousRollups], + parity: ParityPublicInputs, // The below args are all hints: previous_out_hash: AppendOnlyTreeSnapshot, new_out_hash_sibling_path: [Field; OUT_HASH_TREE_HEIGHT], @@ -50,6 +57,7 @@ impl CheckpointRollupPublicInputsComposer { Self { merged_rollup, + parity, previous_out_hash, new_out_hash_sibling_path, start_blob_accumulator, @@ -63,6 +71,22 @@ impl CheckpointRollupPublicInputsComposer { pub fn finish(self) -> CheckpointRollupPublicInputs { let merged_rollup = self.merged_rollup; + // The inbox parity sponge must start empty (the message sponge resets per checkpoint) and must equal the + // sponge accumulated across this checkpoint's block roots. Together with the leftmost block starting from the + // empty sponge (checked in the inputs validator) and the per-block continuity checks in the block merge + // circuit, this proves the blocks inserted exactly the parity-committed message list, in order — no leaf + // arrays cross the circuit boundary. + assert_eq( + self.parity.start_sponge, + L1ToL2MessageSponge::empty(), + "The inbox parity message sponge must start empty", + ); + assert_eq( + merged_rollup.end_msg_sponge, + self.parity.end_sponge, + "The blocks' message sponge does not match the inbox parity's message sponge", + ); + let constants = EpochConstantData { chain_id: merged_rollup.constants.chain_id, version: merged_rollup.constants.version, @@ -96,6 +120,10 @@ impl CheckpointRollupPublicInputsComposer { new_archive: merged_rollup.new_archive, previous_out_hash: self.previous_out_hash, new_out_hash, + // Sourced from the inbox parity proof, which commits to the checkpoint's message list. Checkpoint merges + // assert continuity across checkpoints (`right.start == left.end`). + start_inbox_rolling_hash: self.parity.start_rolling_hash, + end_inbox_rolling_hash: self.parity.end_rolling_hash, checkpoint_header_hashes, fees, start_blob_accumulator: self.start_blob_accumulator, @@ -120,7 +148,8 @@ impl CheckpointRollupPublicInputsComposer { last_archive_root: merged_rollup.previous_archive.root, block_headers_hash: merged_rollup.block_headers_hash, blobs_hash: self.blobs_hash, - in_hash: merged_rollup.in_hash, + // Sourced from the inbox parity proof: the checkpoint's only inbox commitment. + inbox_rolling_hash: self.parity.end_rolling_hash, epoch_out_hash, slot_number: constants.slot_number, timestamp: merged_rollup.timestamp, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_root_inputs_validator.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_root_inputs_validator.nr index f84d83e48071..be280142a773 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_root_inputs_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/checkpoint_root_inputs_validator.nr @@ -1,11 +1,14 @@ -use crate::{abis::BlockRollupPublicInputs, block_merge::validate_consecutive_block_rollups}; +use crate::{ + abis::{BlockRollupPublicInputs, L1ToL2MessageSponge}, + block_merge::validate_consecutive_block_rollups, +}; use types::{ abis::block_header::BlockHeader, blob_data::SpongeBlob, constants::ARCHIVE_HEIGHT, merkle_tree::{check_membership, MembershipWitness}, proof::proof_data::RollupHonkProofData, - traits::Hash, + traits::{Empty, Hash}, }; pub struct CheckpointRootInputsValidator { @@ -86,15 +89,21 @@ impl CheckpointRootInputsVal "The start timestamp must be after the previous block's timestamp", ); - // `in_hash` must be set using the **first** block root rollup circuit for the first block in a checkpoint. - // In `validate_consecutive_block_rollups`, it ensures that the hash only propagates through all merge steps - // exclusively via the left rollup. The value in the left rollup must not be 0 when it reaches the checkpoint - // root (this point). - // Note: If the L1 subtree being copied to L2 is empty, then the in_hash will be the root of a tree whose - // leaves are empty (0) messages. + // The leftmost block of the checkpoint must be a first block root, which is the only variant that sets + // `is_first_block`. `validate_consecutive_block_rollups` asserts every non-first ("right") rollup is not a + // first block, so the merged value can only be true if the leftmost leaf is a first block root. assert( - first_rollup.in_hash != 0, - "in_hash must be set via the first block root in the checkpoint", + first_rollup.is_first_block, + "The first block of the checkpoint must be a first block root", + ); + + // The message sponge resets per checkpoint, so the leftmost block must start from the empty sponge. Combined + // with the checkpoint root asserting the merged end equals the parity root's sponge, this anchors the sponge + // chain to exactly this checkpoint's messages. + assert_eq( + first_rollup.start_msg_sponge, + L1ToL2MessageSponge::empty(), + "The message sponge of the first block was not correctly initialized", ); // `previous_block_header` is provided as a private input and is used to validate the values above. diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/mod.nr index b3e5c7e41e2b..e665b4971813 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/mod.nr @@ -1,5 +1,7 @@ mod checkpoint_root_inputs_validator; mod checkpoint_rollup_public_inputs_composer; +mod validate_inbox_parity; pub use checkpoint_rollup_public_inputs_composer::CheckpointRollupPublicInputsComposer; pub use checkpoint_root_inputs_validator::CheckpointRootInputsValidator; +pub use validate_inbox_parity::validate_inbox_parity; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/validate_inbox_parity.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/validate_inbox_parity.nr new file mode 100644 index 000000000000..858c613d8229 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/components/validate_inbox_parity.nr @@ -0,0 +1,40 @@ +use crate::abis::ParityPublicInputs; +use types::{ + constants::{INBOX_PARITY_1024_VK_INDEX, INBOX_PARITY_256_VK_INDEX, INBOX_PARITY_64_VK_INDEX}, + proof::proof_data::UltraHonkProofData, +}; + +/// Verify the checkpoint's `InboxParity` proof and vk, and check that its vk tree root and prover_id equal the ones in +/// the checkpoint's constants. The proof may be any rung of the size ladder, so the vk index is checked against the +/// allowed `{64, 256, 1024}` set rather than a single value. +pub fn validate_inbox_parity( + data: UltraHonkProofData, + vk_tree_root: Field, + prover_id: Field, +) { + if !::std::runtime::is_unconstrained() { + data.verify_proof(); + } + + // Check that the `vk_tree_root` in the public inputs matches the one in the checkpoint's constants, as it was used + // to verify the vk of the inbox parity proof. + assert_eq( + data.public_inputs.vk_tree_root, + vk_tree_root, + "The vk tree root of the inbox parity does not match the rollup's vk tree root", + ); + + // Check that the `prover_id` in the public inputs matches the one in the checkpoint's constants, preventing sybil + // attacks where the same prover submits an inbox parity proof under different identities. + assert_eq( + data.public_inputs.prover_id, + prover_id, + "The prover id of the inbox parity does not match the rollup's prover id", + ); + + // The proof may be any rung of the size ladder, so accept the whole `{64, 256, 1024}` vk-index set. + data.vk_data.validate_allowed_in_vk_tree( + vk_tree_root, + [INBOX_PARITY_64_VK_INDEX, INBOX_PARITY_256_VK_INDEX, INBOX_PARITY_1024_VK_INDEX], + ); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/consecutive_rollups_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/consecutive_rollups_tests.nr index 30f2889c8f23..320978dc0bdc 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/consecutive_rollups_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/consecutive_rollups_tests.nr @@ -4,11 +4,11 @@ use super::TestBuilder; // validating consecutive block rollups can be found in `block_merge/tests/consecutive_block_rollups_tests.nr`. // Tests for merging out hashes can be found in `out_hash_tests.nr`. -#[test(should_fail_with = "Right rollup must not carry in_hash")] -fn non_zero_in_hash_in_right_rollup() { +#[test(should_fail_with = "Right rollup must not be a first block")] +fn first_block_in_right_rollup() { let mut builder = TestBuilder::default(); - builder.right_rollup.in_hash = 123; + builder.right_rollup.is_first_block = true; builder.execute_with_mock_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/mod.nr index ad894c973294..b2a8f64f802e 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/mod.nr @@ -1,12 +1,14 @@ mod blob_tests; mod child_proof_vk_tests; mod consecutive_rollups_tests; +mod msgs_only_tests; mod out_hash_tests; +mod parity_tests; mod rollup_structure_tests; mod start_states_tests; use crate::{ - abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs}, + abis::{BlockRollupPublicInputs, CheckpointRollupPublicInputs, ParityPublicInputs}, block_merge::accumulate_block_headers_hash, checkpoint_root::{ checkpoint_root_rollup::{ @@ -27,9 +29,9 @@ use types::{ blob_data::{create_checkpoint_end_marker, SpongeBlob}, constants::{ BLOCK_MERGE_ROLLUP_VK_INDEX, BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, - BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_ROLLUP_VK_INDEX, - BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, - OUT_HASH_TREE_LEAF_COUNT, + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + BLOCK_ROOT_ROLLUP_VK_INDEX, BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX, + BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, INBOX_PARITY_1024_VK_INDEX, OUT_HASH_TREE_LEAF_COUNT, }, merkle_tree::compute_sha_tree_root, traits::{Hash, Serialize}, @@ -48,6 +50,8 @@ struct TestBuilder { right_rollup: BlockRollupPublicInputs, right_rollup_vk_index: u32, is_single_block: bool, + inbox_parity: ParityPublicInputs, + inbox_parity_vk_index: u32, hints: CheckpointRootRollupHints, } @@ -150,8 +154,8 @@ impl TestBuilder { let start_block_number = fixture_builder.start_block_number; if !is_first_block(left_rollup_vk_index) & (left_rollup_vk_index != BLOCK_MERGE_ROLLUP_VK_INDEX) { - // Change the start_block_number to be smaller than the left rollup's start_block_number so that the in_hash - // won't be set on the left rollup. + // Change the start_block_number to be smaller than the left rollup's start_block_number so that the + // first-block designation is not on the left rollup. fixture_builder.start_block_number = start_block_number - 1; } let mut left_rollup = fixture_builder.get_merged_block_rollup_public_inputs( @@ -159,8 +163,8 @@ impl TestBuilder { start_block_number + num_left_blocks - 1, ); if is_first_block(right_rollup_vk_index) { - // Change the start_block_number to be the right rollup's start_block_number so that the in_hash will be set - // on the right rollup. + // Change the start_block_number to be the right rollup's start_block_number so that the first-block + // designation is on the right rollup. fixture_builder.start_block_number = start_block_number + num_left_blocks; } let mut right_rollup = fixture_builder.get_merged_block_rollup_public_inputs( @@ -187,12 +191,20 @@ impl TestBuilder { // Update the start state of the left rollup to match the state of the previous block. left_rollup.start_state = hints.previous_block_header.state; + // The InboxParity proof commits to the same checkpoint messages the block roots absorbed. Its message sponge + // (empty to the checkpoint's accumulated value) matches the blocks' merged sponge; its rolling hash feeds the + // checkpoint header. Built at the base slot the block fixtures use for their sponge. + let inbox_parity = + fixture_builder.get_parity_public_inputs(fixture_builder.start_slot_number); + Self { fixture_builder, left_rollup, left_rollup_vk_index, right_rollup, right_rollup_vk_index, + inbox_parity, + inbox_parity_vk_index: INBOX_PARITY_1024_VK_INDEX, hints, is_single_block, } @@ -252,12 +264,16 @@ impl TestBuilder { | (vk_index == BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP_VK_INDEX) | (vk_index == BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX) | (vk_index == BLOCK_ROOT_ROLLUP_VK_INDEX) - | (vk_index == BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX), + | (vk_index == BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX) + | (vk_index == BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX), ); } } pub fn execute(self) -> CheckpointRollupPublicInputs { + let inbox_parity = + RollupFixtureBuilder::make_proof_data(self.inbox_parity, self.inbox_parity_vk_index); + if self.is_single_block { checkpoint_root_single_block_rollup::execute( CheckpointRootSingleBlockRollupPrivateInputs { @@ -265,6 +281,7 @@ impl TestBuilder { self.left_rollup, self.left_rollup_vk_index, ), + inbox_parity, hints: self.hints, }, ) @@ -281,6 +298,7 @@ impl TestBuilder { self.right_rollup_vk_index, ), ], + inbox_parity, hints: self.hints, }, ) @@ -340,6 +358,11 @@ impl TestBuilder { assert_eq(pi.new_archive, right.new_archive); assert(pi.previous_archive != pi.new_archive); + // The checkpoint's rolling-hash pair is sourced from the InboxParity proof (which commits to the checkpoint's + // full message list), not from the block rollups. + assert_eq(pi.start_inbox_rolling_hash, self.inbox_parity.start_rolling_hash); + assert_eq(pi.end_inbox_rolling_hash, self.inbox_parity.end_rolling_hash); + // Safety: This is just for testing. Unconstrained to speed up the tests. let expected_checkpoint_header = unsafe { self.get_expected_checkpoint_header() }; assert_array_eq( @@ -423,7 +446,7 @@ impl TestBuilder { last_archive_root: left.previous_archive.root, block_headers_hash, blobs_hash: self.hints.blobs_hash, - in_hash: left.in_hash, + inbox_rolling_hash: self.inbox_parity.end_rolling_hash, epoch_out_hash, slot_number: left.constants.slot_number, timestamp: right.timestamp, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/msgs_only_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/msgs_only_tests.nr new file mode 100644 index 000000000000..14e321263436 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/msgs_only_tests.nr @@ -0,0 +1,33 @@ +use super::TestBuilder; +use types::constants::{ + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + BLOCK_ROOT_ROLLUP_VK_INDEX, +}; + +// A checkpoint of [first block, message-only block] proves: the message-only block is accepted as a non-first direct +// child of the checkpoint root. +#[test] +fn checkpoint_with_msgs_only_right_block() { + let builder = TestBuilder::new( + BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, + 1, + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + 1, + ); + let (pi, mock) = builder.execute_with_mock(); + builder.assert_expected_public_inputs(pi); + builder.assert_mock_called(mock); +} + +// The message-only block sets `is_first_block = false`, so it can never be the leftmost block of a checkpoint: the +// checkpoint root requires the leftmost rollup's `is_first_block` to be true. +#[test(should_fail_with = "The first block of the checkpoint must be a first block root")] +fn msgs_only_block_cannot_be_leftmost() { + let builder = TestBuilder::new( + BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, + 1, + BLOCK_ROOT_ROLLUP_VK_INDEX, + 1, + ); + builder.execute_with_mock_and_fail(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/parity_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/parity_tests.nr new file mode 100644 index 000000000000..f2776107e8f4 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/parity_tests.nr @@ -0,0 +1,106 @@ +use super::TestBuilder; +use protocol_test_utils::fixtures::vk_tree::{update_vk_hash, VK_MERKLE_TREE}; +use types::constants::{ + CHECKPOINT_ROOT_ROLLUP_VK_INDEX, INBOX_PARITY_256_VK_INDEX, INBOX_PARITY_64_VK_INDEX, +}; + +// --- Inbox parity proof / vk --- + +// The checkpoint root accepts any rung of the inbox parity size ladder. The default builder uses the 1024 rung; here +// we exercise the other two to prove the whole allowed set is accepted. +#[test] +fn accepts_ladder_vk_index_64() { + let mut builder = TestBuilder::default(); + builder.inbox_parity_vk_index = INBOX_PARITY_64_VK_INDEX; + let _ = builder.execute_with_mock(); +} + +#[test] +fn accepts_ladder_vk_index_256_single_block() { + let mut builder = TestBuilder::default_single_block(); + builder.inbox_parity_vk_index = INBOX_PARITY_256_VK_INDEX; + let _ = builder.execute_with_mock(); +} + +#[test(should_fail_with = "Vk index not in allowed list")] +fn incorrect_inbox_parity_vk_index() { + let mut builder = TestBuilder::default(); + + builder.inbox_parity_vk_index = CHECKPOINT_ROOT_ROLLUP_VK_INDEX; + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "Vk index not in allowed list")] +fn incorrect_inbox_parity_vk_index_single_block() { + let mut builder = TestBuilder::default_single_block(); + + builder.inbox_parity_vk_index = CHECKPOINT_ROOT_ROLLUP_VK_INDEX; + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "Membership check failed: vk hash not found in vk tree")] +fn inbox_parity_vk_not_in_vk_tree() { + let mut builder = TestBuilder::default(); + + // Update the inbox parity vk hash so that the old vk hash in the proof data is no longer in the vk tree. + let mut new_vk_tree = VK_MERKLE_TREE; + update_vk_hash(&mut new_vk_tree, builder.inbox_parity_vk_index, 999); + + builder.inbox_parity.vk_tree_root = new_vk_tree.get_root(); + builder.left_rollup.constants.vk_tree_root = new_vk_tree.get_root(); + builder.right_rollup.constants.vk_tree_root = new_vk_tree.get_root(); + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "The vk tree root of the inbox parity does not match the rollup's vk tree root")] +fn mismatched_vk_tree_root_from_parity() { + let mut builder = TestBuilder::default(); + + builder.inbox_parity.vk_tree_root += 1; + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "The prover id of the inbox parity does not match the rollup's prover id")] +fn mismatched_prover_id_from_parity() { + let mut builder = TestBuilder::default(); + + builder.inbox_parity.prover_id += 1; + + builder.execute_with_mock_and_fail(); +} + +// --- Message sponge --- + +#[test(should_fail_with = "The inbox parity message sponge must start empty")] +fn inbox_parity_sponge_not_empty() { + let mut builder = TestBuilder::default(); + + // The inbox parity's message sponge must reset per checkpoint (start empty). + builder.inbox_parity.start_sponge.num_absorbed += 1; + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "The blocks' message sponge does not match the inbox parity's message sponge")] +fn blocks_sponge_mismatch_parity() { + let mut builder = TestBuilder::default(); + + // Break the equality between the blocks' accumulated sponge and the inbox parity's sponge. + builder.inbox_parity.end_sponge.num_absorbed += 1; + + builder.execute_with_mock_and_fail(); +} + +#[test(should_fail_with = "The message sponge of the first block was not correctly initialized")] +fn first_block_start_sponge_not_empty() { + let mut builder = TestBuilder::default(); + + // The first block must start the message sponge from empty. + builder.left_rollup.start_msg_sponge.num_absorbed += 1; + + builder.execute_with_mock_and_fail(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/rollup_structure_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/rollup_structure_tests.nr index cf75a3c16921..c800a306a75b 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/rollup_structure_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/checkpoint_root/tests/rollup_structure_tests.nr @@ -21,7 +21,7 @@ fn with_both_roots_left_is_first() { } } -#[test(should_fail_with = "Right rollup must not carry in_hash")] +#[test(should_fail_with = "Right rollup must not be a first block")] fn with_both_roots_right_is_first() { TestBuilder::new( BLOCK_ROOT_ROLLUP_VK_INDEX, @@ -32,7 +32,7 @@ fn with_both_roots_right_is_first() { .execute_with_mock_and_fail(); } -#[test(should_fail_with = "Right rollup must not carry in_hash")] +#[test(should_fail_with = "Right rollup must not be a first block")] fn with_both_first_roots() { TestBuilder::new( BLOCK_ROOT_FIRST_ROLLUP_VK_INDEX, @@ -43,7 +43,7 @@ fn with_both_first_roots() { .execute_with_mock_and_fail(); } -#[test(should_fail_with = "in_hash must be set via the first block root in the checkpoint")] +#[test(should_fail_with = "The first block of the checkpoint must be a first block root")] fn with_both_non_first_roots() { TestBuilder::new(BLOCK_ROOT_ROLLUP_VK_INDEX, 1, BLOCK_ROOT_ROLLUP_VK_INDEX, 1) .execute_with_mock_and_fail(); @@ -64,7 +64,7 @@ fn with_left_merge_and_right_root() { builder.assert_mock_called(mock); } -#[test(should_fail_with = "in_hash must be set via the first block root in the checkpoint")] +#[test(should_fail_with = "The first block of the checkpoint must be a first block root")] fn with_left_non_first_merge_and_right_root() { let mut builder = TestBuilder::new( // Left rollup is a merge that has 4 blocks. @@ -75,13 +75,13 @@ fn with_left_non_first_merge_and_right_root() { 1, ); - // The merge at the left has 0 in hash since it does not contain the first block root. - builder.left_rollup.in_hash = 0; + // The merge at the left is not a first block since it does not contain the first block root. + builder.left_rollup.is_first_block = false; builder.execute_with_mock_and_fail(); } -#[test(should_fail_with = "Right rollup must not carry in_hash")] +#[test(should_fail_with = "Right rollup must not be a first block")] fn with_left_non_first_merge_and_right_first_root() { let mut builder = TestBuilder::new( // Left rollup is a merge that has 4 blocks. @@ -92,8 +92,8 @@ fn with_left_non_first_merge_and_right_first_root() { 1, ); - // The merge at the left has 0 in hash since it does not contain the first block root. - builder.left_rollup.in_hash = 0; + // The merge at the left is not a first block since it does not contain the first block root. + builder.left_rollup.is_first_block = false; builder.execute_with_mock_and_fail(); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/inbox_rolling_hash.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/inbox_rolling_hash.nr new file mode 100644 index 000000000000..661f898f7fb3 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/inbox_rolling_hash.nr @@ -0,0 +1,94 @@ +use types::hash::accumulate_sha256; + +/// Extends the Inbox rolling sha256 chain by the first `num_leaves` of `leaves`, returning the new rolling hash. +/// +/// Each link is `h' = sha256ToField(h || leaf)` over the two 32-byte big-endian values, i.e. exactly one +/// `accumulate_sha256` step, matching the truncated-to-field sha256 the L1 `Inbox` accumulates and today's `inHash` +/// frontier tree uses at every node. The genesis rolling hash is zero. +/// +/// The function takes a `start` and returns an end with no assumption about chunk position, so it chains sequentially +/// across chunked circuits: a segment's start hash is the previous segment's end. Lanes beyond `num_leaves` are never +/// absorbed — the Inbox chain only ever sees real messages. +pub fn accumulate_inbox_rolling_hash( + start: Field, + leaves: [Field; N], + num_leaves: u32, +) -> Field { + assert(num_leaves <= N, "num_leaves is greater than the leaves array length"); + + let mut acc = start; + for i in 0..N { + if i < num_leaves { + acc = accumulate_sha256(acc, leaves[i]); + } + } + acc +} + +mod tests { + use super::accumulate_inbox_rolling_hash; + use types::{constants::INBOX_PARITY_SIZE_MEDIUM, hash::accumulate_sha256}; + + #[test] + fn empty_bundle_passes_start_through() { + assert_eq(accumulate_inbox_rolling_hash(0, [0; 8], 0), 0); + // A non-zero start with no leaves is returned unchanged (segment threading base case). + assert_eq(accumulate_inbox_rolling_hash(0x2a, [11, 22, 33], 0), 0x2a); + } + + #[test] + fn single_leaf_matches_reference() { + // Independent sha256 reference (see PR description): sha256ToField(0x00..00 || 0x00..0b), last byte dropped. + let expected = 0x00815fb1e9d2076ae5761439b6144ad11da69eb6c41ab2aca39e770407ad8d12; + assert_eq(accumulate_inbox_rolling_hash(0, [11, 0, 0, 0], 1), expected); + assert_eq(accumulate_sha256(0, 11), expected); + } + + #[test] + fn three_leaves_matches_reference() { + let expected = 0x0014cae968461979aab6d33266a2310ed234d3f6cf4472737c57551db07bd0da; + assert_eq(accumulate_inbox_rolling_hash(0, [11, 22, 33, 0, 0], 3), expected); + } + + #[test] + fn batch_matches_reference() { + // 256 leaves valued 1..=256 from a zero start. + let mut leaves = [0; INBOX_PARITY_SIZE_MEDIUM]; + for i in 0..INBOX_PARITY_SIZE_MEDIUM { + leaves[i] = (i + 1) as Field; + } + let expected = 0x00ea95b96f17b75be03525b35a2a1918b42f03ad8c00a437cf641751825f3992; + assert_eq(accumulate_inbox_rolling_hash(0, leaves, INBOX_PARITY_SIZE_MEDIUM), expected); + } + + #[test] + fn non_zero_start_matches_reference() { + let expected = 0x0054d96b8a074a5030a5838972d0a3c04ba47cf5956348c853e02e9566233f65; + assert_eq(accumulate_inbox_rolling_hash(0x2a, [7, 8], 2), expected); + } + + #[test] + fn chain_is_continuous_across_segments() { + // Chaining [7,8,9] from a start equals chaining [7] then [8,9] threaded by the intermediate hash. + let start = 0x2a; + let full = accumulate_inbox_rolling_hash(start, [7, 8, 9, 0, 0], 3); + + let mid = accumulate_inbox_rolling_hash(start, [7, 0], 1); + let split = accumulate_inbox_rolling_hash(mid, [8, 9], 2); + + assert_eq(full, split); + } + + #[test] + fn padding_lanes_are_not_absorbed() { + // A padded array with num_leaves set correctly matches the exact-length chain regardless of lane contents. + let padded = accumulate_inbox_rolling_hash(0, [11, 22, 999, 888], 2); + let exact = accumulate_inbox_rolling_hash(0, [11, 22], 2); + assert_eq(padded, exact); + } + + #[test(should_fail_with = "num_leaves is greater than the leaves array length")] + fn num_leaves_past_array_fails() { + let _ = accumulate_inbox_rolling_hash(0, [11, 22, 33], 4); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/lib.nr index af4d39d00c99..f6c5a2d30577 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/lib.nr @@ -1,6 +1,7 @@ pub(crate) mod abis; pub(crate) mod tests; +pub mod inbox_rolling_hash; pub mod tx_base; pub mod tx_merge; pub mod block_root; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/inbox_parity.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/inbox_parity.nr new file mode 100644 index 000000000000..c8784c827a6f --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/inbox_parity.nr @@ -0,0 +1,57 @@ +use crate::{ + abis::{L1ToL2MessageSponge, ParityPublicInputs}, + inbox_rolling_hash::accumulate_inbox_rolling_hash, +}; +use types::utils::arrays::assert_trailing_zeros; + +/// Private inputs for the `InboxParity` circuit, generic over the message-bundle size `S`. +/// +/// One `InboxParity` proof is produced per checkpoint. The prover picks the smallest ladder size `S ∈ {64, 256, 1024}` +/// with `S >= num_msgs`, so a checkpoint with few messages proves a small circuit. +pub struct InboxParityPrivateInputs { + // The checkpoint's L1-to-L2 message leaves, padded with zeros beyond `num_msgs`. + pub(crate) msgs: [Field; S], + // Number of real (non-padding) messages in `msgs`. + pub(crate) num_msgs: u32, + // Rolling hash of the Inbox chain before this checkpoint's messages (the previous checkpoint's end value; genesis + // is zero). + pub(crate) start_rolling_hash: Field, + // Message-bundle sponge before this checkpoint's messages (empty at checkpoint start). + pub(crate) start_sponge: L1ToL2MessageSponge, + pub(crate) vk_tree_root: Field, + pub(crate) prover_id: Field, +} + +/// The Inbox Parity circuit recomputes, for one checkpoint, the Inbox rolling-hash chain over the checkpoint's real +/// L1-to-L2 messages and absorbs the same real messages into the message-bundle sponge. It replaces the parity base + +/// parity root family with a single variable-size proof per checkpoint. +/// +/// This circuit: +/// - Chains the `num_msgs` real messages into the rolling hash (two sha256 compressions per leaf) +/// - Absorbs the same real messages into the message sponge (real-count absorb; the checkpoint root asserts this +/// equals the sponge the block roots accumulate) +/// - Asserts the padding lanes past `num_msgs` are zero so they cannot silently enter either accumulator +/// +/// The output feeds the Checkpoint Root circuits, which verify this proof against the `{64, 256, 1024}` VK ladder. +/// +/// VkIndex: INBOX_PARITY_{64,256,1024}_VK_INDEX +pub fn execute(inputs: InboxParityPrivateInputs) -> ParityPublicInputs { + // Guard the padding lanes so they can't silently enter either accumulator (`num_msgs <= S` is asserted here too). + assert_trailing_zeros(inputs.msgs, inputs.num_msgs); + + let end_rolling_hash = + accumulate_inbox_rolling_hash(inputs.start_rolling_hash, inputs.msgs, inputs.num_msgs); + + let mut end_sponge = inputs.start_sponge; + end_sponge.absorb(inputs.msgs, inputs.num_msgs); + + ParityPublicInputs { + start_rolling_hash: inputs.start_rolling_hash, + end_rolling_hash, + start_sponge: inputs.start_sponge, + end_sponge, + num_msgs: inputs.num_msgs, + vk_tree_root: inputs.vk_tree_root, + prover_id: inputs.prover_id, + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/mod.nr index 668a2cb50cf5..3fed3a63fef6 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/mod.nr @@ -1,7 +1,5 @@ -pub mod parity_base; -pub mod parity_root; +pub mod inbox_parity; mod tests; pub use crate::abis::ParityPublicInputs; -pub use parity_base::ParityBasePrivateInputs; -pub use parity_root::ParityRootPrivateInputs; +pub use inbox_parity::InboxParityPrivateInputs; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_base.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_base.nr deleted file mode 100644 index 4cc7451d0d34..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_base.nr +++ /dev/null @@ -1,34 +0,0 @@ -use crate::abis::ParityPublicInputs; -use types::{constants::NUM_MSGS_PER_BASE_PARITY, merkle_tree::MerkleTree}; - -pub struct ParityBasePrivateInputs { - pub(crate) msgs: [Field; NUM_MSGS_PER_BASE_PARITY], - pub(crate) vk_tree_root: Field, - pub(crate) prover_id: Field, -} - -/// The Parity Base circuit processes a batch of L1-to-L2 messages and computes their merkle roots. -/// It is the first step in converting L1 messages from SHA256 format (used on L1) to Poseidon format -/// (used in Aztec's state trees). -/// -/// This circuit: -/// - Takes a fixed batch of L1-to-L2 messages as input -/// - Computes a SHA256 merkle tree root over the messages (for verification on L1) -/// - Computes a Poseidon merkle tree root over the same messages (for L2 state tree insertion) -/// - Outputs both roots along with the vk_tree_root for consistency verification -/// -/// The output feeds into the Parity Root circuit, which aggregates multiple Parity Base proofs to form the complete -/// L1-to-L2 message subtree for a checkpoint. -/// -/// VkIndex: PARITY_BASE_VK_INDEX -pub fn execute(inputs: ParityBasePrivateInputs) -> ParityPublicInputs { - let sha_tree = MerkleTree::new_sha(inputs.msgs); - let poseidon_tree = MerkleTree::new(inputs.msgs); - - ParityPublicInputs { - sha_root: sha_tree.get_root(), - converted_root: poseidon_tree.get_root(), - vk_tree_root: inputs.vk_tree_root, - prover_id: inputs.prover_id, - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_root.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_root.nr deleted file mode 100644 index 62bdda658e0b..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/parity_root.nr +++ /dev/null @@ -1,103 +0,0 @@ -use crate::abis::ParityPublicInputs; -use types::{ - constants::{NUM_BASE_PARITY_PER_ROOT_PARITY, PARITY_BASE_VK_INDEX}, - merkle_tree::MerkleTree, - proof::proof_data::UltraHonkProofData, -}; - -pub type ParityBaseProofData = UltraHonkProofData; - -pub struct ParityRootPrivateInputs { - pub(crate) children: [ParityBaseProofData; NUM_BASE_PARITY_PER_ROOT_PARITY], -} - -/// The Parity Root circuit aggregates multiple Parity Base proofs to form the complete L1-to-L2 message subtree for a -/// checkpoint. It combines the merkle roots from child circuits into final roots. -/// -/// This circuit: -/// - Verifies proofs from multiple Parity Base circuits (the children) -/// - Validates that all children use the same vk_tree_root -/// - Validates that all children use the same prover_id -/// - Validates that all children use the same verification key (consistent vk hash, index, and path) -/// - Validates the verification key exists in the vk tree -/// - Computes the final SHA256 merkle root by merging the children's SHA roots -/// - Computes the final Poseidon merkle root by merging the children's converted roots -/// -/// The output feeds into the Block Root First circuits, where the `sha_root` is used to compute the `in_hash` for -/// verification against the value on L1, and the `converted_root` is inserted into the L1-to-L2 message tree to be -/// consumed by the app circuits. -/// -/// VkIndex: PARITY_ROOT_VK_INDEX -pub fn execute(inputs: ParityRootPrivateInputs) -> ParityPublicInputs { - let vk_tree_root = inputs.children[0].public_inputs.vk_tree_root; - for i in 1..NUM_BASE_PARITY_PER_ROOT_PARITY { - assert_eq( - inputs.children[i].public_inputs.vk_tree_root, - vk_tree_root, - "Inconsistent vk tree roots across parity base circuits", - ); - } - - let prover_id = inputs.children[0].public_inputs.prover_id; - for i in 1..NUM_BASE_PARITY_PER_ROOT_PARITY { - assert_eq( - inputs.children[i].public_inputs.prover_id, - prover_id, - "Inconsistent prover ids across parity base circuits", - ); - } - - verify_child_proofs(inputs); - - let mut sha_roots = [0; NUM_BASE_PARITY_PER_ROOT_PARITY]; - let mut converted_roots = [0; NUM_BASE_PARITY_PER_ROOT_PARITY]; - for i in 0..NUM_BASE_PARITY_PER_ROOT_PARITY { - sha_roots[i] = inputs.children[i].public_inputs.sha_root; - converted_roots[i] = inputs.children[i].public_inputs.converted_root; - } - - let sha_tree = MerkleTree::new_sha(sha_roots); - let poseidon_tree = MerkleTree::new(converted_roots); - - ParityPublicInputs { - sha_root: sha_tree.get_root(), - converted_root: poseidon_tree.get_root(), - vk_tree_root, - prover_id, - } -} - -fn verify_child_proofs(inputs: ParityRootPrivateInputs) { - let vk_data = inputs.children[0].vk_data; - let vk_tree_root = inputs.children[0].public_inputs.vk_tree_root; - - inputs.children[0].verify_proof(); - - for i in 1..NUM_BASE_PARITY_PER_ROOT_PARITY { - inputs.children[i].verify_proof(); - - // No need to check `vk_data.vk.key` here, as it's verified in bb that it produces the given hash (`vk_data.vk.hash`). - // So we can ensure that all the keys are the same by asserting that their hashes are equal across all children. - assert_eq( - inputs.children[i].vk_data.vk.hash, - vk_data.vk.hash, - "Inconsistent vk hashes across parity base circuits", - ); - assert_eq( - inputs.children[i].vk_data.leaf_index, - vk_data.leaf_index, - "Inconsistent vk indices across parity base circuits", - ); - assert_eq( - inputs.children[i].vk_data.sibling_path, - vk_data.sibling_path, - "Inconsistent vk paths across parity base circuits", - ); - } - - assert_eq(vk_data.leaf_index, PARITY_BASE_VK_INDEX, "Incorrect vk index for parity base"); - - // Since the vk hashes and paths have been checked to be consistent across all children, - // it's sufficient to validate that one of them exists in the vk tree. - vk_data.validate_in_vk_tree(vk_tree_root); -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/inbox_parity_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/inbox_parity_tests.nr new file mode 100644 index 000000000000..e91bbad3a7e8 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/inbox_parity_tests.nr @@ -0,0 +1,131 @@ +use crate::{ + abis::L1ToL2MessageSponge, + inbox_rolling_hash::accumulate_inbox_rolling_hash, + parity::inbox_parity::{self, InboxParityPrivateInputs}, +}; +use types::traits::Empty; + +global S: u32 = 64; + +#[test] +fn public_inputs_match_expected() { + let mut msgs = [0; S]; + for i in 0..S { + msgs[i] = i as Field; + } + let private_inputs = InboxParityPrivateInputs { + msgs, + num_msgs: S, + start_rolling_hash: 0, + start_sponge: L1ToL2MessageSponge::empty(), + vk_tree_root: 42, + prover_id: 7, + }; + let public_inputs = inbox_parity::execute(private_inputs); + + assert_eq(public_inputs.vk_tree_root, 42); + assert_eq(public_inputs.prover_id, 7); + + // The rolling hash chains all real messages on top of the start value; the circuit echoes back its start/count. + assert_eq(public_inputs.start_rolling_hash, 0); + assert_eq(public_inputs.num_msgs, S); + assert_eq(public_inputs.end_rolling_hash, accumulate_inbox_rolling_hash(0, msgs, S)); + + // The sponge absorbs exactly the real messages (real-count), threading the start. + assert_eq(public_inputs.start_sponge, L1ToL2MessageSponge::empty()); + let mut expected_end_sponge = L1ToL2MessageSponge::empty(); + expected_end_sponge.absorb(msgs, S); + assert_eq(public_inputs.end_sponge, expected_end_sponge); +} + +#[test] +fn rolling_hash_and_sponge_ignore_padding_and_thread_start() { + // Only the first three lanes are real; the rest are zero padding. + let mut msgs = [0; S]; + msgs[0] = 11; + msgs[1] = 22; + msgs[2] = 33; + + let start = 0x2a; + let mut start_sponge = L1ToL2MessageSponge::new(); + start_sponge.absorb([7, 8], 2); + let private_inputs = InboxParityPrivateInputs { + msgs, + num_msgs: 3, + start_rolling_hash: start, + start_sponge, + vk_tree_root: 42, + prover_id: 7, + }; + let public_inputs = inbox_parity::execute(private_inputs); + + assert_eq(public_inputs.start_rolling_hash, start); + assert_eq(public_inputs.num_msgs, 3); + assert_eq( + public_inputs.end_rolling_hash, + accumulate_inbox_rolling_hash(start, [11, 22, 33], 3), + ); + + // Both the rolling hash and the sponge see only the three real leaves (real-count absorb). + assert_eq(public_inputs.start_sponge, start_sponge); + let mut expected_end_sponge = start_sponge; + expected_end_sponge.absorb([11, 22, 33], 3); + assert_eq(public_inputs.end_sponge, expected_end_sponge); +} + +#[test] +fn sponge_matches_block_root_real_count_absorb() { + // The checkpoint root asserts InboxParity's end sponge equals the sponge the block roots accumulate. The block + // roots absorb the real messages (real-count) out of their padded bundle, so InboxParity must reach the same + // state absorbing the same real prefix out of a differently-sized (here smaller) array. + let mut msgs = [0; S]; + msgs[0] = 101; + msgs[1] = 202; + + let private_inputs = InboxParityPrivateInputs { + msgs, + num_msgs: 2, + start_rolling_hash: 0, + start_sponge: L1ToL2MessageSponge::empty(), + vk_tree_root: 42, + prover_id: 7, + }; + let public_inputs = inbox_parity::execute(private_inputs); + + // A block root absorbing the same two real leaves out of its wider bundle reaches the same sponge. + let mut block_sponge = L1ToL2MessageSponge::empty(); + block_sponge.absorb([101, 202, 0, 0, 0], 2); + assert_eq(public_inputs.end_sponge, block_sponge); +} + +#[test(should_fail_with = "Found non-zero field after breakpoint")] +fn non_zero_padding_lane_fails() { + // Claim two real messages but leave a non-zero value in a padding lane. + let mut msgs = [0; S]; + msgs[0] = 11; + msgs[1] = 22; + msgs[5] = 999; + + let private_inputs = InboxParityPrivateInputs { + msgs, + num_msgs: 2, + start_rolling_hash: 0, + start_sponge: L1ToL2MessageSponge::empty(), + vk_tree_root: 42, + prover_id: 7, + }; + let _ = inbox_parity::execute(private_inputs); +} + +#[test(should_fail_with = "in_len is greater than the input array len")] +fn num_msgs_greater_than_size_fails() { + let private_inputs = InboxParityPrivateInputs { + msgs: [0; S], + num_msgs: S + 1, + start_rolling_hash: 0, + start_sponge: L1ToL2MessageSponge::empty(), + vk_tree_root: 42, + prover_id: 7, + }; + let _ = inbox_parity::execute(private_inputs); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/mod.nr index 069b1e4a3565..417040122994 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/mod.nr @@ -1,2 +1 @@ -mod parity_base_tests; -mod parity_root_tests; +mod inbox_parity_tests; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_base_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_base_tests.nr deleted file mode 100644 index 5dc2071f28c4..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_base_tests.nr +++ /dev/null @@ -1,21 +0,0 @@ -use crate::parity::parity_base::{self, ParityBasePrivateInputs}; -use types::constants::NUM_MSGS_PER_BASE_PARITY; - -#[test] -fn public_inputs_match_expected() { - let mut msgs = [0; NUM_MSGS_PER_BASE_PARITY]; - for i in 0..NUM_MSGS_PER_BASE_PARITY { - msgs[i] = i as Field; - } - let private_inputs = ParityBasePrivateInputs { msgs, vk_tree_root: 42, prover_id: 7 }; - let public_inputs = parity_base::execute(private_inputs); - - let expected_sha_root = 0x279d4d4dd5bcb9b1a4e742640588b917102f9f8bc97a6c95706ca4e7a8a76b; - let expected_converted_root = - 0x24425e91123ffa26018e970b92316101d503c5937f145d69569ac907d0bd36ec; - - assert_eq(public_inputs.sha_root, expected_sha_root); - assert_eq(public_inputs.converted_root, expected_converted_root); - assert_eq(public_inputs.vk_tree_root, 42); - assert_eq(public_inputs.prover_id, 7); -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_root_tests.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_root_tests.nr deleted file mode 100644 index beb9ef9f2ab8..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/parity/tests/parity_root_tests.nr +++ /dev/null @@ -1,144 +0,0 @@ -use crate::{ - abis::ParityPublicInputs, - parity::parity_root::{self, ParityBaseProofData, ParityRootPrivateInputs}, -}; -use protocol_test_utils::{fixtures::vk_tree::{get_vk_data, vk_tree_root}, pad_end}; -use types::{ - constants::{ - NUM_BASE_PARITY_PER_ROOT_PARITY, PARITY_BASE_VK_INDEX, PARITY_ROOT_VK_INDEX, - ULTRA_VK_LENGTH_IN_FIELDS, - }, - proof::{proof_data::ProofData, vk_data::VkData}, -}; - -struct TestBuilder { - children: [ParityBaseProofData; NUM_BASE_PARITY_PER_ROOT_PARITY], -} - -impl TestBuilder { - pub fn new() -> Self { - let vk_data = get_vk_data(PARITY_BASE_VK_INDEX); - - // 31 byte test SHA roots - let children_sha_roots = [ - 0xb3a3fc1968999f2c2d798b900bdf0de41311be2a4d20496a7e792a521fc8ab, - 0x43f78e0ebc9633ce336a8c086064d898c32fb5d7d6011f5427459c0b8d14e9, - 0x024259b6404280addcc9319bc5a32c9a5d56af5c93b2f941fa326064fbe963, - 0x53042d820859d80c474d4694e03778f8dc0ac88fc1c3a97b4369c1096e904a, - ]; - - let children = children_sha_roots.map(|sha_root| Self::make_proof_data(sha_root, vk_data)); - - Self { children } - } - - fn make_proof_data( - sha_root: Field, - vk_data: VkData, - ) -> ParityBaseProofData { - let public_inputs = - ParityPublicInputs { sha_root, converted_root: 0, vk_tree_root, prover_id: 42 }; - - let value_offset = sha_root / 2; - ProofData { - public_inputs, - proof: pad_end( - [value_offset + 450343, value_offset + 27394, value_offset + 8003179], - ), - vk_data, - } - } - - pub fn execute(self) -> ParityPublicInputs { - let private_inputs = ParityRootPrivateInputs { children: self.children }; - parity_root::execute(private_inputs) - } -} - -#[test] -fn public_inputs_match_expected() { - let public_inputs = TestBuilder::new().execute(); - - let expected_sha_root = 0xa0c56543aa73140e5ca27231eee3107bd4e11d62164feb411d77c9d9b2da47; - let expected_converted_root = - 0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d; - - assert_eq(public_inputs.sha_root, expected_sha_root); - assert_eq(public_inputs.converted_root, expected_converted_root); - assert_eq(public_inputs.vk_tree_root, vk_tree_root); - assert_eq(public_inputs.prover_id, 42); -} - -#[test(should_fail_with = "Inconsistent vk tree roots across parity base circuits")] -fn inconsistent_vk_tree_root() { - let mut builder = TestBuilder::new(); - - // Tweak the vk tree root of the second child. - builder.children[1].public_inputs.vk_tree_root += 1; - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Membership check failed: vk hash not found in vk tree")] -fn incorrect_vk_tree_root() { - let mut builder = TestBuilder::new(); - - // Change the vk tree root of all children. - for i in 0..NUM_BASE_PARITY_PER_ROOT_PARITY { - builder.children[i].public_inputs.vk_tree_root += 1; - } - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Inconsistent vk hashes across parity base circuits")] -fn inconsistent_vk_hashes() { - let mut builder = TestBuilder::new(); - - // Tweak the vk hash of the third child. - builder.children[2].vk_data.vk.hash += 1; - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Inconsistent vk indices across parity base circuits")] -fn inconsistent_vk_indices() { - let mut builder = TestBuilder::new(); - - // Change the vk leaf index of the last child to be the root parity index. - builder.children[3].vk_data.leaf_index = PARITY_ROOT_VK_INDEX; - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Inconsistent vk paths across parity base circuits")] -fn inconsistent_vk_paths() { - let mut builder = TestBuilder::new(); - - // Tweak the vk path of the first child. - builder.children[0].vk_data.sibling_path[0] += 1; - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Incorrect vk index for parity base")] -fn incorrect_vk_index() { - let mut builder = TestBuilder::new(); - - // Change the vk leaf index of all children to be the root parity index. - for i in 0..NUM_BASE_PARITY_PER_ROOT_PARITY { - builder.children[i].vk_data.leaf_index = PARITY_ROOT_VK_INDEX; - } - - let _ = builder.execute(); -} - -#[test(should_fail_with = "Inconsistent prover ids across parity base circuits")] -fn inconsistent_prover_ids() { - let mut builder = TestBuilder::new(); - - // Tweak the prover_id of the second child. - builder.children[1].public_inputs.prover_id += 1; - - let _ = builder.execute(); -} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup.nr index 8ce096c85a55..e816ba911dfb 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup.nr @@ -119,6 +119,8 @@ pub fn execute(inputs: RootRollupPrivateInputs) -> RootRollupPublicInputs { previous_archive_root: merged.previous_archive.root, new_archive_root: merged.new_archive.root, out_hash: merged.new_out_hash.root, + previous_inbox_rolling_hash: merged.start_inbox_rolling_hash, + end_inbox_rolling_hash: merged.end_inbox_rolling_hash, checkpoint_header_hashes: merged.checkpoint_header_hashes, fees: merged.fees, constants: merged.constants, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/tests/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/tests/mod.nr index be50184fd264..a306decbdb3b 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/tests/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/tests/mod.nr @@ -122,6 +122,10 @@ impl TestBuilder { assert_eq(pi.out_hash, right.new_out_hash.root); + // The epoch exposes the first checkpoint's chain start and the last checkpoint's chain end as a pass-through. + assert_eq(pi.previous_inbox_rolling_hash, left.start_inbox_rolling_hash); + assert_eq(pi.end_inbox_rolling_hash, right.end_inbox_rolling_hash); + let mut expected_header_hashes = [0; MAX_CHECKPOINTS_PER_EPOCH]; let mut expected_fees = [FeeRecipient::empty(); MAX_CHECKPOINTS_PER_EPOCH]; for i in 0..self.num_left_checkpoints as u32 { @@ -153,6 +157,9 @@ impl TestBuilder { assert_eq(pi.out_hash, left.new_out_hash.root); + assert_eq(pi.previous_inbox_rolling_hash, left.start_inbox_rolling_hash); + assert_eq(pi.end_inbox_rolling_hash, left.end_inbox_rolling_hash); + assert_eq(pi.checkpoint_header_hashes, left.checkpoint_header_hashes); assert_eq(pi.fees, left.fees); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/rollup_fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/rollup_fixture_builder.nr index 50ac6d8f71fe..c96feaf9d36e 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/rollup_fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/rollup_fixture_builder.nr @@ -1,5 +1,6 @@ use crate::abis::{ - BlockRollupPublicInputs, CheckpointRollupPublicInputs, ParityPublicInputs, TxRollupPublicInputs, + BlockRollupPublicInputs, CheckpointRollupPublicInputs, L1ToL2MessageSponge, ParityPublicInputs, + TxRollupPublicInputs, }; use bigcurve::BigCurve; use bignum::BigNum; @@ -23,14 +24,22 @@ use types::{ constants::{ ARCHIVE_HEIGHT, BLOBS_PER_CHECKPOINT, DOM_SEP__BLOB_GAMMA_FINAL, EMPTY_EPOCH_OUT_HASH, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, MAX_CHECKPOINTS_PER_EPOCH, - OUT_HASH_TREE_HEIGHT, OUT_HASH_TREE_LEAF_COUNT, + MAX_L1_TO_L2_MSGS_PER_BLOCK, OUT_HASH_TREE_HEIGHT, OUT_HASH_TREE_LEAF_COUNT, }, hash::{poseidon2_hash, poseidon2_hash_with_separator}, - merkle_tree::{compute_empty_tree_root, MerkleTree, test_utils::SingleSubtreeMerkleTree}, + merkle_tree::{ + append_only_tree::append_leaves_to_snapshot, compute_empty_tree_root, MerkleTree, + test_utils::SingleSubtreeMerkleTree, + }, proof::proof_data::{AvmV2ProofData, ProofData}, traits::{Deserialize, Empty, Hash}, }; +// The fixture pre-fills l1-to-l2 leaves into a single subtree of 2^3 = 8 leaves, which bounds how far into the tree a +// block's bundle can be made to start. The bundle append itself is not aligned to that subtree. +global PRE_EXISTING_L1_TO_L2_SUBTREE_HEIGHT: u32 = 3; +global PRE_EXISTING_L1_TO_L2_LEAF_COUNT: u32 = 8; + pub struct RollupFixtureBuilder { // Epoch constants. pub chain_id: Field, @@ -39,7 +48,7 @@ pub struct RollupFixtureBuilder { pub protocol_contracts_hash: Field, pub prover_id: Field, - // Used to identify the first block, which will have an empty start_sponge_blob, and non-empty in_hash. + // Used to identify the first block, which will have an empty start_sponge_blob. pub start_block_number: u32, // Used to identify the first checkpoint, which will have an empty start_blob_accumulator. @@ -176,6 +185,61 @@ impl RollupFixtureBuilder { (previous_snapshot, sibling_path_for_insertion, new_snapshot) } + /// Builds a per-block L1-to-L2 message bundle appended to an empty tree, returning + /// `(previous_snapshot, leaves, frontier_hint, new_snapshot)`. The resulting `new_snapshot` is exactly what the + /// block root circuit recomputes from the same inputs. + pub fn build_l1_to_l2_message_bundle( + self, + num_msgs: u32, + ) -> (AppendOnlyTreeSnapshot, [Field; MAX_L1_TO_L2_MSGS_PER_BLOCK], [Field; L1_TO_L2_MSG_TREE_HEIGHT], AppendOnlyTreeSnapshot) { + self.build_l1_to_l2_message_bundle_at_index(num_msgs, 0) + } + + /// Same as `build_l1_to_l2_message_bundle`, but appending into a tree that already holds `start_index` leaves — + /// the compact, unaligned append every block after the very first one performs. The pre-existing leaves sit in a + /// single subtree of `PRE_EXISTING_L1_TO_L2_LEAF_COUNT` leaves, so `start_index` must stay below that. The frontier + /// hint is the tree's sibling path at `start_index`, which is how a tree database answers for it: the pending left + /// sibling at every level where the index is a right child, and the zero-subtree root everywhere else. + pub fn build_l1_to_l2_message_bundle_at_index( + _self: Self, + num_msgs: u32, + start_index: u32, + ) -> (AppendOnlyTreeSnapshot, [Field; MAX_L1_TO_L2_MSGS_PER_BLOCK], [Field; L1_TO_L2_MSG_TREE_HEIGHT], AppendOnlyTreeSnapshot) { + assert( + start_index < PRE_EXISTING_L1_TO_L2_LEAF_COUNT, + "The fixture cannot pre-fill that many l1-to-l2 leaves", + ); + + let mut pre_existing = [0; PRE_EXISTING_L1_TO_L2_LEAF_COUNT]; + for i in 0..PRE_EXISTING_L1_TO_L2_LEAF_COUNT { + if i < start_index { + pre_existing[i] = (i + 1) as Field * 7; + } + } + let tree = SingleSubtreeMerkleTree::::new( + pre_existing, + ); + + let mut leaves = [0; MAX_L1_TO_L2_MSGS_PER_BLOCK]; + for i in 0..MAX_L1_TO_L2_MSGS_PER_BLOCK { + if i < num_msgs { + leaves[i] = (i + 1) as Field * 100; + } + } + let previous = AppendOnlyTreeSnapshot { + root: tree.get_root(), + next_available_leaf_index: start_index as Field, + }; + let frontier_hint = tree.get_sibling_path(start_index as Field); + let new = append_leaves_to_snapshot::( + previous, + leaves, + num_msgs, + frontier_hint, + ); + (previous, leaves, frontier_hint, new) + } + pub fn build_out_hash_tree_for_insertion( self, slot_number: Field, @@ -315,11 +379,19 @@ impl RollupFixtureBuilder { ) -> BlockRollupPublicInputs { let slot_number = self.start_slot_number; - let in_hash = if start_block_number == self.start_block_number { - self.get_in_hash(slot_number) + // Only the first block of a checkpoint (the leftmost leaf) carries `is_first_block`. + let is_first_block = start_block_number == self.start_block_number; + + // The message sponge threads across the checkpoint's blocks. The leftmost block starts from empty; every block + // ends at the checkpoint's accumulated sponge (in the fixture, only the first block absorbs, so the sponge stays + // constant for the non-first blocks). This matches the transitional wiring where the first block carries the + // whole checkpoint's bundle. + let start_msg_sponge = if is_first_block { + L1ToL2MessageSponge::empty() } else { - 0 + self.get_msg_sponge(slot_number) }; + let end_msg_sponge = self.get_msg_sponge(slot_number); BlockRollupPublicInputs { constants: self.get_checkpoint_constant_data(slot_number), @@ -331,7 +403,9 @@ impl RollupFixtureBuilder { end_sponge_blob: self.get_sponge_blob(end_block_number), timestamp: self.get_timestamp(slot_number), block_headers_hash: self.get_block_headers_hash(end_block_number), - in_hash, + is_first_block, + start_msg_sponge, + end_msg_sponge, out_hash: self.get_out_hash(end_block_number), accumulated_fees: self.get_fee(end_block_number), accumulated_mana_used: self.get_mana_used(end_block_number), @@ -371,6 +445,10 @@ impl RollupFixtureBuilder { checkpoint_header_hashes, previous_out_hash: self.get_out_hash_snapshot(start_checkpoint_index), new_out_hash: self.get_out_hash_snapshot(end_checkpoint_index + 1), + // The chain spans this checkpoint range; consecutive checkpoints chain because each range's end + // (`get_inbox_rolling_hash(end_slot + 1)`) equals the next range's start (`get_inbox_rolling_hash(start_slot)`). + start_inbox_rolling_hash: self.get_inbox_rolling_hash(start_slot_number), + end_inbox_rolling_hash: self.get_inbox_rolling_hash(end_slot_number + 1), fees, start_blob_accumulator: self.get_blob_accumulator(start_slot_number - 1), end_blob_accumulator: self.get_blob_accumulator(end_slot_number), @@ -380,13 +458,26 @@ impl RollupFixtureBuilder { pub fn get_parity_public_inputs(self, slot_number: Field) -> ParityPublicInputs { ParityPublicInputs { - sha_root: slot_number * 85831493, - converted_root: self.get_l1_to_l2_message_subtree_root(slot_number), + start_rolling_hash: self.get_inbox_rolling_hash(slot_number), + end_rolling_hash: self.get_inbox_rolling_hash(slot_number + 1), + // The message sponge resets per checkpoint, so it starts empty and ends at the checkpoint's accumulated + // sponge — the same value the block roots reach across the checkpoint. + start_sponge: L1ToL2MessageSponge::empty(), + end_sponge: self.get_msg_sponge(slot_number), + num_msgs: 7, vk_tree_root: self.vk_tree_root, prover_id: self.prover_id, } } + /// Deterministic non-empty message sponge for a checkpoint, shared by that checkpoint's block roots (as their + /// end sponge) and its parity root (as its end sponge), so the checkpoint root's equality check passes. + pub fn get_msg_sponge(_self: Self, slot_number: Field) -> L1ToL2MessageSponge { + let mut sponge = L1ToL2MessageSponge::new(); + sponge.absorb([slot_number, slot_number * 7, slot_number * 13], 3); + sponge + } + pub fn get_sponge_blob(self, block_number: u32) -> SpongeBlob { let mut sponge: SpongeBlob = self.make_fixture(self.start_slot_number, block_number, 661); sponge.sponge.cache_size = 0; @@ -455,8 +546,8 @@ impl RollupFixtureBuilder { tx_or_block_or_slot_number as Field * 60415 } - fn get_in_hash(_self: Self, slot_number: Field) -> Field { - slot_number * 94297 + fn get_inbox_rolling_hash(_self: Self, slot_number: Field) -> Field { + slot_number * 917231 } fn get_timestamp(_self: Self, slot_number: Field) -> u64 { diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml index 9f03a7f168e9..ef77ac854d04 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-root/Prover.toml @@ -483,11 +483,13 @@ proof = [ ] [inputs.previous_rollups.public_inputs] + start_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_inbox_rolling_hash = "0x00a48b67f417042d5231ac634d609fe03a3884c4757a2afe457a7d1c6ca063ba" checkpoint_header_hashes = [ - "0x003f28245501cd83312b059b7469c9efcbd17cdf1b87748a6684380140e8b8f4", - "0x004395c583aa5d8b61d95de30020015595c6ff15a98a908376053c285e760047", - "0x001610d9516c5c3da43228cf8c78b4f8b0fbc41ac4fb52e8c263f5389f0c39c2", - "0x00cc4a04e2f982d4a235549d9cea86e657f0f84a2624baed667bc007ac6adbbf", + "0x00035c9310226ee7aee14a5aead32b294ffaaed741adcbec5a6326c4b9f99264", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -519,51 +521,51 @@ proof = [ ] [inputs.previous_rollups.public_inputs.constants] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x1842a814b068f699565f4df77ab9139f1cfab687ef959bf92ba0bb3adf93d8dd" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000009" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x02b768bc715afcefe7acc2a4394dc1ec3d36e9051f52662c42c795597ad03956" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" + root = "0x2273e2d62f8531ba33939e5dc5790c5e03aeaa738012eb9fb81c0b51c2b0f5b6" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" [inputs.previous_rollups.public_inputs.previous_out_hash] root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.new_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" + root = "0x00aab5a9def4ce98b37101d06c1371e6978c474b666624b56da1ebeec25ba39d" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000198e45581dc500" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000030e6f24b2fa80" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x00000000000000000000000000000000000000000000000000028969d4e88180" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000002c99033813280" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -772,15 +774,15 @@ proof = [ ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x003c3d7634e4804fa2d1579984557d5e0f193db092992632750e0f02435c536e" - z_acc = "0x2e5590725ce897557051bcd8e235179ca85612f775e25899d41e2e6d429bab8f" - gamma_acc = "0x1a92da981183c7c99558cbbf36266f907c24981e57e22325cd913d6c0b511f0c" + blob_commitments_hash_acc = "0x00be5a90788e9a2b1a2b3d3291074553390f4e85e143b9cdf1e90b559dadd9f5" + z_acc = "0x0323ea98046e7dfb23bb8afa0e3b88cb5418dc5857c0660552ba8cfafc9d86a0" + gamma_acc = "0x2c28ff8aec12721f8f95289aaadd60790f5a0fdb21abe9ad4bc7b619fdd29837" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0x51460e3323b2335762b279af363d8f", - "0xfb02d1de4f7cbf4de93446d5162177", - "0x64ca" + "0x6e84f8217c58b53c360b64b4e24482", + "0xf7cd75a85811a7f2baf55323c1b802", + "0x01f2" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] @@ -788,168 +790,168 @@ proof = [ [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0xe30b704d93a13e80d6b61851ffbb42", - "0xa6582dfbfe7c7fb2e4cb46ca26a4a9", - "0x58d8f47578a73f78ec55404027113b", - "0x088313" + "0x4da4aae2c5530b730c9c5f26ffc9e8", + "0xe4c843f7701b89c766d5f201f3bd61", + "0xbd0346ed5ed1dbda59247d62c3fef7", + "0x00ba3b" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0xac35297801db6e89bc7c01cccf1c2c", - "0x5a8cdb9c6da878c061855cde01bada", - "0xf8ade47e6b400bf343963bce4206ac", - "0x02c72c" + "0x03d1aa5a043df52839c019d32d9f64", + "0x4724dffeb46756ed087769f4404d1e", + "0x736cf13e91bbeda8581787d66646c2", + "0x10c72e" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xf3d1444be1d67a5ae57a7a5347f063", - "0xd40b5f08dc03ca05b5c582e87600d8", - "0x11f8" + "0x96bd142e5d415a97f10cda549bd108", + "0xa9a5bde904e677ea35648dbc58905b", + "0x262e" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" + z = "0x0323ea98046e7dfb23bb8afa0e3b88cb5418dc5857c0660552ba8cfafc9d86a0" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x96bd142e5d415a97f10cda549bd108", + "0xa9a5bde904e677ea35648dbc58905b", + "0x262e" ] [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000013" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000011" sibling_path = [ - "0x1e7976567fc760772e92450d8ac6f02ef47edb23baa7459dc33c0ceb6c88497d", - "0x23545acba1dbc9308d912f371ee6d2f31ab1da4eccf3d019473d8ab7205adf27", - "0x035c573a1f2634405482213a2b805e186d6b81073e2b7a5bd3f64c2e4e8bc21e", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x25ece109d362b4b8dbb8966f2fe94ddb217a6c63f7ac83b96c4f385ab2d03cf5", + "0x151ec971d9b291d78b1d405b001fc9a60d1bc918252466d6a4774554135802ac", + "0x29c4f2a137ff5c5b54eb911f6add38eb5ec9d139f54d95a7db432abbae472256", + "0x02dfab3acbc7708b1b3654912e946fe846568b8cb0e8af8da6a1845278664e55", + "0x2a6f812baf5176557f2f41b40fa4cb962d52e2e0c8ff7bf6b1fd7fe3a4223ac2", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x00000000000000000000000000000000000000000000000000000000000000a5", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000f3dd0027a9bf9c90623274e2cc4875fbfd", - "0x00000000000000000000000000000000002a19be4ee556f81b7cbc51e13981b9", - "0x0000000000000000000000000000006d291b56c49351fc5a528fd75fbbf1c83b", - "0x00000000000000000000000000000000001ed738716857bcff1d30c099caddf0", - "0x000000000000000000000000000000e70468dab546f5284ddfc417d7478d50a7", - "0x00000000000000000000000000000000002634edf447b025ff7b0f031c1d6898", - "0x000000000000000000000000000000cb51451d962a6b1373a5566882e3bd7612", - "0x000000000000000000000000000000000022d2ad6385d6c74a2288c40f27ebba", - "0x000000000000000000000000000000259e820c9844f19c90497d75ccce660ac6", - "0x000000000000000000000000000000000016eef7f67298ae6159c36a0fa3b2fe", - "0x00000000000000000000000000000061222490df831b2aa7b8aa9af315e096da", - "0x00000000000000000000000000000000002bb5ae61acd094f19640ebfbff6ef5", - "0x00000000000000000000000000000067fcdc39c34668b73db34138fa2a13d42b", - "0x000000000000000000000000000000000005edc94bba74d353b164ad0f90b1a5", - "0x000000000000000000000000000000743f06c041c3427babcaca40dd044d4600", - "0x00000000000000000000000000000000002caddbb3ed06bc9a68b956e71b7b8c", - "0x000000000000000000000000000000298d5ff6c30fa2c6aaa462da0b8026dcf6", - "0x00000000000000000000000000000000000dbf750297b0120823ac105092b636", - "0x000000000000000000000000000000eefbda437339cd7ccd82615d7fc3055b8a", - "0x0000000000000000000000000000000000095a30873abbdcab60be8cb914002b", - "0x0000000000000000000000000000005fca3b5450b4a333f804ed504abb5f222a", - "0x000000000000000000000000000000000014c5cbb7c9e0298a8e3bf402349a7c", - "0x0000000000000000000000000000005f47381b518fe4c3b7a18b19e681bbbfc9", - "0x000000000000000000000000000000000003d309068671af359529cf66887086", - "0x000000000000000000000000000000b394609589f105b795e4766958d7e47627", - "0x00000000000000000000000000000000002701a644dee43ce6f48a05ca60148d", - "0x000000000000000000000000000000f9c3f63945c15da781a5d4f67a4e13e279", - "0x00000000000000000000000000000000001b1b6eda68dcd4d392f18b3239267e", - "0x0000000000000000000000000000004020a1c978fdc4b03b701c5ae4342661e2", - "0x00000000000000000000000000000000000fa4d30bed48c7aef7caeb872e6b46", - "0x0000000000000000000000000000006bc830878b123b5a8039753f5fc28f9f56", - "0x00000000000000000000000000000000000686c78e1454d26d0298ab5a461bef", + "0x00000000000000000000000000000036d2157369305013c8479b661e9bffe8ff", + "0x00000000000000000000000000000000002c0aec83bfae212c5618a01dc5032f", + "0x00000000000000000000000000000079637952a9432b6c04de26b960419c2406", + "0x000000000000000000000000000000000016f81bd583fca03c4d6921866b2f4e", + "0x000000000000000000000000000000605da43776fb998e8f5a8f8f59493d1bdf", + "0x0000000000000000000000000000000000054fa1fe31a30b843030aa85747cc3", + "0x000000000000000000000000000000430e08eab747886838a73b7eb93d6a7049", + "0x00000000000000000000000000000000000fc7c1272750c481ab3aa64f760871", + "0x0000000000000000000000000000007b6c487b081cd42381fc2c5f460756fabf", + "0x00000000000000000000000000000000001c13765984a1558018db6833e2c706", + "0x000000000000000000000000000000e006291b1d02535c4f3f8796a584e253a3", + "0x00000000000000000000000000000000001497cc705bbd9bfaa96f7211db87d3", + "0x000000000000000000000000000000610db7fe4bfe6171822260ba25cf7fd7e5", + "0x00000000000000000000000000000000002cf5b96da296aa3d0d33e0897a3671", + "0x000000000000000000000000000000dbe98ae829fef8e64f045d80ed2aa380c6", + "0x000000000000000000000000000000000008c6b12c1e28f07325f3bc43328181", + "0x000000000000000000000000000000e11a616a8bf2e45900cb16ef7a387547a1", + "0x00000000000000000000000000000000000899d4536ca132a3255187d4bdcd3a", + "0x000000000000000000000000000000d7409e9b99d91622a75f1936d63d13ce21", + "0x0000000000000000000000000000000000010eb0051652a1e12fd910841b7380", + "0x000000000000000000000000000000a4d763a025d63693086d5e42b4dd09c983", + "0x0000000000000000000000000000000000057f7ee27662a1a3a797e9d5be3b23", + "0x0000000000000000000000000000000c00705cf8d7cb905d5bbea77f847bb1a1", + "0x00000000000000000000000000000000000ad3c7dbc5a0d102219b06b5425fab", + "0x0000000000000000000000000000003b3d6b7d7dfa41a114fdd2bb06d47fd826", + "0x00000000000000000000000000000000002e64810b091045697d64d9cd1590c9", + "0x0000000000000000000000000000004d92a88e43bae24502d046bf0ed7fe0623", + "0x0000000000000000000000000000000000168ebacff5cdf9c2ece95c81807f81", + "0x000000000000000000000000000000af15f3f90f76892655ae5ea104ab710df0", + "0x000000000000000000000000000000000012c00b8679fb65c6261e29481d20e1", + "0x00000000000000000000000000000097d1e3059e77dbcb559ae7ec59f4f1799c", + "0x00000000000000000000000000000000001bdc813cfa0a8f0b5b5dce352bfa5c", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x00000000000000000000000000000004c85ca29bf8c683168a980c9a3397e522", - "0x00000000000000000000000000000000001e30d912e04a18b2014b734fb6c293", - "0x00000000000000000000000000000068c88aa053154f24a7cd3a9e5062ce9533", - "0x00000000000000000000000000000000000f1013091f36c091808d58cf427546", - "0x000000000000000000000000000000f09823147b5a2f1315af76f84626faacc5", - "0x00000000000000000000000000000000002cfa957d32526624e97ec08d0763b4", - "0x00000000000000000000000000000095f75874399828c93364b7d272bdd91ad8", - "0x0000000000000000000000000000000000169d8b404b534c0a246767dc1b6cc2", - "0x000000000000000000000000000000c5cafa7e75b7c69af15b1a1e1bc905d603", - "0x00000000000000000000000000000000000056634d879eaebb861aab7f6f754f", - "0x00000000000000000000000000000075b6c4cb8ee2d596e52fe1b3d9405cb208", - "0x00000000000000000000000000000000002bf855c3a58ee0e60041a921be728b", - "0x000000000000000000000000000000a4e608225e21e96a15388fd855afcb8bd9", - "0x000000000000000000000000000000000001eb45674390c99d0df7b66959f3a6", - "0x000000000000000000000000000000da7a7c3519858b8c78980a95a3c0ace91c", - "0x000000000000000000000000000000000004b30cecdd534cbfb3c9ffdf2ef2c3", - "0x0000000000000000000000000000003a35ed1dc0d1ff7aae4209529a34930921", - "0x0000000000000000000000000000000000210c99ed727129a1d40e9f9a7adcaf", - "0x000000000000000000000000000000fd35d6cbde8ca6b8e64652a47a495d4eac", - "0x000000000000000000000000000000000019c18ce002d04e602c1607ffe9a256", - "0x0000000000000000000000000000005e643893fe0397c603829ee5eec8cd1b57", - "0x00000000000000000000000000000000000e58f7d675efa17dc8fb8784a3d3ec", - "0x00000000000000000000000000000001a62a5467501b9ba3f907057f217c5842", - "0x0000000000000000000000000000000000085ee99d6a97c76d6b87ed12e998dd", - "0x00000000000000000000000000000019fa1cc7006ec07a362874e5899347d3b5", - "0x00000000000000000000000000000000002dd21ac74693f12eae15e19ac3f4e9", - "0x0000000000000000000000000000005a1ea35dfbcf743b3ce11ce2e8629f19e6", - "0x00000000000000000000000000000000002fa64b3bd8b9921723317b2b3bc016", - "0x00000000000000000000000000000000c8749e8b44fbafa0cb783908f71ca43c", - "0x00000000000000000000000000000000000452edc05eda610ee588e3bf496292", - "0x000000000000000000000000000000d9780c71504a1870651ec671b124a36f6f", - "0x00000000000000000000000000000000002e594354b67060c97f311225fa34ae", - "0x000000000000000000000000000000170753b4fb55d2a839346eaa20855c2ce7", - "0x000000000000000000000000000000000006c3bdda1a4d3ece70c8a57f1f0263", - "0x0000000000000000000000000000003dd4b48e3e37919c109c3b18cc3b2265a7", - "0x0000000000000000000000000000000000152eca2c022ee0e6340d62891c5228", - "0x00000000000000000000000000000027857e742687fcbb8a1776c44fc89bd992", - "0x00000000000000000000000000000000000d43515b1f31d2c281a679e9a60597", - "0x00000000000000000000000000000021a6c141043aba99a2455fe9d3162aea31", - "0x0000000000000000000000000000000000116eca793064aa52816099d7b1b856", - "0x00000000000000000000000000000080d8af2c3a7eb09247b224d69feb59db7f", - "0x00000000000000000000000000000000000cdc3dc774bc9cf885f22340c55e34", - "0x0000000000000000000000000000009b3dce5761fcef7f34b7daefcac691acfc", - "0x0000000000000000000000000000000000175cc08fc63b1b7e3d01ac07be17ba", - "0x0000000000000000000000000000000fdb0290862616c081ab8bcf9871c309c2", - "0x00000000000000000000000000000000002bff3e69b075b3aa3104ab8b4b0c55", - "0x0000000000000000000000000000003b79cb77993965a3aadd9ca90e23180bdf", - "0x00000000000000000000000000000000002b82418b647333b049ddb4a0f00036", - "0x0000000000000000000000000000003ee1123375c63e3aa50d9b10730a110f2b", - "0x000000000000000000000000000000000029a5aef768ee4d574df39792435c39", - "0x000000000000000000000000000000b04cfb4ff8a6a6f75c3c12e7c3907fe47c", - "0x000000000000000000000000000000000007e07a88f0efa047b6d1159e5433c6", - "0x0000000000000000000000000000000380f8a411e8cd6729fc91b78f0a7e30e4", - "0x00000000000000000000000000000000002c12b6bf8709a904fa3125c44e700f", - "0x000000000000000000000000000000cd7ca3e9ed8bb9a6121f522023dfa8b26e", - "0x0000000000000000000000000000000000283538b42da44b4bec7290be552dfd", - "0x000000000000000000000000000000662f3ca47840d128223a7eccf2f8bfdc96", - "0x000000000000000000000000000000000024d658e9e6acb83221331c656807d3", - "0x000000000000000000000000000000f85d8aab4282d54e5f0eeb7c2135fd427a", - "0x00000000000000000000000000000000002599d73eb9093c7a13848d307874a0", - "0x000000000000000000000000000000ff7ddb01808894d4e1f81d238eb5869363", - "0x00000000000000000000000000000000000ae65f87c37152d4c5e012874d5bf0", - "0x0000000000000000000000000000006793e0f1bf87ca4917287881df03901ad7", - "0x000000000000000000000000000000000005e93e00058f2566596a419f9dc5ce", - "0x000000000000000000000000000000767da639e35d5d1ef71478a950cf288513", - "0x00000000000000000000000000000000002afd252e8615e7eeda46b48225961d", - "0x0000000000000000000000000000007def46ee76f6ea569e02646c04537d31e0", - "0x00000000000000000000000000000000001fe6504150f81283f95b42498506a4", - "0x000000000000000000000000000000a4c1f600b7652e539371dc66a0e235337d", - "0x00000000000000000000000000000000000b101b006770c17530fa8330b6dc04", - "0x00000000000000000000000000000074377052aa69f94a755cde3f9ce8138ce2", - "0x0000000000000000000000000000000000165266c7414a3b474914dba91316bd", - "0x000000000000000000000000000000a8ed603c54c796e5ec3c7cc3caa2d33449", - "0x0000000000000000000000000000000000043a3877cf735247a6a67190477bea", - "0x000000000000000000000000000000d63cbc50845d49f0709bb8eff860f4a382", - "0x0000000000000000000000000000000000270e1c50ec474ac2fd022ba73c40f2" + "0x000000000000000000000000000000a720f425c05a4825b46e027afd0a6fd671", + "0x00000000000000000000000000000000001fcf1da494426fbf2621511cbd70eb", + "0x00000000000000000000000000000018a2e7cbf823397368dc4b87db4c644619", + "0x0000000000000000000000000000000000052e92af9a02920e4e179c4f67214b", + "0x000000000000000000000000000000825a267e5cfd171426338e2d9b3b9838d1", + "0x0000000000000000000000000000000000171fc66ae3ce33b767fbab8d5fbbdd", + "0x000000000000000000000000000000d5c49f2d00924b287efe89dea6879ff77b", + "0x000000000000000000000000000000000011f85546a9cd87a6b2b635c4771b94", + "0x00000000000000000000000000000027f61f3b9d8cd56f2a70ca35c2ba7e31a8", + "0x0000000000000000000000000000000000025050331a4428aed5b520dca6bd63", + "0x000000000000000000000000000000a41247254c9c0a191ebf6b4b27818cc313", + "0x00000000000000000000000000000000000be606e57a400a3f8579ce40332a7a", + "0x000000000000000000000000000000ffccc8bdab452ad48ae9f3a068de887c8a", + "0x00000000000000000000000000000000000c2a7bdf80e4f60a5ac20e3b9c6544", + "0x000000000000000000000000000000b7c80a222c2a6ae46bc9f64e581bf7271e", + "0x0000000000000000000000000000000000205b8c3084d3f5bb5db7d9590acaec", + "0x0000000000000000000000000000002a609fcebe46daf0c552761c19228be9c5", + "0x00000000000000000000000000000000000947b7d62dd0fa528f93ad462244bb", + "0x0000000000000000000000000000009dff2728b1e8ece8f977dd5f17c2c78105", + "0x00000000000000000000000000000000002d440b35f618fde819e1506404b866", + "0x000000000000000000000000000000ac37642801b1ef63703d72c94a15203772", + "0x00000000000000000000000000000000001bbe645b815c8305a5626fd64ed05c", + "0x000000000000000000000000000000ca1770abe5384c224b2cb8623ef53a891f", + "0x00000000000000000000000000000000000ea2e1c7b5a6b648868a1fbda389d5", + "0x0000000000000000000000000000008d6c11553db2a55004627c023b0e249573", + "0x00000000000000000000000000000000001cd0294ac6bce284bfd5e7c2a052a4", + "0x000000000000000000000000000000452503cff155bfcdc7a19e5f332b377870", + "0x0000000000000000000000000000000000150185e04d84d9b6ffbd2bb9052295", + "0x000000000000000000000000000000f3d6ba952c2b5b06d98e0b38222a510fce", + "0x0000000000000000000000000000000000277241267c9a7ff692b8f4a91039a7", + "0x000000000000000000000000000000a6e09a49d41c587395657bf22bae9f860a", + "0x00000000000000000000000000000000001ccb77f5c0bfe18ce719db97108493", + "0x00000000000000000000000000000009e276023bea7cb392a3ff9f7e2ecf364e", + "0x00000000000000000000000000000000001eb222312f45556a06e2c1a09eff73", + "0x00000000000000000000000000000017439a8fd7a316e174faabb48101bbf30e", + "0x00000000000000000000000000000000001b50b9d5fe4c43d61fc72fb8667869", + "0x00000000000000000000000000000094d24031f5c3c0f952282a186f2b2771a0", + "0x0000000000000000000000000000000000114af0d951e8098442447c796dd53d", + "0x00000000000000000000000000000043ff61c245cfed1afca45f10338f26f398", + "0x000000000000000000000000000000000029d3ccaf2bb1347618eab89bd09dff", + "0x000000000000000000000000000000151aeefea0cabef34bc27be650b1ea310a", + "0x00000000000000000000000000000000000f2f9770fce59054a8f14ccc9cfc71", + "0x000000000000000000000000000000344430ca97860eec6bef9811cf0248309d", + "0x00000000000000000000000000000000002fc0aa17a61a27fb1695ec956e1762", + "0x000000000000000000000000000000ea7eab06aeb8bcdd1119cd6dc0c4d5a928", + "0x0000000000000000000000000000000000009802fdcab28040b969b68ab9304a", + "0x000000000000000000000000000000be464a1807845060ccd8ed02952dff3c42", + "0x00000000000000000000000000000000001261948934bec645944b279144c0c6", + "0x000000000000000000000000000000e939eb8746a3940d252f066182db1ebaea", + "0x00000000000000000000000000000000001893928a8f5c0b449cfedddc616208", + "0x000000000000000000000000000000b547fa88f4cbcf2cc699e010df114ef488", + "0x00000000000000000000000000000000001855c0805882b38a94f77c4954ee63", + "0x000000000000000000000000000000941b647c5ae6e7f56b546111c81c74d0ce", + "0x000000000000000000000000000000000008bf6ae4485da8f6b85da2294eb827", + "0x000000000000000000000000000000745670ce1763611988377f9ac6564eb5fd", + "0x00000000000000000000000000000000000301e521f41d74a9ecb4d01c0420a6", + "0x000000000000000000000000000000cecdcb68e1d824e8ff0e1141bbb7241469", + "0x000000000000000000000000000000000024268af5f26bc3f68c9e01f1bb5f8c", + "0x0000000000000000000000000000000f14a7eb43fb641f0df2376be3c3142503", + "0x00000000000000000000000000000000001b76722b102ed6e7047b2ae4e5e231", + "0x000000000000000000000000000000383ced98d5cec8a4402527be6f5e7051fe", + "0x000000000000000000000000000000000022bb60f3feb6266eb8162fa04f39f1", + "0x0000000000000000000000000000007bd40dd0a298fc81c05dd9fed45875e3c2", + "0x00000000000000000000000000000000001c15c8c22696761205c439f69d5901", + "0x000000000000000000000000000000ea1e1b77dbba23394273a0fcc91d2f0028", + "0x0000000000000000000000000000000000296071a24eb3b9fd36d48bde2d940b", + "0x0000000000000000000000000000004faa047a8080c62ba37675f1025770dd46", + "0x00000000000000000000000000000000002be549ad4ae6dd609c8d19d2eafcb2", + "0x000000000000000000000000000000474079f7ebdc0d8d3a9eb468fcca6ffc07", + "0x00000000000000000000000000000000002ec8274bbb27ccec0982e7a9a251e3", + "0x00000000000000000000000000000002fe71f79eed108e0a5d260e85a99a4421", + "0x0000000000000000000000000000000000141c12a891f86b645a5cd828da5765", + "0x0000000000000000000000000000002dc9a42df3d5364488b418d610251242b4", + "0x0000000000000000000000000000000000290e01132bc34d5e15b6e02b4a759e", + "0x000000000000000000000000000000c16b5a7cce01d055cf28364a3d018dd5d1", + "0x00000000000000000000000000000000001847d542cff1a613b4d76aa92254de" ] - hash = "0x1f58925ff616b4fd1e9957536f379ea1a3a79bad46033bd094797cf1000f5fa4" + hash = "0x157b40a6fa6e0c8b1aa9182c66ce9c22deec7a7a1507dabb4c78f3a05cb67dee" [[inputs.previous_rollups]] proof = [ @@ -1436,9 +1438,11 @@ proof = [ ] [inputs.previous_rollups.public_inputs] + start_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + end_inbox_rolling_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" checkpoint_header_hashes = [ - "0x0004d83706262d94ec97b0559d4e179a4f09a706bb9eb8b2058a66c51326acf6", - "0x002aac8a431c2893be6234fa1bad8e46feaa3f51f373e8257ae75b10d086b9eb", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1472,39 +1476,39 @@ proof = [ ] [inputs.previous_rollups.public_inputs.constants] - chain_id = "0x0000000000000000000000000000000000000000000000000000000000007a69" - version = "0x000000000000000000000000000000000000000000000000000000005fe47cc3" - vk_tree_root = "0x1cd59fb7641f17e0fe2998b3ebc3c3d71e3f4ad4eeb883be55e3bf04749fe247" - protocol_contracts_hash = "0x080e3881bdd4a4e78d52691e5543b50cf820f51baf52af42d7b58c9e15f96ec7" - prover_id = "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc" + chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" + version = "0x0000000000000000000000000000000000000000000000000000000000000000" + vk_tree_root = "0x0000000000000000000000000000000000000000000000000000000000000000" + protocol_contracts_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" + prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_archive] - root = "0x02b768bc715afcefe7acc2a4394dc1ec3d36e9051f52662c42c795597ad03956" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000d" + root = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.new_archive] - root = "0x253b8ea9561900b964ddb9bbc5e4545faa4fb79db30b2da3643242530c2ab4f7" - next_available_leaf_index = "0x000000000000000000000000000000000000000000000000000000000000000f" + root = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.previous_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000004" + root = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.new_out_hash] - root = "0x00c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af093" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000006" + root = "0x0000000000000000000000000000000000000000000000000000000000000000" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x0000000000000000000000000000000000000000000000000001646623a26e00" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] - value = "0x000000000000000000000000000000000000000000000000000083a35fe8cc00" + value = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.fees.recipient] - inner = "0x00000000000000000000000096a3970e323d4410d1f969fdea80c679edfca17f" + inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [[inputs.previous_rollups.public_inputs.fees]] value = "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -1687,219 +1691,219 @@ proof = [ inner = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator] - blob_commitments_hash_acc = "0x003c3d7634e4804fa2d1579984557d5e0f193db092992632750e0f02435c536e" - z_acc = "0x2e5590725ce897557051bcd8e235179ca85612f775e25899d41e2e6d429bab8f" - gamma_acc = "0x1a92da981183c7c99558cbbf36266f907c24981e57e22325cd913d6c0b511f0c" + blob_commitments_hash_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + z_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + gamma_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_blob_accumulator.y_acc] limbs = [ - "0x51460e3323b2335762b279af363d8f", - "0xfb02d1de4f7cbf4de93446d5162177", - "0x64ca" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x0000" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc] - is_infinity = false + is_infinity = true [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.x] limbs = [ - "0xe30b704d93a13e80d6b61851ffbb42", - "0xa6582dfbfe7c7fb2e4cb46ca26a4a9", - "0x58d8f47578a73f78ec55404027113b", - "0x088313" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.c_acc.y] limbs = [ - "0xac35297801db6e89bc7c01cccf1c2c", - "0x5a8cdb9c6da878c061855cde01bada", - "0xf8ade47e6b400bf343963bce4206ac", - "0x02c72c" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000" ] [inputs.previous_rollups.public_inputs.start_blob_accumulator.gamma_pow_acc] limbs = [ - "0xf3d1444be1d67a5ae57a7a5347f063", - "0xd40b5f08dc03ca05b5c582e87600d8", - "0x11f8" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x0000" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator] - blob_commitments_hash_acc = "0x002ef8497a6a3685caf08c21021103b7296ab9f749a488e56b8db55182d8d4ae" - z_acc = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" - gamma_acc = "0x1071981792a53848b917053086bc7150d9d1cf18ffa05498555c36810bcecafd" + blob_commitments_hash_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + z_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" + gamma_acc = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.end_blob_accumulator.y_acc] limbs = [ - "0xb60ca1feed35bf28340ef17cd871b9", - "0x698569825a1ff49eccccd108c34514", - "0x5410" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x0000" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc] - is_infinity = false + is_infinity = true [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.x] limbs = [ - "0x43aaf3d0c121b4d96780dd687e365d", - "0xededee37534fd55f1e3decf2d6631a", - "0x788976bdd69c9611dc7639f3de0668", - "0x165528" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.c_acc.y] limbs = [ - "0x7132fd22120449831964d6a5a42921", - "0xf87224d4a7813465361b659fbc6c27", - "0x7fc9439e7e2242a18bdfd802227a55", - "0x133ea3" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x000000" ] [inputs.previous_rollups.public_inputs.end_blob_accumulator.gamma_pow_acc] limbs = [ - "0xdc7bf8e5c80213b175acab6de8764d", - "0x2602f93c359de53d2a3f3a57561292", - "0x4978" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x0000" ] [inputs.previous_rollups.public_inputs.final_blob_challenges] - z = "0x1fdc12adc29013642cd3e65ed4fe6257a51f0de3dbf9aab308d2eb764d2e2a6c" + z = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.final_blob_challenges.gamma] limbs = [ - "0x3091f45075ebc6c0e8bd0d0b55148a", - "0xba36f4511ca8e170b8a14a64a7418f", - "0x070d" + "0x000000000000000000000000000000", + "0x000000000000000000000000000000", + "0x0000" ] [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000013" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000012" sibling_path = [ - "0x1e7976567fc760772e92450d8ac6f02ef47edb23baa7459dc33c0ceb6c88497d", - "0x23545acba1dbc9308d912f371ee6d2f31ab1da4eccf3d019473d8ab7205adf27", - "0x035c573a1f2634405482213a2b805e186d6b81073e2b7a5bd3f64c2e4e8bc21e", - "0x033c4d295fe10d44c10ab7dd6b98731454b30ab8a3b175477338750c07bc4023", - "0x234c347546637311dad66534e5274a6a5db5da51b51baab040dac88807024ce5", - "0x118d25fdd2c4cc96d5af69bd85930dd49d101d463e3f5ee9f2cc9236384b5d41", - "0x19dd00df005acafea7173682679ac59d437120260bc4c6179b6dc40d3154cfed" + "0x1d4e1314d2ee8b837cf3d658a023b01dc80e2d6f94fd2f5ad5b37811443d0603", + "0x134dc2249f9878bdf75a5a572675b039f9f9e266b28ce7a90adde9ef2d2e46e7", + "0x29c4f2a137ff5c5b54eb911f6add38eb5ec9d139f54d95a7db432abbae472256", + "0x02dfab3acbc7708b1b3654912e946fe846568b8cb0e8af8da6a1845278664e55", + "0x2a6f812baf5176557f2f41b40fa4cb962d52e2e0c8ff7bf6b1fd7fe3a4223ac2", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000015", - "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x00000000000000000000000000000000000000000000000000000000000000a5", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x000000000000000000000000000000f3dd0027a9bf9c90623274e2cc4875fbfd", - "0x00000000000000000000000000000000002a19be4ee556f81b7cbc51e13981b9", - "0x0000000000000000000000000000006d291b56c49351fc5a528fd75fbbf1c83b", - "0x00000000000000000000000000000000001ed738716857bcff1d30c099caddf0", - "0x000000000000000000000000000000e70468dab546f5284ddfc417d7478d50a7", - "0x00000000000000000000000000000000002634edf447b025ff7b0f031c1d6898", - "0x000000000000000000000000000000cb51451d962a6b1373a5566882e3bd7612", - "0x000000000000000000000000000000000022d2ad6385d6c74a2288c40f27ebba", - "0x000000000000000000000000000000259e820c9844f19c90497d75ccce660ac6", - "0x000000000000000000000000000000000016eef7f67298ae6159c36a0fa3b2fe", - "0x00000000000000000000000000000061222490df831b2aa7b8aa9af315e096da", - "0x00000000000000000000000000000000002bb5ae61acd094f19640ebfbff6ef5", - "0x00000000000000000000000000000067fcdc39c34668b73db34138fa2a13d42b", - "0x000000000000000000000000000000000005edc94bba74d353b164ad0f90b1a5", - "0x000000000000000000000000000000743f06c041c3427babcaca40dd044d4600", - "0x00000000000000000000000000000000002caddbb3ed06bc9a68b956e71b7b8c", - "0x000000000000000000000000000000298d5ff6c30fa2c6aaa462da0b8026dcf6", - "0x00000000000000000000000000000000000dbf750297b0120823ac105092b636", - "0x000000000000000000000000000000eefbda437339cd7ccd82615d7fc3055b8a", - "0x0000000000000000000000000000000000095a30873abbdcab60be8cb914002b", - "0x0000000000000000000000000000005fca3b5450b4a333f804ed504abb5f222a", - "0x000000000000000000000000000000000014c5cbb7c9e0298a8e3bf402349a7c", - "0x0000000000000000000000000000005f47381b518fe4c3b7a18b19e681bbbfc9", - "0x000000000000000000000000000000000003d309068671af359529cf66887086", - "0x000000000000000000000000000000b394609589f105b795e4766958d7e47627", - "0x00000000000000000000000000000000002701a644dee43ce6f48a05ca60148d", - "0x000000000000000000000000000000f9c3f63945c15da781a5d4f67a4e13e279", - "0x00000000000000000000000000000000001b1b6eda68dcd4d392f18b3239267e", - "0x0000000000000000000000000000004020a1c978fdc4b03b701c5ae4342661e2", - "0x00000000000000000000000000000000000fa4d30bed48c7aef7caeb872e6b46", - "0x0000000000000000000000000000006bc830878b123b5a8039753f5fc28f9f56", - "0x00000000000000000000000000000000000686c78e1454d26d0298ab5a461bef", + "0x0000000000000000000000000000001aa2e6a7eefcf67a1c54a49ff0a81aa790", + "0x000000000000000000000000000000000017203bebc1aa1938ef9268ea3ca89c", + "0x000000000000000000000000000000a61e1b17525b908a9f4b6a8376cf5fca7e", + "0x000000000000000000000000000000000012466ca65d98b691bbf931acfe1b7a", + "0x0000000000000000000000000000008b31bffcdde7c529f04c24902a1c2f0e78", + "0x0000000000000000000000000000000000242178a54cf9609bcb9195fd002ffe", + "0x000000000000000000000000000000d6512c0b39c067dd15e0580e5e4b2a567e", + "0x0000000000000000000000000000000000067c4c8b4b3f12889b70b91e76c429", + "0x00000000000000000000000000000097dd9450d1b681c88735875fcc6d0b4f61", + "0x000000000000000000000000000000000005c0627478cb8eac9ae816df6fbcda", + "0x000000000000000000000000000000c2a8966d4023907b10a1e714e9e8892b1b", + "0x00000000000000000000000000000000001ce75e6d831343969da02c1d02c600", + "0x000000000000000000000000000000ccccd71b8f35ae5cf291771d950f68f3da", + "0x000000000000000000000000000000000003c4d39cdc62445481623e62aee2eb", + "0x0000000000000000000000000000007866c0021c809de9466d440ed11ad06e2d", + "0x00000000000000000000000000000000001be4807329f829d87fe72bc72ea425", + "0x00000000000000000000000000000034db09f2a0954e121607b022f655bea165", + "0x00000000000000000000000000000000002fd4277bc2dc6982e34890d4b49682", + "0x000000000000000000000000000000f8cb23cce947a97193ae91204b3689fba9", + "0x000000000000000000000000000000000013cafea361342986c4d452947efe2b", + "0x000000000000000000000000000000cc44ebd033adff111038b46546004dcb75", + "0x00000000000000000000000000000000000d96f091add60f8747307f2d6f72f0", + "0x000000000000000000000000000000b3c22cb3f7c6722416b4b660c29fd79b94", + "0x00000000000000000000000000000000000b9289b001e07a165bf4d98cf60b31", + "0x0000000000000000000000000000005cc837a8b9babe98e7889b46f76641226b", + "0x0000000000000000000000000000000000290d6792db836056ee48c04d257023", + "0x0000000000000000000000000000007c315ccad12ec8ed76fdebae4a372267a3", + "0x000000000000000000000000000000000025ea4c55c9f64a9d9a29509137aea8", + "0x00000000000000000000000000000078ee5f9a2c619405dd3c7bdb0e09350100", + "0x00000000000000000000000000000000000b10e34e2703d335ff9a3a855df9a4", + "0x000000000000000000000000000000c834ba6990f3ecb2dbe630e41b9cadc7de", + "0x00000000000000000000000000000000001e589991bea6d97a496fcc27aa76a7", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x00000000000000000000000000000004c85ca29bf8c683168a980c9a3397e522", - "0x00000000000000000000000000000000001e30d912e04a18b2014b734fb6c293", - "0x00000000000000000000000000000068c88aa053154f24a7cd3a9e5062ce9533", - "0x00000000000000000000000000000000000f1013091f36c091808d58cf427546", - "0x000000000000000000000000000000f09823147b5a2f1315af76f84626faacc5", - "0x00000000000000000000000000000000002cfa957d32526624e97ec08d0763b4", - "0x00000000000000000000000000000095f75874399828c93364b7d272bdd91ad8", - "0x0000000000000000000000000000000000169d8b404b534c0a246767dc1b6cc2", - "0x000000000000000000000000000000c5cafa7e75b7c69af15b1a1e1bc905d603", - "0x00000000000000000000000000000000000056634d879eaebb861aab7f6f754f", - "0x00000000000000000000000000000075b6c4cb8ee2d596e52fe1b3d9405cb208", - "0x00000000000000000000000000000000002bf855c3a58ee0e60041a921be728b", - "0x000000000000000000000000000000a4e608225e21e96a15388fd855afcb8bd9", - "0x000000000000000000000000000000000001eb45674390c99d0df7b66959f3a6", - "0x000000000000000000000000000000da7a7c3519858b8c78980a95a3c0ace91c", - "0x000000000000000000000000000000000004b30cecdd534cbfb3c9ffdf2ef2c3", - "0x0000000000000000000000000000003a35ed1dc0d1ff7aae4209529a34930921", - "0x0000000000000000000000000000000000210c99ed727129a1d40e9f9a7adcaf", - "0x000000000000000000000000000000fd35d6cbde8ca6b8e64652a47a495d4eac", - "0x000000000000000000000000000000000019c18ce002d04e602c1607ffe9a256", - "0x0000000000000000000000000000005e643893fe0397c603829ee5eec8cd1b57", - "0x00000000000000000000000000000000000e58f7d675efa17dc8fb8784a3d3ec", - "0x00000000000000000000000000000001a62a5467501b9ba3f907057f217c5842", - "0x0000000000000000000000000000000000085ee99d6a97c76d6b87ed12e998dd", - "0x00000000000000000000000000000019fa1cc7006ec07a362874e5899347d3b5", - "0x00000000000000000000000000000000002dd21ac74693f12eae15e19ac3f4e9", - "0x0000000000000000000000000000005a1ea35dfbcf743b3ce11ce2e8629f19e6", - "0x00000000000000000000000000000000002fa64b3bd8b9921723317b2b3bc016", - "0x00000000000000000000000000000000c8749e8b44fbafa0cb783908f71ca43c", - "0x00000000000000000000000000000000000452edc05eda610ee588e3bf496292", - "0x000000000000000000000000000000d9780c71504a1870651ec671b124a36f6f", - "0x00000000000000000000000000000000002e594354b67060c97f311225fa34ae", - "0x000000000000000000000000000000170753b4fb55d2a839346eaa20855c2ce7", - "0x000000000000000000000000000000000006c3bdda1a4d3ece70c8a57f1f0263", - "0x0000000000000000000000000000003dd4b48e3e37919c109c3b18cc3b2265a7", - "0x0000000000000000000000000000000000152eca2c022ee0e6340d62891c5228", - "0x00000000000000000000000000000027857e742687fcbb8a1776c44fc89bd992", - "0x00000000000000000000000000000000000d43515b1f31d2c281a679e9a60597", - "0x00000000000000000000000000000021a6c141043aba99a2455fe9d3162aea31", - "0x0000000000000000000000000000000000116eca793064aa52816099d7b1b856", - "0x00000000000000000000000000000080d8af2c3a7eb09247b224d69feb59db7f", - "0x00000000000000000000000000000000000cdc3dc774bc9cf885f22340c55e34", - "0x0000000000000000000000000000009b3dce5761fcef7f34b7daefcac691acfc", - "0x0000000000000000000000000000000000175cc08fc63b1b7e3d01ac07be17ba", - "0x0000000000000000000000000000000fdb0290862616c081ab8bcf9871c309c2", - "0x00000000000000000000000000000000002bff3e69b075b3aa3104ab8b4b0c55", - "0x0000000000000000000000000000003b79cb77993965a3aadd9ca90e23180bdf", - "0x00000000000000000000000000000000002b82418b647333b049ddb4a0f00036", - "0x0000000000000000000000000000003ee1123375c63e3aa50d9b10730a110f2b", - "0x000000000000000000000000000000000029a5aef768ee4d574df39792435c39", - "0x000000000000000000000000000000b04cfb4ff8a6a6f75c3c12e7c3907fe47c", - "0x000000000000000000000000000000000007e07a88f0efa047b6d1159e5433c6", - "0x0000000000000000000000000000000380f8a411e8cd6729fc91b78f0a7e30e4", - "0x00000000000000000000000000000000002c12b6bf8709a904fa3125c44e700f", - "0x000000000000000000000000000000cd7ca3e9ed8bb9a6121f522023dfa8b26e", - "0x0000000000000000000000000000000000283538b42da44b4bec7290be552dfd", - "0x000000000000000000000000000000662f3ca47840d128223a7eccf2f8bfdc96", - "0x000000000000000000000000000000000024d658e9e6acb83221331c656807d3", - "0x000000000000000000000000000000f85d8aab4282d54e5f0eeb7c2135fd427a", - "0x00000000000000000000000000000000002599d73eb9093c7a13848d307874a0", - "0x000000000000000000000000000000ff7ddb01808894d4e1f81d238eb5869363", - "0x00000000000000000000000000000000000ae65f87c37152d4c5e012874d5bf0", - "0x0000000000000000000000000000006793e0f1bf87ca4917287881df03901ad7", - "0x000000000000000000000000000000000005e93e00058f2566596a419f9dc5ce", - "0x000000000000000000000000000000767da639e35d5d1ef71478a950cf288513", - "0x00000000000000000000000000000000002afd252e8615e7eeda46b48225961d", - "0x0000000000000000000000000000007def46ee76f6ea569e02646c04537d31e0", - "0x00000000000000000000000000000000001fe6504150f81283f95b42498506a4", - "0x000000000000000000000000000000a4c1f600b7652e539371dc66a0e235337d", - "0x00000000000000000000000000000000000b101b006770c17530fa8330b6dc04", - "0x00000000000000000000000000000074377052aa69f94a755cde3f9ce8138ce2", - "0x0000000000000000000000000000000000165266c7414a3b474914dba91316bd", - "0x000000000000000000000000000000a8ed603c54c796e5ec3c7cc3caa2d33449", - "0x0000000000000000000000000000000000043a3877cf735247a6a67190477bea", - "0x000000000000000000000000000000d63cbc50845d49f0709bb8eff860f4a382", - "0x0000000000000000000000000000000000270e1c50ec474ac2fd022ba73c40f2" + "0x000000000000000000000000000000d0d50af0bddcab0ed97122701d58270068", + "0x00000000000000000000000000000000000277e40a68ec404b450c141bb5d040", + "0x00000000000000000000000000000044addfcb623a146bc81a6e5523cf95b731", + "0x000000000000000000000000000000000004cf2654c61618fba84e111562cad2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000b00d67fbc2caa70fdd0bd3b337dd11b8ed", + "0x000000000000000000000000000000000016245a29ff339811781222b2740a74", + "0x000000000000000000000000000000abbfe0482d5c93d6349a709c58337fcb8d", + "0x000000000000000000000000000000000024c2a5fcb33c386f63fadf7a3ffb00", + "0x000000000000000000000000000000444001256044e0bf83954108525c07f8d0", + "0x00000000000000000000000000000000000a1fc8db190ab9d20829e6413925ed", + "0x000000000000000000000000000000431cc0a1600d5355297cc712bb4c2a422e", + "0x00000000000000000000000000000000002240c414b644cb8adfe16555116f5a", + "0x000000000000000000000000000000f09b1d8d8f55f61c67f867d9f334de9ab0", + "0x00000000000000000000000000000000001ffd5ee5f381d3e582b95979ce6338", + "0x000000000000000000000000000000f6a11e6609de1a389609bb85f1a84626f3", + "0x000000000000000000000000000000000017a6f1561d9b913c9989d7ca07f413", + "0x0000000000000000000000000000007248127e960f07383be9cb74ef2470cc0b", + "0x00000000000000000000000000000000002b96a06fab78b22fcace8b4070a989", + "0x000000000000000000000000000000324757a9f9265992aa248e34ed25e8133b", + "0x000000000000000000000000000000000003fa305e0b0804b2ee3c0f7603c5d7", + "0x000000000000000000000000000000eba8c64f7f53f2da452a3ec99147d827b6", + "0x00000000000000000000000000000000002a0b6329fd782bdb2e86c36a3c6582", + "0x000000000000000000000000000000fd97d949b09a00fd0d8db5d3b8bfa0b82d", + "0x00000000000000000000000000000000002b2881621ff875a9c4f802a0ad3efd", + "0x00000000000000000000000000000091002843edeae9e3cf15528a5999bbd350", + "0x0000000000000000000000000000000000289afffdcd7b17f51b6b6f7310414e", + "0x000000000000000000000000000000e6c14854c824b5342f1a57671dc954322a", + "0x00000000000000000000000000000000002b1188993dba8da6145250d8c18a6d", + "0x0000000000000000000000000000006fa41747fdec8819b6e899563259e5f3c6", + "0x000000000000000000000000000000000020f78d6cb618375a58d8039cbbe95a", + "0x000000000000000000000000000000bd81bfa81ae056999ab4f6de054e3067d4", + "0x000000000000000000000000000000000006c3ee65fcd76a731d9db949113260", + "0x000000000000000000000000000000c6b8f74f0c78b6e2a31d6950c7bdccf8f6", + "0x00000000000000000000000000000000000bbef400fb7ca9778f1d874ca581d6", + "0x000000000000000000000000000000366187bf840bb19f3b3f3a9cb668837016", + "0x000000000000000000000000000000000009c808ffdcd7ebd05c9c8a6c0b5fe2", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000008c2de12a23e5bc60f4fa838a0dadde0a89", + "0x0000000000000000000000000000000000232a4873260f5774bfa580e0ed8741", + "0x0000000000000000000000000000007af9d52d5c49322de98cd9f5bb718d6bfa", + "0x0000000000000000000000000000000000181e32ab40464653b89481cd801494", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] - hash = "0x1f58925ff616b4fd1e9957536f379ea1a3a79bad46033bd094797cf1000f5fa4" + hash = "0x00d92d4d619e34fd738729123258d13da4089df3e7fb376f985ba2cdf35332a4" diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml index 5523912ffe8d..bdf88f58fcbb 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml +++ b/noir-projects/noir-protocol-circuits/crates/rollup-tx-merge/Prover.toml @@ -484,27 +484,27 @@ proof = [ [inputs.previous_rollups.public_inputs] num_txs = "0x0000000000000000000000000000000000000000000000000000000000000001" - out_hash = "0x0018febbd74d861e38064a4ff9d3b5ed7a39b398576ef75e104848700819a700" + out_hash = "0x006bd7618b0cf7b40e3f107022eee2d411bcc5850fbb774dacc46a15957659c4" accumulated_fees = "0x0000000000000000000000000000000000000000000000000000000000000000" - accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" + accumulated_mana_used = "0x000000000000000000000000000000000000000000000000000000000006b6c0" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x26c404240cb9d3965fdd677de1d4ea1d907e460403e304ed198e839901a4cebc" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000002" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000001" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" @@ -531,110 +531,110 @@ root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000007" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922", - "0x18935581a8ed73d08ffd00386fba55ba6c89f3ab848a76b8fedfa9034cee0454", - "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" ] state = [ - "0x0f19f1d5a0d014c8f9cb5070b6a72c7efb81b4971bc364738cea68076cfc9128", - "0x1e62eaea4ad0390925cb2382c5f4dc22f4d23495e0890061050f08c37ca8c9cd", - "0x143fae3a86f2ed36eca31eccf44ce149d098395a86dd8c9d541a15c155870153", - "0x2643afd339189b520e780ca47df76348b0d58825939d38dd1b1b0df9e8239947" + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000060000000000000000000" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000000" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000552" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004cd" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7d1b34c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c" ] state = [ - "0x0df722e23d212237afafa5c3ad409696de00ed5a6d040df1df5741c30783ab8d", - "0x1f51a080b417c648bdba25c5f1effbb13ef3cb2b3ad1c9f2650b842f7e08534a", - "0x0d5006c76bcd6126118b6ad75ec54e789213be33b6785d56921ac5bee5198c1e", - "0x26682892f284a033692202f2db9ee5552a727e91de309eb4aa74c20894def508" + "0x18134bd9cba7d2cfc160875a460f388c06c9be8bd2bdad23202426c0d0d985ec", + "0x181719b331f5a865a1ab500c089896a3606636dc0006adcf508a05a0ce702ccc", + "0x2099effc3095782b2705ec21faff150c85134e7cfa6b04af5868e014a4b9020c", + "0x2d212822493f22c35892994822a04497feb3a4e5ed82d4733e7972f4bed1958a" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollups.vk_data] - leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" + leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000007" sibling_path = [ - "0x20ab775da5bb45344ffe17866237142b9321b97b2e93ccfb1c299476a262e0b5", - "0x2a9ef81b082ec4212c08eba71c46e645efc1ae573e9cca5b480785be9dcc4d21", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x1fc39d0a428c8536dbca551ea79848acf67d89d090fd8c643c7d90f2e8f32340", + "0x12ce5a49a1ceca53ada7bee003f929bbd65abaa74e8072a81f304c2c96c44e31", + "0x276f60617ee2c3b406af56bfe9216a7d99be56ad316ff557cee0446f08e14135", + "0x1dab7bce1884db3c7fa09243adb445f93156a1a0546582123d8c1d6c89e7fe41", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] key = [ - "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000000000000000000000000000000000000000000016", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001393476211d0127a80dce177bd2139b525", - "0x00000000000000000000000000000000000a64db7a774dad381e4034cb2457f3", - "0x000000000000000000000000000000d5fb425ef17d829bcbd2f2212397cc69ba", - "0x00000000000000000000000000000000002902ad5d5e880ce9d3ff8815ad1554", - "0x0000000000000000000000000000009b94b4b71ebf49ca1ccee622099eb37a96", - "0x0000000000000000000000000000000000217517f2a6d3c0ad2a63c69b28d392", - "0x00000000000000000000000000000038d8df60934ce84e0ed3e7f5ca09c1ee4d", - "0x000000000000000000000000000000000013384c8161e64209078ece69fcaa19", - "0x00000000000000000000000000000093c2a0c6ec49f39474bd6782c5cd6b01b2", - "0x000000000000000000000000000000000008ff5813561afc758759d27f19b55c", - "0x00000000000000000000000000000097291956465f3aa94d25b11bc567a6c287", - "0x000000000000000000000000000000000007f14a03af147b21368785d869ca98", - "0x0000000000000000000000000000006a811b91c5970c9c2acd7a754d7b7f9cb1", - "0x0000000000000000000000000000000000190a1ac15c24fdafc83b205b9a284b", - "0x000000000000000000000000000000b61bdc9c40c5c1e94e290d7b383b2ee122", - "0x00000000000000000000000000000000002f5117ca48de83b07881d30427d341", - "0x00000000000000000000000000000012095bbac1cead43059d0a230818a027b7", - "0x00000000000000000000000000000000001c7b3a018ad17b7cbb3752d56c6f80", - "0x00000000000000000000000000000018c18cff602c8434b90273cb1ff38dd751", - "0x000000000000000000000000000000000003bd5bfa0c05c005fcbde355422947", - "0x0000000000000000000000000000009dac7aa803151cb1966b812422755d8e9e", - "0x000000000000000000000000000000000010f818617b14b429abcd3acd46653c", - "0x0000000000000000000000000000007951c87d59a7b4319ddc32a19635675d94", - "0x000000000000000000000000000000000005be6b96d6eb897429b815388db99b", - "0x000000000000000000000000000000d7e7c851d3ba4e42b00b50dcb9a40159ff", - "0x00000000000000000000000000000000002750be703cf6981c927c48de088588", - "0x00000000000000000000000000000048b23b4fb077032ac487b882dec8a8c38b", - "0x000000000000000000000000000000000017150b214b8aa285fed8a5b374a4f9", - "0x000000000000000000000000000000416e099bfce67a459c5a20a4311705f6c4", - "0x00000000000000000000000000000000002b684b94d2f1f96e86dfad7af6171d", - "0x000000000000000000000000000000651160cf941fb73a15062e12bfc9e35804", - "0x000000000000000000000000000000000007a1bb9d8533d71515e6e3b5e6866d", + "0x00000000000000000000000000000002dae7e831ed78b9726034fdf56e583ace", + "0x00000000000000000000000000000000002b3f4d616e8027a20f8edc16cfbe3b", + "0x0000000000000000000000000000004c72b92cbd48ecea19ad5642f7d557f5a4", + "0x0000000000000000000000000000000000168654a45c7d8664e75623ab72ffab", + "0x00000000000000000000000000000083005b55cabaef097051546fbfd7685d43", + "0x0000000000000000000000000000000000085264859c243091d0290fee66961d", + "0x000000000000000000000000000000a3609a137f0c64e9af9d672c82bb879030", + "0x00000000000000000000000000000000002f2816311eb3afd6c30a91f05a906c", + "0x000000000000000000000000000000e4511cf49697e16a74e0d6730d364cd6e4", + "0x00000000000000000000000000000000000d9b15c1ab4aafa9870030fb1f01f1", + "0x0000000000000000000000000000006dde861e212bf26640ef1436d7bdc4f201", + "0x00000000000000000000000000000000001ffaf73c05b99d1722a697b54ea994", + "0x000000000000000000000000000000396ba274703ebf4a03e4339dbc26d099a0", + "0x0000000000000000000000000000000000022e3ee5ffc2dc0533c2bbeb9099ec", + "0x000000000000000000000000000000e6e227b60dc9057a88f8cb4471a9fea86a", + "0x0000000000000000000000000000000000246959db6c3a295438492d935eaacb", + "0x0000000000000000000000000000003191ffb83d7d42b1add187223d067540a7", + "0x00000000000000000000000000000000001c6597787b5ebaa53b48a9fecacda8", + "0x000000000000000000000000000000e9f6be3f78c38204280bc224a2fd27c65d", + "0x00000000000000000000000000000000001c3e420965e904cac372ef32dc7923", + "0x0000000000000000000000000000007da218400340a430b8cf011f7892173af8", + "0x00000000000000000000000000000000000a31a316504c8be7ae5701acb98ced", + "0x0000000000000000000000000000003cf75706f021e6a661df64ef16d9a42b55", + "0x0000000000000000000000000000000000177148b7da28c2bf2cfe5737c85963", + "0x000000000000000000000000000000e0bc19695db19d2b16f525fa63874ddd68", + "0x00000000000000000000000000000000000ad3d70c629c5446ac4b2065893923", + "0x0000000000000000000000000000001617d14d968bc2679b85973347963a6329", + "0x00000000000000000000000000000000002c77cb09381821d1d62a74c81bcafb", + "0x000000000000000000000000000000915addec4b02be7e5599bbb1f41fbb9e0f", + "0x000000000000000000000000000000000028bcf441b36723bf95e0be039533f0", + "0x000000000000000000000000000000954535ac3a2cb2b7ea19315aca8ffff3bd", + "0x00000000000000000000000000000000000473d4f91369383b78b9324f8d83a3", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bada1572761d2d57e5d206da78afa472c5", - "0x00000000000000000000000000000000000248453a876b49502a5a8259818f44", - "0x000000000000000000000000000000ec45f0511c4ef04800c3d31e152e9265de", - "0x00000000000000000000000000000000001fff1bef8afe963c3b78c3c2549ca4", + "0x000000000000000000000000000000a0309c5acf411dabd67697d4075710b60f", + "0x0000000000000000000000000000000000017125ed54d5f16d50c2be55f8d80b", + "0x000000000000000000000000000000c3884b62c59c37f43e8acad4f15afdba7a", + "0x00000000000000000000000000000000001a3bfaf919de7e9b9af2d6281c6374", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -655,60 +655,60 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000e379faf5ffdd383be5ce0f1ee38f5e73fe", - "0x00000000000000000000000000000000001429616496865cd170bc83c40d415a", - "0x00000000000000000000000000000066e08b7ad48415290d2ff590e84057e60e", - "0x000000000000000000000000000000000023a625e90ae9701e33c52be8f0d396", - "0x000000000000000000000000000000774fc954a6adaa4e4db1da6228184e1354", - "0x000000000000000000000000000000000015ca4073735e39fd5dc55567dc1068", - "0x000000000000000000000000000000fd9e5f594db01e4b2625e1e3dcfd400f6e", - "0x00000000000000000000000000000000000f4a392bbee96bddd468b2c9a18896", - "0x000000000000000000000000000000d28954aef28e666d63ee0fb401ab7bc1b6", - "0x0000000000000000000000000000000000253b48f95132d1a3183e26dbd56884", - "0x00000000000000000000000000000022887784410bf17c157fc004401281c342", - "0x00000000000000000000000000000000000a249d88427c50df84670228613493", - "0x0000000000000000000000000000000f495c15c8a9098c779fef9227f1c5a897", - "0x000000000000000000000000000000000016d74e40a54fe1961a01c0a275941e", - "0x000000000000000000000000000000a968320348365b69bc59ded07a855fb88c", - "0x000000000000000000000000000000000010c9846c3754b0fb4b4c9ab8d68cd3", - "0x00000000000000000000000000000088ee0f0a54893f8b1e8b56a7fa7bee9d4f", - "0x000000000000000000000000000000000021d14db4aa9ae9f88641b9336d9dba", - "0x0000000000000000000000000000000f46a800020405196bda0c07afe5154eac", - "0x0000000000000000000000000000000000062e98c038c271784c9fb61136242f", - "0x00000000000000000000000000000024ed87f3417bd5bbaa53682680b1b915c8", - "0x000000000000000000000000000000000003beb3d385de2c0a7a40cebe01d34a", - "0x000000000000000000000000000000f85b812b32412267c5221f3600eaa3f3d2", - "0x00000000000000000000000000000000000289ace5de4f3e7a721b5a184d1e76", - "0x0000000000000000000000000000002e30085e1c74fe70d1d2ab68faf0984ca4", - "0x00000000000000000000000000000000001adb7660db50eb3c9d70b137871b2f", - "0x0000000000000000000000000000008e05ae370a270eeb6d282e3bc2b7889cc3", - "0x000000000000000000000000000000000020e76f33b00bccd1f97095bece663a", - "0x000000000000000000000000000000d71d8a40f7c9f1984d513aa7eb1a895e6e", - "0x0000000000000000000000000000000000021aee4d83119d0af331d5893af9fe", - "0x000000000000000000000000000000dec3abe29c9aa4bf73251a0c748d11e9dc", - "0x0000000000000000000000000000000000153c1ed58f5394ad372869f471ca8b", - "0x000000000000000000000000000000bf4d6e6ed9dad1b05bd3d5cb3b3740d3e2", - "0x000000000000000000000000000000000006803b1ef715809ab5085220b7c284", - "0x00000000000000000000000000000041efece86e20c4323fb08d7aad7345c79c", - "0x0000000000000000000000000000000000096fab6acc87fe26e0eefb5660a7db", - "0x0000000000000000000000000000002d550983acbdea743f381bf4d55b8c6110", - "0x0000000000000000000000000000000000107455727dcf49837ee29622f4e9ae", - "0x000000000000000000000000000000a07bfb26d2f33a45866564f6fb630fc1b3", - "0x000000000000000000000000000000000004b58a9a3d784d5857e224b300b97a", - "0x000000000000000000000000000000c0f8d7d2fa6eac6b45b736e838db02e437", - "0x0000000000000000000000000000000000012728fef15749f6355802ac76d166", - "0x000000000000000000000000000000caa9dd21f786e491093e94a42326c20c4b", - "0x0000000000000000000000000000000000181c00a5273565ed45cde6516b7267", - "0x000000000000000000000000000000f791b0a7d2376523eebf266bd58c615a72", - "0x00000000000000000000000000000000001658c7b51e5eb76e58124a4bf26d30", - "0x0000000000000000000000000000007ffefc9b69f9b9f766f98d9390ad49a8f6", - "0x00000000000000000000000000000000002700900f023bdb2524f5ce218af8a6", - "0x0000000000000000000000000000001d12e2e9feedc5df84ac9cb8e405fc64ea", - "0x00000000000000000000000000000000001645d7c72fd8844ddf0659d2b77656", - "0x00000000000000000000000000000098eaadb9c8f156e98d8dfde6f90be22a80", - "0x000000000000000000000000000000000028291c89dafd88dced57d87f6d8ab7" + "0x000000000000000000000000000000af74c853140d3b0cf48ac5426ad44e3a5c", + "0x00000000000000000000000000000000000cb504c2196f73934d76e059397164", + "0x000000000000000000000000000000684b219a630e4770c224f7391ce903b574", + "0x000000000000000000000000000000000003d04c0a020da0ff25d4d81a4d60cc", + "0x0000000000000000000000000000003a547a2ea7e16e11451dbbeff89a46927d", + "0x00000000000000000000000000000000000fe460a80b11f07f28d016ffcbbdd5", + "0x000000000000000000000000000000ef84584cfec94dd3c5125887edc8b15648", + "0x00000000000000000000000000000000002775675418cc4ce82c6c45ee105a60", + "0x000000000000000000000000000000a78629fdc8d0021839d214273a985802a3", + "0x000000000000000000000000000000000010a06e7102f85337eb4c8b60d97c25", + "0x000000000000000000000000000000518765c5253492c980ea80aac7e9986f75", + "0x00000000000000000000000000000000000a622d7d27836ced89d7a2c1ff2967", + "0x0000000000000000000000000000006460b6c05ba8ae4c71040cd807a630f6d8", + "0x00000000000000000000000000000000002879f62ac90caf8d067aa57f0a2cb6", + "0x00000000000000000000000000000071bf565e74a124d3587a0d63adc7f29b32", + "0x0000000000000000000000000000000000122c536450106d4844375b13d9ba2a", + "0x0000000000000000000000000000009133f308fcba6ba2e78c78f1540f56e805", + "0x00000000000000000000000000000000001cabb18101f26c315098c437934f63", + "0x0000000000000000000000000000002622d42a77800505a1cb7d4d76702cf100", + "0x000000000000000000000000000000000006b02f8ebd2ac84a9c6991c39dab4d", + "0x00000000000000000000000000000018d1dbeba31941616af05128326ec86ea5", + "0x000000000000000000000000000000000007c9f24379b75927ccb4d7ad3b8c82", + "0x00000000000000000000000000000092277632f048f820823839ad073172915a", + "0x00000000000000000000000000000000000a09bb921f8ca99cb19752b1bac91d", + "0x000000000000000000000000000000d91ca36caa7bd53f0c6da30743948a8639", + "0x000000000000000000000000000000000021e7290c49f78addda4ccd9eef9c8c", + "0x00000000000000000000000000000081b433648af06686217c238ce4b13cf535", + "0x00000000000000000000000000000000002047531ed8535e381cffae559b6bb0", + "0x0000000000000000000000000000007ffdec7092f6d520c0209c640bfadc695d", + "0x00000000000000000000000000000000000a26fbb3d9d87f4ab3dd718c3bb75e", + "0x000000000000000000000000000000c636bdd1555ebce8fb6a9751c48376b7dd", + "0x0000000000000000000000000000000000017cb50edda28183e752c7e00faa40", + "0x000000000000000000000000000000ec2af0c236db172d1e5c00f7de73ae4fef", + "0x0000000000000000000000000000000000053be81fcb74e5cbb36dc0f630a49a", + "0x000000000000000000000000000000080baf1731ad04c68e93e7045d03ef4fd3", + "0x00000000000000000000000000000000001e593590b8049fe6542e11d3606aa5", + "0x000000000000000000000000000000575f11519d26bc15d34402b3331befb097", + "0x00000000000000000000000000000000001b7eed68e0e1c24fbf77cbfa588283", + "0x000000000000000000000000000000e1cdf4c6808f1f53377d276a0214b9af54", + "0x000000000000000000000000000000000002c44f6a43320eb961560c6a40262b", + "0x0000000000000000000000000000009f48843445d33387ce0134c37a9b82037a", + "0x00000000000000000000000000000000000a2852b8f7464eefbba66e39124b2f", + "0x00000000000000000000000000000077e865b0eef6500d62b5ed5b71795e1fdd", + "0x00000000000000000000000000000000001bc28e177eaebca799a38f9b96bd41", + "0x0000000000000000000000000000008a3623ef604d2b654cbc7b6f898ab36fd2", + "0x0000000000000000000000000000000000239c355843996ddcf4f3330873dc58", + "0x0000000000000000000000000000001fd35d9c3df35c0ab05822a8a7672f307d", + "0x000000000000000000000000000000000008eff9c124dc7092426dbfef4f367f", + "0x000000000000000000000000000000045c0a8172f53ba9a5c8e00908c493018e", + "0x00000000000000000000000000000000002ca001cbe15bf21d7bc13cb56f8272", + "0x0000000000000000000000000000001842209bfe3ad1cfba506322320f9c1a8f", + "0x000000000000000000000000000000000005e47c6d153729d8788d2a9c9cd993" ] - hash = "0x016a3b94e0b04a9f99ca3c31a475b4b5b1854bb2f3cea14fc49177110c9d7142" + hash = "0x035b62916d53f6a30d14dfd8245816108afd3d59028ddcf59607c26f190a855c" [[inputs.previous_rollups]] proof = [ @@ -1201,22 +1201,22 @@ proof = [ accumulated_mana_used = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants] - vk_tree_root = "0x11065543c9a42eac842466277ee9149b27403e398e94c6bba4f525931a2ac6bc" - protocol_contracts_hash = "0x24b2bd6e0456d2d2e64beb505010896a57017c6dedf7516d314d551720c3e6b4" + vk_tree_root = "0x0554f6effd553d130db46a6b8936b481c95ea2f460edde3b3d2af680b82715db" + protocol_contracts_hash = "0x08d0026a4983c49638d0910859942c6648d5ea0a3a152c8a376e4983d0a003d9" prover_id = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.constants.last_archive] - root = "0x26c404240cb9d3965fdd677de1d4ea1d907e460403e304ed198e839901a4cebc" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000002" + root = "0x0fb2945d3438d906d88a216364dbfe9760e96001343468610e01d18182d493d0" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000001" [inputs.previous_rollups.public_inputs.constants.l1_to_l2_tree_snapshot] - root = "0x2077efe63b8c3de3bfdbc1e1be837185a8f1d817c8321418fcfe110cd518a922" - next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000400" + root = "0x0c123047b777079e8db5f669ddaf1ffa1c7780d56b21e29f35e4772ac0f6280c" + next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.constants.global_variables] chain_id = "0x0000000000000000000000000000000000000000000000000000000000000000" version = "0x0000000000000000000000000000000000000000000000000000000000000000" - block_number = "0x0000000000000000000000000000000000000000000000000000000000000002" + block_number = "0x0000000000000000000000000000000000000000000000000000000000000001" slot_number = "0x000000000000000000000000000000000000000000000000000000000000000f" timestamp = "0x0000000000000000000000000000000000000000000000000000000000000186" @@ -1231,75 +1231,75 @@ proof = [ fee_per_l2_gas = "0x0000000000000000000000000000000000000000000000000000000000000000" [inputs.previous_rollups.public_inputs.start_tree_snapshots.note_hash_tree] -root = "0x24543462563d01f3fa7d2995feb0568f0868807616f9135cbcec47610a688576" +root = "0x01612d24a146efc2df9d815a2f733c17486304424577ffb4232fe4cb0c94e1e7" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000040" [inputs.previous_rollups.public_inputs.start_tree_snapshots.nullifier_tree] -root = "0x0d5183688b388e23b4fe243d466e4d50acaf63d7afa00ca046fe2bf2e83db99d" +root = "0x2d9141720c810b831246b0e50c0ad9d4b935418ba2ae8a06c395bb80340ee684" next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000c0" [inputs.previous_rollups.public_inputs.start_tree_snapshots.public_data_tree] -root = "0x27b8cdfd5211a289e0aa40da120fa969649354b3a0084d32d1ba1aca6b16f5b9" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" +root = "0x1a90881964e28a92a419f1d8361c14ac147b6f9175c04fdf57dadf0d7ba781c9" +next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.note_hash_tree] -root = "0x092658df33d4badeaa54da3bee987ed4b7a973d285a96229bbd71c564cad7449" +root = "0x2326bf220c6839c1856478f0c082f0c5883b2baed0bc222a1fa5e1244184c82b" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000080" [inputs.previous_rollups.public_inputs.end_tree_snapshots.nullifier_tree] -root = "0x2fd0dfe2f0d0f4977a6c6d880237e4462686a8caf9e3eacf34b6a5159feac6f8" +root = "0x1e1c597744057b88e39a9780ed087c39b1fc42864e05ef03a59ebd9e96b70b00" next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000100" [inputs.previous_rollups.public_inputs.end_tree_snapshots.public_data_tree] -root = "0x1e18fe9a8c877ed096fe353567b6aef5b3dd4bbd987fec03c759c7cde4b3be5f" -next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000fe" +root = "0x2306af8b455a9cbf87331182183be8c0759fd5e1a4f606cea8a9e24efa461759" +next_available_leaf_index = "0x00000000000000000000000000000000000000000000000000000000000000bf" [inputs.previous_rollups.public_inputs.start_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000552" + num_absorbed_fields = "0x00000000000000000000000000000000000000000000000000000000000004cd" [inputs.previous_rollups.public_inputs.start_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7d1b34c", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34d", - "0x00000000000000000000000000000000000000000000000000000000b7d1b34e" + "0x00000000000000000000000000000000000000000000000000000000b7d1b44d", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44e", + "0x00000000000000000000000000000000000000000000000000000000b7d1b44c" ] state = [ - "0x0df722e23d212237afafa5c3ad409696de00ed5a6d040df1df5741c30783ab8d", - "0x1f51a080b417c648bdba25c5f1effbb13ef3cb2b3ad1c9f2650b842f7e08534a", - "0x0d5006c76bcd6126118b6ad75ec54e789213be33b6785d56921ac5bee5198c1e", - "0x26682892f284a033692202f2db9ee5552a727e91de309eb4aa74c20894def508" + "0x18134bd9cba7d2cfc160875a460f388c06c9be8bd2bdad23202426c0d0d985ec", + "0x181719b331f5a865a1ab500c089896a3606636dc0006adcf508a05a0ce702ccc", + "0x2099effc3095782b2705ec21faff150c85134e7cfa6b04af5868e014a4b9020c", + "0x2d212822493f22c35892994822a04497feb3a4e5ed82d4733e7972f4bed1958a" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000003" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" squeeze_mode = false [inputs.previous_rollups.public_inputs.end_sponge_blob] - num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a9d" + num_absorbed_fields = "0x0000000000000000000000000000000000000000000000000000000000000a18" [inputs.previous_rollups.public_inputs.end_sponge_blob.sponge] cache = [ - "0x00000000000000000000000000000000000000000000000000000000b7e5c34d", "0x00000000000000000000000000000000000000000000000000000000b7e5c34e", - "0x00000000000000000000000000000000000000000000000000000000b7e5c34c" + "0x00000000000000000000000000000000000000000000000000000000b7e5c34c", + "0x00000000000000000000000000000000000000000000000000000000b7e5c34d" ] state = [ - "0x0b7c9bbfac21d3c59031a865ee1f7abea9012d898a238d0b9d545e7e15be4f9a", - "0x11e47e7e5a97cace7b8cb5c63eeaf7cb076e5e19a4e89c1d3f4c3fb1faddf0b3", - "0x03a1357263e162410b5a70343adea4b373f3006660d9b40c28425be41749a8f7", - "0x100bc00d33720748142a7cd2ab57c5c140b681cdeec9b6197841f983ed05a3e2" + "0x066ed8d59656f317204a938dd07fa4468c320a6b111db7e1dca0f076722defc2", + "0x0435d82cba6a560012ad91adb17e18e1bbd0418b5829103b42df4247b06d8b58", + "0x04d968e8ea37d341ebbfb1a2135f97078e35f1bc03f478988064727a83d307ad", + "0x09d2cd576dd52ee863b4528b671d2e317262ae07136942de09eb54267049c116" ] - cache_size = "0x0000000000000000000000000000000000000000000000000000000000000002" + cache_size = "0x0000000000000000000000000000000000000000000000000000000000000001" squeeze_mode = false [inputs.previous_rollups.vk_data] leaf_index = "0x0000000000000000000000000000000000000000000000000000000000000008" sibling_path = [ - "0x20ab775da5bb45344ffe17866237142b9321b97b2e93ccfb1c299476a262e0b5", - "0x2a9ef81b082ec4212c08eba71c46e645efc1ae573e9cca5b480785be9dcc4d21", - "0x18b9d1703288fad007e0e97212dedf18305ab172790fe8d5c7aeea5c2634673b", - "0x0481dbd69f3e084904030eb9771134ae7be848ec7b4af69e75933270ceeb544d", - "0x1fe698f1a6368c855525a9abcc3713bb49b1dec627f796bf4e23cc86473621ec", - "0x1c7b07f7b3f8344fece2e6a10bc9480dc4b90f89d2a51f344bee80ca5a4bda6e", - "0x12ed8e93726f8b5b79d1291566a72c1775861d60bba2daa19edb3f28d0ae7a3e" + "0x10b6730f1d1e9c6bf8d7c4b42b64b40d2603e3ae6ddbd464c3d8fcfb9e06e6d4", + "0x11017f6408ff020bf1556ed3f4d41fba9dfe9fe312cd5430ec7c1abf7e3a9bcc", + "0x093393cd4297faa0e57bf0b8d98a1488e9dbf4e5faa27c9410505c75a590c41e", + "0x20f1c701d84b280c9f80a517272153688a9e1b92166d1000cfe7c829b7c25f69", + "0x07ebb028f1e2f438160a9f6b62d7db60805be6119e0ba2d72158044a0c2a620c", + "0x0db3ab63c7556f8724d86819156701855018cc79140a052893d67fb67c99c1f1", + "0x058218a8605b041acde73bf034f139d830ed6b74dcb38f6ee06556729be2a765" ] [inputs.previous_rollups.vk_data.vk] @@ -1307,46 +1307,46 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x0000000000000000000000000000000000000000000000000000000000000017", "0x0000000000000000000000000000000000000000000000000000000000000042", "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000001393476211d0127a80dce177bd2139b525", - "0x00000000000000000000000000000000000a64db7a774dad381e4034cb2457f3", - "0x000000000000000000000000000000d5fb425ef17d829bcbd2f2212397cc69ba", - "0x00000000000000000000000000000000002902ad5d5e880ce9d3ff8815ad1554", - "0x0000000000000000000000000000009b94b4b71ebf49ca1ccee622099eb37a96", - "0x0000000000000000000000000000000000217517f2a6d3c0ad2a63c69b28d392", - "0x00000000000000000000000000000038d8df60934ce84e0ed3e7f5ca09c1ee4d", - "0x000000000000000000000000000000000013384c8161e64209078ece69fcaa19", - "0x00000000000000000000000000000093c2a0c6ec49f39474bd6782c5cd6b01b2", - "0x000000000000000000000000000000000008ff5813561afc758759d27f19b55c", - "0x00000000000000000000000000000097291956465f3aa94d25b11bc567a6c287", - "0x000000000000000000000000000000000007f14a03af147b21368785d869ca98", - "0x0000000000000000000000000000006a811b91c5970c9c2acd7a754d7b7f9cb1", - "0x0000000000000000000000000000000000190a1ac15c24fdafc83b205b9a284b", - "0x000000000000000000000000000000b61bdc9c40c5c1e94e290d7b383b2ee122", - "0x00000000000000000000000000000000002f5117ca48de83b07881d30427d341", - "0x00000000000000000000000000000012095bbac1cead43059d0a230818a027b7", - "0x00000000000000000000000000000000001c7b3a018ad17b7cbb3752d56c6f80", - "0x00000000000000000000000000000018c18cff602c8434b90273cb1ff38dd751", - "0x000000000000000000000000000000000003bd5bfa0c05c005fcbde355422947", - "0x0000000000000000000000000000009dac7aa803151cb1966b812422755d8e9e", - "0x000000000000000000000000000000000010f818617b14b429abcd3acd46653c", - "0x0000000000000000000000000000007951c87d59a7b4319ddc32a19635675d94", - "0x000000000000000000000000000000000005be6b96d6eb897429b815388db99b", - "0x000000000000000000000000000000d7e7c851d3ba4e42b00b50dcb9a40159ff", - "0x00000000000000000000000000000000002750be703cf6981c927c48de088588", - "0x00000000000000000000000000000048b23b4fb077032ac487b882dec8a8c38b", - "0x000000000000000000000000000000000017150b214b8aa285fed8a5b374a4f9", - "0x000000000000000000000000000000416e099bfce67a459c5a20a4311705f6c4", - "0x00000000000000000000000000000000002b684b94d2f1f96e86dfad7af6171d", - "0x000000000000000000000000000000651160cf941fb73a15062e12bfc9e35804", - "0x000000000000000000000000000000000007a1bb9d8533d71515e6e3b5e6866d", + "0x000000000000000000000000000000be3ef7df55faad770dd417b568b334bb61", + "0x0000000000000000000000000000000000020dbb5be28ee0dddbe361d4210575", + "0x0000000000000000000000000000002a9a30c0f428736335b3eb03271a7faa35", + "0x0000000000000000000000000000000000011eeab7deb21addfa7d56d1c588a1", + "0x000000000000000000000000000000cd7414d72fbdd24b1bad570941833708ea", + "0x0000000000000000000000000000000000125ab5466e467ad79893fe6fb71dac", + "0x000000000000000000000000000000275ffdc4a6a9c963cff9f4bfc97ff47ae5", + "0x000000000000000000000000000000000009b0fc1fdcf1eb4720e77df4bf579e", + "0x0000000000000000000000000000004b41b33ed09d6f2e0d1e2778bcc0a412bf", + "0x00000000000000000000000000000000002431de0fcb1f1e513962b6ddaff0cb", + "0x000000000000000000000000000000ceacbeb3107979529c12c1d0eee1557e98", + "0x000000000000000000000000000000000015157c061d1d61cf7dd3a7ce845922", + "0x0000000000000000000000000000003f7443a3cea90f0e6730b33675efbbda73", + "0x00000000000000000000000000000000002ca6b067638c1c24bbadd530a94798", + "0x000000000000000000000000000000f4d7b640687e4a07ea713f599fa766d14f", + "0x00000000000000000000000000000000001da3ebbf464dad0213d7cbb620146c", + "0x000000000000000000000000000000a5e9f66b74ff0bfcb7cb43d4ae9f154cf7", + "0x00000000000000000000000000000000001b50d6d924c13b8138405d313f1875", + "0x00000000000000000000000000000091dda1fdadf6e5bb631936d41c3e919572", + "0x0000000000000000000000000000000000218f9e93fa7efcdb8d89b8303acc50", + "0x000000000000000000000000000000f659c8815b22bacd330bee0c95d2a77cfd", + "0x00000000000000000000000000000000002aee8b729bc510e581461f3c3d3f20", + "0x000000000000000000000000000000d35405c664cefb21dd45302fa07ce6e1ae", + "0x0000000000000000000000000000000000168af130006e1ff22ea8737f0207e3", + "0x0000000000000000000000000000004b9beda85c743bfc49ac3aa711ccf95ca3", + "0x000000000000000000000000000000000028fb89c6da361c392f36475551e5c7", + "0x000000000000000000000000000000c5d8af9e91084202d30bd24e2ae1787dd1", + "0x00000000000000000000000000000000002ea1690f1652415522380675b4f298", + "0x00000000000000000000000000000004cc26069474a70fefc9e011a297d3659a", + "0x00000000000000000000000000000000002c4ca65f1f3ce11e955002f76823b7", + "0x000000000000000000000000000000caa9709b37a3f896da980148bd862f79ad", + "0x00000000000000000000000000000000001cdab1dc53ddf21433efb20a019aed", "0x0000000000000000000000000000001eee81b23a887f299049b14c11e98460d6", "0x00000000000000000000000000000000002a56ce41f6b0be13b9c26747621b82", "0x000000000000000000000000000000d5827d6338c78656c0d12ca1aea6ef2c7c", "0x00000000000000000000000000000000001aa98f2de3ddda547d8f6de4e725de", - "0x000000000000000000000000000000bada1572761d2d57e5d206da78afa472c5", - "0x00000000000000000000000000000000000248453a876b49502a5a8259818f44", - "0x000000000000000000000000000000ec45f0511c4ef04800c3d31e152e9265de", - "0x00000000000000000000000000000000001fff1bef8afe963c3b78c3c2549ca4", + "0x00000000000000000000000000000091be1f8e738e8cf74c39dcff97e574049a", + "0x0000000000000000000000000000000000253b1d48e89dea2387345d1f190cf8", + "0x00000000000000000000000000000001f523e64316ec12df1d1fed701b1fc3ff", + "0x0000000000000000000000000000000000254e8bc817fd854d25dce4ca34bbb9", "0x0000000000000000000000000000006f206a04895661d3bd004222a1f8a7fc73", "0x00000000000000000000000000000000001b12a59a820d3aa543a594a1b9d92f", "0x0000000000000000000000000000002103559842aca1e08af33bb1f714ebc02a", @@ -1367,57 +1367,57 @@ next_available_leaf_index = "0x0000000000000000000000000000000000000000000000000 "0x000000000000000000000000000000000021a0543de0bc42d6586454ec8b623b", "0x00000000000000000000000000000016bf0724359c9a09ceffdc9371a2d6e5dc", "0x00000000000000000000000000000000002fd4c13c6f5523a7f44b28ce3d342a", - "0x000000000000000000000000000000e379faf5ffdd383be5ce0f1ee38f5e73fe", - "0x00000000000000000000000000000000001429616496865cd170bc83c40d415a", - "0x00000000000000000000000000000066e08b7ad48415290d2ff590e84057e60e", - "0x000000000000000000000000000000000023a625e90ae9701e33c52be8f0d396", - "0x000000000000000000000000000000774fc954a6adaa4e4db1da6228184e1354", - "0x000000000000000000000000000000000015ca4073735e39fd5dc55567dc1068", - "0x000000000000000000000000000000fd9e5f594db01e4b2625e1e3dcfd400f6e", - "0x00000000000000000000000000000000000f4a392bbee96bddd468b2c9a18896", - "0x000000000000000000000000000000d28954aef28e666d63ee0fb401ab7bc1b6", - "0x0000000000000000000000000000000000253b48f95132d1a3183e26dbd56884", - "0x00000000000000000000000000000022887784410bf17c157fc004401281c342", - "0x00000000000000000000000000000000000a249d88427c50df84670228613493", - "0x0000000000000000000000000000000f495c15c8a9098c779fef9227f1c5a897", - "0x000000000000000000000000000000000016d74e40a54fe1961a01c0a275941e", - "0x000000000000000000000000000000a968320348365b69bc59ded07a855fb88c", - "0x000000000000000000000000000000000010c9846c3754b0fb4b4c9ab8d68cd3", - "0x00000000000000000000000000000088ee0f0a54893f8b1e8b56a7fa7bee9d4f", - "0x000000000000000000000000000000000021d14db4aa9ae9f88641b9336d9dba", - "0x0000000000000000000000000000000f46a800020405196bda0c07afe5154eac", - "0x0000000000000000000000000000000000062e98c038c271784c9fb61136242f", - "0x00000000000000000000000000000024ed87f3417bd5bbaa53682680b1b915c8", - "0x000000000000000000000000000000000003beb3d385de2c0a7a40cebe01d34a", - "0x000000000000000000000000000000f85b812b32412267c5221f3600eaa3f3d2", - "0x00000000000000000000000000000000000289ace5de4f3e7a721b5a184d1e76", - "0x0000000000000000000000000000002e30085e1c74fe70d1d2ab68faf0984ca4", - "0x00000000000000000000000000000000001adb7660db50eb3c9d70b137871b2f", - "0x0000000000000000000000000000008e05ae370a270eeb6d282e3bc2b7889cc3", - "0x000000000000000000000000000000000020e76f33b00bccd1f97095bece663a", - "0x000000000000000000000000000000d71d8a40f7c9f1984d513aa7eb1a895e6e", - "0x0000000000000000000000000000000000021aee4d83119d0af331d5893af9fe", - "0x000000000000000000000000000000dec3abe29c9aa4bf73251a0c748d11e9dc", - "0x0000000000000000000000000000000000153c1ed58f5394ad372869f471ca8b", - "0x000000000000000000000000000000bf4d6e6ed9dad1b05bd3d5cb3b3740d3e2", - "0x000000000000000000000000000000000006803b1ef715809ab5085220b7c284", - "0x00000000000000000000000000000041efece86e20c4323fb08d7aad7345c79c", - "0x0000000000000000000000000000000000096fab6acc87fe26e0eefb5660a7db", - "0x0000000000000000000000000000002d550983acbdea743f381bf4d55b8c6110", - "0x0000000000000000000000000000000000107455727dcf49837ee29622f4e9ae", - "0x000000000000000000000000000000a07bfb26d2f33a45866564f6fb630fc1b3", - "0x000000000000000000000000000000000004b58a9a3d784d5857e224b300b97a", - "0x000000000000000000000000000000c0f8d7d2fa6eac6b45b736e838db02e437", - "0x0000000000000000000000000000000000012728fef15749f6355802ac76d166", - "0x000000000000000000000000000000caa9dd21f786e491093e94a42326c20c4b", - "0x0000000000000000000000000000000000181c00a5273565ed45cde6516b7267", - "0x000000000000000000000000000000f791b0a7d2376523eebf266bd58c615a72", - "0x00000000000000000000000000000000001658c7b51e5eb76e58124a4bf26d30", - "0x0000000000000000000000000000007ffefc9b69f9b9f766f98d9390ad49a8f6", - "0x00000000000000000000000000000000002700900f023bdb2524f5ce218af8a6", - "0x0000000000000000000000000000001d12e2e9feedc5df84ac9cb8e405fc64ea", - "0x00000000000000000000000000000000001645d7c72fd8844ddf0659d2b77656", - "0x00000000000000000000000000000098eaadb9c8f156e98d8dfde6f90be22a80", - "0x000000000000000000000000000000000028291c89dafd88dced57d87f6d8ab7" + "0x00000000000000000000000000000063a793166969e30306b1a33ee3140ab639", + "0x00000000000000000000000000000000000689ae6c5351a0c7d2bddd28760eba", + "0x000000000000000000000000000000e9e058e78b28069998e0b545635c751505", + "0x000000000000000000000000000000000029d041f64f9c7a4b574afdd84eb2bc", + "0x000000000000000000000000000000de0e873aad4dce9c296b5822c49119b396", + "0x00000000000000000000000000000000001e622a80763bdce9e84c5936947ea4", + "0x000000000000000000000000000000ff979afed880f8777a1d7edb65ce1450e3", + "0x000000000000000000000000000000000012be4428cf92f37d4329f288edd6d7", + "0x000000000000000000000000000000d68061ce1bad9ac1e54cdf86b65d18b89f", + "0x000000000000000000000000000000000020fdf737ed00586f6db007044965a8", + "0x000000000000000000000000000000946bb34bc2173c2659e824f5fd377a3cbf", + "0x000000000000000000000000000000000022da84ec41699f355efa9e9550e4e4", + "0x0000000000000000000000000000008b0f4ef158c13087ed0e80688fe8373342", + "0x00000000000000000000000000000000002a4cae8c1411ba84463b850ab1844a", + "0x00000000000000000000000000000081d9bb13936c0676b987efe4a7ccd38a7e", + "0x00000000000000000000000000000000001e527e0c58ebec97285f8d47471778", + "0x000000000000000000000000000000c17602371eddd69a1e0e5b82a51441f2d3", + "0x000000000000000000000000000000000010fd74deb218f4d0d58aee589c31a6", + "0x000000000000000000000000000000dc8cd28e055e13b175149f797af895f0f4", + "0x000000000000000000000000000000000014d50f3e5a64cc7500ed82e02796e5", + "0x000000000000000000000000000000c61024b9433cc9b608636d33133501734f", + "0x0000000000000000000000000000000000080ffdff074611822ac0029ae9ac87", + "0x000000000000000000000000000000251c0f33e1f84d4365571cd965fc9b951c", + "0x00000000000000000000000000000000002e7e699ac6cc777970c0d5dd410bc0", + "0x0000000000000000000000000000009e1f4030259589018ce84f6f1dd736ae5d", + "0x000000000000000000000000000000000006154a1e0fea69f24bf7ac004afb7a", + "0x000000000000000000000000000000189020ea1ed822257549ab99ac2b33647e", + "0x00000000000000000000000000000000002a384f4831d00b56c6219abcb3b785", + "0x00000000000000000000000000000035fb02b0d2e793607a238e08539424c438", + "0x00000000000000000000000000000000001d0e75eecc618b087887f7d14ddf24", + "0x000000000000000000000000000000eae70e5ed566bcad446daa8f1059119fb5", + "0x00000000000000000000000000000000001f16d342675b048447aec1d841ea6f", + "0x000000000000000000000000000000dec8287d2ca445b6611951692aceb93f09", + "0x00000000000000000000000000000000000d237ea339d430164ddcf07c98eebb", + "0x00000000000000000000000000000069bd0705898ec802324165e180c23cca88", + "0x00000000000000000000000000000000002b2487b0a0cad2ab8b703eda79048b", + "0x000000000000000000000000000000526f89287c9fa8d0869c89341b300cd057", + "0x00000000000000000000000000000000000da86b460feb2479d72b91bad3aa4e", + "0x000000000000000000000000000000aba6055db467fa492b870fccd9251c0cb4", + "0x000000000000000000000000000000000022e849a8f64faebc36288439518d4b", + "0x000000000000000000000000000000ab679268e81d4770ddc1861ac7485ac4e8", + "0x000000000000000000000000000000000009a186caa2f074b8b5d3d26afddfc5", + "0x000000000000000000000000000000694fbc055e1f0045837b2bcf0d60f82934", + "0x00000000000000000000000000000000000ffba7e4a28991553a68d277bf2aa3", + "0x000000000000000000000000000000de4a494414853cc677e6f0de0f19a070c8", + "0x000000000000000000000000000000000004485188f222785e8455584b3632e6", + "0x0000000000000000000000000000001e68682a2d646f241b36838e8627fe4258", + "0x00000000000000000000000000000000001cd86d75f808b92947367db49e99b3", + "0x000000000000000000000000000000a21f994888d69ad0e60ea74b527f54a7ed", + "0x00000000000000000000000000000000001bbdaa75acb6eb653db71e1666d066", + "0x000000000000000000000000000000eb0694220d1a490792b0165b98d9b8bf71", + "0x000000000000000000000000000000000025729291a976e4cbed01962ee0b0d0" ] - hash = "0x016a3b94e0b04a9f99ca3c31a475b4b5b1854bb2f3cea14fc49177110c9d7142" + hash = "0x242e942739553143b651d041e96bc6bc5e09baa6142d959488ffa864ce063d69" diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/block_constant_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/block_constant_data.nr index 45772eeb1d19..a0d54a59a610 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/block_constant_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/block_constant_data.nr @@ -8,10 +8,10 @@ use std::meta::derive; pub struct BlockConstantData { // Archive tree snapshot at the very beginning of the entire block. pub last_archive: AppendOnlyTreeSnapshot, - // L1-to-L2 message tree snapshot after this block lands. - // For the first block in a checkpoint, this should be the snapshot after inserting the new l1-to-l2 message subtree - // into the last l1-to-l2 tree snapshot in `last_archive`. - // For subsequent blocks, this should match the snapshot of the previous block. + // L1-to-L2 message tree snapshot after this block's own message bundle has been inserted. The AVM validates this + // block's l1-to-l2 message read requests against it, so a tx in this block can read the messages this block + // inserts (same-block consumption). Every block-root variant that carries txs asserts this equals its computed + // post-bundle root, whether or not the block is the first in its checkpoint. pub l1_to_l2_tree_snapshot: AppendOnlyTreeSnapshot, pub vk_tree_root: Field, pub protocol_contracts_hash: Field, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/checkpoint_header.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/checkpoint_header.nr index 95ba92af8da8..95443d82da75 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/checkpoint_header.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/checkpoint_header.nr @@ -14,7 +14,10 @@ pub struct CheckpointHeader { pub last_archive_root: Field, pub block_headers_hash: Field, pub blobs_hash: Field, - pub in_hash: Field, + // Inbox rolling-hash chain value after consuming all L1-to-L2 messages bundled into this checkpoint: + // the truncated-to-field sha256 chain the L1 Inbox accumulates. This is the checkpoint's only inbox + // commitment. + pub inbox_rolling_hash: Field, // The root of the epoch out hash balanced tree. The out hash of the first checkpoint in the epoch is inserted at // index 0, the second at index 1, and so on. // Note: This is not necessarily the final epoch out hash. It includes only the out hashes of checkpoints up to and @@ -39,7 +42,7 @@ impl Empty for CheckpointHeader { last_archive_root: 0, block_headers_hash: 0, blobs_hash: 0, - in_hash: 0, + inbox_rolling_hash: 0, epoch_out_hash: 0, slot_number: 0, timestamp: 0, @@ -57,7 +60,7 @@ impl CheckpointHeader { let last_archive_root_bytes: [u8; 32] = self.last_archive_root.to_be_bytes(); let block_headers_hash_bytes: [u8; 32] = self.block_headers_hash.to_be_bytes(); let blobs_hash_bytes: [u8; 32] = self.blobs_hash.to_be_bytes(); - let in_hash_bytes: [u8; 32] = self.in_hash.to_be_bytes(); + let inbox_rolling_hash_bytes: [u8; 32] = self.inbox_rolling_hash.to_be_bytes(); let epoch_out_hash_bytes: [u8; 32] = self.epoch_out_hash.to_be_bytes(); let slot_number_bytes: [u8; 32] = self.slot_number.to_be_bytes(); let timestamp_bytes: [u8; 8] = (self.timestamp as Field).to_be_bytes(); @@ -77,7 +80,7 @@ impl CheckpointHeader { last_archive_root_bytes .concat(block_headers_hash_bytes) .concat(blobs_hash_bytes) - .concat(in_hash_bytes) + .concat(inbox_rolling_hash_bytes) .concat(epoch_out_hash_bytes) .concat(slot_number_bytes) .concat(timestamp_bytes) @@ -113,7 +116,7 @@ fn checkpoint_header_hash_matches_ts() { last_archive_root: 123, block_headers_hash: 456, blobs_hash: 77, - in_hash: 88, + inbox_rolling_hash: 89, epoch_out_hash: 99, slot_number: 1234, timestamp: 5678, @@ -131,7 +134,7 @@ fn checkpoint_header_hash_matches_ts() { // Generated from checkpoint_header.test.ts let checkpoint_header_hash_from_ts = - 0x00d0dc440023ae006b0880b29ebfd5fda599d1aa7707f925229a362c5f24f3fc; + 0x00751391e842cd7b2014478255dd3309df86327197a0feb03f0af1b758f62ba5; assert_eq(header.hash(), checkpoint_header_hash_from_ts); } @@ -144,7 +147,7 @@ fn checkpoint_header_hash_large_values_matches_ts() { last_archive_root: MAX_FIELD_VALUE - 123, block_headers_hash: MAX_FIELD_VALUE - 456, blobs_hash: MAX_FIELD_VALUE - 77, - in_hash: MAX_FIELD_VALUE - 88, + inbox_rolling_hash: MAX_FIELD_VALUE - 89, epoch_out_hash: MAX_FIELD_VALUE - 99, slot_number: MAX_FIELD_VALUE - 1234, timestamp: MAX_U64_VALUE - 5678, @@ -164,7 +167,7 @@ fn checkpoint_header_hash_large_values_matches_ts() { // Generated from checkpoint_header.test.ts let checkpoint_header_hash_large_values_from_ts = - 0x0077f763e5840cc3f24686ac79f58ef8a7f08c6418fd757e7e84566dc2eb032a; + 0x005bd09725c6e77a4a28a7ccdaf7875ba5882431ca3c82e62db96e8a12769ce5; assert_eq(header.hash(), checkpoint_header_hash_large_values_from_ts); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/blob_data/sponge_blob.nr b/noir-projects/noir-protocol-circuits/crates/types/src/blob_data/sponge_blob.nr index 9467ca4bd1eb..98dbb9c5b265 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/blob_data/sponge_blob.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/blob_data/sponge_blob.nr @@ -127,7 +127,6 @@ impl SpongeBlob { state: StateReference, num_txs: u16, total_mana_used: Field, - is_first_block_in_checkpoint: bool, ) { let blob_data = create_block_end_blob_data( global_variables, @@ -137,15 +136,10 @@ impl SpongeBlob { total_mana_used, ); - // Include the last field (the l1-to-l2 message tree root) only for the first block, since this value is the - // same for all blocks in the checkpoint. - let num_blob_data_to_absorb = if is_first_block_in_checkpoint { - blob_data.len() - } else { - blob_data.len() - 1 - }; - - self.absorb(blob_data, num_blob_data_to_absorb); + // The l1-to-l2 message tree root (the last field) is absorbed for every block: any block + // can now insert its own bundle, so the root differs per block and blob-syncing nodes reconstruct each block's + // message-tree root from the blob alone. + self.absorb(blob_data, blob_data.len()); } /// |----------|---------------------------------------------|---------| diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 0da946df4b89..58dbd4831614 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -61,8 +61,16 @@ pub global NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH: u32 = NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT; pub global NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH: u32 = NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT; -pub global L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH: u32 = - L1_TO_L2_MSG_TREE_HEIGHT - L1_TO_L2_MSG_SUBTREE_HEIGHT; +// Cap on L1-to-L2 messages bundled into a single L2 block. One quarter of the per-checkpoint +// cap: a checkpoint drains its Inbox consumption across up to four message-bearing blocks. +pub global MAX_L1_TO_L2_MSGS_PER_BLOCK: u32 = 256; +// Cap on L1-to-L2 messages consumed by a single checkpoint. +pub global MAX_L1_TO_L2_MSGS_PER_CHECKPOINT: u32 = 1024; +// Minimum bucket age, in seconds, at the start of a checkpoint's build frame for its consumption to be mandatory under +// the streaming Inbox censorship cutoff. One L1 slot: validators cannot be required to act on +// buckets they may not yet have seen. L2 consensus policy consumed by the sequencer and validator (and mirrored by +// ProposeLib on L1); the protocol circuits do not read it. +pub global INBOX_LAG_SECONDS: u32 = 12; // Maximum number of subtrees a L2ToL1Msg unbalanced tree can have. Used when calculating the out hash of a tx. pub global MAX_L2_TO_L1_MSG_SUBTREES_PER_TX: u32 = 3; // ceil(log2(MAX_L2_TO_L1_MSGS_PER_TX)) @@ -99,9 +107,6 @@ pub global MAX_NULLIFIER_READ_REQUESTS_PER_CALL: u32 = 16; pub global MAX_KEY_VALIDATION_REQUESTS_PER_CALL: u32 = MAX_PRIVATE_LOGS_PER_CALL; // docs:end:constants -// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts -pub global NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: u32 = 1 << L1_TO_L2_MSG_SUBTREE_HEIGHT; - // VK TREE CONSTANTS pub global PRIVATE_KERNEL_INIT_VK_INDEX: u32 = 0; pub global PRIVATE_KERNEL_INNER_VK_INDEX: u32 = 1; @@ -123,8 +128,8 @@ pub global CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP_VK_INDEX: u32 = 17; pub global CHECKPOINT_PADDING_ROLLUP_VK_INDEX: u32 = 18; pub global CHECKPOINT_MERGE_ROLLUP_VK_INDEX: u32 = 19; pub global ROOT_ROLLUP_VK_INDEX: u32 = 20; -pub global PARITY_BASE_VK_INDEX: u32 = 21; -pub global PARITY_ROOT_VK_INDEX: u32 = 22; +// VK indices 21 and 22 are intentionally unallocated: they were the parity base / parity root, replaced by the +// InboxParity size ladder (appended at 74-76 below, since the reset range 23-64 is reserved). // The three families below carve up the reset-family range (23-42). Each base is the VK index // of its family's first variant; subsequent variants occupy successive indices. Bases must // stay ascending; `validate_vk_in_vk_tree` depends on this ordering. @@ -147,6 +152,14 @@ pub global PRIVATE_KERNEL_INNER_2_VK_INDEX: u32 = 69; pub global PRIVATE_KERNEL_INNER_3_VK_INDEX: u32 = 70; pub global PRIVATE_KERNEL_INNER_4_VK_INDEX: u32 = 71; pub global PRIVATE_KERNEL_INNER_5_VK_INDEX: u32 = 72; +// The block-root variants at 10-14 are full; the non-first message-only block root is appended after the +// multi-app kernel indices (65-72), since 43-64 are reserved for reset variants. +pub global BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX: u32 = 73; +// The InboxParity size ladder: one VK per size, checked as an allowed set by the checkpoint root. Appended here +// (rather than reusing the freed 21/22) so the three sizes stay contiguous and read in order. +pub global INBOX_PARITY_64_VK_INDEX: u32 = 74; +pub global INBOX_PARITY_256_VK_INDEX: u32 = 75; +pub global INBOX_PARITY_1024_VK_INDEX: u32 = 76; // Maximum number of apps absorbed by a single private kernel iteration. pub global MAX_APPS_PER_KERNEL: u32 = 5; @@ -347,6 +360,7 @@ pub global GLOBAL_VARIABLES_LENGTH: u32 = 7 + GAS_FEES_LENGTH; pub global APPEND_ONLY_TREE_SNAPSHOT_LENGTH: u32 = 2; pub global APPEND_ONLY_TREE_SNAPSHOT_LENGTH_BYTES: u32 = 36; pub global SPONGE_BLOB_LENGTH: u32 = 10; +pub global L1_TO_L2_MESSAGE_SPONGE_LENGTH: u32 = 10; pub global BLS12_FR_LIMBS: u32 = 3; // TODO(#14646): get this from bignum pub global BLS12_FQ_LIMBS: u32 = 4; // TODO(#14646): get this from bignum pub global BLS12_POINT_LENGTH: u32 = 2 * BLS12_FQ_LIMBS + 1; // TODO(#14646): reduce num fields needed here? @@ -434,7 +448,7 @@ pub global BLOCK_HEADER_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH pub global CHECKPOINT_HEADER_LENGTH: u32 = 1 /* last_archive_root */ + 1 /* block_headers_hash */ + 1 /* blobs_hash */ - + 1 /* in_hash */ + + 1 /* inbox_rolling_hash */ + 1 /* out_hash */ + 1 /* slot_number */ + 1 /* timestamp */ @@ -621,20 +635,25 @@ pub global BLOCK_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = CHECKPOINT_CONSTANT_DATA_LEN + 2 * SPONGE_BLOB_LENGTH /* start_sponge_blob and end_sponge_blob */ + 1 /* timestamp */ + 1 /* block_headers_hash */ - + 1 /* in_hash */ + + 1 /* is_first_block */ + + 2 * L1_TO_L2_MESSAGE_SPONGE_LENGTH /* start_msg_sponge and end_msg_sponge */ + 1 /* out_hash */ + 1 /* accumulated_fees */ + 1 /* accumulated_mana_used */; pub global CHECKPOINT_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = EPOCH_CONSTANT_DATA_LENGTH + 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH /* previous_archive and new_archive */ - + MAX_CHECKPOINTS_PER_EPOCH /* checkpoint_header_hashes */ + 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH /* start_out_hash and end_out_hash */ + + 1 /* start_inbox_rolling_hash */ + + 1 /* end_inbox_rolling_hash */ + + MAX_CHECKPOINTS_PER_EPOCH /* checkpoint_header_hashes */ + MAX_CHECKPOINTS_PER_EPOCH * FEE_RECIPIENT_LENGTH /* fees */ + 2 * BLOB_ACCUMULATOR_LENGTH /* start and end blob accumulators */ + FINAL_BLOB_BATCHING_CHALLENGES_LENGTH; pub global ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = 1 /* previous_archive_root */ + 1 /* end_archive_root */ + 1 /* out_hash */ + + 1 /* previous_inbox_rolling_hash */ + + 1 /* end_inbox_rolling_hash */ + 1 /* chain_id */ + 1 /* version */ + 1 /* vk_tree_root */ @@ -644,11 +663,11 @@ pub global ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = 1 /* previous_archive_root */ + MAX_CHECKPOINTS_PER_EPOCH * FEE_RECIPIENT_LENGTH /* fees */ + FINAL_BLOB_ACCUMULATOR_LENGTH /* blob_public_inputs */; -// Depends on the final number of messages per checkpoint. -pub global NUM_MSGS_PER_BASE_PARITY: u32 = 256; -// pub global NUM_BASE_PARITY_PER_ROOT_PARITY: u32 = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP / NUM_MSGS_PER_BASE_PARITY; -// FIX: Sadly, writing this as above causes a type error in type_conversion.ts. -pub global NUM_BASE_PARITY_PER_ROOT_PARITY: u32 = 4; +// The InboxParity size ladder: one variable-size parity proof is produced per checkpoint, and the prover picks the +// smallest size >= the checkpoint's real message count. The largest rung equals the per-checkpoint message cap. +pub global INBOX_PARITY_SIZE_SMALL: u32 = 64; +pub global INBOX_PARITY_SIZE_MEDIUM: u32 = 256; +pub global INBOX_PARITY_SIZE_LARGE: u32 = 1024; // Lengths of the different types of proofs in fields pub global RECURSIVE_PROOF_LENGTH: u32 = 410; @@ -1411,9 +1430,9 @@ mod test { use crate::merkle_tree::root::compute_empty_sha_tree_root; use crate::traits::ToField; use super::{ - GLOBAL_INDEX_CONTRACT_MIN_REVERTIBLE_SIDE_EFFECT_COUNTER_OFFSET, MAX_ETH_ADDRESS_VALUE, - NUM_BASE_PARITY_PER_ROOT_PARITY, NUM_MSGS_PER_BASE_PARITY, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, TOTAL_COUNTED_SIDE_EFFECTS_PER_CALL, + GLOBAL_INDEX_CONTRACT_MIN_REVERTIBLE_SIDE_EFFECT_COUNTER_OFFSET, INBOX_PARITY_SIZE_LARGE, + MAX_ETH_ADDRESS_VALUE, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + TOTAL_COUNTED_SIDE_EFFECTS_PER_CALL, }; #[test] @@ -1458,10 +1477,8 @@ mod test { #[test] fn parity_covers_all_l1_to_l2_msgs() { - assert_eq( - NUM_BASE_PARITY_PER_ROOT_PARITY * NUM_MSGS_PER_BASE_PARITY, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - ); + // The largest InboxParity rung must be able to hold a full checkpoint's worth of messages. + assert_eq(INBOX_PARITY_SIZE_LARGE, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT); } #[test] diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr index 4cd8804ddbe0..757d1941ea08 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr @@ -5,6 +5,7 @@ use crate::{ merkle_tree::{merkle_hash, sha_merkle_hash}, root::{compute_empty_tree_root_with_hasher, root_from_sibling_path_with_hasher}, }, + utils::arrays::assert_trailing_zeros, }; pub fn append_leaf_to_snapshot( @@ -104,6 +105,150 @@ pub fn insert_subtree_root_to_snapshot_with_hasher( + snapshot: AppendOnlyTreeSnapshot, + leaves: [Field; MaxLeaves], + num_leaves: u32, + frontier_hint: [Field; TreeHeight], +) -> AppendOnlyTreeSnapshot { + // We cast the leaf index to a u64, so heights above 64 would insert at the wrong index once the tree grows past + // 2^64 leaves. Checking at compile time turns a bad instantiation into a build error rather than a circuit no + // prover can satisfy. + std::static_assert( + TreeHeight <= 64, + "`append_leaves_to_snapshot` does not support trees with height greater than 64", + ); + assert(num_leaves <= MaxLeaves, "num_leaves is greater than the leaves array length"); + // Hint lanes past `num_leaves` must be zero so they cannot smuggle values into anything a caller later absorbs. + assert_trailing_zeros(leaves, num_leaves); + + // `zero_subtree_roots[level]` is the root of an all-zero subtree of height `level`; index 0 is the empty leaf, 0. + let mut zero_subtree_roots = [0; TreeHeight]; + for level in 1..TreeHeight { + zero_subtree_roots[level] = + merkle_hash(zero_subtree_roots[level - 1], zero_subtree_roots[level - 1]); + } + + // The cast below truncates, so an index above 2^64 would silently drop its high bits and append at the wrong + // position. Callers keep the index far below that by only ever advancing it by the number of leaves appended, but + // nothing in this function's signature enforces it, so pin it here. + snapshot.next_available_leaf_index.assert_max_bit_size::<64>(); + let start_index = snapshot.next_available_leaf_index as u64; + let end_index = start_index + num_leaves as u64; + // Guard against wrapping past the tree capacity, which would otherwise silently produce a wrong root. + let mut tree_is_filled_exactly = false; + if TreeHeight < 64 { + let capacity = 1 as u64 << TreeHeight as u64; + assert(end_index <= capacity, "append_leaves_to_snapshot exceeds the tree capacity"); + tree_is_filled_exactly = end_index == capacity; + } + + // Validate the hint pins to the snapshot: recompute the root of a tree holding `start_index` leaves from the hint's + // left siblings and the zero subtrees to the right. + assert( + recompute_root_from_frontier(frontier_hint, zero_subtree_roots, start_index) + == snapshot.root, + "Frontier hint does not match the snapshot root", + ); + + // Merge the batch into the frontier one level at a time. At each level, `working` holds the batch's nodes, + // starting at absolute position `s` with `c` real entries (lanes past `c` hold garbage that is never read): + // - If `s` is odd the batch starts as a right child, so its pending left sibling — the validated hint entry — is + // prepended via a mux shift (no hashes) to make the batch start even. + // - If the count is then odd, the dangling last node sits at an even position: it is the level's new pending left + // child, so it becomes the frontier entry and drops out of pairing. On an even count the old entry is left in + // place; at the new tree size it is unused garbage, just like unread hint lanes. + // - The remaining nodes are hashed pairwise into the next level. + let mut frontier = frontier_hint; + let mut working = [0; MaxLeaves + 2]; + for i in 0..MaxLeaves { + working[i] = leaves[i]; + } + let mut s = start_index; + let mut c = num_leaves; + for level in 0..TreeHeight { + let prepend = (s % 2 == 1) & (c != 0); + let mut shifted = [0; MaxLeaves + 2]; + shifted[0] = if prepend { frontier[level] } else { working[0] }; + // The loop bounds below only need to upper-bound the batch size at this level; the shift amounts are clamped + // below 32 because a u32 shift by 32+ does not const-fold, and `MaxLeaves >> 31` is already 0. + for j in 1..(MaxLeaves >> std::cmp::min(level, 31)) + 2 { + shifted[j] = if prepend { working[j - 1] } else { working[j] }; + } + let s2 = s - prepend as u64; + let c2 = c + prepend as u32; + + // `c2 - 1` is only meaningful when `c2` is odd (hence >= 1); the subtraction is kept unconditionally safe. + let dangling_index = c2 - (c2 != 0) as u32; + frontier[level] = if c2 % 2 == 1 { + shifted[dangling_index] + } else { + frontier[level] + }; + + for i in 0..(MaxLeaves >> std::cmp::min(level + 1, 31)) + 1 { + working[i] = merkle_hash(shifted[2 * i], shifted[2 * i + 1]); + } + s = s2 / 2; + c = c2 / 2; + } + + // The frontier is now the end-state frontier, so the final root falls out of the same recomputation used to + // validate the hint. The exception is an append that fills the tree exactly: a full tree has no representable + // frontier, but in that case the batch was merged all the way up and `working[0]` is the root itself. + let root = if num_leaves == 0 { + snapshot.root + } else if tree_is_filled_exactly { + working[0] + } else { + recompute_root_from_frontier(frontier, zero_subtree_roots, end_index) + }; + + AppendOnlyTreeSnapshot { + root, + next_available_leaf_index: snapshot.next_available_leaf_index + num_leaves as Field, + } +} + +/// Recomputes the root of an append-only tree that holds `index` leaves (positions `0..index` filled, the rest zero) +/// from its frontier of left siblings and the all-zero subtree roots to the right. +fn recompute_root_from_frontier( + frontier: [Field; TreeHeight], + zero_subtree_roots: [Field; TreeHeight], + index: u64, +) -> Field { + let mut node = 0; // the empty leaf sitting at `index` + let mut idx = index; + for level in 0..TreeHeight { + node = if idx % 2 == 0 { + merkle_hash(node, zero_subtree_roots[level]) + } else { + merkle_hash(frontier[level], node) + }; + idx = idx / 2; + } + node +} + mod tests { use crate::{ abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, @@ -304,3 +449,315 @@ mod tests { let _ = insert_subtree_root_to_snapshot::<64, 64>(empty_snapshot, sibling_path, 0); } } + +mod append_leaves_tests { + use crate::{ + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, + merkle_tree::{ + compute_empty_tree_root, + merkle_tree::{merkle_hash, MerkleTree}, + test_utils::compute_zero_hashes, + }, + utils::arrays::subarray, + }; + use super::{append_leaves_to_snapshot, insert_subtree_root_to_snapshot}; + + fn padded(items: [Field; N]) -> [Field; M] { + let mut out = [0; M]; + for i in 0..N { + out[i] = items[i]; + } + out + } + + fn empty_snapshot() -> AppendOnlyTreeSnapshot { + AppendOnlyTreeSnapshot { + root: compute_empty_tree_root::(), + next_available_leaf_index: 0, + } + } + + #[test] + fn append_empty_bundle_is_noop() { + let snapshot = empty_snapshot::<5>(); + let result = append_leaves_to_snapshot::<5, 8>(snapshot, [0; 8], 0, [0; 5]); + assert_eq(result, snapshot); + } + + #[test] + fn append_single_leaf() { + let snapshot = empty_snapshot::<5>(); + let leaves: [Field; 8] = padded([42]); + let result = append_leaves_to_snapshot::<5, 8>(snapshot, leaves, 1, [0; 5]); + + let expected_root = MerkleTree::<32>::new(padded([42])).get_root(); + assert_eq(result.root, expected_root); + assert_eq(result.next_available_leaf_index, 1); + } + + #[test] + fn append_at_non_aligned_index() { + // Tree already holds 3 leaves, so the next index (3) is not aligned to any power-of-two boundary. + let before_root = MerkleTree::<32>::new(padded([11, 22, 33])).get_root(); + let snapshot = AppendOnlyTreeSnapshot { root: before_root, next_available_leaf_index: 3 }; + // Frontier at index 3: level 0 left sibling is leaf 2 (33), level 1 left sibling is hash(leaf0, leaf1). + // Higher levels are left children at index 3, so their hint entries are unused (and left zero). + let frontier = [33, merkle_hash(11, 22), 0, 0, 0]; + + let new_leaves: [Field; 8] = padded([44, 55]); + let result = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 2, frontier); + + let expected_root = MerkleTree::<32>::new(padded([11, 22, 33, 44, 55])).get_root(); + assert_eq(result.root, expected_root); + assert_eq(result.next_available_leaf_index, 5); + } + + #[test] + fn append_max_size_bundle() { + let snapshot = empty_snapshot::<5>(); + let leaves = [101, 102, 103, 104, 105, 106, 107, 108]; + let result = append_leaves_to_snapshot::<5, 8>(snapshot, leaves, 8, [0; 5]); + + let expected_root = MerkleTree::<32>::new(padded(leaves)).get_root(); + assert_eq(result.root, expected_root); + assert_eq(result.next_available_leaf_index, 8); + } + + #[test] + fn append_partial_bundle_skips_padding_lanes() { + let snapshot = empty_snapshot::<5>(); + let leaves: [Field; 8] = padded([11, 22, 33]); + let result = append_leaves_to_snapshot::<5, 8>(snapshot, leaves, 3, [0; 5]); + + let expected_root = MerkleTree::<32>::new(padded([11, 22, 33])).get_root(); + assert_eq(result.root, expected_root); + assert_eq(result.next_available_leaf_index, 3); + } + + #[test] + fn append_matches_subtree_insert_small() { + // Appending 8 compact leaves at aligned index 0 reproduces inserting a height-3 subtree of the same leaves. + let snapshot = empty_snapshot::<5>(); + let leaves = [101, 102, 103, 104, 105, 106, 107, 108]; + + let subtree_root = MerkleTree::<8>::new(leaves).get_root(); + let sibling_path: [Field; 2] = subarray(compute_zero_hashes::<5>(), 2); + let ref_snapshot = + insert_subtree_root_to_snapshot::<5, 3>(snapshot, sibling_path, subtree_root); + + let leaves8: [Field; 8] = leaves; + let app_snapshot = append_leaves_to_snapshot::<5, 8>(snapshot, leaves8, 8, [0; 5]); + + assert_eq(app_snapshot, ref_snapshot); + } + + #[test] + fn append_matches_subtree_insert_1024() { + // The transitional first-block scenario: appending a full 1024-leaf bundle at aligned index 0 into the + // production-height (36) tree must reproduce today's fixed height-10 subtree insertion bit-for-bit. + let mut leaves = [0; 1024]; + for i in 0..1024 { + leaves[i] = (i + 1) as Field; + } + + let snapshot = empty_snapshot::<36>(); + + let subtree_root = MerkleTree::<1024>::new(leaves).get_root(); + let sibling_path: [Field; 26] = subarray(compute_zero_hashes::<36>(), 9); + let ref_snapshot = + insert_subtree_root_to_snapshot::<36, 10>(snapshot, sibling_path, subtree_root); + + let app_snapshot = append_leaves_to_snapshot::<36, 1024>(snapshot, leaves, 1024, [0; 36]); + + // Both paths produce root 0x27b87d4d3b78d1fc49a6cb4d83e0cc81de7f5972cda7fe29a6a82aa2c255cb3d. + assert_eq(app_snapshot.root, ref_snapshot.root); + assert_eq(app_snapshot.next_available_leaf_index, 1024); + } + + #[test(should_fail_with = "Frontier hint does not match the snapshot root")] + fn append_wrong_frontier_hint_fails() { + let before_root = MerkleTree::<32>::new(padded([11, 22, 33])).get_root(); + let snapshot = AppendOnlyTreeSnapshot { root: before_root, next_available_leaf_index: 3 }; + // Corrupt a pinned frontier entry (level 0), which the root recomputation must reject. + let frontier = [34, merkle_hash(11, 22), 0, 0, 0]; + + let new_leaves: [Field; 8] = padded([44, 55]); + let _ = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 2, frontier); + } + + #[test] + fn append_ignores_unpinned_frontier_lanes() { + // At start index 3 only levels 0 and 1 are right children, so those are the only hint lanes the validation + // reads; the rest are unpinned and entirely prover-chosen. A tree database answering with a sibling path puts + // the zero-subtree roots there, while the tests here pass zeros. Neither may influence the result. + let before_root = MerkleTree::<32>::new(padded([11, 22, 33])).get_root(); + let snapshot = AppendOnlyTreeSnapshot { root: before_root, next_available_leaf_index: 3 }; + let new_leaves: [Field; 8] = padded([44, 55]); + let expected_root = MerkleTree::<32>::new(padded([11, 22, 33, 44, 55])).get_root(); + + // `compute_zero_hashes[i]` is the root of an all-zero subtree of height `i + 1`, i.e. the right sibling a + // sibling path carries at level `i + 1`. + let zero_hashes = compute_zero_hashes::<5>(); + let from_db = [33, merkle_hash(11, 22), zero_hashes[1], zero_hashes[2], zero_hashes[3]]; + let adversarial = [33, merkle_hash(11, 22), 0xdead, 0xbeef, 0xf00d]; + + let from_db_result = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 2, from_db); + assert_eq(from_db_result.root, expected_root); + assert_eq(from_db_result.next_available_leaf_index, 5); + + let junk_result = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 2, adversarial); + assert_eq(junk_result.root, expected_root); + assert_eq(junk_result.next_available_leaf_index, 5); + } + + #[test] + fn append_reuses_stale_pinned_frontier_entry() { + // Appending one leaf at index 5 leaves level 2 untouched by the merge: the batch has no node there. The final + // root recomputation still reads that entry, because the end index 6 is a right child at level 2. The reuse is + // sound only because the start index 5 is a right child at level 2 as well, so the entry is pinned. + let before_root = MerkleTree::<32>::new(padded([11, 22, 33, 44, 55])).get_root(); + let snapshot = AppendOnlyTreeSnapshot { root: before_root, next_available_leaf_index: 5 }; + let level_2_node = merkle_hash(merkle_hash(11, 22), merkle_hash(33, 44)); + let frontier = [55, 0, level_2_node, 0, 0]; + + let new_leaves: [Field; 8] = padded([66]); + let result = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 1, frontier); + + let expected_root = MerkleTree::<32>::new(padded([11, 22, 33, 44, 55, 66])).get_root(); + assert_eq(result.root, expected_root); + assert_eq(result.next_available_leaf_index, 6); + } + + #[test(should_fail_with = "Frontier hint does not match the snapshot root")] + fn append_wrong_stale_pinned_frontier_entry_fails() { + // The level-2 entry that `append_reuses_stale_pinned_frontier_entry` reuses is pinned, so corrupting it is + // rejected instead of silently producing a wrong root. + let before_root = MerkleTree::<32>::new(padded([11, 22, 33, 44, 55])).get_root(); + let snapshot = AppendOnlyTreeSnapshot { root: before_root, next_available_leaf_index: 5 }; + let level_2_node = merkle_hash(merkle_hash(11, 22), merkle_hash(33, 44)); + let frontier = [55, 0, level_2_node + 1, 0, 0]; + + let new_leaves: [Field; 8] = padded([66]); + let _ = append_leaves_to_snapshot::<5, 8>(snapshot, new_leaves, 1, frontier); + } + + #[test] + fn append_filling_tree_exactly() { + // Filling the last four leaves of a height-4 tree takes the exact-fill branch: the post-state has no + // representable frontier, so the root comes from the top of the merged batch instead of a recomputation. + // Levels 0 and 1 are left children at index 12, so their junk hint lanes must not reach the result. + let mut pre_leaves = [0; 16]; + for i in 0..12 { + pre_leaves[i] = (100 + i) as Field; + } + let pre_tree = MerkleTree::new(pre_leaves); + let snapshot = + AppendOnlyTreeSnapshot { root: pre_tree.get_root(), next_available_leaf_index: 12 }; + // Levels 2 and 3 are right children at index 12: the node over leaves 8..11 and the node over leaves 0..7. + let level_2_node = merkle_hash(merkle_hash(108, 109), merkle_hash(110, 111)); + let left_half = MerkleTree::<8>::new([100, 101, 102, 103, 104, 105, 106, 107]); + let frontier = [0xdead, 0xbeef, level_2_node, left_half.get_root()]; + + let batch: [Field; 6] = padded([201, 202, 203, 204]); + let result = append_leaves_to_snapshot::<4, 6>(snapshot, batch, 4, frontier); + + let mut all_leaves = pre_leaves; + for i in 0..4 { + all_leaves[12 + i] = (201 + i) as Field; + } + assert_eq(result.root, MerkleTree::new(all_leaves).get_root()); + assert_eq(result.next_available_leaf_index, 16); + } + + #[test(should_fail_with = "append_leaves_to_snapshot exceeds the tree capacity")] + fn append_past_tree_capacity_fails() { + // A height-4 tree holds 16 leaves, so appending 3 from index 14 overruns it. The capacity check runs before + // the hint validation, hence the all-zero frontier here. + let mut pre_leaves = [0; 16]; + for i in 0..14 { + pre_leaves[i] = (100 + i) as Field; + } + let pre_tree = MerkleTree::new(pre_leaves); + let snapshot = + AppendOnlyTreeSnapshot { root: pre_tree.get_root(), next_available_leaf_index: 14 }; + + let batch: [Field; 6] = padded([201, 202, 203]); + let _ = append_leaves_to_snapshot::<4, 6>(snapshot, batch, 3, [0; 4]); + } + + #[test(should_fail_with = "Found non-zero field after breakpoint")] + fn append_non_zero_padding_lane_fails() { + let snapshot = empty_snapshot::<5>(); + // num_leaves is 1, but a later lane carries a non-zero value. + let leaves = [42, 0, 99, 0, 0, 0, 0, 0]; + let _ = append_leaves_to_snapshot::<5, 8>(snapshot, leaves, 1, [0; 5]); + } + + /// Extracts the frontier at `index` from a height-4 reference tree: the node at each level's position + /// `(index >> level) - 1` when that position is odd, i.e. the pending left sibling. + unconstrained fn frontier_of_height_4_tree(tree: MerkleTree<16>, index: u32) -> [Field; 4] { + // Level offsets into `MerkleTree.nodes` for N = 16: level 1 starts at 0, level 2 at 8, level 3 at 12. + let offsets = [0, 8, 12]; + let mut frontier = [0; 4]; + if index % 2 == 1 { + frontier[0] = tree.leaves[index - 1]; + } + for level in 1..4 { + let p = index >> level; + if p % 2 == 1 { + frontier[level] = tree.nodes[offsets[level - 1] + p - 1]; + } + } + frontier + } + + #[test] + unconstrained fn append_exhaustive_small_tree_sweep() { + // Height-4 tree (capacity 16) with MaxLeaves = 6: every (start, num) with start + num <= capacity, compared + // against a reference tree built over the concatenated leaves. Exercises every parity combination of the + // prepend/dangling logic, including appends that fill the tree exactly. + for start in 0..16 { + for num in 0..7 { + if start + num <= 16 { + let mut pre_leaves = [0; 16]; + for i in 0..start { + pre_leaves[i] = (100 + i) as Field; + } + let pre_tree = MerkleTree::new(pre_leaves); + let snapshot = AppendOnlyTreeSnapshot { + root: pre_tree.get_root(), + next_available_leaf_index: start as Field, + }; + let frontier = frontier_of_height_4_tree(pre_tree, start); + + let mut batch = [0; 6]; + let mut all_leaves = pre_leaves; + for i in 0..num { + let value = (200 + start + i) as Field; + batch[i] = value; + all_leaves[start + i] = value; + } + + let result = append_leaves_to_snapshot::<4, 6>(snapshot, batch, num, frontier); + + let expected_tree = MerkleTree::new(all_leaves); + assert_eq(result.root, expected_tree.get_root()); + assert_eq(result.next_available_leaf_index, (start + num) as Field); + } + } + } + } + + #[test(should_fail_with = "Frontier hint does not match the snapshot root")] + fn append_to_completely_full_tree_fails() { + // A full tree has no representable frontier; even a num_leaves = 0 call fails hint validation (fail-closed). + let mut leaves = [0; 16]; + for i in 0..16 { + leaves[i] = (100 + i) as Field; + } + let tree = MerkleTree::new(leaves); + let snapshot = + AppendOnlyTreeSnapshot { root: tree.get_root(), next_available_leaf_index: 16 }; + let _ = append_leaves_to_snapshot::<4, 6>(snapshot, [0; 6], 0, [0; 4]); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr b/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr index b56b419c225d..7883a04a4f8b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr @@ -23,7 +23,7 @@ impl Poseidon2Sponge { Poseidon2Sponge::hash_internal(input, message_size, message_size != N) } - pub(crate) fn new(iv: Field) -> Poseidon2Sponge { + pub fn new(iv: Field) -> Poseidon2Sponge { let mut result = Poseidon2Sponge { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false }; result.state[RATE] = iv; diff --git a/noir-projects/noir-protocol-circuits/pinned-build.tar.gz b/noir-projects/noir-protocol-circuits/pinned-build.tar.gz deleted file mode 100644 index f9f2151659bf..000000000000 Binary files a/noir-projects/noir-protocol-circuits/pinned-build.tar.gz and /dev/null differ diff --git a/noir-projects/noir-protocol-circuits/private_kernel_reset_config.json b/noir-projects/noir-protocol-circuits/private_kernel_reset_config.json index 0735ad3580a2..928919fa84aa 100644 --- a/noir-projects/noir-protocol-circuits/private_kernel_reset_config.json +++ b/noir-projects/noir-protocol-circuits/private_kernel_reset_config.json @@ -1,28 +1,28 @@ { "inner": [ - { "name": "inner_sm", "dimensions": [4, 4, 4, 4, 4, 4, 0, 0, 0], "cost": 63990 }, - { "name": "inner_lg", "dimensions": [32, 32, 32, 32, 16, 16, 0, 0, 0], "cost": 156931 }, - { "name": "inner_nhpr_overflow", "dimensions": [64, 0, 0, 0, 0, 0, 0, 0, 0], "cost": 42301 }, - { "name": "inner_nhsr_overflow", "dimensions": [0, 64, 0, 0, 0, 0, 0, 0, 0], "cost": 130489 }, - { "name": "inner_nfpr_overflow", "dimensions": [0, 0, 64, 0, 0, 0, 0, 0, 0], "cost": 42301 }, - { "name": "inner_nfsr_overflow", "dimensions": [0, 0, 0, 64, 0, 0, 0, 0, 0], "cost": 133206 }, - { "name": "inner_key_overflow", "dimensions": [0, 0, 0, 0, 64, 0, 0, 0, 0], "cost": 81902 }, - { "name": "inner_squash_overflow", "dimensions": [0, 0, 0, 0, 0, 64, 0, 0, 0], "cost": 54735 } + { "name": "inner_sm", "dimensions": [4, 4, 4, 4, 4, 4, 0, 0, 0], "cost": 67089 }, + { "name": "inner_lg", "dimensions": [32, 32, 32, 32, 16, 16, 0, 0, 0], "cost": 160999 }, + { "name": "inner_nhpr_overflow", "dimensions": [64, 0, 0, 0, 0, 0, 0, 0, 0], "cost": 44307 }, + { "name": "inner_nhsr_overflow", "dimensions": [0, 64, 0, 0, 0, 0, 0, 0, 0], "cost": 132216 }, + { "name": "inner_nfpr_overflow", "dimensions": [0, 0, 64, 0, 0, 0, 0, 0, 0], "cost": 44307 }, + { "name": "inner_nfsr_overflow", "dimensions": [0, 0, 0, 64, 0, 0, 0, 0, 0], "cost": 134939 }, + { "name": "inner_key_overflow", "dimensions": [0, 0, 0, 0, 64, 0, 0, 0, 0], "cost": 83060 }, + { "name": "inner_squash_overflow", "dimensions": [0, 0, 0, 0, 0, 64, 0, 0, 0], "cost": 58030 } ], "finalTail": [ - { "name": "md_pay", "dimensions": [0, 8, 0, 8, 4, 0, 4, 16, 8], "cost": 71775 }, - { "name": "all_4", "dimensions": [4, 4, 4, 4, 4, 4, 4, 4, 4], "cost": 69253 }, - { "name": "all_8", "dimensions": [8, 8, 8, 8, 8, 8, 8, 8, 8], "cost": 85476 }, - { "name": "all_16", "dimensions": [16, 16, 16, 16, 16, 16, 16, 16, 16], "cost": 117920 }, - { "name": "all_32", "dimensions": [32, 32, 32, 32, 32, 32, 32, 32, 32], "cost": 182808 }, - { "name": "all_64", "dimensions": [64, 64, 64, 64, 64, 64, 64, 64, 64], "cost": 312870 } + { "name": "md_pay", "dimensions": [0, 8, 0, 8, 4, 0, 4, 16, 8], "cost": 73990 }, + { "name": "all_4", "dimensions": [4, 4, 4, 4, 4, 4, 4, 4, 4], "cost": 72722 }, + { "name": "all_8", "dimensions": [8, 8, 8, 8, 8, 8, 8, 8, 8], "cost": 89167 }, + { "name": "all_16", "dimensions": [16, 16, 16, 16, 16, 16, 16, 16, 16], "cost": 122054 }, + { "name": "all_32", "dimensions": [32, 32, 32, 32, 32, 32, 32, 32, 32], "cost": 187831 }, + { "name": "all_64", "dimensions": [64, 64, 64, 64, 64, 64, 64, 64, 64], "cost": 319669 } ], "finalTailToPublic": [ - { "name": "md_pay", "dimensions": [0, 8, 0, 8, 4, 0, 4, 16, 8], "cost": 100827 }, - { "name": "all_4", "dimensions": [4, 4, 4, 4, 4, 4, 4, 4, 4], "cost": 98307 }, - { "name": "all_8", "dimensions": [8, 8, 8, 8, 8, 8, 8, 8, 8], "cost": 114528 }, - { "name": "all_16", "dimensions": [16, 16, 16, 16, 16, 16, 16, 16, 16], "cost": 146968 }, - { "name": "all_32", "dimensions": [32, 32, 32, 32, 32, 32, 32, 32, 32], "cost": 211854 }, - { "name": "all_64", "dimensions": [64, 64, 64, 64, 64, 64, 64, 64, 64], "cost": 341888 } + { "name": "md_pay", "dimensions": [0, 8, 0, 8, 4, 0, 4, 16, 8], "cost": 104206 }, + { "name": "all_4", "dimensions": [4, 4, 4, 4, 4, 4, 4, 4, 4], "cost": 102939 }, + { "name": "all_8", "dimensions": [8, 8, 8, 8, 8, 8, 8, 8, 8], "cost": 119382 }, + { "name": "all_16", "dimensions": [16, 16, 16, 16, 16, 16, 16, 16, 16], "cost": 152266 }, + { "name": "all_32", "dimensions": [32, 32, 32, 32, 32, 32, 32, 32, 32], "cost": 218040 }, + { "name": "all_64", "dimensions": [64, 64, 64, 64, 64, 64, 64, 64, 64], "cost": 349850 } ] } diff --git a/playground/vite.config.ts b/playground/vite.config.ts index 203141d50d52..e8b7ad459007 100644 --- a/playground/vite.config.ts +++ b/playground/vite.config.ts @@ -145,9 +145,10 @@ export default defineConfig(({ mode }) => { // - JB: bumped from 1750 => 1800 after adding the `aztec_utl_getTxEffect` oracle handler, which pulls TxEffect / FlatPublicLogs / PrivateLog / PublicDataWrite into the eager PXE import path (#22979). // - 2026-05-12: bumped from 1800 => 1850 after merge-train/barretenberg brought in further bb-side changes (multi-app kernel circuits #23076 etc.) that pushed the main entrypoint to 1801.31 KB, just over the limit raised four days earlier. // - 2026-06-08: bumped from 1850 => 1925 after aztec RPC namespace / client surface changes pushed the main entrypoint to 1872.57 KB on CI (playground cold build). + // - 2026-07-17: bumped from 1925 => 1960 after the fast-inbox per-block L1-to-L2 message bundle changes to the rollup circuit artifacts pushed the main entrypoint to 1936.60 KB on CI. { pattern: /assets\/index-.*\.js$/, - maxSizeKB: 1925, + maxSizeKB: 1960, description: 'Main entrypoint, hard limit', }, // Bump log: diff --git a/spartan/environments/bench-10tps.env b/spartan/environments/bench-10tps.env index 3e7899fe1916..fd3222ca3961 100644 --- a/spartan/environments/bench-10tps.env +++ b/spartan/environments/bench-10tps.env @@ -18,7 +18,6 @@ AZTEC_SLOT_DURATION=72 AZTEC_PROOF_SUBMISSION_EPOCHS=2 AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -AZTEC_INBOX_LAG=2 # 2B mana target - good for about ~800 txs at 2.5M mana each AZTEC_MANA_TARGET=2000000000 diff --git a/spartan/environments/bench-inclusion-sweep.env b/spartan/environments/bench-inclusion-sweep.env index 393dadcbf755..fcb2a94fc18f 100644 --- a/spartan/environments/bench-inclusion-sweep.env +++ b/spartan/environments/bench-inclusion-sweep.env @@ -19,7 +19,6 @@ AZTEC_SLOT_DURATION=72 AZTEC_PROOF_SUBMISSION_EPOCHS=100 AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=1 AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=1 -AZTEC_INBOX_LAG=2 AZTEC_MANA_TARGET=2000000000 diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index 6b6bb4bf127b..a412219b9a34 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -59,8 +59,6 @@ l1-contracts: &l1-contracts-defaults #--------------------------------------------------------------------------- # Proof & Block Configuration #--------------------------------------------------------------------------- - # Checkpoints to lag in inbox (prevents sequencer DOS attacks). - AZTEC_INBOX_LAG: 2 # Epochs after end that proofs are still accepted. AZTEC_PROOF_SUBMISSION_EPOCHS: 1 # Target mana consumption per block. diff --git a/spartan/environments/next-net.env b/spartan/environments/next-net.env index de59eced52a6..4a6ba4281702 100644 --- a/spartan/environments/next-net.env +++ b/spartan/environments/next-net.env @@ -39,7 +39,6 @@ SEQ_MAX_TX_PER_CHECKPOINT=12 SEQ_BUILD_CHECKPOINT_IF_EMPTY=true SEQ_BLOCK_DURATION_MS=5500 -AZTEC_INBOX_LAG=2 VALIDATOR_REPLICAS=2 VALIDATORS_PER_NODE=24 diff --git a/spartan/environments/next-scenario.env b/spartan/environments/next-scenario.env index 1f5adb8ebf0f..b7b198419a04 100644 --- a/spartan/environments/next-scenario.env +++ b/spartan/environments/next-scenario.env @@ -7,7 +7,6 @@ DESTROY_ETH_DEVNET=true CREATE_ETH_DEVNET=true AZTEC_EPOCH_DURATION=32 AZTEC_SLOT_DURATION=36 -AZTEC_INBOX_LAG=2 ETHEREUM_CHAIN_ID=1337 LABS_INFRA_MNEMONIC="test test test test test test test test test test test junk" FUNDING_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" diff --git a/spartan/environments/staging-internal.env b/spartan/environments/staging-internal.env index 69da3a5a1fd6..c3568e106c9c 100644 --- a/spartan/environments/staging-internal.env +++ b/spartan/environments/staging-internal.env @@ -36,7 +36,6 @@ SPONSORED_FPC=false # Rollup AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 AZTEC_MANA_TARGET=75000000 AZTEC_PROVING_COST_PER_MANA=12500000 diff --git a/spartan/environments/staging-public.env b/spartan/environments/staging-public.env index 7749f4f3533a..4da560112d34 100644 --- a/spartan/environments/staging-public.env +++ b/spartan/environments/staging-public.env @@ -36,7 +36,6 @@ SPONSORED_FPC=false # Rollup AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET=2 AZTEC_LAG_IN_EPOCHS_FOR_RANDAO=2 -AZTEC_INBOX_LAG=2 AZTEC_MANA_TARGET=75000000 AZTEC_PROVING_COST_PER_MANA=12500000 diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index 5b574dfd8635..1165fc41a471 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -460,7 +460,6 @@ AZTEC_LAG_IN_EPOCHS_FOR_RANDAO = ${AZTEC_LAG_IN_EPOCHS_FOR_RANDAO:-null} AZTEC_SLOT_DURATION = ${AZTEC_SLOT_DURATION:-null} AZTEC_EPOCH_DURATION = ${AZTEC_EPOCH_DURATION:-null} AZTEC_TARGET_COMMITTEE_SIZE = ${AZTEC_TARGET_COMMITTEE_SIZE:-null} -AZTEC_INBOX_LAG = ${AZTEC_INBOX_LAG:-null} AZTEC_PROOF_SUBMISSION_EPOCHS = ${AZTEC_PROOF_SUBMISSION_EPOCHS:-null} AZTEC_ACTIVATION_THRESHOLD = ${AZTEC_ACTIVATION_THRESHOLD:-null} AZTEC_EJECTION_THRESHOLD = ${AZTEC_EJECTION_THRESHOLD:-null} diff --git a/spartan/terraform/deploy-rollup-contracts/main.tf b/spartan/terraform/deploy-rollup-contracts/main.tf index 690ef063b2e3..d1dd567cad99 100644 --- a/spartan/terraform/deploy-rollup-contracts/main.tf +++ b/spartan/terraform/deploy-rollup-contracts/main.tf @@ -43,7 +43,6 @@ locals { AZTEC_SLOT_DURATION = var.AZTEC_SLOT_DURATION AZTEC_EPOCH_DURATION = var.AZTEC_EPOCH_DURATION AZTEC_TARGET_COMMITTEE_SIZE = var.AZTEC_TARGET_COMMITTEE_SIZE - AZTEC_INBOX_LAG = var.AZTEC_INBOX_LAG AZTEC_PROOF_SUBMISSION_EPOCHS = var.AZTEC_PROOF_SUBMISSION_EPOCHS AZTEC_ACTIVATION_THRESHOLD = var.AZTEC_ACTIVATION_THRESHOLD AZTEC_EJECTION_THRESHOLD = var.AZTEC_EJECTION_THRESHOLD diff --git a/spartan/terraform/deploy-rollup-contracts/variables.tf b/spartan/terraform/deploy-rollup-contracts/variables.tf index f0031b7768ed..c40b8a2ef02a 100644 --- a/spartan/terraform/deploy-rollup-contracts/variables.tf +++ b/spartan/terraform/deploy-rollup-contracts/variables.tf @@ -86,12 +86,6 @@ variable "AZTEC_PROOF_SUBMISSION_EPOCHS" { nullable = true } -variable "AZTEC_INBOX_LAG" { - description = "Checkpoints to lag in inbox (prevents sequencer DOS attacks)" - type = string - nullable = true -} - variable "AZTEC_ACTIVATION_THRESHOLD" { description = "Aztec activation threshold" type = string diff --git a/yarn-project/archiver/README.md b/yarn-project/archiver/README.md index 959f16f819dc..29735e31f2ea 100644 --- a/yarn-project/archiver/README.md +++ b/yarn-project/archiver/README.md @@ -44,9 +44,9 @@ Two independent syncpoints track progress on L1: ### L1-to-L2 Messages -Messages are synced from the Inbox contract. The sync compares local state (message count and rolling hash) against the Inbox contract state on L1, downloads any missing messages, and verifies consistency afterwards. On success, the syncpoint advances to the current L1 block. On failure (L1 reorg or inconsistency), the syncpoint rolls back to the last known-good message and the operation retries (up to 3 times within the same sync iteration). +Messages are synced from the Inbox contract. The sync compares local state (message count and consensus rolling hash) against the Inbox's current rolling-hash bucket on L1, downloads any missing messages, and verifies consistency afterwards. On success, the syncpoint advances to the current L1 block. On failure (L1 reorg or inconsistency), the syncpoint rolls back to the last known-good message and the operation retries (up to 3 times within the same sync iteration). -1. Query Inbox state at the current L1 block (message count + rolling hash) +1. Query the Inbox's current bucket at the current L1 block (cumulative message count + consensus rolling hash) 2. Compare local state against remote 3. If they match, advance syncpoint and return 4. If mismatch, fetch `MessageSent` events in batches and store them @@ -55,7 +55,7 @@ Messages are synced from the Inbox contract. The sync compares local state (mess - If still mismatched (e.g., messages missed due to a concurrent L1 reorg), rollback and retry 6. On success, advance the syncpoint -The syncpoint and the `inboxTreeInProgress` marker (which tracks which checkpoint's messages are currently being filled on L1) are updated atomically. The marker is only advanced after messages are stored, so concurrent reads don't see an unsealed checkpoint as readable before its messages are available. +Messages are stored with compact (unpadded) global indices matching the Inbox's insertion order, and each carries the consensus rolling hash (a truncated sha256 chain) and the sequence of the Inbox bucket it was absorbed into (AZIP-22 Fast Inbox). Bucket snapshots let the sequencer and validator resolve message bundles per block. ### Checkpoints @@ -70,13 +70,12 @@ Checkpoints are synced from the Rollup contract via `handleCheckpoints()`: - Verify archive matches (checkpoint still in chain) - Validate attestations (2/3 + 1 committee signatures required) - Skip invalid checkpoints (see "Invalid Checkpoints" in Edge Cases) - - Verify `inHash` matches expected value (see below) - Store valid checkpoints with their blocks 6. Update proven checkpoint again (may have advanced after storing new checkpoints) 7. Handle epoch prune if applicable 8. Check for checkpoints behind syncpoint (L1 reorg case) -The `inHash` is a hash of all L1-to-L2 messages consumed by a checkpoint. The archiver computes the expected `inHash` from locally stored messages and compares it against the checkpoint header. A mismatch indicates a bug (messages out of sync with checkpoints) and causes a fatal error. +L1 enforces at propose time that a checkpoint header's consensus rolling hash matches the Inbox bucket the checkpoint consumes through (AZIP-22 Fast Inbox), so the archiver does not re-derive or cross-check a per-checkpoint message hash while syncing. The `blocksSynchedTo` syncpoint is updated: - When checkpoints are stored: set to the L1 block of the last stored checkpoint diff --git a/yarn-project/archiver/src/archiver-store.test.ts b/yarn-project/archiver/src/archiver-store.test.ts index d6f41c6925a8..b79ade3f86c9 100644 --- a/yarn-project/archiver/src/archiver-store.test.ts +++ b/yarn-project/archiver/src/archiver-store.test.ts @@ -462,6 +462,7 @@ describe('Archiver Store', () => { totalManaUsed: 100n, feeAssetPriceModifier: 0n, }); + return block; } it('returns the latest proposed entry when called with no args', async () => { @@ -477,6 +478,13 @@ describe('Archiver Store', () => { expect(result).toBeUndefined(); }); + it('reports the consumed Inbox total of the last block in the checkpoint', async () => { + const block = await addProposedCheckpoint(CheckpointNumber(1), SlotNumber(3), BlockNumber(1)); + + const result = await archiver.getProposedCheckpointData(); + expect(result!.inboxMsgTotal).toBe(BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex)); + }); + it('returns the latest proposed entry for tag=proposed', async () => { await addProposedCheckpoint(CheckpointNumber(1), SlotNumber(5), BlockNumber(1)); diff --git a/yarn-project/archiver/src/archiver-sync.test.ts b/yarn-project/archiver/src/archiver-sync.test.ts index c8595cfe9e43..05120d1a9798 100644 --- a/yarn-project/archiver/src/archiver-sync.test.ts +++ b/yarn-project/archiver/src/archiver-sync.test.ts @@ -16,6 +16,7 @@ import { sum, times } from '@aztec/foundation/collection'; import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { toArray } from '@aztec/foundation/iterable'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { retryFastUntil } from '@aztec/foundation/retry'; import { TestDateProvider } from '@aztec/foundation/timer'; @@ -23,7 +24,6 @@ import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { GENESIS_BLOCK_HEADER_HASH, L2BlockSourceEvents, type L2BlockSourceUpdatedEvent } from '@aztec/stdlib/block'; import type { ProposedCheckpointInput } from '@aztec/stdlib/checkpoint'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; -import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { mockCheckpointAndMessages } from '@aztec/stdlib/testing'; import { ConsensusTimetable } from '@aztec/stdlib/timetable'; @@ -37,7 +37,7 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import type { GetBlockReturnType } from 'viem'; import { Archiver, type ArchiverEmitter } from './archiver.js'; -import { BlockOrCheckpointSlotExpiredError, L1ToL2MessagesNotReadyError } from './errors.js'; +import { BlockOrCheckpointSlotExpiredError } from './errors.js'; import type { ArchiverInstrumentation } from './modules/instrumentation.js'; import { ArchiverL1Synchronizer } from './modules/l1_synchronizer.js'; import { type ArchiverDataStores, createArchiverDataStores } from './store/data_stores.js'; @@ -187,6 +187,11 @@ describe('Archiver Sync', () => { await archiver?.stop(); }); + // Returns every stored L1-to-L2 message leaf (as hex), in insertion order (compact indexing). + const getStoredLeaves = async () => + (await toArray(archiverStore.messages.iterateL1ToL2Messages())).map(m => m.leaf.toString()); + const asHex = (leaves: Fr[]) => leaves.map(l => l.toString()); + describe('basic sync', () => { it('syncs l1 to l2 messages and checkpoints', async () => { expect(await archiver.getCheckpointNumber()).toEqual(CheckpointNumber(0)); @@ -221,7 +226,7 @@ describe('Archiver Sync', () => { expect(await archiver.getCheckpointNumber()).toEqual(CheckpointNumber(1)); // Verify messages for checkpoint 1 - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toEqual(msgs1); + expect(await getStoredLeaves()).toEqual(asHex(msgs1)); // Mark checkpoint 1 as proven fake.markCheckpointAsProven(CheckpointNumber(1)); @@ -234,11 +239,8 @@ describe('Archiver Sync', () => { await archiver.syncImmediate(); expect(await archiver.getCheckpointNumber()).toEqual(CheckpointNumber(3)); - // Verify messages for all checkpoints - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toEqual(msgs1); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(2))).toEqual(msgs2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(3))).toEqual(msgs3); - await expect(archiver.getL1ToL2Messages(CheckpointNumber(4))).rejects.toThrow(L1ToL2MessagesNotReadyError); + // Verify messages for all checkpoints, stored contiguously in insertion order. + expect(await getStoredLeaves()).toEqual(asHex([...msgs1, ...msgs2, ...msgs3])); // Verify private logs are surfaced through the block body. for (const checkpoint of [cp1, cp2, cp3]) { @@ -259,6 +261,34 @@ describe('Archiver Sync', () => { expect( (await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 100 })).map(b => b.checkpoint.number), ).toEqual([1, 2, 3]); + + // Inbox buckets: each of the three L1 message blocks opened its own bucket, in insertion order. + const t1 = fake.getTimestampAtL1Block(98n); + const t2 = fake.getTimestampAtL1Block(2504n); + const t3 = fake.getTimestampAtL1Block(2511n); + + expect(await archiver.getInboxBucket(1n)).toMatchObject({ + seq: 1n, + msgCount: 3, + totalMsgCount: 3n, + timestamp: t1, + }); + expect(await archiver.getInboxBucket(3n)).toMatchObject({ + seq: 3n, + msgCount: 3, + totalMsgCount: 9n, + timestamp: t3, + }); + + // At-or-before lookups resolve the latest bucket not opened after the given timestamp. + expect((await archiver.getLatestInboxBucketAtOrBefore(t3))!.seq).toEqual(3n); + expect((await archiver.getLatestInboxBucketAtOrBefore(t2))!.seq).toEqual(2n); + expect(await archiver.getLatestInboxBucketAtOrBefore(t1 - 1n)).toBeUndefined(); + + // Messages between buckets, in insertion order. + expect(await archiver.getL1ToL2MessagesBetweenBuckets(0n, 3n)).toEqual([...msgs1, ...msgs2, ...msgs3]); + expect(await archiver.getL1ToL2MessagesBetweenBuckets(1n, 2n)).toEqual(msgs2); + expect(await archiver.getL1ToL2MessagesBetweenBuckets(2n, 3n)).toEqual(msgs3); }, 30_000); it('ignores checkpoint 3 because it has been pruned', async () => { @@ -308,53 +338,6 @@ describe('Archiver Sync', () => { ); }); - it('stop processing if one of the checkpoints has a mismatch inHash', async () => { - expect(await archiver.getCheckpointNumber()).toEqual(CheckpointNumber(0)); - - // Add checkpoint 1 and 2 with all messages visible - await fake.addCheckpoint(CheckpointNumber(1), { - l1BlockNumber: 70n, - messagesL1BlockNumber: 50n, - numL1ToL2Messages: 3, - }); - - await fake.addCheckpoint(CheckpointNumber(2), { - l1BlockNumber: 80n, - messagesL1BlockNumber: 60n, - numL1ToL2Messages: 3, - }); - - // Add checkpoint 3 with 3 messages at L1 block 100n - const { checkpoint: cp3, messages: msgs3 } = await fake.addCheckpoint(CheckpointNumber(3), { - l1BlockNumber: 90n, - messagesL1BlockNumber: 100n, - numL1ToL2Messages: 3, - }); - - // Move last 2 messages of checkpoint 3 to L1 block 103n (beyond current L1 block) - // This simulates partial message visibility - const totalMessages = 3 + 3 + 3; // 9 messages total - fake.moveMessageAtIndexToL1Block(totalMessages - 1, 103n); // Move last message - fake.moveMessageAtIndexToL1Block(totalMessages - 2, 103n); // Move second to last - - // Set current L1 block to 102n - only 1 message from checkpoint 3 will be visible - fake.setL1BlockNumber(102n); - - // The archiver will compute inHash from only the first message, - // which won't match the checkpoint's inHash (computed from all 3 messages) - const visibleMessages = msgs3.slice(0, 1); - const computedInHash = computeInHashFromL1ToL2Messages(visibleMessages); - - // Run archiver (expect failure) - await expect(() => archiver.syncImmediate()).rejects.toThrow( - new RegExp(`mismatch inHash for checkpoint 3.*${computedInHash}.*${cp3.header.inHash}`, 'i'), - ); - - // Should still be at checkpoint 0 since the error prevents checkpoint processing - // (checkpoints 1 and 2 also fail because they're in the same batch) - expect(await archiver.getCheckpointNumber()).toEqual(CheckpointNumber(0)); - }, 10_000); - it('skip event search if no changes found', async () => { const loggerSpy = jest.spyOn(syncLogger, 'debug'); @@ -458,29 +441,29 @@ describe('Archiver Sync', () => { logger.warn('Initial sync'); await archiver.syncImmediate(); - expect(inboxContract.getState).toHaveBeenCalledTimes(1); + expect(inboxContract.getCurrentBucket).toHaveBeenCalledTimes(1); expect(rollupContract.status).toHaveBeenCalledTimes(1); - inboxContract.getState.mockClear(); + inboxContract.getCurrentBucket.mockClear(); rollupContract.status.mockClear(); // We sync again, but since chain didn't move, no new calls should be expected logger.warn('Sync with no L1 advancement'); await archiver.syncImmediate(); - expect(inboxContract.getState).toHaveBeenCalledTimes(0); + expect(inboxContract.getCurrentBucket).toHaveBeenCalledTimes(0); expect(rollupContract.status).toHaveBeenCalledTimes(0); // Advance the chain and we should see calls again fake.setL1BlockNumber(150n); logger.warn('Sync after L1 advancement'); await archiver.syncImmediate(); - expect(inboxContract.getState).toHaveBeenCalledTimes(1); + expect(inboxContract.getCurrentBucket).toHaveBeenCalledTimes(1); expect(rollupContract.status).toHaveBeenCalledTimes(1); }); it('does not fetch messages when local and remote state both have zero messages', async () => { - // When there are no messages on L1, the remote inbox state has messagesRollingHash = Buffer16.ZERO - // and totalMessagesInserted = 0. The local store also returns 0 messages and undefined lastMessage. - // The fallback for the local rolling hash must use Buffer16.ZERO (not Buffer32.ZERO) to match. + // When there are no messages on L1, the remote Inbox current bucket is genesis (rolling hash Fr.ZERO, + // total 0). The local store also returns 0 messages and undefined lastMessage, whose rolling-hash fallback + // is Fr.ZERO — so local and remote state match and no message fetch is attempted. fake.setL1BlockNumber(100n); // Add a checkpoint with zero messages so the sync has something to process @@ -1112,10 +1095,7 @@ describe('Archiver Sync', () => { // Sync await archiver.syncImmediate(); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(0); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(4); - await expect(archiver.getL1ToL2Messages(CheckpointNumber(4))).rejects.toThrow(L1ToL2MessagesNotReadyError); + expect(await getStoredLeaves()).toEqual(asHex([...msgs1, ...msgs3])); // Simulate L1 reorg: remove last 2 messages from checkpoint 3, add new messages for checkpoints 4 and 5 logger.warn('Reorging L1 to L2 messages'); @@ -1132,18 +1112,8 @@ describe('Archiver Sync', () => { fake.setL1BlockNumber(111n); await archiver.syncImmediate(); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(0); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(2); // Reduced from 4 to 2 - expect(await archiver.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(1); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(5))).toHaveLength(2); - - expect((await archiver.getL1ToL2Messages(CheckpointNumber(4))).map(leaf => leaf.toString())).toEqual( - [msg40].map(leaf => leaf.toString()), - ); - expect((await archiver.getL1ToL2Messages(CheckpointNumber(5))).map(leaf => leaf.toString())).toEqual( - [msg50, msg51].map(leaf => leaf.toString()), - ); + // The reorg kept the first 4 messages (2 from CP1, 2 from CP3) and appended the new ones. + expect(await getStoredLeaves()).toEqual(asHex([msgs1[0], msgs1[1], msgs3[0], msgs3[1], msg40, msg50, msg51])); }); it('short-circuits rollback at the finalized L1 block', async () => { @@ -1159,8 +1129,7 @@ describe('Archiver Sync', () => { fake.setL1BlockNumber(110n); await archiver.syncImmediate(); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(4); + expect(await getStoredLeaves()).toEqual(asHex([...msgs1, ...msgs3])); // Simulate L1 reorg: remove the last 2 messages from checkpoint 3 and add new ones. fake.removeMessagesAfter(4); @@ -1181,8 +1150,7 @@ describe('Archiver Sync', () => { ); expect(callsAtFinalizedOrBelow).toHaveLength(0); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(1); + expect(await getStoredLeaves()).toEqual(asHex([msgs1[0], msgs1[1], msgs3[0], msgs3[1], msg40])); }); it('falls back to per-message log queries when finalized block is undefined', async () => { @@ -1211,8 +1179,7 @@ describe('Archiver Sync', () => { // 2 messages mismatch on remote (msgs3[2], msgs3[3]) and one matches (msgs3[1]) before we break. expect(eventByHashSpy).toHaveBeenCalledTimes(3); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(2); - expect(await archiver.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(1); + expect(await getStoredLeaves()).toEqual(asHex([msgs1[0], msgs1[1], msgs3[0], msgs3[1], msg40])); }); it('persists the finalized L1 block monotonically after message sync', async () => { diff --git a/yarn-project/archiver/src/archiver.ts b/yarn-project/archiver/src/archiver.ts index 501d624da8eb..1ba6df8b6d8d 100644 --- a/yarn-project/archiver/src/archiver.ts +++ b/yarn-project/archiver/src/archiver.ts @@ -764,14 +764,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra `Removing checkpoints after checkpoint ${targetCheckpointNumber} (target block ${targetL2BlockNumber})`, ); await this.updater.removeCheckpointsAfter(targetCheckpointNumber); - this.log.info(`Rolling back L1 to L2 messages to checkpoint ${targetCheckpointNumber}`); - await this.stores.messages.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber); + this.log.info(`Rolling back L1 to L2 messages inserted after L1 block ${targetL1BlockNumber}`); + await this.stores.messages.rollbackL1ToL2MessagesAfterL1Block(targetL1BlockNumber); this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`); await this.stores.blocks.setSynchedL1BlockNumber(targetL1BlockNumber); - await this.stores.messages.setMessageSyncState( - { l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash }, - undefined, - ); + await this.stores.messages.setMessageSyncState({ + l1BlockNumber: targetL1BlockNumber, + l1BlockHash: targetL1BlockHash, + }); if (targetL2BlockNumber < currentProvenBlock) { this.log.info(`Rolling back proven L2 checkpoint to ${targetCheckpointNumber}`); await this.updater.setProvenCheckpointNumber(targetCheckpointNumber); diff --git a/yarn-project/archiver/src/errors.ts b/yarn-project/archiver/src/errors.ts index db3be133c0b0..60661d9ea296 100644 --- a/yarn-project/archiver/src/errors.ts +++ b/yarn-project/archiver/src/errors.ts @@ -102,17 +102,25 @@ export class BlockAlreadyCheckpointedError extends Error { } } -/** Thrown when L1 to L2 messages are requested for a checkpoint whose message tree hasn't been sealed yet. */ -export class L1ToL2MessagesNotReadyError extends Error { - constructor( - public readonly checkpointNumber: number, - public readonly inboxTreeInProgress: bigint, - ) { - super( - `Cannot get L1 to L2 messages for checkpoint ${checkpointNumber}: ` + - `inbox tree in progress is ${inboxTreeInProgress}, messages not yet sealed`, - ); - this.name = 'L1ToL2MessagesNotReadyError'; +/** + * Thrown when a query names an Inbox bucket this archiver has not synced. Distinguishes "not synced yet, retry once + * L1 sync catches up" from a genuinely empty result. + */ +export class InboxBucketNotSyncedError extends Error { + constructor(public readonly bucketSeq: bigint) { + super(`Inbox bucket ${bucketSeq} has not been synced`); + this.name = 'InboxBucketNotSyncedError'; + } +} + +/** + * Thrown when a cumulative Inbox message count does not resolve to a bucket boundary this archiver has synced, either + * because the count sits inside a bucket or because the bucket is not synced yet. + */ +export class InboxBucketBoundaryNotSyncedError extends Error { + constructor(public readonly totalMsgCount: bigint) { + super(`No synced Inbox bucket ends at cumulative message count ${totalMsgCount}`); + this.name = 'InboxBucketBoundaryNotSyncedError'; } } diff --git a/yarn-project/archiver/src/l1/calldata_retriever.test.ts b/yarn-project/archiver/src/l1/calldata_retriever.test.ts index 716c3cb23b22..ce2fa5c3f3c3 100644 --- a/yarn-project/archiver/src/l1/calldata_retriever.test.ts +++ b/yarn-project/archiver/src/l1/calldata_retriever.test.ts @@ -140,6 +140,7 @@ describe('CalldataRetriever', () => { archive, oracleInput: { feeAssetPriceModifier: BigInt(0) }, header: viemHeader, + bucketHint: BigInt(0), }, attestations, signers, @@ -368,6 +369,7 @@ describe('CalldataRetriever', () => { archive, oracleInput: { feeAssetPriceModifier }, header, + bucketHint: BigInt(0), }, attestations, [], // signers @@ -1246,7 +1248,7 @@ describe('CalldataRetriever', () => { expect(result.blockHash).toBe(tx.blockHash); // Verify all components are properly decoded - expect(result.header.inHash).toBeInstanceOf(Fr); + expect(result.header.inboxRollingHash).toBeInstanceOf(Fr); expect(result.header.gasFees).toBeInstanceOf(GasFees); // Verify instrumentation was called @@ -1320,7 +1322,7 @@ describe('CalldataRetriever', () => { expect(result.blockHash).toBe(blockHash); // Verify all components are properly decoded - expect(result.header.inHash).toBeInstanceOf(Fr); + expect(result.header.inboxRollingHash).toBeInstanceOf(Fr); expect(result.header.gasFees).toBeInstanceOf(GasFees); // Verify proxy implementation was checked diff --git a/yarn-project/archiver/src/l1/data_retrieval.test.ts b/yarn-project/archiver/src/l1/data_retrieval.test.ts index 341d6b8b7fc6..93eed1186c01 100644 --- a/yarn-project/archiver/src/l1/data_retrieval.test.ts +++ b/yarn-project/archiver/src/l1/data_retrieval.test.ts @@ -16,9 +16,9 @@ describe('data_retrieval', () => { const body3 = await Body.random({ txsPerBlock: 2 }); // Convert to BlockBlobData - const block1BlobData = makeBlockBlobDataFromBody(body1, BlockNumber(1), true, 1000); - const block2BlobData = makeBlockBlobDataFromBody(body2, BlockNumber(2), false, 2000); - const block3BlobData = makeBlockBlobDataFromBody(body3, BlockNumber(3), false, 3000); + const block1BlobData = makeBlockBlobDataFromBody(body1, BlockNumber(1), 1000); + const block2BlobData = makeBlockBlobDataFromBody(body2, BlockNumber(2), 2000); + const block3BlobData = makeBlockBlobDataFromBody(body3, BlockNumber(3), 3000); // Calculate total blob fields for checkpoint end marker const numBlobFields = 100; // Approximate, doesn't need to be exact for this test @@ -79,11 +79,24 @@ describe('data_retrieval', () => { expect(reconstructedBlock1.body.txEffects.map(tx => tx.txHash.toString())).not.toEqual( reconstructedBlock3.body.txEffects.map(tx => tx.txHash.toString()), ); + + // Each block's L1-to-L2 message tree root must be reconstructed from its own blob data, not the + // checkpoint's first block. Any block can insert messages, so + // intra-checkpoint blocks carry distinct roots; using the first block's root forks follower nodes. + expect(reconstructedBlock1.header.state.l1ToL2MessageTree.root.toString()).toEqual( + block1BlobData.l1ToL2MessageRoot.toString(), + ); + expect(reconstructedBlock2.header.state.l1ToL2MessageTree.root.toString()).toEqual( + block2BlobData.l1ToL2MessageRoot.toString(), + ); + expect(reconstructedBlock3.header.state.l1ToL2MessageTree.root.toString()).toEqual( + block3BlobData.l1ToL2MessageRoot.toString(), + ); }); it('handles single-block checkpoint', async () => { const body1 = await Body.random({ txsPerBlock: 3 }); - const block1BlobData = makeBlockBlobDataFromBody(body1, BlockNumber(1), true, 5000); + const block1BlobData = makeBlockBlobDataFromBody(body1, BlockNumber(1), 5000); const checkpointBlobData: CheckpointBlobData = { blocks: [block1BlobData], @@ -121,15 +134,9 @@ describe('data_retrieval', () => { * Helper to create a BlockBlobData from a Body. This ensures the blob data is compatible * with Body.fromTxBlobData. */ -function makeBlockBlobDataFromBody( - body: Body, - blockNumber: BlockNumber, - isFirstBlock: boolean, - seed: number, -): BlockBlobData { +function makeBlockBlobDataFromBody(body: Body, blockNumber: BlockNumber, seed: number): BlockBlobData { const blockEndBlobData = makeBlockEndBlobData({ seed, - isFirstBlock, blockEndMarker: { numTxs: body.txEffects.length, blockNumber, diff --git a/yarn-project/archiver/src/l1/data_retrieval.ts b/yarn-project/archiver/src/l1/data_retrieval.ts index 18282920db60..7f0602f06fb4 100644 --- a/yarn-project/archiver/src/l1/data_retrieval.ts +++ b/yarn-project/archiver/src/l1/data_retrieval.ts @@ -83,16 +83,22 @@ export async function retrievedToPublishedCheckpoint({ .slice(1) .concat([archiveRoot]); - // An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the - // `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists: - const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!; - const spongeBlob = SpongeBlob.init(); const l2Blocks: L2Block[] = []; for (let i = 0; i < blocksBlobData.length; i++) { const blockBlobData = blocksBlobData[i]; - const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } = - blockBlobData; + // The blob carries a per-block L1-to-L2 message tree root: any block + // within a checkpoint can insert messages, so reconstruction must use each block's own root rather than + // the checkpoint's first block. + const { + blockEndMarker, + blockEndStateField, + lastArchiveRoot, + noteHashRoot, + nullifierRoot, + publicDataRoot, + l1ToL2MessageRoot, + } = blockBlobData; const l2BlockNumber = blockEndMarker.blockNumber; @@ -109,7 +115,7 @@ export async function retrievedToPublishedCheckpoint({ const state = StateReference.from({ l1ToL2MessageTree: new AppendOnlyTreeSnapshot( - l1toL2MessageTreeRoot, + l1ToL2MessageRoot, blockEndStateField.l1ToL2MessageNextAvailableLeafIndex, ), partial: PartialStateReference.from({ @@ -357,7 +363,7 @@ export async function retrieveL1ToL2Message( * @param inbox - The inbox contract wrapper. * @param searchStartBlock - The block number to use for starting the search. * @param searchEndBlock - The highest block number that we should search up to. - * @returns An array of InboxLeaf and next eth block to search from. + * @returns The L1 to L2 messages retrieved from the Inbox, as an array of InboxMessage. */ export async function retrieveL1ToL2Messages( inbox: InboxContract, @@ -385,8 +391,9 @@ function mapLogInboxMessage(log: MessageSentLog): InboxMessage { leaf: log.args.leaf, l1BlockNumber: log.l1BlockNumber, l1BlockHash: log.l1BlockHash, - checkpointNumber: log.args.checkpointNumber, - rollingHash: log.args.rollingHash, + inboxRollingHash: log.args.inboxRollingHash, + bucketSeq: log.args.bucketSeq, + bucketTimestamp: log.l1BlockTimestamp, }; } diff --git a/yarn-project/archiver/src/modules/data_source_base.ts b/yarn-project/archiver/src/modules/data_source_base.ts index 6cde2b44b0d8..9e407d9e6765 100644 --- a/yarn-project/archiver/src/modules/data_source_base.ts +++ b/yarn-project/archiver/src/modules/data_source_base.ts @@ -40,7 +40,7 @@ import { } from '@aztec/stdlib/epoch-helpers'; import type { L2LogsSource } from '@aztec/stdlib/interfaces/server'; import type { LogResult, PrivateLogsQuery, PublicLogsQuery } from '@aztec/stdlib/logs'; -import type { L1ToL2MessageSource, L2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource, L2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees'; import type { BlockHeader, IndexedTxEffect, TxHash } from '@aztec/stdlib/tx'; import type { UInt64 } from '@aztec/stdlib/types'; @@ -316,14 +316,30 @@ export abstract class ArchiverDataSourceBase return this.stores.functionNames.register(signatures); } - public getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise { - return this.stores.messages.getL1ToL2Messages(checkpointNumber); - } - public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise { return this.stores.messages.getL1ToL2MessageIndex(l1ToL2Message); } + public getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise { + return this.stores.messages.getLatestInboxBucketAtOrBefore(timestamp); + } + + public getInboxBucket(seq: bigint): Promise { + return this.stores.messages.getInboxBucket(seq); + } + + public getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + return this.stores.messages.getInboxBucketByTotalMsgCount(totalMsgCount); + } + + public getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + return this.stores.messages.getL1ToL2MessagesBetweenBuckets(fromExclusive, toInclusive); + } + + public getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise { + return this.stores.messages.getL1ToL2MessagesBetweenLeafCounts(startLeafCount, endLeafCount); + } + private async getPublishedCheckpointFromCheckpointData(checkpoint: CheckpointData): Promise { const blocksForCheckpoint = await this.stores.blocks.getBlocksForCheckpoint(checkpoint.checkpointNumber); if (!blocksForCheckpoint) { diff --git a/yarn-project/archiver/src/modules/l1_synchronizer.ts b/yarn-project/archiver/src/modules/l1_synchronizer.ts index 1739dffccde2..be1bbf0b2d17 100644 --- a/yarn-project/archiver/src/modules/l1_synchronizer.ts +++ b/yarn-project/archiver/src/modules/l1_synchronizer.ts @@ -1,13 +1,13 @@ import type { BlobClientInterface } from '@aztec/blob-client/client'; import { EpochCache } from '@aztec/epoch-cache'; -import { InboxContract, type InboxContractState, RollupContract } from '@aztec/ethereum/contracts'; +import { InboxContract, type InboxContractBucket, RollupContract } from '@aztec/ethereum/contracts'; import type { L1BlockId } from '@aztec/ethereum/l1-types'; import { getFinalizedL1Block } from '@aztec/ethereum/queries'; import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types'; import { asyncPool } from '@aztec/foundation/async-pool'; import { maxBigint } from '@aztec/foundation/bigint'; import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { compactArray, partition, pick } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -30,7 +30,6 @@ import { PublishedCheckpoint, } from '@aztec/stdlib/checkpoint'; import { type L1RollupConstants, getEpochAtSlot, getSlotAtNextL1Block } from '@aztec/stdlib/epoch-helpers'; -import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; import { type Traceable, type Tracer, execInSpan, trackSpan } from '@aztec/telemetry-client'; @@ -431,16 +430,14 @@ export class ArchiverL1Synchronizer implements Traceable { return true; } - // Compare local message store state with the remote. If they match, we just advance the match pointer. - const remoteMessagesState = await this.inbox.getState({ blockNumber: currentL1BlockNumber }); + // Compare local message store state with the remote. If they match, we just advance the match pointer. The + // remote state is the Inbox's current bucket: its cumulative total and consensus rolling + // hash are the Inbox's live chain position. + const remoteBucket = await this.inbox.getCurrentBucket({ blockNumber: currentL1BlockNumber }); const localLastMessage = await this.stores.messages.getLastMessage(); - if (await this.localStateMatches(localLastMessage, remoteMessagesState)) { + if (await this.localStateMatches(localLastMessage, remoteBucket)) { this.log.trace(`Local L1 to L2 messages are already in sync with remote at L1 block ${currentL1BlockNumber}`); - await this.stores.messages.setMessageSyncState( - currentL1Block, - remoteMessagesState.treeInProgress, - finalizedL1Block, - ); + await this.stores.messages.setMessageSyncState(currentL1Block, finalizedL1Block); return true; } @@ -456,7 +453,7 @@ export class ArchiverL1Synchronizer implements Traceable { `Failed to store L1 to L2 messages retrieved from L1: ${error.message}. Rolling back syncpoint to retry.`, { inboxMessage: error.inboxMessage }, ); - await this.rollbackL1ToL2Messages(remoteMessagesState); + await this.rollbackL1ToL2Messages(remoteBucket); return false; } throw error; @@ -466,36 +463,35 @@ export class ArchiverL1Synchronizer implements Traceable { // we'd notice by comparing our local state with the remote one again, and seeing they don't match even after // our sync attempt. In this case, we also rollback our syncpoint, and trigger a retry. const localLastMessageAfterSync = await this.stores.messages.getLastMessage(); - if (!(await this.localStateMatches(localLastMessageAfterSync, remoteMessagesState))) { + if (!(await this.localStateMatches(localLastMessageAfterSync, remoteBucket))) { this.log.warn( `Local L1 to L2 messages state does not match remote after sync attempt. Rolling back syncpoint to retry.`, - { localLastMessageAfterSync, remoteMessagesState }, + { localLastMessageAfterSync, remoteBucket }, ); - await this.rollbackL1ToL2Messages(remoteMessagesState); + await this.rollbackL1ToL2Messages(remoteBucket); return false; } // Advance the syncpoint after a successful sync - await this.stores.messages.setMessageSyncState( - currentL1Block, - remoteMessagesState.treeInProgress, - finalizedL1Block, - ); + await this.stores.messages.setMessageSyncState(currentL1Block, finalizedL1Block); return true; } - /** Checks if the local rolling hash and message count matches the remote state */ - private async localStateMatches(localLastMessage: InboxMessage | undefined, remoteState: InboxContractState) { + /** Checks if the local consensus rolling hash and message count match the remote Inbox current bucket. */ + private async localStateMatches(localLastMessage: InboxMessage | undefined, remoteBucket: InboxContractBucket) { const localMessageCount = await this.stores.messages.getTotalL1ToL2MessageCount(); - this.log.trace(`Comparing local and remote inbox state`, { localMessageCount, localLastMessage, remoteState }); + this.log.trace(`Comparing local and remote inbox state`, { localMessageCount, localLastMessage, remoteBucket }); return ( - remoteState.totalMessagesInserted === localMessageCount && - remoteState.messagesRollingHash.equals(localLastMessage?.rollingHash ?? Buffer16.ZERO) + remoteBucket.totalMsgCount === localMessageCount && + remoteBucket.rollingHash.equals(localLastMessage?.inboxRollingHash ?? Fr.ZERO) ); } - /** Retrieves L1 to L2 messages from L1 in batches and stores them. */ + /** + * Retrieves L1 to L2 messages from L1 in batches and stores them. Batches must span whole L1 blocks so that every + * message of an Inbox bucket is stored in a single call, which the message store requires. + */ private async retrieveAndStoreMessages(fromL1Block: bigint, toL1Block: bigint): Promise { let searchStartBlock: bigint = 0n; let searchEndBlock: bigint = fromL1Block; @@ -508,7 +504,7 @@ export class ArchiverL1Synchronizer implements Traceable { this.log.trace(`Retrieving L1 to L2 messages in L1 blocks ${searchStartBlock}-${searchEndBlock}`); const messages = await retrieveL1ToL2Messages(this.inbox, searchStartBlock, searchEndBlock); const timer = new Timer(); - await this.stores.messages.addL1ToL2Messages(messages); + await this.stores.messages.addL1ToL2MessageBuckets(messages); const perMsg = timer.ms() / messages.length; this.instrumentation.processNewMessages(messages.length, perMsg); for (const msg of messages) { @@ -519,10 +515,10 @@ export class ArchiverL1Synchronizer implements Traceable { } while (searchEndBlock < toL1Block); if (messageCount > 0) { - this.log.info( - `Retrieved ${messageCount} new L1 to L2 messages up to message with index ${lastMessage?.index} for checkpoint ${lastMessage?.checkpointNumber}`, - { lastMessage, messageCount }, - ); + this.log.info(`Retrieved ${messageCount} new L1 to L2 messages up to message with index ${lastMessage?.index}`, { + lastMessage, + messageCount, + }); } } @@ -530,8 +526,8 @@ export class ArchiverL1Synchronizer implements Traceable { * Rolls back local L1 to L2 messages to the last common message with L1, and updates the syncpoint to the L1 block of that message. * If no common message is found, rolls back all messages and sets the syncpoint to the start block. */ - private async rollbackL1ToL2Messages(remoteMessagesState: InboxContractState): Promise { - const { treeInProgress: remoteTreeInProgress, messagesRollingHash: remoteRollingHash } = remoteMessagesState; + private async rollbackL1ToL2Messages(remoteBucket: InboxContractBucket): Promise { + const remoteRollingHash = remoteBucket.rollingHash; const messagesFinalizedL1Block = await this.stores.messages.getMessagesFinalizedL1Block(); const finalizedL1BlockNumber = messagesFinalizedL1Block?.l1BlockNumber; @@ -543,12 +539,12 @@ export class ArchiverL1Synchronizer implements Traceable { let messagesToDelete = 0; this.log.verbose(`Searching most recent common L1 to L2 message`); for await (const localMsg of this.stores.messages.iterateL1ToL2Messages({ reverse: true })) { - const logCtx = { remoteMsg: undefined as InboxMessage | undefined, localMsg, remoteMessagesState }; + const logCtx = { remoteMsg: undefined as InboxMessage | undefined, localMsg, remoteBucket }; // First check if the local message rolling hash matches the current rolling hash of the inbox contract, // which means we just need to rollback some local messages and we should be back in sync. This means there // was an L1 reorg that removed some of the messages we had, but no new messages were added compared. - if (localMsg.rollingHash.equals(remoteRollingHash)) { + if (localMsg.inboxRollingHash.equals(remoteRollingHash)) { this.log.info( `Found common L1 to L2 message at index ${localMsg.index} on L1 block ${localMsg.l1BlockNumber} matching current remote state`, logCtx, @@ -571,7 +567,7 @@ export class ArchiverL1Synchronizer implements Traceable { // an archival rpc node, since the message could be from a long time ago if we're catching up with syncing. const remoteMsg = await retrieveL1ToL2Message(this.inbox, localMsg); logCtx.remoteMsg = remoteMsg; - if (remoteMsg && remoteMsg.rollingHash.equals(localMsg.rollingHash)) { + if (remoteMsg && remoteMsg.inboxRollingHash.equals(localMsg.inboxRollingHash)) { this.log.info( `Found most recent common L1 to L2 message at index ${localMsg.index} on L1 block ${localMsg.l1BlockNumber}`, logCtx, @@ -613,10 +609,9 @@ export class ArchiverL1Synchronizer implements Traceable { : await this.getL1BlockHash(syncPointL1BlockNumber); const messagesSyncPoint = { l1BlockNumber: syncPointL1BlockNumber, l1BlockHash: syncPointL1BlockHash }; - await this.stores.messages.setMessageSyncState(messagesSyncPoint, remoteTreeInProgress); + await this.stores.messages.setMessageSyncState(messagesSyncPoint); this.log.verbose(`Updated messages syncpoint to L1 block ${messagesSyncPoint.l1BlockNumber}`, { ...messagesSyncPoint, - remoteTreeInProgress, }); return messagesSyncPoint; } @@ -1013,25 +1008,6 @@ export class ArchiverL1Synchronizer implements Traceable { for (const calldataCheckpoint of checkpointsToIngest) { const published = publishedByNumber.get(calldataCheckpoint.checkpointNumber)!; - // Check the inHash of the checkpoint against the l1->l2 messages. - // The messages should've been synced up to the currentL1BlockNumber and must be available for the published - // checkpoints we just retrieved. - const l1ToL2Messages = await this.stores.messages.getL1ToL2Messages(published.checkpoint.number); - const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages); - const publishedInHash = published.checkpoint.header.inHash; - if (!computedInHash.equals(publishedInHash)) { - this.log.fatal(`Mismatch inHash for checkpoint ${published.checkpoint.number}`, { - checkpointHash: published.checkpoint.hash(), - l1BlockNumber: published.l1.blockNumber, - computedInHash, - publishedInHash, - }); - // Throwing an error since this is most likely caused by a bug. - throw new Error( - `Mismatch inHash for checkpoint ${published.checkpoint.number}. Expected ${computedInHash} but got ${publishedInHash}`, - ); - } - validCheckpoints.push(published); this.log.debug( `Ingesting new checkpoint ${published.checkpoint.number} with ${published.checkpoint.blocks.length} blocks`, diff --git a/yarn-project/archiver/src/store/block_store.ts b/yarn-project/archiver/src/store/block_store.ts index d670702f512c..83525e469460 100644 --- a/yarn-project/archiver/src/store/block_store.ts +++ b/yarn-project/archiver/src/store/block_store.ts @@ -125,6 +125,7 @@ type CheckpointStorage = CommonCheckpointStorage & { type ProposedCheckpointStorage = CommonCheckpointStorage & { totalManaUsed: string; feeAssetPriceModifier: string; + inboxMsgTotal: string; }; export type RemoveCheckpointsResult = { blocksRemoved: L2Block[] | undefined }; @@ -930,6 +931,7 @@ export class BlockStore { blockCount: stored.blockCount, totalManaUsed: BigInt(stored.totalManaUsed), feeAssetPriceModifier: BigInt(stored.feeAssetPriceModifier), + inboxMsgTotal: BigInt(stored.inboxMsgTotal), }; } @@ -1361,7 +1363,7 @@ export class BlockStore { * Adds a proposed checkpoint to the pending queue. * Accepts proposed.checkpointNumber === latestTip + 1, where latestTip is the highest of * confirmed and the highest pending checkpoint number. - * Computes archive and checkpointOutHash from the stored blocks. + * Computes archive, checkpointOutHash and the consumed Inbox message total from the stored blocks. */ async addProposedCheckpoint(proposed: ProposedCheckpointInput) { return await this.db.transactionAsync(async () => { @@ -1387,8 +1389,12 @@ export class BlockStore { } this.validateCheckpointBlocks(blocks, previousBlock); - const archive = blocks[blocks.length - 1].archive; + const lastBlock = blocks[blocks.length - 1]; + const archive = lastBlock.archive; const checkpointOutHash = Checkpoint.getCheckpointOutHash(blocks); + // The last block's L1-to-L2 leaf count is the checkpoint's cumulative consumed Inbox total under compact + // indexing, which is what `propose` records on L1 for it. + const inboxMsgTotal = BigInt(lastBlock.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); await this.#proposedCheckpoints.set(proposed.checkpointNumber, { header: proposed.header.toBuffer(), @@ -1399,6 +1405,7 @@ export class BlockStore { blockCount: proposed.blockCount, totalManaUsed: proposed.totalManaUsed.toString(), feeAssetPriceModifier: proposed.feeAssetPriceModifier.toString(), + inboxMsgTotal: inboxMsgTotal.toString(), }); }); } diff --git a/yarn-project/archiver/src/store/data_stores.ts b/yarn-project/archiver/src/store/data_stores.ts index d34d9497b152..0db4c23fca7c 100644 --- a/yarn-project/archiver/src/store/data_stores.ts +++ b/yarn-project/archiver/src/store/data_stores.ts @@ -13,7 +13,7 @@ import { FunctionNamesCache } from './function_names_cache.js'; import { LogStore } from './log_store.js'; import { MessageStore } from './message_store.js'; -export const ARCHIVER_DB_VERSION = 7; +export const ARCHIVER_DB_VERSION = 9; /** * Represents the latest L1 block processed by the archiver for various objects in L2. diff --git a/yarn-project/archiver/src/store/message_store.test.ts b/yarn-project/archiver/src/store/message_store.test.ts index ef2ca57b9013..b60745673c09 100644 --- a/yarn-project/archiver/src/store/message_store.test.ts +++ b/yarn-project/archiver/src/store/message_store.test.ts @@ -1,12 +1,13 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { toArray } from '@aztec/foundation/iterable'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; import { Checkpoint, type PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; +import { updateInboxRollingHash } from '@aztec/stdlib/messaging'; import '@aztec/stdlib/testing/jest'; -import { L1ToL2MessagesNotReadyError } from '../errors.js'; +import { InboxBucketBoundaryNotSyncedError, InboxBucketNotSyncedError } from '../errors.js'; import type { InboxMessage } from '../structs/inbox_message.js'; import { makeInboxMessage, @@ -77,9 +78,9 @@ describe('MessageStore', () => { it('returns the L1 block set via setMessageSyncState', async () => { const l1BlockHash = Buffer32.random(); const l1BlockNumber = 10n; - await messageStore.setMessageSyncState({ l1BlockNumber, l1BlockHash }, 1n); - await messageStore.addL1ToL2Messages([ - makeInboxMessage(Buffer16.ZERO, { l1BlockNumber: 5n, l1BlockHash: Buffer32.random() }), + await messageStore.setMessageSyncState({ l1BlockNumber, l1BlockHash }); + await messageStore.addL1ToL2MessageBuckets([ + makeInboxMessage(Fr.ZERO, { l1BlockNumber: 5n, l1BlockHash: Buffer32.random() }), ]); await expect(getSynchPoint(blockStore, messageStore)).resolves.toEqual({ blocksSynchedTo: undefined, @@ -89,8 +90,6 @@ describe('MessageStore', () => { }); describe('L1 to L2 Messages', () => { - const initialCheckpointNumber = CheckpointNumber(13); - const checkMessages = async (msgs: InboxMessage[]) => { expect(await messageStore.getLastMessage()).toEqual(msgs.at(-1)); expect(await toArray(messageStore.iterateL1ToL2Messages())).toEqual(msgs); @@ -98,102 +97,73 @@ describe('MessageStore', () => { }; it('stores first message ever', async () => { - const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, checkpointNumber: CheckpointNumber(1) }); - await messageStore.addL1ToL2Messages([msg]); - - await checkMessages([msg]); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msg.leaf]); - }); - - it('stores single message', async () => { - const msg = makeInboxMessage(Buffer16.ZERO, { checkpointNumber: CheckpointNumber(2) }); - await messageStore.addL1ToL2Messages([msg]); + const msg = makeInboxMessage(Fr.ZERO, { index: 0n }); + await messageStore.addL1ToL2MessageBuckets([msg]); await checkMessages([msg]); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(2))).toEqual([msg.leaf]); }); it('stores and returns messages across different blocks', async () => { - const msgs = makeInboxMessages(5, { initialCheckpointNumber }); - await messageStore.addL1ToL2Messages(msgs); + const msgs = makeInboxMessages(5); + await messageStore.addL1ToL2MessageBuckets(msgs); await checkMessages(msgs); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual( - [msgs[2]].map(m => m.leaf), - ); }); it('stores the same messages again', async () => { - const msgs = makeInboxMessages(5, { initialCheckpointNumber }); - await messageStore.addL1ToL2Messages(msgs); - await messageStore.addL1ToL2Messages(msgs.slice(2)); + const msgs = makeInboxMessages(5); + await messageStore.addL1ToL2MessageBuckets(msgs); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(2)); await checkMessages(msgs); }); - it('stores and returns messages across different blocks with gaps', async () => { - const msgs1 = makeInboxMessages(3, { initialCheckpointNumber: CheckpointNumber(1) }); + it('stores messages added in two chained batches', async () => { + const msgs1 = makeInboxMessages(3); const msgs2 = makeInboxMessages(3, { - initialCheckpointNumber: CheckpointNumber(20), - initialHash: msgs1.at(-1)!.rollingHash, + initialInboxHash: msgs1.at(-1)!.inboxRollingHash, + initialIndex: BigInt(msgs1.length), }); - await messageStore.addL1ToL2Messages(msgs1); - await messageStore.addL1ToL2Messages(msgs2); + await messageStore.addL1ToL2MessageBuckets(msgs1); + await messageStore.addL1ToL2MessageBuckets(msgs2); await checkMessages([...msgs1, ...msgs2]); - - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msgs1[0].leaf]); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(4))).toEqual([]); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(20))).toEqual([msgs2[0].leaf]); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(24))).toEqual([]); }); it('stores and returns messages with block numbers larger than a byte', async () => { - const msgs = makeInboxMessages(5, { initialCheckpointNumber: CheckpointNumber(1000) }); - await messageStore.addL1ToL2Messages(msgs); + const msgs = makeInboxMessages(5, { overrideFn: (msg, i) => ({ ...msg, l1BlockNumber: BigInt(1000 + i) }) }); + await messageStore.addL1ToL2MessageBuckets(msgs); await checkMessages(msgs); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(1002))).toEqual([msgs[2]].map(m => m.leaf)); }); it('stores and returns multiple messages per block', async () => { const msgs = makeInboxMessagesWithFullBlocks(4); - await messageStore.addL1ToL2Messages(msgs); + await messageStore.addL1ToL2MessageBuckets(msgs); await checkMessages(msgs); - const blockMessages = await messageStore.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 1)); - expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); - expect(blockMessages).toEqual( - msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map(m => m.leaf), - ); }); it('stores messages in multiple operations', async () => { - const msgs = makeInboxMessages(20, { initialCheckpointNumber }); - await messageStore.addL1ToL2Messages(msgs.slice(0, 10)); - await messageStore.addL1ToL2Messages(msgs.slice(10, 20)); + const msgs = makeInboxMessages(20); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(0, 10)); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(10, 20)); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual( - [msgs[2]].map(m => m.leaf), - ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 12))).toEqual( - [msgs[12]].map(m => m.leaf), - ); await checkMessages(msgs); }); it('iterates over messages from start index', async () => { - const msgs = makeInboxMessages(10, { initialCheckpointNumber }); - await messageStore.addL1ToL2Messages(msgs); + const msgs = makeInboxMessages(10); + await messageStore.addL1ToL2MessageBuckets(msgs); const iterated = await toArray(messageStore.iterateL1ToL2Messages({ start: msgs[3].index })); expect(iterated).toEqual(msgs.slice(3)); }); it('iterates over messages in reverse', async () => { - const msgs = makeInboxMessages(10, { initialCheckpointNumber }); - await messageStore.addL1ToL2Messages(msgs); + const msgs = makeInboxMessages(10); + await messageStore.addL1ToL2MessageBuckets(msgs); const iterated = await toArray(messageStore.iterateL1ToL2Messages({ reverse: true, end: msgs[3].index })); expect(iterated).toEqual(msgs.slice(0, 4).reverse()); @@ -201,130 +171,372 @@ describe('MessageStore', () => { it('throws if messages are added out of order', async () => { const msgs = makeInboxMessages(5, { overrideFn: (msg, i) => ({ ...msg, index: BigInt(10 - i) }) }); - await expect(messageStore.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError); + await expect(messageStore.addL1ToL2MessageBuckets(msgs)).rejects.toThrow(MessageStoreError); }); - it('throws if block number for the first message is out of order', async () => { - const msgs = makeInboxMessages(4, { initialCheckpointNumber }); - msgs[2].checkpointNumber = CheckpointNumber(initialCheckpointNumber - 1); - await messageStore.addL1ToL2Messages(msgs.slice(0, 2)); - await expect(messageStore.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError); + it('throws if index is not contiguous with the previous message', async () => { + const msgs = makeInboxMessages(5); + msgs.at(-1)!.index += 100n; + await expect(messageStore.addL1ToL2MessageBuckets(msgs)).rejects.toThrow(MessageStoreError); }); - it('throws if rolling hash is not correct', async () => { - const msgs = makeInboxMessages(5); - msgs[1].rollingHash = Buffer16.random(); - await expect(messageStore.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError); + it('throws if there is a gap in the indices', async () => { + const msgs = makeInboxMessages(4); + msgs[2].index++; + await expect(messageStore.addL1ToL2MessageBuckets(msgs)).rejects.toThrow(MessageStoreError); }); - it('throws if rolling hash for first message is not correct', async () => { + it('throws if the first index of a batch does not follow the last stored message', async () => { const msgs = makeInboxMessages(4); - msgs[2].rollingHash = Buffer16.random(); - await messageStore.addL1ToL2Messages(msgs.slice(0, CheckpointNumber(2))); - await expect(messageStore.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(0, 2)); + msgs[2].index++; + await expect(messageStore.addL1ToL2MessageBuckets(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError); }); - it('throws if index is not in the correct range', async () => { - const msgs = makeInboxMessages(5, { initialCheckpointNumber }); - msgs.at(-1)!.index += 100n; - await expect(messageStore.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError); + it('throws if the consensus rolling hash is not correct', async () => { + const msgs = makeInboxMessages(5); + msgs[1].inboxRollingHash = Fr.random(); + await expect(messageStore.addL1ToL2MessageBuckets(msgs)).rejects.toThrow(MessageStoreError); }); - it('throws if first index in block has gaps', async () => { - const msgs = makeInboxMessages(4, { initialCheckpointNumber }); - msgs[2].index++; - await expect(messageStore.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError); + it('removes messages inserted after a given L1 block', async () => { + // Two messages per L1 block: [100, 100, 101, 101, 102, 102]. + const msgs = makeInboxMessages(6, { + overrideFn: (msg, i) => ({ ...msg, l1BlockNumber: BigInt(100 + Math.floor(i / 2)) }), + }); + await messageStore.addL1ToL2MessageBuckets(msgs); + await checkMessages(msgs); + + await messageStore.rollbackL1ToL2MessagesAfterL1Block(101n); + + // Only the messages inserted at or before L1 block 101 survive. + await checkMessages(msgs.slice(0, 4)); + }); + + it('removes messages starting with the given index', async () => { + const msgs = makeInboxMessagesWithFullBlocks(4); + await messageStore.addL1ToL2MessageBuckets(msgs); + + await messageStore.removeL1ToL2Messages(msgs[13].index); + await checkMessages(msgs.slice(0, 13)); }); + }); - it('throws if index does not follow previous one', async () => { - const msgs = makeInboxMessages(2, { - initialCheckpointNumber, - overrideFn: (msg, i) => ({ - ...msg, - checkpointNumber: CheckpointNumber(2), - index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2), - }), + describe('Inbox buckets', () => { + // Builds `count` consecutive valid messages, then reassigns their bucket sequence and timestamp per the given + // per-message spec so we can exercise multi-message and rollover buckets. + const makeBucketedMessages = ( + spec: { seq: bigint; timestamp: bigint; l1BlockNumber?: bigint }[], + ): InboxMessage[] => { + const msgs = makeInboxMessages(spec.length); + msgs.forEach((msg, i) => { + msg.bucketSeq = spec[i].seq; + msg.bucketTimestamp = spec[i].timestamp; + msg.l1BlockNumber = spec[i].l1BlockNumber ?? msg.l1BlockNumber; }); - msgs[1].index++; - await expect(messageStore.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError); + return msgs; + }; + + // Builds a valid message continuing the chain after `previous`, absorbed into the given bucket. + const makeNextMessage = (previous: InboxMessage, bucket: { seq: bigint; timestamp: bigint }): InboxMessage => { + const leaf = Fr.random(); + return { + ...previous, + leaf, + index: previous.index + 1n, + inboxRollingHash: updateInboxRollingHash(previous.inboxRollingHash, leaf), + bucketSeq: bucket.seq, + bucketTimestamp: bucket.timestamp, + }; + }; + + // Three buckets over six messages: bucket 1 = [0,1,2], bucket 2 = [3,4], bucket 3 = [5]. + const threeBucketSpec = [ + { seq: 1n, timestamp: 100n }, + { seq: 1n, timestamp: 100n }, + { seq: 1n, timestamp: 100n }, + { seq: 2n, timestamp: 200n }, + { seq: 2n, timestamp: 200n }, + { seq: 3n, timestamp: 300n }, + ]; + + it('snapshots buckets as messages are inserted', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + + expect(await messageStore.getInboxBucket(1n)).toEqual({ + seq: 1n, + inboxRollingHash: msgs[2].inboxRollingHash, + totalMsgCount: 3n, + timestamp: 100n, + msgCount: 3, + lastMessageIndex: msgs[2].index, + }); + expect(await messageStore.getInboxBucket(2n)).toEqual({ + seq: 2n, + inboxRollingHash: msgs[4].inboxRollingHash, + totalMsgCount: 5n, + timestamp: 200n, + msgCount: 2, + lastMessageIndex: msgs[4].index, + }); + expect(await messageStore.getInboxBucket(3n)).toEqual({ + seq: 3n, + inboxRollingHash: msgs[5].inboxRollingHash, + totalMsgCount: 6n, + timestamp: 300n, + msgCount: 1, + lastMessageIndex: msgs[5].index, + }); + expect(await messageStore.getInboxBucket(4n)).toBeUndefined(); }); - it('removes messages up to the given block number', async () => { - const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) }); + it('resolves a bucket by its cumulative message total', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + + // Each bucket boundary (cumulative totals 3, 5, 6) resolves to its bucket. + expect((await messageStore.getInboxBucketByTotalMsgCount(3n))?.seq).toEqual(1n); + expect((await messageStore.getInboxBucketByTotalMsgCount(5n))?.seq).toEqual(2n); + expect((await messageStore.getInboxBucketByTotalMsgCount(6n))?.seq).toEqual(3n); + // A total inside a bucket (not on a boundary) does not resolve. + expect(await messageStore.getInboxBucketByTotalMsgCount(4n)).toBeUndefined(); + // A total past the last synced bucket does not resolve. + expect(await messageStore.getInboxBucketByTotalMsgCount(7n)).toBeUndefined(); + }); - await messageStore.addL1ToL2Messages(msgs); - await checkMessages(msgs); + it('synthesizes the genesis sentinel bucket (sequence 0, total 0) which is never ingested', async () => { + // With real messages present but no ingested sequence-0 snapshot, both lookups still resolve genesis. + await messageStore.addL1ToL2MessageBuckets(makeBucketedMessages(threeBucketSpec)); + + expect(await messageStore.getInboxBucket(0n)).toMatchObject({ seq: 0n, totalMsgCount: 0n, msgCount: 0 }); + expect(await messageStore.getInboxBucketByTotalMsgCount(0n)).toMatchObject({ seq: 0n, totalMsgCount: 0n }); + }); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + it('rejects a bucket delivered without the messages already stored for it', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(0, 2)); + + // The second batch continues bucket 1 from its third message, so its snapshot would undercount the bucket. + await expect(messageStore.addL1ToL2MessageBuckets(msgs.slice(2))).rejects.toThrow(/Incomplete Inbox bucket 1/); + }); + + it('rebuilds a stored bucket re-delivered in full with a replaced tail', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(0, 3)); + // An L1 reorg drops bucket 1's last message; the re-sync replays the whole L1 block it lives in. + await messageStore.removeL1ToL2Messages(msgs[2].index); + const replacement = makeNextMessage(msgs[1], { seq: 1n, timestamp: 100n }); + await messageStore.addL1ToL2MessageBuckets([msgs[0], msgs[1], replacement]); + + expect(await messageStore.getInboxBucket(1n)).toEqual({ + seq: 1n, + inboxRollingHash: replacement.inboxRollingHash, + totalMsgCount: 3n, + timestamp: 100n, + msgCount: 3, + lastMessageIndex: replacement.index, + }); + expect(await messageStore.getTotalL1ToL2MessageCount()).toEqual(3n); + }); + + it('rejects a message opening a bucket older than the newest stored one', async () => { + const msgs = makeBucketedMessages([ + { seq: 1n, timestamp: 100n }, + { seq: 2n, timestamp: 200n }, + { seq: 4n, timestamp: 400n }, + ]); + await messageStore.addL1ToL2MessageBuckets(msgs); + + const stale = makeNextMessage(msgs[2], { seq: 3n, timestamp: 300n }); + await expect(messageStore.addL1ToL2MessageBuckets([stale])).rejects.toThrow(/Cannot open Inbox bucket 3/); + }); + + it('throws if the consensus rolling hash is not correct', async () => { + const msgs = makeInboxMessages(5); + msgs[1].inboxRollingHash = Fr.random(); + await expect(messageStore.addL1ToL2MessageBuckets(msgs)).rejects.toThrow(MessageStoreError); + }); + + it('resolves the latest bucket at or before a timestamp', async () => { + await messageStore.addL1ToL2MessageBuckets(makeBucketedMessages(threeBucketSpec)); + + expect((await messageStore.getLatestInboxBucketAtOrBefore(100n))!.seq).toEqual(1n); + expect((await messageStore.getLatestInboxBucketAtOrBefore(150n))!.seq).toEqual(1n); + expect((await messageStore.getLatestInboxBucketAtOrBefore(300n))!.seq).toEqual(3n); + expect((await messageStore.getLatestInboxBucketAtOrBefore(10_000n))!.seq).toEqual(3n); + expect(await messageStore.getLatestInboxBucketAtOrBefore(99n)).toBeUndefined(); + }); + + it('resolves rollover buckets that share a timestamp to the highest sequence', async () => { + // Buckets 2 and 3 share timestamp 200 (a full bucket rolling over within the same L1 block). + const msgs = makeBucketedMessages([ + { seq: 1n, timestamp: 100n }, + { seq: 2n, timestamp: 200n }, + { seq: 3n, timestamp: 200n }, + ]); + await messageStore.addL1ToL2MessageBuckets(msgs); + + expect((await messageStore.getLatestInboxBucketAtOrBefore(200n))!.seq).toEqual(3n); + }); + + it('returns messages between buckets in insertion order', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + const leaves = msgs.map(m => m.leaf); + + expect(await messageStore.getL1ToL2MessagesBetweenBuckets(0n, 3n)).toEqual(leaves); + expect(await messageStore.getL1ToL2MessagesBetweenBuckets(1n, 2n)).toEqual(leaves.slice(3, 5)); + expect(await messageStore.getL1ToL2MessagesBetweenBuckets(2n, 3n)).toEqual(leaves.slice(5)); + // An empty (fromExclusive, toInclusive] range yields no messages. + expect(await messageStore.getL1ToL2MessagesBetweenBuckets(3n, 3n)).toEqual([]); + }); + + it('throws when a bucket bound has not been synced', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + + // An unsynced bound is reported rather than collapsing into an empty range. + await expect(messageStore.getL1ToL2MessagesBetweenBuckets(0n, 9n)).rejects.toThrow(InboxBucketNotSyncedError); + await expect(messageStore.getL1ToL2MessagesBetweenBuckets(9n, 12n)).rejects.toThrow(InboxBucketNotSyncedError); + // A nonzero lower bound is never treated as genesis. + await expect(messageStore.getL1ToL2MessagesBetweenBuckets(4n, 5n)).rejects.toThrow(InboxBucketNotSyncedError); + await expect(messageStore.getL1ToL2MessagesBetweenBuckets(4n, 3n)).rejects.toThrow(/Invalid Inbox bucket range/); + }); + + it('returns messages between cumulative leaf counts', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + const leaves = msgs.map(m => m.leaf); + + // Bucket boundaries sit at cumulative counts 0 (genesis), 3, 5 and 6. + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(0n, 6n)).toEqual(leaves); + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(0n, 3n)).toEqual(leaves.slice(0, 3)); + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(3n, 5n)).toEqual(leaves.slice(3, 5)); + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(5n, 6n)).toEqual(leaves.slice(5)); + // An empty range consumes nothing, at a bucket boundary or at genesis. + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(5n, 5n)).toEqual([]); + expect(await messageStore.getL1ToL2MessagesBetweenLeafCounts(0n, 0n)).toEqual([]); + }); + + it('throws when a leaf count does not land on a synced bucket boundary', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + + // Counts inside a bucket and past the last synced bucket both fail rather than returning a partial range. + await expect(messageStore.getL1ToL2MessagesBetweenLeafCounts(0n, 4n)).rejects.toThrow( + InboxBucketBoundaryNotSyncedError, ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + await expect(messageStore.getL1ToL2MessagesBetweenLeafCounts(4n, 6n)).rejects.toThrow( + InboxBucketBoundaryNotSyncedError, ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + await expect(messageStore.getL1ToL2MessagesBetweenLeafCounts(3n, 9n)).rejects.toThrow( + InboxBucketBoundaryNotSyncedError, ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + await expect(messageStore.getL1ToL2MessagesBetweenLeafCounts(5n, 3n)).rejects.toThrow( + /Invalid Inbox leaf count range/, ); + }); - await messageStore.rollbackL1ToL2MessagesToCheckpoint(CheckpointNumber(2)); - - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength( - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - ); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(0); - expect(await messageStore.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(0); + it('rewinds buckets when messages are removed', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); + + // Remove the last two messages (msgs[4] in bucket 2, msgs[5] in bucket 3), splitting bucket 2. + await messageStore.removeL1ToL2Messages(msgs[4].index); + + expect(await messageStore.getInboxBucket(3n)).toBeUndefined(); + expect(await messageStore.getInboxBucket(2n)).toEqual({ + seq: 2n, + inboxRollingHash: msgs[3].inboxRollingHash, + totalMsgCount: 4n, + timestamp: 200n, + msgCount: 1, + lastMessageIndex: msgs[3].index, + }); + expect(await messageStore.getInboxBucket(1n)).toMatchObject({ msgCount: 3, totalMsgCount: 3n }); - await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2)); + // Bucket 3's timestamp index entry is gone, so an at-or-before lookup falls back to bucket 2. + expect((await messageStore.getLatestInboxBucketAtOrBefore(300n))!.seq).toEqual(2n); }); - it('removes messages starting with the given index', async () => { - const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) }); - await messageStore.addL1ToL2Messages(msgs); + it('rewinds a rollover bucket sharing a timestamp with the surviving boundary', async () => { + const msgs = makeBucketedMessages([ + { seq: 1n, timestamp: 100n }, + { seq: 2n, timestamp: 200n }, + { seq: 3n, timestamp: 200n }, + ]); + await messageStore.addL1ToL2MessageBuckets(msgs); - await messageStore.removeL1ToL2Messages(msgs[13].index); - await checkMessages(msgs.slice(0, 13)); + // Removing the last message deletes bucket 3, whose timestamp (200) is shared with the surviving bucket 2. + await messageStore.removeL1ToL2Messages(msgs[2].index); + + expect(await messageStore.getInboxBucket(3n)).toBeUndefined(); + expect((await messageStore.getLatestInboxBucketAtOrBefore(200n))!.seq).toEqual(2n); }); - describe('inbox tree in progress guard', () => { - it('throws when checkpointNumber >= treeInProgress', async () => { - const msgs = makeInboxMessages(3, { initialCheckpointNumber: CheckpointNumber(5) }); - await messageStore.addL1ToL2Messages(msgs); + it('keeps rollover siblings indexed when a bucket sharing their timestamp is removed', async () => { + // Three buckets rolling over within one L1 block, so all three share timestamp 100. + const msgs = makeBucketedMessages([ + { seq: 1n, timestamp: 100n }, + { seq: 2n, timestamp: 100n }, + { seq: 3n, timestamp: 100n }, + ]); + await messageStore.addL1ToL2MessageBuckets(msgs); - // Set treeInProgress to 7, meaning checkpoints 5 and 6 are sealed, 7+ are not - await messageStore.setMessageSyncState({ l1BlockNumber: 1n, l1BlockHash: Buffer32.random() }, 7n); + await messageStore.removeL1ToL2Messages(msgs[2].index); - // Sealed checkpoint should succeed - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(5))).resolves.toEqual([msgs[0].leaf]); + expect(await messageStore.getInboxBucket(3n)).toBeUndefined(); + expect(await messageStore.getInboxBucket(1n)).toMatchObject({ msgCount: 1, totalMsgCount: 1n }); + expect((await messageStore.getLatestInboxBucketAtOrBefore(100n))!.seq).toEqual(2n); + }); - // Unsealed checkpoint (== treeInProgress) should throw - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(7))).rejects.toThrow(L1ToL2MessagesNotReadyError); + it('reindexes a bucket re-delivered from an L1 block with a different timestamp', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs.slice(0, 3)); + await messageStore.removeL1ToL2Messages(msgs[2].index); + + // The reorged L1 block holding bucket 1 was re-mined at a later timestamp. + const replayed = [msgs[0], msgs[1], makeNextMessage(msgs[1], { seq: 1n, timestamp: 100n })].map(msg => ({ + ...msg, + bucketTimestamp: 150n, + })); + await messageStore.addL1ToL2MessageBuckets(replayed); + + expect(await messageStore.getInboxBucket(1n)).toMatchObject({ timestamp: 150n, msgCount: 3 }); + expect(await messageStore.getLatestInboxBucketAtOrBefore(100n)).toBeUndefined(); + expect((await messageStore.getLatestInboxBucketAtOrBefore(150n))!.seq).toEqual(1n); + }); - // Future checkpoint should also throw - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(8))).rejects.toThrow(L1ToL2MessagesNotReadyError); - }); + it('rolls back whole buckets past an L1 block', async () => { + // Bucket 1 fills L1 block 100, bucket 2 fills L1 block 101 and bucket 3 fills L1 block 102. + const msgs = makeBucketedMessages([ + { seq: 1n, timestamp: 100n, l1BlockNumber: 100n }, + { seq: 1n, timestamp: 100n, l1BlockNumber: 100n }, + { seq: 1n, timestamp: 100n, l1BlockNumber: 100n }, + { seq: 2n, timestamp: 200n, l1BlockNumber: 101n }, + { seq: 2n, timestamp: 200n, l1BlockNumber: 101n }, + { seq: 3n, timestamp: 300n, l1BlockNumber: 102n }, + ]); + await messageStore.addL1ToL2MessageBuckets(msgs); - it('returns messages when checkpointNumber < treeInProgress', async () => { - const msgs = makeInboxMessages(3, { initialCheckpointNumber: CheckpointNumber(10) }); - await messageStore.addL1ToL2Messages(msgs); + await messageStore.rollbackL1ToL2MessagesAfterL1Block(100n); - await messageStore.setMessageSyncState({ l1BlockNumber: 1n, l1BlockHash: Buffer32.random() }, 13n); + expect(await toArray(messageStore.iterateL1ToL2Messages())).toEqual(msgs.slice(0, 3)); + expect(await messageStore.getInboxBucket(2n)).toBeUndefined(); + expect(await messageStore.getInboxBucket(3n)).toBeUndefined(); + expect(await messageStore.getInboxBucket(1n)).toMatchObject({ msgCount: 3, totalMsgCount: 3n }); + expect((await messageStore.getLatestInboxBucketAtOrBefore(300n))!.seq).toEqual(1n); + }); - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(10))).resolves.toEqual([msgs[0].leaf]); - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(11))).resolves.toEqual([msgs[1].leaf]); - }); + it('clears all buckets when every message is removed', async () => { + const msgs = makeBucketedMessages(threeBucketSpec); + await messageStore.addL1ToL2MessageBuckets(msgs); - it('skips guard when treeInProgress is not set', async () => { - const msgs = makeInboxMessages(2, { initialCheckpointNumber: CheckpointNumber(1) }); - await messageStore.addL1ToL2Messages(msgs); + await messageStore.removeL1ToL2Messages(msgs[0].index); - // No setMessageSyncState call — guard should be permissive - await expect(messageStore.getL1ToL2Messages(CheckpointNumber(1))).resolves.toEqual([msgs[0].leaf]); - }); + expect(await messageStore.getInboxBucket(1n)).toBeUndefined(); + expect(await messageStore.getLatestInboxBucketAtOrBefore(300n)).toBeUndefined(); }); }); }); diff --git a/yarn-project/archiver/src/store/message_store.ts b/yarn-project/archiver/src/store/message_store.ts index 5aaf949ee3b0..0590a060f4f2 100644 --- a/yarn-project/archiver/src/store/message_store.ts +++ b/yarn-project/archiver/src/store/message_store.ts @@ -1,26 +1,96 @@ import type { L1BlockId } from '@aztec/ethereum/l1-types'; -import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { Fr } from '@aztec/foundation/curves/bn254'; import { toArray } from '@aztec/foundation/iterable'; import { createLogger } from '@aztec/foundation/log'; -import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, bigintToUInt64BE, numToUInt32BE, serializeToBuffer } from '@aztec/foundation/serialize'; import { type AztecAsyncKVStore, type AztecAsyncMap, + type AztecAsyncMultiMap, type AztecAsyncSingleton, type CustomRange, mapRange, } from '@aztec/kv-store'; -import { InboxLeaf } from '@aztec/stdlib/messaging'; +import { type InboxBucket, updateInboxRollingHash } from '@aztec/stdlib/messaging'; + +import { InboxBucketBoundaryNotSyncedError, InboxBucketNotSyncedError } from '../errors.js'; +import { type InboxMessage, deserializeInboxMessage, serializeInboxMessage } from '../structs/inbox_message.js'; + +/** + * Persisted snapshot of an Inbox rolling-hash bucket. Mirrors the fields the on-chain Inbox tracks per bucket, plus + * the L1 block the bucket was opened in and the index span of its messages, so rollbacks and range queries can work + * off bucket records alone without scanning messages. + */ +type BucketSnapshot = { + inboxRollingHash: Fr; + totalMsgCount: bigint; + timestamp: bigint; + l1BlockNumber: bigint; + msgCount: number; + firstMessageIndex: bigint; + lastMessageIndex: bigint; +}; + +function serializeBucketSnapshot(snapshot: BucketSnapshot): Buffer { + return serializeToBuffer([ + snapshot.inboxRollingHash, + bigintToUInt64BE(snapshot.totalMsgCount), + bigintToUInt64BE(snapshot.timestamp), + bigintToUInt64BE(snapshot.l1BlockNumber), + numToUInt32BE(snapshot.msgCount), + bigintToUInt64BE(snapshot.firstMessageIndex), + bigintToUInt64BE(snapshot.lastMessageIndex), + ]); +} -import { L1ToL2MessagesNotReadyError } from '../errors.js'; -import { - type InboxMessage, - deserializeInboxMessage, - serializeInboxMessage, - updateRollingHash, -} from '../structs/inbox_message.js'; +function deserializeBucketSnapshot(buffer: Buffer): BucketSnapshot { + const reader = BufferReader.asReader(buffer); + const inboxRollingHash = reader.readObject(Fr); + const totalMsgCount = reader.readUInt64(); + const timestamp = reader.readUInt64(); + const l1BlockNumber = reader.readUInt64(); + const msgCount = reader.readNumber(); + const firstMessageIndex = reader.readUInt64(); + const lastMessageIndex = reader.readUInt64(); + return { inboxRollingHash, totalMsgCount, timestamp, l1BlockNumber, msgCount, firstMessageIndex, lastMessageIndex }; +} + +/** The messages of a single Inbox bucket within an incoming batch, in insertion order. */ +type IncomingBucket = { + seq: bigint; + messages: InboxMessage[]; +}; + +/** + * Splits an incoming batch of messages into per-bucket groups, in delivery order. Messages arrive ordered by index + * and a bucket's messages are contiguous within that order, so a group ends as soon as the bucket sequence changes. + */ +function groupMessagesByBucket(messages: InboxMessage[]): IncomingBucket[] { + const buckets: IncomingBucket[] = []; + for (const message of messages) { + const current = buckets.at(-1); + if (current !== undefined && current.seq === message.bucketSeq) { + current.messages.push(message); + } else { + buckets.push({ seq: message.bucketSeq, messages: [message] }); + } + } + return buckets; +} + +// The genesis sentinel bucket: sequence 0 with a zero rolling hash and no messages, mirroring the +// on-chain Inbox's base case. The archiver never ingests a snapshot for it (no message is absorbed into sequence 0), so +// it is synthesized on read. Consumers use its sequence number and zero total; its deploy-time timestamp is not tracked +// here and is unused. +const GENESIS_INBOX_BUCKET: InboxBucket = { + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, +}; export class MessageStoreError extends Error { constructor( @@ -41,10 +111,16 @@ export class MessageStore { #lastSynchedL1Block: AztecAsyncSingleton; /** Stores total messages stored */ #totalMessageCount: AztecAsyncSingleton; - /** Stores the checkpoint number whose message tree is currently being filled on L1. */ - #inboxTreeInProgress: AztecAsyncSingleton; /** Stores the L1 finalized block as of the last successful message sync. */ #messagesFinalizedL1Block: AztecAsyncSingleton; + /** Maps from Inbox bucket sequence number to its serialized snapshot. */ + #inboxBuckets: AztecAsyncMap; + /** + * Maps from a bucket's L1 timestamp (key) to the sequence numbers of the buckets opened at that timestamp. Holds + * several sequences per timestamp when a full bucket rolls over within one L1 block, so that deleting one bucket + * leaves its rollover siblings indexed. + */ + #bucketTimestampToSeq: AztecAsyncMultiMap; #log = createLogger('archiver:message_store'); @@ -53,8 +129,9 @@ export class MessageStore { this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices'); this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_id'); this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count'); - this.#inboxTreeInProgress = db.openSingleton('archiver_inbox_tree_in_progress'); this.#messagesFinalizedL1Block = db.openSingleton('archiver_messages_finalized_l1_block'); + this.#inboxBuckets = db.openMap('archiver_inbox_buckets'); + this.#bucketTimestampToSeq = db.openMultiMap('archiver_inbox_bucket_timestamps'); } public async getTotalL1ToL2MessageCount(): Promise { @@ -99,11 +176,20 @@ export class MessageStore { } /** - * Append L1 to L2 messages to the store. - * Requires new messages to be in order and strictly after the last message added. - * Throws if out of order messages are added or if the rolling hash is invalid. + * Appends L1 to L2 messages to the store, one whole Inbox bucket at a time. + * + * A bucket is opened and closed within a single L1 block, and callers retrieve Inbox logs in whole-L1-block ranges, + * so every message of a bucket reaches this method in the same call — including the rollover buckets a full block + * spills into. The bucket snapshots are derived from that: the batch is split per bucket sequence and each bucket + * gets a single snapshot built from its complete message set. Delivering only part of a bucket already held in the + * store is rejected, since the snapshot would then undercount the bucket. Delivering a stored bucket again from its + * first message is allowed: an L1 reorg can replace a bucket's tail, and the re-sync that follows replays the whole + * L1 block it lives in. + * + * Requires messages to be ordered by index and to continue the stored chain. Throws a `MessageStoreError` if + * messages arrive out of order, if the rolling hash chain breaks, or if a bucket arrives incomplete. */ - public addL1ToL2Messages(messages: InboxMessage[]): Promise { + public addL1ToL2MessageBuckets(messages: InboxMessage[]): Promise { if (messages.length === 0) { return Promise.resolve(); } @@ -112,11 +198,14 @@ export class MessageStore { let lastMessage = await this.getLastMessage(); let messageCount = 0; + const incomingBuckets = groupMessagesByBucket(messages); + await this.assertIncomingBucketsAreComplete(incomingBuckets); + for (const message of messages) { // Check messages are inserted in increasing order, but allow reinserting messages. if (lastMessage && message.index <= lastMessage.index) { const existing = await this.#l1ToL2Messages.getAsync(this.indexToKey(message.index)); - if (existing && deserializeInboxMessage(existing).rollingHash.equals(message.rollingHash)) { + if (existing && deserializeInboxMessage(existing).inboxRollingHash.equals(message.inboxRollingHash)) { // We reinsert instead of skipping in case the message was re-orged and got added in a different L1 block. this.#log.trace(`Reinserting message with index ${message.index} in the store`); await this.#l1ToL2Messages.set(this.indexToKey(message.index), serializeInboxMessage(message)); @@ -129,49 +218,27 @@ export class MessageStore { ); } - // Check rolling hash is valid. - const previousRollingHash = lastMessage?.rollingHash ?? Buffer16.ZERO; - const expectedRollingHash = updateRollingHash(previousRollingHash, message.leaf); - if (!expectedRollingHash.equals(message.rollingHash)) { - throw new MessageStoreError( - `Invalid rolling hash for incoming L1 to L2 message ${message.leaf.toString()} ` + - `with index ${message.index} ` + - `(expected ${expectedRollingHash.toString()} from previous hash ${previousRollingHash} but got ${message.rollingHash.toString()})`, - message, - ); - } - - // Check index corresponds to the checkpoint number. - const [expectedStart, expectedEnd] = InboxLeaf.indexRangeForCheckpoint(message.checkpointNumber); - if (message.index < expectedStart || message.index >= expectedEnd) { + // Check the compact-indexed messages arrive contiguously: the global insertion index of + // each message is exactly one past the previous one. + const expectedIndex = lastMessage === undefined ? 0n : lastMessage.index + 1n; + if (message.index !== expectedIndex) { throw new MessageStoreError( `Invalid index ${message.index} for incoming L1 to L2 message ${message.leaf.toString()} ` + - `at checkpoint ${message.checkpointNumber} (expected value in range [${expectedStart}, ${expectedEnd}))`, + `(expected ${expectedIndex})`, message, ); } - // Check there are no gaps in the indices within the same checkpoint. - if ( - lastMessage && - message.checkpointNumber === lastMessage.checkpointNumber && - message.index !== lastMessage.index + 1n - ) { + // Check the consensus rolling-hash chain is valid: each message's rolling hash must + // continue the chain from the previously inserted message. + const previousInboxRollingHash = lastMessage?.inboxRollingHash ?? Fr.ZERO; + const expectedInboxRollingHash = updateInboxRollingHash(previousInboxRollingHash, message.leaf); + if (!expectedInboxRollingHash.equals(message.inboxRollingHash)) { throw new MessageStoreError( - `Missing prior message for incoming L1 to L2 message ${message.leaf.toString()} ` + - `with index ${message.index}`, - message, - ); - } - - // Check the first message in a checkpoint has the correct index. - if ( - (!lastMessage || message.checkpointNumber > lastMessage.checkpointNumber) && - message.index !== expectedStart - ) { - throw new MessageStoreError( - `Message ${message.leaf.toString()} for checkpoint ${message.checkpointNumber} has wrong index ` + - `${message.index} (expected ${expectedStart})`, + `Invalid inbox rolling hash for incoming L1 to L2 message ${message.leaf.toString()} ` + + `with index ${message.index} ` + + `(expected ${expectedInboxRollingHash.toString()} from previous hash ${previousInboxRollingHash.toString()} ` + + `but got ${message.inboxRollingHash.toString()})`, message, ); } @@ -180,15 +247,75 @@ export class MessageStore { await this.#l1ToL2Messages.set(this.indexToKey(message.index), serializeInboxMessage(message)); await this.#l1ToL2MessageIndices.set(this.leafToIndexKey(message.leaf), message.index); messageCount++; + this.#log.trace(`Inserted L1 to L2 message ${message.leaf} with index ${message.index} into the store`); lastMessage = message; } + await this.writeIncomingBucketSnapshots(incomingBuckets); + // Update total message count with the number of inserted messages. await this.increaseTotalMessageCount(messageCount); }); } + /** + * Rejects a batch that delivers an Inbox bucket the store already holds without replaying it from its first message, + * or that opens a bucket older than the newest one stored. Either would produce a snapshot that disagrees with the + * messages it covers, since each snapshot is derived from the batch's messages for that bucket alone. + */ + private async assertIncomingBucketsAreComplete(incomingBuckets: IncomingBucket[]): Promise { + const newestStoredSeq = await this.getNewestBucketSeq(); + let previousSeq: bigint | undefined; + for (const bucket of incomingBuckets) { + if (previousSeq !== undefined && bucket.seq <= previousSeq) { + throw new MessageStoreError( + `Inbox bucket ${bucket.seq} arrives after bucket ${previousSeq} in the same batch`, + bucket.messages[0], + ); + } + previousSeq = bucket.seq; + + const stored = await this.getBucketSnapshotBySeq(bucket.seq); + if (stored === undefined) { + if (newestStoredSeq !== undefined && bucket.seq <= newestStoredSeq) { + throw new MessageStoreError( + `Cannot open Inbox bucket ${bucket.seq} after bucket ${newestStoredSeq} has been stored`, + bucket.messages[0], + ); + } + } else if (stored.firstMessageIndex !== bucket.messages[0].index) { + throw new MessageStoreError( + `Incomplete Inbox bucket ${bucket.seq}: stored messages start at index ${stored.firstMessageIndex} ` + + `but the batch starts at index ${bucket.messages[0].index}`, + bucket.messages[0], + ); + } + } + } + + /** + * Writes one snapshot per bucket in the batch, each derived from the bucket's complete message set. Cumulative + * totals thread forward from the bucket preceding the batch, so a bucket re-delivered with extra messages shifts + * the totals of the buckets after it within the same batch. + */ + private async writeIncomingBucketSnapshots(incomingBuckets: IncomingBucket[]): Promise { + let cumulativeTotal = await this.getTotalMsgCountBeforeBucket(incomingBuckets[0].seq); + for (const { seq, messages } of incomingBuckets) { + const lastInBucket = messages.at(-1)!; + cumulativeTotal += BigInt(messages.length); + await this.writeBucketSnapshot(seq, { + inboxRollingHash: lastInBucket.inboxRollingHash, + totalMsgCount: cumulativeTotal, + timestamp: lastInBucket.bucketTimestamp, + l1BlockNumber: lastInBucket.l1BlockNumber, + msgCount: messages.length, + firstMessageIndex: messages[0].index, + lastMessageIndex: lastInBucket.index, + }); + } + } + /** * Gets the L1 to L2 message index in the L1 to L2 message tree. * @param l1ToL2Message - The L1 to L2 message. @@ -203,63 +330,19 @@ export class MessageStore { return msg ? deserializeInboxMessage(msg) : undefined; } - /** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */ - public getInboxTreeInProgress(): Promise { - return this.#inboxTreeInProgress.getAsync(); - } - /** - * Atomically updates the message sync state: the L1 sync point, the inbox tree-in-progress marker, and - * (optionally) the L1 finalized block as of this sync. The finalized block is advanced monotonically. + * Atomically updates the message sync state: the L1 sync point and (optionally) the L1 finalized block as of this + * sync. The finalized block is advanced monotonically. */ - public setMessageSyncState( - l1Block: L1BlockId, - treeInProgress: bigint | undefined, - finalizedL1Block?: L1BlockId, - ): Promise { + public setMessageSyncState(l1Block: L1BlockId, finalizedL1Block?: L1BlockId): Promise { return this.db.transactionAsync(async () => { await this.setSynchedL1Block(l1Block); - if (treeInProgress !== undefined) { - await this.#inboxTreeInProgress.set(treeInProgress); - } else { - await this.#inboxTreeInProgress.delete(); - } if (finalizedL1Block !== undefined) { await this.maybeAdvanceFinalizedL1Block(finalizedL1Block); } }); } - public async getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise { - const treeInProgress = await this.#inboxTreeInProgress.getAsync(); - if (treeInProgress !== undefined && BigInt(checkpointNumber) >= treeInProgress) { - throw new L1ToL2MessagesNotReadyError(checkpointNumber, treeInProgress); - } - - const messages: Fr[] = []; - - const [startIndex, endIndex] = InboxLeaf.indexRangeForCheckpoint(checkpointNumber); - let lastIndex = startIndex - 1n; - - for await (const msgBuffer of this.#l1ToL2Messages.valuesAsync({ - start: this.indexToKey(startIndex), - end: this.indexToKey(endIndex), - })) { - const msg = deserializeInboxMessage(msgBuffer); - if (msg.checkpointNumber !== checkpointNumber) { - throw new Error( - `L1 to L2 message with index ${msg.index} has invalid checkpoint number ${msg.checkpointNumber}`, - ); - } else if (msg.index !== lastIndex + 1n) { - throw new Error(`Expected L1 to L2 message with index ${lastIndex + 1n} but got ${msg.index}`); - } - lastIndex = msg.index; - messages.push(msg.leaf); - } - - return messages; - } - public async *iterateL1ToL2Messages(range: CustomRange = {}): AsyncIterableIterator { const entriesRange = mapRange(range, this.indexToKey); for await (const msgBuffer of this.#l1ToL2Messages.valuesAsync(entriesRange)) { @@ -281,14 +364,241 @@ export class MessageStore { deleteCount++; } await this.increaseTotalMessageCount(-deleteCount); + await this.rewindBucketsAfterRemoval(); this.#log.warn(`Deleted ${deleteCount} L1 to L2 messages from index ${startIndex} from the store`); }); } - public rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise { - this.#log.debug(`Deleting L1 to L2 messages up to target checkpoint ${targetCheckpointNumber}`); - const startIndex = InboxLeaf.smallestIndexForCheckpoint(CheckpointNumber(targetCheckpointNumber + 1)); - return this.removeL1ToL2Messages(startIndex); + /** + * Rewinds the Inbox bucket snapshots to match the messages left after a removal. Each bucket past the surviving tip + * is deleted together with its own timestamp index entry, leaving the entries of the rollover siblings it shares a + * timestamp with in place. + * + * The bucket holding the last surviving message is rewritten from the messages it has left, because a removal can + * cut inside a bucket: the synchronizer rolls back to the last message it still shares with L1 after a reorg, and + * that message need not be the last of its bucket. Must run inside the removal transaction, after the total message + * count has been updated. + */ + private async rewindBucketsAfterRemoval(): Promise { + const lastRemaining = await this.getLastMessage(); + const boundarySeq = lastRemaining?.bucketSeq; + + const deleteFromKey = boundarySeq === undefined ? 0 : this.bucketSeqToKey(boundarySeq) + 1; + for await (const [seqKey, snapBuffer] of this.#inboxBuckets.entriesAsync({ start: deleteFromKey })) { + const snapshot = deserializeBucketSnapshot(snapBuffer); + await this.#bucketTimestampToSeq.deleteValue(this.timestampToKey(snapshot.timestamp), seqKey); + await this.#inboxBuckets.delete(seqKey); + } + + if (lastRemaining === undefined || boundarySeq === undefined) { + return; + } + let msgCount = 0; + for await (const msg of this.iterateL1ToL2Messages({ reverse: true })) { + if (msg.bucketSeq !== boundarySeq) { + break; + } + msgCount += 1; + } + const stored = await this.getSyncedBucketSnapshot(boundarySeq); + await this.writeBucketSnapshot(boundarySeq, { + ...stored, + inboxRollingHash: lastRemaining.inboxRollingHash, + totalMsgCount: await this.getTotalL1ToL2MessageCount(), + msgCount, + lastMessageIndex: lastRemaining.index, + }); + } + + /** + * Returns the Inbox bucket with the given sequence number, or undefined if it has not been synced. Sequence 0 is + * the genesis sentinel: the on-chain Inbox reserves it as the "consumed nothing" base case + * and never absorbs a message into it, so the archiver ingests no snapshot for it; it is synthesized here (rolling + * hash 0, total 0) so streaming consumers can resolve a genesis parent or an empty checkpoint's last-consumed bucket. + */ + public async getInboxBucket(seq: bigint): Promise { + const snapshot = await this.getBucketSnapshotBySeq(seq); + if (snapshot !== undefined) { + return this.toInboxBucket(seq, snapshot); + } + return seq === 0n ? GENESIS_INBOX_BUCKET : undefined; + } + + /** + * Returns the Inbox bucket whose cumulative message total equals `totalMsgCount`, or undefined if no synced bucket + * sits on that boundary. Sequence 0 (total 0) is the genesis sentinel base case; otherwise the + * message at global index `totalMsgCount - 1` is the last message of the bucket with that cumulative total, so its + * `bucketSeq` resolves the bucket. A total that does not land on a bucket boundary returns undefined. + */ + public async getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + if (totalMsgCount === 0n) { + return this.getInboxBucket(0n); + } + const buffer = await this.#l1ToL2Messages.getAsync(this.indexToKey(totalMsgCount - 1n)); + if (buffer === undefined) { + return undefined; + } + const bucket = await this.getInboxBucket(deserializeInboxMessage(buffer).bucketSeq); + return bucket !== undefined && bucket.totalMsgCount === totalMsgCount ? bucket : undefined; + } + + /** + * Returns the message leaves in the cumulative Inbox message-count range `[startLeafCount, endLeafCount)`, in + * insertion order. The bounds are compact L1-to-L2 tree leaf counts, which every block header + * carries, so consumers can ask for the messages a block or checkpoint consumed without resolving buckets + * themselves. Both bounds must land on a bucket boundary this archiver has synced; it throws otherwise, since a + * caller asking for a range always expects the messages in it. + */ + public async getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise { + if (startLeafCount > endLeafCount) { + throw new Error(`Invalid Inbox leaf count range [${startLeafCount}, ${endLeafCount})`); + } + const startBucket = await this.getBucketAtBoundary(startLeafCount); + const endBucket = await this.getBucketAtBoundary(endLeafCount); + return this.getL1ToL2MessagesBetweenBuckets(startBucket.seq, endBucket.seq); + } + + /** Resolves the bucket ending at the given cumulative message count, failing loudly if there is none. */ + private async getBucketAtBoundary(totalMsgCount: bigint): Promise { + const bucket = await this.getInboxBucketByTotalMsgCount(totalMsgCount); + if (bucket === undefined) { + throw new InboxBucketBoundaryNotSyncedError(totalMsgCount); + } + return bucket; + } + + /** + * Returns the latest Inbox bucket opened at or before the given L1 timestamp, or undefined if every synced bucket + * was opened strictly after it. + */ + public async getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise { + // Bucket timestamps are non-decreasing in sequence number, so the bucket we want is the highest sequence indexed + // at the largest timestamp at-or-before the requested one. A reverse scan bounded above (inclusively) by that + // timestamp visits it first; rollover buckets share a timestamp, so keep the highest of its sequences. + let latestTimestampKey: number | undefined; + let latestSeqKey: number | undefined; + for await (const [timestampKey, seqKey] of this.#bucketTimestampToSeq.entriesAsync({ + end: this.timestampToKey(timestamp), + reverse: true, + })) { + if (latestTimestampKey !== undefined && timestampKey !== latestTimestampKey) { + break; + } + latestTimestampKey = timestampKey; + latestSeqKey = latestSeqKey === undefined ? seqKey : Math.max(latestSeqKey, seqKey); + } + return latestSeqKey === undefined ? undefined : this.getInboxBucket(BigInt(latestSeqKey)); + } + + /** + * Returns the message leaves absorbed into buckets in the range `(fromExclusive, toInclusive]`, in insertion order. + * Both bounds must name buckets this archiver has synced, so that an empty result means the + * range holds no messages rather than hiding an unsynced bound; callers route the + * `InboxBucketNotSyncedError` to their own catch-up handling. Sequence 0 is the genesis base case and always + * resolves: the range then starts at the first message of the Inbox. + */ + public async getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + if (fromExclusive > toInclusive) { + throw new Error(`Invalid Inbox bucket range (${fromExclusive}, ${toInclusive}]`); + } + if (toInclusive === 0n) { + return []; + } + const endIndexExclusive = (await this.getSyncedBucketSnapshot(toInclusive)).lastMessageIndex + 1n; + const startIndex = + fromExclusive === 0n ? 0n : (await this.getSyncedBucketSnapshot(fromExclusive)).lastMessageIndex + 1n; + return this.getMessageLeavesInIndexRange(startIndex, endIndexExclusive); + } + + /** Collects the message leaves in the global index range `[startIndex, endIndexExclusive)`, in insertion order. */ + private async getMessageLeavesInIndexRange(startIndex: bigint, endIndexExclusive: bigint): Promise { + const leaves: Fr[] = []; + for await (const msgBuffer of this.#l1ToL2Messages.valuesAsync({ + start: this.indexToKey(startIndex), + end: this.indexToKey(endIndexExclusive), + })) { + leaves.push(deserializeInboxMessage(msgBuffer).leaf); + } + return leaves; + } + + private async getBucketSnapshotBySeq(seq: bigint): Promise { + const buffer = await this.#inboxBuckets.getAsync(this.bucketSeqToKey(seq)); + return buffer && deserializeBucketSnapshot(buffer); + } + + /** Reads a bucket snapshot, failing loudly if the archiver has not synced that bucket. */ + private async getSyncedBucketSnapshot(seq: bigint): Promise { + const snapshot = await this.getBucketSnapshotBySeq(seq); + if (snapshot === undefined) { + throw new InboxBucketNotSyncedError(seq); + } + return snapshot; + } + + private async writeBucketSnapshot(seq: bigint, snapshot: BucketSnapshot): Promise { + // A reorg can re-deliver a bucket from an L1 block mined at a different timestamp, so drop the stale index entry. + const stored = await this.getBucketSnapshotBySeq(seq); + if (stored !== undefined && stored.timestamp !== snapshot.timestamp) { + await this.#bucketTimestampToSeq.deleteValue(this.timestampToKey(stored.timestamp), this.bucketSeqToKey(seq)); + } + await this.#inboxBuckets.set(this.bucketSeqToKey(seq), serializeBucketSnapshot(snapshot)); + await this.#bucketTimestampToSeq.set(this.timestampToKey(snapshot.timestamp), this.bucketSeqToKey(seq)); + } + + /** Returns the sequence number of the newest stored bucket, or undefined if none has been stored yet. */ + private async getNewestBucketSeq(): Promise { + const [seqKey] = await toArray(this.#inboxBuckets.keysAsync({ reverse: true, limit: 1 })); + return seqKey === undefined ? undefined : BigInt(seqKey); + } + + /** Returns the cumulative Inbox message count through the newest stored bucket before the given sequence number. */ + private async getTotalMsgCountBeforeBucket(seq: bigint): Promise { + const [snapBuffer] = await toArray( + this.#inboxBuckets.valuesAsync({ end: this.bucketSeqToKey(seq) - 1, reverse: true, limit: 1 }), + ); + return snapBuffer === undefined ? 0n : deserializeBucketSnapshot(snapBuffer).totalMsgCount; + } + + private toInboxBucket(seq: bigint, snapshot: BucketSnapshot): InboxBucket { + return { + seq, + inboxRollingHash: snapshot.inboxRollingHash, + totalMsgCount: snapshot.totalMsgCount, + timestamp: snapshot.timestamp, + msgCount: snapshot.msgCount, + lastMessageIndex: snapshot.lastMessageIndex, + }; + } + + private bucketSeqToKey(seq: bigint): number { + return Number(seq); + } + + private timestampToKey(timestamp: bigint): number { + return Number(timestamp); + } + + /** + * Removes every L1 to L2 message inserted after the given L1 block, so the message store matches the L1 Inbox state + * as of that block. Used when rolling the archiver back to an earlier checkpoint, whose L1 block is passed here. + * + * A bucket lives entirely within one L1 block, so the cut always falls on a bucket boundary and can be found from + * the bucket snapshots alone, without reading the messages being removed. + */ + public async rollbackL1ToL2MessagesAfterL1Block(l1BlockNumber: bigint): Promise { + this.#log.debug(`Deleting L1 to L2 messages inserted after L1 block ${l1BlockNumber}`); + let removeFromIndex: bigint | undefined; + for await (const snapBuffer of this.#inboxBuckets.valuesAsync({ reverse: true })) { + const snapshot = deserializeBucketSnapshot(snapBuffer); + if (snapshot.l1BlockNumber <= l1BlockNumber) { + break; + } + removeFromIndex = snapshot.firstMessageIndex; + } + if (removeFromIndex !== undefined) { + await this.removeL1ToL2Messages(removeFromIndex); + } } private indexToKey(index: bigint): number { diff --git a/yarn-project/archiver/src/structs/inbox_message.ts b/yarn-project/archiver/src/structs/inbox_message.ts index 9f981b505e9b..a27192e6cd32 100644 --- a/yarn-project/archiver/src/structs/inbox_message.ts +++ b/yarn-project/archiver/src/structs/inbox_message.ts @@ -1,31 +1,29 @@ -import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; -import { keccak256 } from '@aztec/foundation/crypto/keccak'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { BufferReader, bigintToUInt64BE, numToUInt32BE, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize'; export type InboxMessage = { index: bigint; leaf: Fr; - checkpointNumber: CheckpointNumber; l1BlockNumber: bigint; l1BlockHash: Buffer32; - rollingHash: Buffer16; + /** Consensus rolling hash (truncated sha256 chain) of all messages up to and including this one. */ + inboxRollingHash: Fr; + /** Sequence number of the Inbox bucket this message was absorbed into. */ + bucketSeq: bigint; + /** L1 block timestamp at which this message's bucket was opened; the bucket's recency key, in seconds. */ + bucketTimestamp: bigint; }; -export function updateRollingHash(currentRollingHash: Buffer16, leaf: Fr): Buffer16 { - const input = Buffer.concat([currentRollingHash.toBuffer(), leaf.toBuffer()]); - return Buffer16.fromBuffer(keccak256(input)); -} - export function serializeInboxMessage(message: InboxMessage): Buffer { return serializeToBuffer([ bigintToUInt64BE(message.index), message.leaf, message.l1BlockHash, - numToUInt32BE(Number(message.l1BlockNumber)), - numToUInt32BE(message.checkpointNumber), - message.rollingHash, + bigintToUInt64BE(message.l1BlockNumber), + message.inboxRollingHash, + bigintToUInt64BE(message.bucketSeq), + bigintToUInt64BE(message.bucketTimestamp), ]); } @@ -34,8 +32,17 @@ export function deserializeInboxMessage(buffer: Buffer): InboxMessage { const index = reader.readUInt64(); const leaf = reader.readObject(Fr); const l1BlockHash = reader.readObject(Buffer32); - const l1BlockNumber = BigInt(reader.readNumber()); - const checkpointNumber = CheckpointNumber(reader.readNumber()); - const rollingHash = reader.readObject(Buffer16); - return { index, leaf, l1BlockHash, l1BlockNumber, checkpointNumber, rollingHash }; + const l1BlockNumber = reader.readUInt64(); + const inboxRollingHash = reader.readObject(Fr); + const bucketSeq = reader.readUInt64(); + const bucketTimestamp = reader.readUInt64(); + return { + index, + leaf, + l1BlockHash, + l1BlockNumber, + inboxRollingHash, + bucketSeq, + bucketTimestamp, + }; } diff --git a/yarn-project/archiver/src/test/fake_l1_state.ts b/yarn-project/archiver/src/test/fake_l1_state.ts index 0b9cbcb177f2..101248149525 100644 --- a/yarn-project/archiver/src/test/fake_l1_state.ts +++ b/yarn-project/archiver/src/test/fake_l1_state.ts @@ -1,11 +1,10 @@ import type { BlobClientInterface } from '@aztec/blob-client/client'; import { type Blob, getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib'; -import { INITIAL_CHECKPOINT_NUMBER } from '@aztec/constants'; import type { CheckpointProposedLog, InboxContract, MessageSentLog, RollupContract } from '@aztec/ethereum/contracts'; import { MULTI_CALL_3_ADDRESS } from '@aztec/ethereum/contracts'; import type { ViemPublicClient } from '@aztec/ethereum/types'; import { type BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -14,7 +13,7 @@ import { RollupAbi } from '@aztec/l1-artifacts'; import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block'; import { Checkpoint } from '@aztec/stdlib/checkpoint'; import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers'; -import { InboxLeaf } from '@aztec/stdlib/messaging'; +import { updateInboxRollingHash } from '@aztec/stdlib/messaging'; import { ConsensusPayload, getHashedSignaturePayloadTypedData } from '@aztec/stdlib/p2p'; import { mockCheckpointAndMessages } from '@aztec/stdlib/testing'; import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees'; @@ -31,8 +30,6 @@ import { toHex, } from 'viem'; -import { updateRollingHash } from '../structs/inbox_message.js'; - /** Configuration for the fake L1 state. */ export type FakeL1StateConfig = { /** Genesis archive root. */ @@ -105,12 +102,15 @@ type CheckpointData = { /** Data stored for a message. */ type MessageData = { l1BlockNumber: bigint; - checkpointNumber: CheckpointNumber; index: bigint; leaf: Fr; - rollingHash: Buffer16; + inboxRollingHash: Fr; + bucketSeq: bigint; }; +// Mirror of the on-chain per-bucket message cap: further messages in the same L1 block spill into the next bucket. +const MAX_MSGS_PER_BUCKET = 256; + /** * Stateful fake for L1 data used by the archiver. * @@ -137,7 +137,11 @@ export class FakeL1State { private l1BlockNumber: bigint; private checkpoints: CheckpointData[] = []; private messages: MessageData[] = []; - private messagesRollingHash: Buffer16 = Buffer16.ZERO; + // Consensus rolling-hash and bucket-ring state, mirroring the on-chain Inbox. + private messagesConsensusRollingHash: Fr = Fr.ZERO; + private currentBucketSeq: bigint = 0n; + private currentBucketTimestamp: bigint = 0n; + private currentBucketMsgCount: number = 0; private lastArchive: AppendOnlyTreeSnapshot; private provenCheckpointNumber: CheckpointNumber = CheckpointNumber(0); private targetCommitteeSize: number = 0; @@ -165,21 +169,56 @@ export class FakeL1State { * Note: For most use cases, use `addCheckpoint` which creates both checkpoint and messages. * Use this method only when you need to add messages without creating a checkpoint (e.g., for reorg tests). */ - addMessages(checkpointNumber: CheckpointNumber, l1BlockNumber: bigint, messageLeaves: Fr[]): void { - messageLeaves.forEach((leaf, i) => { - const index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i); - this.messagesRollingHash = updateRollingHash(this.messagesRollingHash, leaf); + addMessages(_checkpointNumber: CheckpointNumber, l1BlockNumber: bigint, messageLeaves: Fr[]): void { + const timestamp = this.getTimestampAtL1Block(l1BlockNumber); + messageLeaves.forEach(leaf => { + // Compact global insertion index: the position in the Inbox's insertion order. + const index = BigInt(this.messages.length); + const { bucketSeq, inboxRollingHash } = this.absorbIntoBucket(leaf, timestamp); this.messages.push({ l1BlockNumber, - checkpointNumber, index, leaf, - rollingHash: this.messagesRollingHash, + inboxRollingHash, + bucketSeq, }); }); } + /** Mirrors the on-chain `_absorbIntoBucket`: opens a new bucket on a strictly larger timestamp or a full bucket. */ + private absorbIntoBucket(leaf: Fr, timestamp: bigint): { bucketSeq: bigint; inboxRollingHash: Fr } { + if ( + this.currentBucketSeq === 0n || + this.currentBucketTimestamp < timestamp || + this.currentBucketMsgCount === MAX_MSGS_PER_BUCKET + ) { + this.currentBucketSeq += 1n; + this.currentBucketTimestamp = timestamp; + this.currentBucketMsgCount = 0; + } + this.messagesConsensusRollingHash = updateInboxRollingHash(this.messagesConsensusRollingHash, leaf); + this.currentBucketMsgCount += 1; + return { bucketSeq: this.currentBucketSeq, inboxRollingHash: this.messagesConsensusRollingHash }; + } + + /** Rebuilds all per-message derived state (rolling hashes and bucket assignments) after the message set changes. */ + private recomputeDerivedMessageState(): void { + this.messagesConsensusRollingHash = Fr.ZERO; + this.currentBucketSeq = 0n; + this.currentBucketTimestamp = 0n; + this.currentBucketMsgCount = 0; + this.messages.forEach((msg, i) => { + const { bucketSeq, inboxRollingHash } = this.absorbIntoBucket( + msg.leaf, + this.getTimestampAtL1Block(msg.l1BlockNumber), + ); + msg.index = BigInt(i); + msg.inboxRollingHash = inboxRollingHash; + msg.bucketSeq = bucketSeq; + }); + } + /** * Creates blocks for a checkpoint without adding them to L1 state. * Useful for creating blocks to pass to addBlock() for testing provisional block handling. @@ -354,8 +393,7 @@ export class FakeL1State { */ removeMessagesAfter(totalIndex: number): void { this.messages = this.messages.slice(0, totalIndex); - // Recalculate rolling hash - this.messagesRollingHash = this.messages.reduce((hash, msg) => updateRollingHash(hash, msg.leaf), Buffer16.ZERO); + this.recomputeDerivedMessageState(); } /** @@ -418,11 +456,6 @@ export class FakeL1State { return this.checkpoints.findLast(cpData => cpData.checkpointNumber === checkpointNumber)?.checkpoint; } - /** Gets messages for a checkpoint. */ - getMessages(checkpointNumber: CheckpointNumber): Fr[] { - return this.messages.filter(m => m.checkpointNumber === checkpointNumber).map(m => m.leaf); - } - /** Gets the blobs for a checkpoint. */ getCheckpointBlobs(checkpointNumber: CheckpointNumber): Blob[] { return this.checkpoints.findLast(cpData => cpData.checkpointNumber === checkpointNumber)?.blobs ?? []; @@ -468,33 +501,26 @@ export class FakeL1State { const mockInbox = mock(); mockInbox.getState.mockImplementation((opts: { blockTag?: string; blockNumber?: bigint } = {}) => { - // Filter messages visible at the given block number (or all if not specified) const blockNumber = opts.blockNumber ?? this.l1BlockNumber; const visibleMessages = this.messages.filter(m => m.l1BlockNumber <= blockNumber); + return Promise.resolve({ totalMessagesInserted: BigInt(visibleMessages.length) }); + }); - // treeInProgress must be > any sealed checkpoint. On L1, a checkpoint can only be proposed - // after its messages are sealed, so treeInProgress > checkpointNumber for all published checkpoints. - const maxFromMessages = - visibleMessages.length > 0 ? Math.max(...visibleMessages.map(m => Number(m.checkpointNumber))) + 1 : 0; - const maxFromCheckpoints = - this.checkpoints.length > 0 - ? Math.max( - ...this.checkpoints - .filter(cp => !cp.pruned && cp.l1BlockNumber <= blockNumber) - .map(cp => Number(cp.checkpointNumber)), - 0, - ) + 1 - : 0; - const treeInProgress = Math.max(maxFromMessages, maxFromCheckpoints, INITIAL_CHECKPOINT_NUMBER); - - // Compute rolling hash only for visible messages - const rollingHash = - visibleMessages.length > 0 ? visibleMessages[visibleMessages.length - 1].rollingHash : Buffer16.ZERO; - + // Mirror the on-chain Inbox current bucket: its consensus rolling hash and cumulative total are the live chain + // position the archiver's message sync compares against. + mockInbox.getCurrentBucket.mockImplementation((opts: { blockTag?: string; blockNumber?: bigint } = {}) => { + const blockNumber = opts.blockNumber ?? this.l1BlockNumber; + const visibleMessages = this.messages.filter(m => m.l1BlockNumber <= blockNumber); + const last = visibleMessages.at(-1); + if (last === undefined) { + return Promise.resolve({ rollingHash: Fr.ZERO, totalMsgCount: 0n, timestamp: 0n, msgCount: 0 }); + } + const msgCount = visibleMessages.filter(m => m.bucketSeq === last.bucketSeq).length; return Promise.resolve({ - messagesRollingHash: rollingHash, - totalMessagesInserted: BigInt(visibleMessages.length), - treeInProgress: BigInt(treeInProgress), + rollingHash: last.inboxRollingHash, + totalMsgCount: BigInt(visibleMessages.length), + timestamp: this.getTimestampAtL1Block(last.l1BlockNumber), + msgCount, }); }); @@ -623,11 +649,12 @@ export class FakeL1State { l1BlockNumber: msg.l1BlockNumber, l1BlockHash: Buffer32.fromBigInt(msg.l1BlockNumber), l1TransactionHash: `0x${msg.l1BlockNumber.toString(16)}` as `0x${string}`, + l1BlockTimestamp: this.getTimestampAtL1Block(msg.l1BlockNumber), args: { - checkpointNumber: msg.checkpointNumber, index: msg.index, leaf: msg.leaf, - rollingHash: msg.rollingHash, + inboxRollingHash: msg.inboxRollingHash, + bucketSeq: msg.bucketSeq, }, })); } @@ -646,11 +673,12 @@ export class FakeL1State { l1BlockNumber: msg.l1BlockNumber, l1BlockHash: Buffer32.fromBigInt(msg.l1BlockNumber), l1TransactionHash: `0x${msg.l1BlockNumber.toString(16)}` as `0x${string}`, + l1BlockTimestamp: this.getTimestampAtL1Block(msg.l1BlockNumber), args: { - checkpointNumber: msg.checkpointNumber, index: msg.index, leaf: msg.leaf, - rollingHash: msg.rollingHash, + inboxRollingHash: msg.inboxRollingHash, + bucketSeq: msg.bucketSeq, }, }; } @@ -692,6 +720,7 @@ export class FakeL1State { header, archive, oracleInput: { feeAssetPriceModifier: 0n }, + bucketHint: 0n, }, verbatimAttestations, attestationsAndSigners.getSigners().map(signer => signer.toString()), diff --git a/yarn-project/archiver/src/test/mock_archiver.ts b/yarn-project/archiver/src/test/mock_archiver.ts index bcdcc3928d96..357c09d673e0 100644 --- a/yarn-project/archiver/src/test/mock_archiver.ts +++ b/yarn-project/archiver/src/test/mock_archiver.ts @@ -1,8 +1,7 @@ -import type { CheckpointNumber } from '@aztec/foundation/branded-types'; -import type { Fr } from '@aztec/foundation/curves/bn254'; +import { Fr } from '@aztec/foundation/curves/bn254'; import type { L2BlockSource } from '@aztec/stdlib/block'; import type { Checkpoint } from '@aztec/stdlib/checkpoint'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { MockL1ToL2MessageSource } from './mock_l1_to_l2_message_source.js'; import { MockL2BlockSource } from './mock_l2_block_source.js'; @@ -13,17 +12,33 @@ import { MockL2BlockSource } from './mock_l2_block_source.js'; export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1ToL2MessageSource { private messageSource = new MockL1ToL2MessageSource(0); - public setL1ToL2Messages(checkpointNumber: CheckpointNumber, msgs: Fr[]) { - this.messageSource.setL1ToL2Messages(checkpointNumber, msgs); - } - - getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise { - return this.messageSource.getL1ToL2Messages(checkpointNumber); + public setInboxBucket(bucket: InboxBucket, msgs: Fr[] = []) { + this.messageSource.setInboxBucket(bucket, msgs); } getL1ToL2MessageIndex(_l1ToL2Message: Fr): Promise { return this.messageSource.getL1ToL2MessageIndex(_l1ToL2Message); } + + getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise { + return this.messageSource.getLatestInboxBucketAtOrBefore(timestamp); + } + + getInboxBucket(seq: bigint): Promise { + return this.messageSource.getInboxBucket(seq); + } + + getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + return this.messageSource.getInboxBucketByTotalMsgCount(totalMsgCount); + } + + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + return this.messageSource.getL1ToL2MessagesBetweenBuckets(fromExclusive, toInclusive); + } + + getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise { + return this.messageSource.getL1ToL2MessagesBetweenLeafCounts(startLeafCount, endLeafCount); + } } /** @@ -31,6 +46,7 @@ export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1 */ export class MockPrefilledArchiver extends MockArchiver { private prefilled: Checkpoint[] = []; + private prefilledMessages: Fr[][] = []; constructor(prefilled: { checkpoint: Checkpoint; messages: Fr[] }[]) { super(); @@ -38,12 +54,54 @@ export class MockPrefilledArchiver extends MockArchiver { } public setPrefilled(prefilled: { checkpoint: Checkpoint; messages: Fr[] }[]) { - for (const { checkpoint, messages } of prefilled) { + for (const { checkpoint } of prefilled) { this.prefilled[checkpoint.number - 1] = checkpoint; if (checkpoint.blocks.length !== 1) { throw new Error('Prefilled checkpoint must only have 1 block at the moment.'); } - this.setL1ToL2Messages(checkpoint.number, messages); + } + + for (const { checkpoint, messages } of prefilled) { + this.prefilledMessages[checkpoint.number - 1] = messages; + } + + // Register the Inbox buckets the streaming world-state synchronizer reconstructs each block's consumed + // message bundle from: a genesis sentinel (totalMsgCount 0) so a leaf count of 0 + // resolves to a bucket, plus one bucket per message-carrying checkpoint whose cumulative totalMsgCount + // matches the block's post-insertion L1-to-L2 leaf count. Rebuilt from the full prefilled chain (not just + // this call's checkpoints) so a reorg re-prefill that replaces a suffix keeps the cumulative aligned. + // Without these the synchronizer derives an empty bundle and the reconstructed block state diverges. + this.setInboxBucket( + { + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }, + [], + ); + let bucketSeq = 0n; + let totalMsgCount = 0n; + for (let i = 0; i < this.prefilled.length; i++) { + const messages = this.prefilledMessages[i] ?? []; + if (messages.length === 0) { + continue; + } + bucketSeq += 1n; + totalMsgCount += BigInt(messages.length); + this.setInboxBucket( + { + seq: bucketSeq, + inboxRollingHash: Fr.ZERO, + totalMsgCount, + timestamp: bucketSeq, + msgCount: messages.length, + lastMessageIndex: totalMsgCount - 1n, + }, + messages, + ); } } diff --git a/yarn-project/archiver/src/test/mock_l1_to_l2_message_source.ts b/yarn-project/archiver/src/test/mock_l1_to_l2_message_source.ts index f3b72a1c940f..53b652f8d279 100644 --- a/yarn-project/archiver/src/test/mock_l1_to_l2_message_source.ts +++ b/yarn-project/archiver/src/test/mock_l1_to_l2_message_source.ts @@ -1,32 +1,64 @@ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { CheckpointId, L2BlockId, L2TipId, L2Tips } from '@aztec/stdlib/block'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; /** * A mocked implementation of L1ToL2MessageSource to be used in tests. */ export class MockL1ToL2MessageSource implements L1ToL2MessageSource { - private messagesPerCheckpoint = new Map(); + private buckets = new Map(); + private messagesPerBucket = new Map(); constructor(private blockNumber: number) {} - public setL1ToL2Messages(checkpointNumber: CheckpointNumber, msgs: Fr[]) { - this.messagesPerCheckpoint.set(checkpointNumber, msgs); + public setInboxBucket(bucket: InboxBucket, msgs: Fr[] = []) { + this.buckets.set(bucket.seq, bucket); + this.messagesPerBucket.set(bucket.seq, msgs); } public setBlockNumber(blockNumber: number) { this.blockNumber = blockNumber; } - getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise { - return Promise.resolve(this.messagesPerCheckpoint.get(checkpointNumber) ?? []); - } - getL1ToL2MessageIndex(_l1ToL2Message: Fr): Promise { throw new Error('Method not implemented.'); } + getInboxBucket(seq: bigint): Promise { + return Promise.resolve(this.buckets.get(seq)); + } + + getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + if (totalMsgCount === 0n) { + return Promise.resolve(this.buckets.get(0n)); + } + return Promise.resolve([...this.buckets.values()].find(bucket => bucket.totalMsgCount === totalMsgCount)); + } + + getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise { + const atOrBefore = [...this.buckets.values()] + .filter(bucket => bucket.timestamp <= timestamp) + .sort((a, b) => Number(a.seq - b.seq)); + return Promise.resolve(atOrBefore.at(-1)); + } + + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + const seqs = [...this.messagesPerBucket.keys()] + .filter(seq => seq > fromExclusive && seq <= toInclusive) + .sort((a, b) => Number(a - b)); + return Promise.resolve(seqs.flatMap(seq => this.messagesPerBucket.get(seq) ?? [])); + } + + async getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise { + const startBucket = await this.getInboxBucketByTotalMsgCount(startLeafCount); + const endBucket = await this.getInboxBucketByTotalMsgCount(endLeafCount); + if (startBucket === undefined || endBucket === undefined) { + throw new Error(`No mocked Inbox bucket boundary at ${startLeafCount} or ${endLeafCount}`); + } + return this.getL1ToL2MessagesBetweenBuckets(startBucket.seq, endBucket.seq); + } + getBlockNumber() { return Promise.resolve(BlockNumber(this.blockNumber)); } diff --git a/yarn-project/archiver/src/test/mock_structs.ts b/yarn-project/archiver/src/test/mock_structs.ts index 91145fcfcb11..5e6539ce0c59 100644 --- a/yarn-project/archiver/src/test/mock_structs.ts +++ b/yarn-project/archiver/src/test/mock_structs.ts @@ -1,13 +1,9 @@ -import { - MAX_NOTE_HASHES_PER_TX, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - PRIVATE_LOG_SIZE_IN_FIELDS, -} from '@aztec/constants'; +import { MAX_L1_TO_L2_MSGS_PER_BLOCK, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants'; import { makeTuple } from '@aztec/foundation/array'; import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { times, timesParallel } from '@aztec/foundation/collection'; -import { randomBigInt, randomInt } from '@aztec/foundation/crypto/random'; +import { randomBigInt } from '@aztec/foundation/crypto/random'; import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -15,88 +11,81 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block'; import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint'; import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs'; -import { InboxLeaf } from '@aztec/stdlib/messaging'; +import { updateInboxRollingHash } from '@aztec/stdlib/messaging'; import { orderAttestations } from '@aztec/stdlib/p2p'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { makeCheckpointAttestationFromCheckpoint } from '@aztec/stdlib/testing'; import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees'; import { PartialStateReference, StateReference, TxEffect } from '@aztec/stdlib/tx'; -import { type InboxMessage, updateRollingHash } from '../structs/inbox_message.js'; +import type { InboxMessage } from '../structs/inbox_message.js'; export function makeInboxMessage( - previousRollingHash = Buffer16.ZERO, + previousInboxRollingHash = Fr.ZERO, overrides: Partial = {}, ): InboxMessage { - const { checkpointNumber = CheckpointNumber(randomInt(100) + 1) } = overrides; const { l1BlockNumber = randomBigInt(100n) + 1n } = overrides; const { l1BlockHash = Buffer32.random() } = overrides; const { leaf = Fr.random() } = overrides; - const { rollingHash = updateRollingHash(previousRollingHash, leaf) } = overrides; - const { index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) } = overrides; + // Compact global insertion index: defaults to the first slot. + const { index = 0n } = overrides; + const { inboxRollingHash = updateInboxRollingHash(previousInboxRollingHash, leaf) } = overrides; + // Default each message to its own bucket, keyed monotonically off its global index. + const { bucketSeq = index + 1n } = overrides; + const { bucketTimestamp = index + 1n } = overrides; return { index, leaf, - checkpointNumber, l1BlockNumber, l1BlockHash, - rollingHash, + inboxRollingHash, + bucketSeq, + bucketTimestamp, }; } +/** + * Builds a contiguous run of `totalCount` inbox messages with compact global indices starting at `initialIndex` + * and a chained consensus rolling hash starting from `initialInboxHash`. + */ export function makeInboxMessages( totalCount: number, opts: { - initialHash?: Buffer16; - initialCheckpointNumber?: CheckpointNumber; - messagesPerCheckpoint?: number; + initialInboxHash?: Fr; + initialIndex?: bigint; overrideFn?: (msg: InboxMessage, index: number) => InboxMessage; } = {}, ): InboxMessage[] { - const { - initialHash = Buffer16.ZERO, - overrideFn = msg => msg, - initialCheckpointNumber = CheckpointNumber(1), - messagesPerCheckpoint = 1, - } = opts; + const { initialInboxHash = Fr.ZERO, initialIndex = 0n, overrideFn = msg => msg } = opts; const messages: InboxMessage[] = []; - let rollingHash = initialHash; + let inboxRollingHash = initialInboxHash; for (let i = 0; i < totalCount; i++) { - const msgIndex = i % messagesPerCheckpoint; - const checkpointNumber = CheckpointNumber.fromBigInt( - BigInt(initialCheckpointNumber) + BigInt(i) / BigInt(messagesPerCheckpoint), - ); const leaf = Fr.random(); + inboxRollingHash = updateInboxRollingHash(inboxRollingHash, leaf); const message = overrideFn( - makeInboxMessage(rollingHash, { + makeInboxMessage(Fr.ZERO, { leaf, - checkpointNumber, - index: InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(msgIndex), + index: initialIndex + BigInt(i), + inboxRollingHash, }), i, ); - rollingHash = message.rollingHash; messages.push(message); } return messages; } -/** Creates inbox messages distributed across multiple blocks with proper checkpoint numbering. */ -export function makeInboxMessagesWithFullBlocks( - blockCount: number, - opts: { initialCheckpointNumber?: CheckpointNumber } = {}, -): InboxMessage[] { - const { initialCheckpointNumber = CheckpointNumber(13) } = opts; - return makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, { +/** + * Creates `blockCount` full buckets of `MAX_L1_TO_L2_MSGS_PER_BLOCK` inbox messages each, with compact indices and one + * bucket sequence per block. + */ +export function makeInboxMessagesWithFullBlocks(blockCount: number): InboxMessage[] { + return makeInboxMessages(MAX_L1_TO_L2_MSGS_PER_BLOCK * blockCount, { overrideFn: (msg, i) => { - const checkpointNumber = CheckpointNumber( - initialCheckpointNumber + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), - ); - const index = - InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); - return { ...msg, checkpointNumber, index }; + const bucketSeq = BigInt(Math.floor(i / MAX_L1_TO_L2_MSGS_PER_BLOCK)) + 1n; + return { ...msg, bucketSeq, bucketTimestamp: bucketSeq }; }, }); } diff --git a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts index 7fbfa0bbdcb3..3fc1008c01ee 100644 --- a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.test.ts @@ -1,4 +1,3 @@ -import { L1ToL2MessagesNotReadyError } from '@aztec/archiver'; import type { EpochCacheInterface } from '@aztec/epoch-cache'; import { type FeeHeader, RollupContract } from '@aztec/ethereum/contracts'; import { @@ -24,9 +23,10 @@ import { } from '@aztec/stdlib/block'; import type { ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; import type { ContractDataSource } from '@aztec/stdlib/contract'; +import { EmptyL1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import { GasFees } from '@aztec/stdlib/gas'; import type { MerkleTreeWriteOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { mockTx } from '@aztec/stdlib/testing'; import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees'; @@ -114,6 +114,26 @@ describe('NodePublicCallsSimulator', () => { gasFees: GasFees.empty(), }); + /** + * Mocks the Inbox so the next-block prediction selects a two-message bundle: the fork's message total (0) + * resolves to bucket 0, and bucket 1 is lag-eligible and holds both messages. + */ + const mockInboxSelection = () => { + const makeBucket = (seq: bigint, totalMsgCount: bigint): InboxBucket => ({ + seq, + inboxRollingHash: Fr.ZERO, + totalMsgCount, + timestamp: 0n, + msgCount: Number(totalMsgCount), + lastMessageIndex: totalMsgCount === 0n ? 0n : totalMsgCount - 1n, + }); + const bundle = [new Fr(0x1234), new Fr(0x5678)]; + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue(makeBucket(0n, 0n)); + l1ToL2MessageSource.getLatestInboxBucketAtOrBefore.mockResolvedValue(makeBucket(1n, 2n)); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue(bundle); + return bundle; + }; + const lowGasTx = () => mockTx(0x10000, { numberOfNonRevertiblePublicCallRequests: 0, @@ -140,9 +160,18 @@ describe('NodePublicCallsSimulator', () => { (merkleTreeFork as unknown as { [Symbol.asyncDispose]: () => Promise })[Symbol.asyncDispose] = () => Promise.resolve(); worldStateSynchronizer.fork.mockResolvedValue(merkleTreeFork); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); + merkleTreeFork.getTreeInfo.mockResolvedValue({ + treeId: MerkleTreeId.L1_TO_L2_MESSAGE_TREE, + root: Buffer.alloc(32), + size: 0n, + depth: 16, + }); blockSource.getPendingChainValidationStatus.mockResolvedValue({ valid: true }); blockSource.getProposedCheckpointData.mockResolvedValue(undefined); + // No Inbox bucket resolves to the fork's message total by default, so the next-block message prediction + // bails out and tests see the bare tip state unless they opt into it. + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue(undefined); + epochCache.getL1Constants.mockReturnValue(EmptyL1RollupConstants); globalVariableBuilder.buildCheckpointGlobalVariables.mockImplementation((_c, _f, slotNumber) => Promise.resolve(checkpointGlobals(slotNumber)), @@ -222,17 +251,31 @@ describe('NodePublicCallsSimulator', () => { expect(rollupContract.getManaTarget).not.toHaveBeenCalled(); }); - it('does not insert L1-to-L2 messages', async () => { + it('appends the message bundle the next block would consume', async () => { const tx = await lowGasTx(); setupMidCheckpoint(); blockSource.getBlockData.mockImplementation((query: BlockQuery) => Promise.resolve('number' in query ? makeBlockData(query.number, SlotNumber(42)) : undefined), ); mockNextL1Slot(SlotNumber(100)); + const bundle = mockInboxSelection(); await simulator.simulate(tx); - expect(l1ToL2MessageSource.getL1ToL2Messages).not.toHaveBeenCalled(); + expect(merkleTreeFork.appendLeaves).toHaveBeenCalledWith(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, bundle); + }); + + it('simulates against the tip when the parent Inbox bucket is not synced', async () => { + const tx = await lowGasTx(); + setupMidCheckpoint(); + blockSource.getBlockData.mockImplementation((query: BlockQuery) => + Promise.resolve('number' in query ? makeBlockData(query.number, SlotNumber(42)) : undefined), + ); + mockNextL1Slot(SlotNumber(100)); + // Default mock: no bucket resolves the fork's message total. + + await expect(simulator.simulate(tx)).resolves.toBeDefined(); + expect(merkleTreeFork.appendLeaves).not.toHaveBeenCalled(); }); @@ -245,8 +288,7 @@ describe('NodePublicCallsSimulator', () => { await expect(simulator.simulate(tx)).rejects.toThrow(); - // Must not treat the next block as opening a new checkpoint and re-insert the ongoing checkpoint's messages. - expect(l1ToL2MessageSource.getL1ToL2Messages).not.toHaveBeenCalled(); + // Must not treat the next block as opening a new checkpoint. expect(merkleTreeFork.appendLeaves).not.toHaveBeenCalled(); expect(globalVariableBuilder.buildCheckpointGlobalVariables).not.toHaveBeenCalled(); }); @@ -281,36 +323,19 @@ describe('NodePublicCallsSimulator', () => { expect(plan?.chainTipsOverride).toEqual({ pending: CheckpointNumber(1), proven: CheckpointNumber(1) }); }); - it('inserts L1-to-L2 messages for the next checkpoint', async () => { - const tx = await lowGasTx(); - const messages = [Fr.fromString('0x1234'), Fr.fromString('0x5678')]; - blockSource.getL2Tips.mockResolvedValue(setupBoundary()); - blockSource.getBlockData.mockImplementation((query: BlockQuery) => - Promise.resolve('number' in query ? makeBlockData(query.number, SlotNumber(5)) : undefined), - ); - mockNextL1Slot(SlotNumber(20)); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue(messages); - - await simulator.simulate(tx); - - // targetCheckpoint = proposedCheckpoint.number + 1 - expect(l1ToL2MessageSource.getL1ToL2Messages).toHaveBeenCalledWith(CheckpointNumber(2)); - const [treeId, appended] = merkleTreeFork.appendLeaves.mock.calls[0]; - expect(treeId).toEqual(MerkleTreeId.L1_TO_L2_MESSAGE_TREE); - expect(appended.slice(0, 2)).toEqual(messages); - }); - - it('tolerates L1ToL2MessagesNotReadyError and simulates without messages', async () => { + it('appends the message bundle the next block would consume', async () => { const tx = await lowGasTx(); blockSource.getL2Tips.mockResolvedValue(setupBoundary()); blockSource.getBlockData.mockImplementation((query: BlockQuery) => Promise.resolve('number' in query ? makeBlockData(query.number, SlotNumber(5)) : undefined), ); mockNextL1Slot(SlotNumber(20)); - l1ToL2MessageSource.getL1ToL2Messages.mockRejectedValue(new L1ToL2MessagesNotReadyError(CheckpointNumber(2), 0n)); + const bundle = mockInboxSelection(); await expect(simulator.simulate(tx)).resolves.toBeDefined(); - expect(merkleTreeFork.appendLeaves).not.toHaveBeenCalled(); + + // Only the first block's worth of messages: a fresh checkpoint starts its per-checkpoint budget at the tip. + expect(merkleTreeFork.appendLeaves).toHaveBeenCalledWith(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, bundle); }); it('targets parentSlot + 1 and carries the parent overrides when pipelining on a proposed checkpoint', async () => { @@ -438,6 +463,7 @@ function makeProposedCheckpointData(args: { feeAssetPriceModifier: 7n, archive: new AppendOnlyTreeSnapshot(args.archiveRoot ?? Fr.ZERO, 0), checkpointOutHash: Fr.fromString('0xfeed'), + inboxMsgTotal: 0n, }; } diff --git a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.ts b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.ts index a563ac5432c1..07c9ed0adde9 100644 --- a/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.ts +++ b/yarn-project/aztec-node/src/aztec-node/node_public_calls_simulator.ts @@ -1,4 +1,4 @@ -import { L1ToL2MessagesNotReadyError } from '@aztec/archiver'; +import { INBOX_LAG_SECONDS, MAX_L1_TO_L2_MSGS_PER_BLOCK, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT } from '@aztec/constants'; import { PROPOSER_PIPELINING_SLOT_OFFSET } from '@aztec/epoch-cache'; import type { EpochCacheInterface } from '@aztec/epoch-cache'; import { @@ -8,21 +8,21 @@ import { } from '@aztec/ethereum/contracts'; import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { compactArray } from '@aztec/foundation/collection'; -import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { BadRequestError } from '@aztec/foundation/json-rpc'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { DateProvider } from '@aztec/foundation/timer'; -import { isErrorClass } from '@aztec/foundation/types'; +import { type InboxBucketSource, selectInboxBucketForBlock } from '@aztec/sequencer-client'; import { type AvmSimulator, PublicContractsDB, PublicProcessorFactory } from '@aztec/simulator/server'; import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2BlockSource, L2Tips } from '@aztec/stdlib/block'; import { type ProposedCheckpointData, buildCheckpointSimulationOverridesPlan } from '@aztec/stdlib/checkpoint'; import type { ContractDataSource } from '@aztec/stdlib/contract'; -import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import { type L1ToL2MessageSource, appendL1ToL2MessagesToTree } from '@aztec/stdlib/messaging'; +import type { MerkleTreeWriteOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; +import { type L1ToL2MessageSource, appendL1ToL2MessagesToTree, getInboxCutoffTimestamp } from '@aztec/stdlib/messaging'; import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { MerkleTreeId } from '@aztec/stdlib/trees'; import { type GlobalVariableBuilder, GlobalVariables, @@ -34,6 +34,9 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien import { applyPublicDataOverrides } from './public_data_overrides.js'; +/** Inbox queries the simulator needs to predict the message bundle the next block would consume. */ +type SimulatorInboxSource = InboxBucketSource & Pick; + /** Config fields the simulator needs — a narrow subset of `AztecNodeConfig`. */ export interface NodePublicCallsSimulatorConfig { /** Maximum total gas limit accepted for an incoming simulation. */ @@ -46,7 +49,8 @@ export interface NodePublicCallsSimulatorConfig { export interface NodePublicCallsSimulatorDeps { blockSource: L2BlockSource; worldStateSynchronizer: WorldStateSynchronizer; - l1ToL2MessageSource: L1ToL2MessageSource; + /** Inbox bucket queries, used to predict the L1-to-L2 messages the next block will consume. */ + l1ToL2MessageSource: SimulatorInboxSource; contractDataSource: ContractDataSource; globalVariableBuilder: GlobalVariableBuilder; /** @@ -78,16 +82,20 @@ export interface NodePublicCallsSimulatorDeps { * - **When the next block continues an in-progress checkpoint** (the latest proposed block is ahead of * the proposed-checkpoint frontier): every block in a checkpoint shares the same * `CheckpointGlobalVariables`, so we copy the latest proposed block's globals verbatim and only - * bump the block number. No L1 calls, no L1-to-L2 message insertion. + * bump the block number. No L1 calls. * - **When the next block opens a new checkpoint** (the latest proposed block coincides with the * proposed-checkpoint frontier): we compute fresh globals for the slot the next block will land in, * applying the same `SimulationOverridesPlan` the sequencer applies so the simulated mana min fee * matches what the sequencer will write into the block header. + * + * Either way it also predicts the L1-to-L2 message bundle the next block would consume and appends it + * to the fork, so a transaction consuming a message that is in the Inbox but not yet in a block + * simulates against the state it will actually run in. */ export class NodePublicCallsSimulator { private readonly blockSource: L2BlockSource; private readonly worldStateSynchronizer: WorldStateSynchronizer; - private readonly l1ToL2MessageSource: L1ToL2MessageSource; + private readonly l1ToL2MessageSource: SimulatorInboxSource; private readonly contractDataSource: ContractDataSource; private readonly globalVariableBuilder: GlobalVariableBuilder; private readonly rollupContract: RollupContract | undefined; @@ -97,6 +105,7 @@ export class NodePublicCallsSimulator { private readonly avmSimulator?: AvmSimulator; private readonly telemetry: TelemetryClient; private readonly log: Logger; + private readonly dateProvider = new DateProvider(); constructor(deps: NodePublicCallsSimulatorDeps) { this.blockSource = deps.blockSource; @@ -157,9 +166,7 @@ export class NodePublicCallsSimulator { // the proposed-checkpoint terminating block; it opens a new checkpoint when they coincide. const atCheckpointBoundary = proposedCheckpointLastBlock === l2Tips.proposed.number; - // `targetCheckpoint` is the checkpoint whose L1-to-L2 messages must be inserted into the fork - // before simulation. Only set when opening a new checkpoint, where the next block is its first block. - const { globalVariables: newGlobalVariables, targetCheckpoint } = atCheckpointBoundary + const { globalVariables: newGlobalVariables } = atCheckpointBoundary ? await this.buildGlobalVariablesForNewCheckpoint(l2Tips, proposedCheckpointData, blockNumber) : { globalVariables: await this.copyGlobalVariablesFromLatestProposedBlock(latestBlockNumber, blockNumber) }; @@ -169,7 +176,7 @@ export class NodePublicCallsSimulator { const publicProcessorFactory = new PublicProcessorFactory( this.contractDataSource, this.avmSimulator, - new DateProvider(), + this.dateProvider, this.telemetry, this.log.getBindings(), ); @@ -184,18 +191,14 @@ export class NodePublicCallsSimulator { // Ensure world-state has caught up with the latest block we loaded from the archiver await this.worldStateSynchronizer.syncImmediate(latestBlockNumber); - const nextCheckpointMessages = await this.getNextCheckpointMessages(targetCheckpoint); - - // Request a new fork of the world state at the latest block number, and apply any overrides and next checkpoint messages to it before simulation + // Request a new fork of the world state at the latest block number, then apply the next block's predicted + // L1-to-L2 message bundle and any caller overrides to it before simulation. await using merkleTreeFork = await this.worldStateSynchronizer.fork(latestBlockNumber); - if (nextCheckpointMessages !== undefined) { - this.log.debug( - `Appending ${nextCheckpointMessages.length} L1-to-L2 messages to the world state tree for the next checkpoint`, - { checkpointNumber: targetCheckpoint }, - ); - await appendL1ToL2MessagesToTree(merkleTreeFork, nextCheckpointMessages); - } + await this.appendPredictedL1ToL2Messages(merkleTreeFork, { + slotNumber: newGlobalVariables.slotNumber, + checkpointStartBlock: atCheckpointBoundary ? undefined : proposedCheckpointLastBlock, + }); await applyPublicDataOverrides(merkleTreeFork, overrides?.publicStorage); @@ -236,47 +239,88 @@ export class NodePublicCallsSimulator { } /** - * Fetches the next checkpoint's L1-to-L2 messages to insert into the fork before simulation. Only set - * when opening a new checkpoint; when continuing an in-progress checkpoint the ongoing checkpoint's - * messages were already applied when its first block synced, so inserting here would double-count them - * — which is why a missing header for the latest proposed block throws rather than falling through to - * this path. A not-ready or failed fetch degrades to simulating without the messages rather than - * failing the request. + * Appends the L1-to-L2 message bundle the next block would consume to the simulation fork, so a transaction + * consuming a message that has reached the Inbox but no block yet simulates against the state it will run in. + * Runs the same bucket selection the sequencer runs (lag eligibility plus the per-block and per-checkpoint caps), + * treating the next block as non-final: the censorship cutoff only widens consumption on a checkpoint's last + * block, and the node cannot know whether the next block is it. + * + * Best-effort. Any failure — Inbox buckets not synced yet, a torn archiver snapshot — leaves the fork at the tip + * state, which is what the transaction sees if the next block consumes nothing. */ - private async getNextCheckpointMessages(targetCheckpoint: CheckpointNumber | undefined): Promise { - if (targetCheckpoint === undefined) { - return undefined; - } + private async appendPredictedL1ToL2Messages( + fork: MerkleTreeWriteOperations, + opts: { + /** Slot the next block lands in; anchors the censorship cutoff. */ + slotNumber: SlotNumber; + /** Last block of the checkpoint the next block extends; undefined when the next block opens a checkpoint. */ + checkpointStartBlock: BlockNumber | undefined; + }, + ): Promise { try { - return await this.l1ToL2MessageSource.getL1ToL2Messages(targetCheckpoint); - } catch (err) { - if (isErrorClass(err, L1ToL2MessagesNotReadyError)) { - this.log.warn( - `L1-to-L2 messages for checkpoint ${targetCheckpoint} are not ready yet (simulating without them)`, - { checkpointNumber: targetCheckpoint }, - ); - } else { - this.log.error( - `Failed to get L1-to-L2 messages for checkpoint ${targetCheckpoint} (simulating without them)`, - err, - { checkpointNumber: targetCheckpoint }, - ); + const parentTotalMsgCount = (await fork.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE)).size; + const parentBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(parentTotalMsgCount); + if (parentBucket === undefined) { + this.log.debug(`Inbox bucket at message total ${parentTotalMsgCount} not synced; simulating against the tip`, { + parentTotalMsgCount, + }); + return; } - return undefined; + + // Origin of the per-checkpoint cap: the total consumed as of the checkpoint's parent. A block extending an + // in-progress checkpoint reads it off that checkpoint's parent block; a block opening one starts from the tip. + const checkpointStartTotalMsgCount = + opts.checkpointStartBlock === undefined + ? parentTotalMsgCount + : await this.getConsumedMessageTotal(opts.checkpointStartBlock); + if (checkpointStartTotalMsgCount === undefined) { + this.log.debug(`Block ${opts.checkpointStartBlock} has no header on this node; simulating against the tip`); + return; + } + + const selection = await selectInboxBucketForBlock({ + messageSource: this.l1ToL2MessageSource, + now: BigInt(Math.floor(this.dateProvider.now() / 1000)), + lagSeconds: BigInt(INBOX_LAG_SECONDS), + parent: { seq: parentBucket.seq, totalMsgCount: parentBucket.totalMsgCount }, + checkpointStartTotalMsgCount, + perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + isLastBlock: false, + cutoffTimestamp: getInboxCutoffTimestamp(opts.slotNumber, this.epochCache.getL1Constants(), INBOX_LAG_SECONDS), + }); + if (!selection.consume || selection.bundle.length === 0) { + return; + } + + await appendL1ToL2MessagesToTree(fork, selection.bundle); + this.log.debug(`Appended ${selection.bundle.length} predicted L1-to-L2 messages to the simulation fork`, { + bucketSeq: selection.bucket.seq, + messageCount: selection.bundle.length, + }); + } catch (err) { + this.log.verbose(`Could not predict the next block's L1-to-L2 messages, simulating against the tip: ${err}`); + } + } + + /** Cumulative Inbox message total consumed as of `blockNumber`, i.e. its L1-to-L2 message tree leaf count. */ + private async getConsumedMessageTotal(blockNumber: BlockNumber): Promise { + if (blockNumber === BlockNumber.ZERO) { + return 0n; } + const block = await this.blockSource.getBlockData({ number: blockNumber }); + return block === undefined ? undefined : BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); } /** * Continues an in-progress checkpoint: the next block extends the checkpoint the latest proposed * block belongs to. Every block in a checkpoint shares the same `CheckpointGlobalVariables`, so the * next block's globals are the latest proposed block's globals with only the block number bumped — - * including the proposer's real coinbase/feeRecipient. No L1 reads and no L1-to-L2 message insertion - * happen here. + * including the proposer's real coinbase/feeRecipient. No L1 reads happen here. * * A missing header means the archiver reported a proposed tip via `getL2Tips` but no longer has its * data (a torn snapshot). We throw a transient/retryable error rather than treating the next block as - * opening a new checkpoint: the fork at `latestBlockNumber` already contains the ongoing checkpoint's - * L1-to-L2 messages, so inserting the next checkpoint's messages would append them a second time. + * opening a new checkpoint, whose globals would be built for the wrong slot. */ private async copyGlobalVariablesFromLatestProposedBlock( latestBlockNumber: BlockNumber, @@ -298,19 +342,14 @@ export class NodePublicCallsSimulator { * sequencer applies so the simulated mana min fee matches what the sequencer will write into the * block header. Coinbase and fee recipient stay zero (we cannot know the future proposer's payout * addresses), unlike continuing an in-progress checkpoint which inherits the real ones from the - * proposed header. Returns the target checkpoint so the caller inserts that checkpoint's L1-to-L2 - * messages into the fork. + * proposed header. */ private async buildGlobalVariablesForNewCheckpoint( l2Tips: L2Tips, proposedCheckpointData: ProposedCheckpointData | undefined, blockNumber: BlockNumber, - ): Promise<{ globalVariables: GlobalVariables; targetCheckpoint: CheckpointNumber }> { + ): Promise<{ globalVariables: GlobalVariables }> { const checkpointedCheckpointNumber = l2Tips.checkpointed.checkpoint.number; - // The new checkpoint sits on top of the proposed one when pipelining, otherwise on the - // checkpointed tip. The target slot and the overrides plan both derive from the single - // `proposedCheckpointData` read, so they cannot disagree about the proposed parent. - const proposedCheckpointNumber = proposedCheckpointData?.checkpointNumber ?? checkpointedCheckpointNumber; const targetSlot = this.computeTargetSlot(proposedCheckpointData); const plan = await this.buildSimulationOverridesPlan(proposedCheckpointData, checkpointedCheckpointNumber); @@ -324,7 +363,6 @@ export class NodePublicCallsSimulator { return { globalVariables: GlobalVariables.from({ blockNumber, ...checkpointGlobalVariables }), - targetCheckpoint: CheckpointNumber(proposedCheckpointNumber + 1), }; } diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index 734c0ba01e16..3b4d4300f13f 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -37,7 +37,6 @@ import type { ContractDataSource, ContractInstanceWithAddress } from '@aztec/std import { EmptyL1RollupConstants, type L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import { GasFees } from '@aztec/stdlib/gas'; import type { L2LogsSource, MerkleTreeReadOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import { InboxLeaf } from '@aztec/stdlib/messaging'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { mockTx, randomContractInstanceWithAddress } from '@aztec/stdlib/testing'; @@ -1396,6 +1395,7 @@ describe('aztec node', () => { blockCount: 1, totalManaUsed: 0n, feeAssetPriceModifier: 0n, + inboxMsgTotal: 0n, }; } @@ -1568,22 +1568,19 @@ describe('aztec node', () => { }); }); - describe('getL1ToL2MessageCheckpoint', () => { - it('returns the checkpoint for a message at index 0n', async () => { + describe('getL1ToL2MessageIndex', () => { + it('returns the compact leaf index the node assigned to the message', async () => { const msg = Fr.random(); - l1ToL2MessageSource.getL1ToL2MessageIndex.mockResolvedValue(0n); + l1ToL2MessageSource.getL1ToL2MessageIndex.mockResolvedValue(7n); - const result = await node.getL1ToL2MessageCheckpoint(msg); - expect(result).toEqual(InboxLeaf.checkpointNumberFromIndex(0n)); - expect(result).not.toBeUndefined(); + expect(await node.getL1ToL2MessageIndex(msg)).toEqual(7n); }); it('returns undefined when the message is not found', async () => { const msg = Fr.random(); l1ToL2MessageSource.getL1ToL2MessageIndex.mockResolvedValue(undefined); - const result = await node.getL1ToL2MessageCheckpoint(msg); - expect(result).toBeUndefined(); + expect(await node.getL1ToL2MessageIndex(msg)).toBeUndefined(); }); }); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 526557ca861c..b7768e5416f9 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -674,8 +674,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb return this.worldStateQueries.getL1ToL2MessageMembershipWitness(referenceBlock, l1ToL2Message); } - public getL1ToL2MessageCheckpoint(l1ToL2Message: Fr): Promise { - return this.worldStateQueries.getL1ToL2MessageCheckpoint(l1ToL2Message); + public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise { + return this.worldStateQueries.getL1ToL2MessageIndex(l1ToL2Message); } /** diff --git a/yarn-project/aztec-node/src/modules/node_world_state_queries.ts b/yarn-project/aztec-node/src/modules/node_world_state_queries.ts index 1e7f6dcd0a22..0bbdefb67302 100644 --- a/yarn-project/aztec-node/src/modules/node_world_state_queries.ts +++ b/yarn-project/aztec-node/src/modules/node_world_state_queries.ts @@ -1,5 +1,5 @@ import { ARCHIVE_HEIGHT, type L1_TO_L2_MSG_TREE_HEIGHT, type NOTE_HASH_TREE_HEIGHT } from '@aztec/constants'; -import { BlockNumber, type CheckpointNumber, type EpochNumber } from '@aztec/foundation/branded-types'; +import { BlockNumber, type EpochNumber } from '@aztec/foundation/branded-types'; import { chunkBy } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { type Logger, createLogger } from '@aztec/foundation/log'; @@ -16,7 +16,7 @@ import { } from '@aztec/stdlib/block'; import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash'; import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import { InboxLeaf, type L1ToL2MessageSource, type L2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; +import type { L1ToL2MessageSource, L2ToL1MembershipWitness } from '@aztec/stdlib/messaging'; import { MerkleTreeId, type NullifierLeafPreimage, @@ -177,9 +177,8 @@ export class NodeWorldStateQueries { return [witness.index, witness.path]; } - public async getL1ToL2MessageCheckpoint(l1ToL2Message: Fr): Promise { - const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message); - return messageIndex !== undefined ? InboxLeaf.checkpointNumberFromIndex(messageIndex) : undefined; + public getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise { + return this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message); } /** diff --git a/yarn-project/aztec.js/src/utils/cross_chain.test.ts b/yarn-project/aztec.js/src/utils/cross_chain.test.ts index 573c6453ce2a..839cc1a47c3d 100644 --- a/yarn-project/aztec.js/src/utils/cross_chain.test.ts +++ b/yarn-project/aztec.js/src/utils/cross_chain.test.ts @@ -1,4 +1,3 @@ -import { CheckpointNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { BlockData } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/client'; @@ -8,19 +7,20 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import { isL1ToL2MessageReady } from './cross_chain.js'; describe('isL1ToL2MessageReady', () => { - let node: MockProxy>; + let node: MockProxy>; let messageHash: Fr; - const blockAtCheckpoint = (checkpointNumber: number) => - ({ checkpointNumber: CheckpointNumber(checkpointNumber) }) as BlockData; + /** A block whose L1-to-L2 message tree holds `leafCount` leaves, i.e. leaf indices 0..leafCount-1. */ + const blockWithMessageLeaves = (leafCount: number) => + ({ header: { state: { l1ToL2MessageTree: { nextAvailableLeafIndex: leafCount } } } }) as BlockData; beforeEach(() => { node = mock(); messageHash = Fr.random(); }); - it('returns false when the message is not yet in any checkpoint', async () => { - node.getL1ToL2MessageCheckpoint.mockResolvedValue(undefined); + it('returns false when the node has not seen the message yet', async () => { + node.getL1ToL2MessageIndex.mockResolvedValue(undefined); expect(await isL1ToL2MessageReady(node, messageHash)).toBe(false); expect(node.getBlockData).not.toHaveBeenCalled(); @@ -28,24 +28,24 @@ describe('isL1ToL2MessageReady', () => { describe('latest fallback (no chain tip)', () => { beforeEach(() => { - node.getL1ToL2MessageCheckpoint.mockResolvedValue(CheckpointNumber(5)); + node.getL1ToL2MessageIndex.mockResolvedValue(5n); }); - it('checks readiness against the latest block', async () => { - node.getBlockData.mockResolvedValue(blockAtCheckpoint(5)); + it('returns true once the latest block has consumed the message leaf', async () => { + node.getBlockData.mockResolvedValue(blockWithMessageLeaves(6)); expect(await isL1ToL2MessageReady(node, messageHash)).toBe(true); expect(node.getBlockData).toHaveBeenCalledWith('latest'); }); - it('returns true once the latest block reaches the message checkpoint', async () => { - node.getBlockData.mockResolvedValue(blockAtCheckpoint(6)); + it('returns false when the latest block stops exactly at the message leaf', async () => { + node.getBlockData.mockResolvedValue(blockWithMessageLeaves(5)); - expect(await isL1ToL2MessageReady(node, messageHash)).toBe(true); + expect(await isL1ToL2MessageReady(node, messageHash)).toBe(false); }); - it('returns false when the latest block is behind the message checkpoint', async () => { - node.getBlockData.mockResolvedValue(blockAtCheckpoint(4)); + it('returns false when the latest block is behind the message leaf', async () => { + node.getBlockData.mockResolvedValue(blockWithMessageLeaves(4)); expect(await isL1ToL2MessageReady(node, messageHash)).toBe(false); }); @@ -59,13 +59,13 @@ describe('isL1ToL2MessageReady', () => { describe('with an explicit chain tip', () => { beforeEach(() => { - node.getL1ToL2MessageCheckpoint.mockResolvedValue(CheckpointNumber(5)); + node.getL1ToL2MessageIndex.mockResolvedValue(5n); }); it('compares against the requested tip instead of latest', async () => { - // The proven tip lags behind latest: the message is in checkpoint 5 but proven is only at 4. + // The proven tip lags behind latest: latest consumed the message leaf, proven has not. node.getBlockData.mockImplementation(param => - Promise.resolve(param === 'proven' ? blockAtCheckpoint(4) : blockAtCheckpoint(6)), + Promise.resolve(param === 'proven' ? blockWithMessageLeaves(5) : blockWithMessageLeaves(7)), ); expect(await isL1ToL2MessageReady(node, messageHash, 'latest')).toBe(true); @@ -73,9 +73,9 @@ describe('isL1ToL2MessageReady', () => { expect(node.getBlockData).toHaveBeenLastCalledWith('proven'); }); - it('returns true once the requested tip reaches the message checkpoint', async () => { + it('returns true once the requested tip has consumed the message leaf', async () => { node.getBlockData.mockImplementation(param => - Promise.resolve(param === 'proven' ? blockAtCheckpoint(5) : blockAtCheckpoint(7)), + Promise.resolve(param === 'proven' ? blockWithMessageLeaves(6) : blockWithMessageLeaves(8)), ); expect(await isL1ToL2MessageReady(node, messageHash, 'proven')).toBe(true); diff --git a/yarn-project/aztec.js/src/utils/cross_chain.ts b/yarn-project/aztec.js/src/utils/cross_chain.ts index 3010e6eab40a..9a0fec7dd9bd 100644 --- a/yarn-project/aztec.js/src/utils/cross_chain.ts +++ b/yarn-project/aztec.js/src/utils/cross_chain.ts @@ -10,7 +10,7 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/client'; * @param opts - Options */ export function waitForL1ToL2MessageReady( - node: Pick, + node: Pick, l1ToL2MessageHash: Fr, opts: { /** Timeout for the operation in seconds */ timeoutSeconds: number; @@ -39,16 +39,17 @@ export function waitForL1ToL2MessageReady( * @returns True if the message is ready to be consumed, false otherwise */ export async function isL1ToL2MessageReady( - node: Pick, + node: Pick, l1ToL2MessageHash: Fr, chainTip: BlockTag = 'latest', ): Promise { - const messageCheckpointNumber = await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash); - if (messageCheckpointNumber === undefined) { + const messageIndex = await node.getL1ToL2MessageIndex(l1ToL2MessageHash); + if (messageIndex === undefined) { return false; } - // L1 to L2 messages are included in the first block of a checkpoint + // Blocks consume L1-to-L2 messages in Inbox order into consecutive leaves of the message tree, so the message is + // available at a tip exactly when that tip's tree has grown past the message's leaf index. const block = await node.getBlockData(chainTip); - return block !== undefined && block.checkpointNumber >= messageCheckpointNumber; + return block !== undefined && messageIndex < BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); } diff --git a/yarn-project/bb-prover/src/honk.ts b/yarn-project/bb-prover/src/honk.ts index 552f7c79beab..6c8f4219a278 100644 --- a/yarn-project/bb-prover/src/honk.ts +++ b/yarn-project/bb-prover/src/honk.ts @@ -3,7 +3,11 @@ import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_starknet_honk' | 'ultra_rollup_honk'; const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ServerProtocolArtifact[]; -const UltraHonkCircuits = ['ParityBaseArtifact', 'ParityRootArtifact'] as const satisfies ServerProtocolArtifact[]; +const UltraHonkCircuits = [ + 'InboxParity64Artifact', + 'InboxParity256Artifact', + 'InboxParity1024Artifact', +] as const satisfies ServerProtocolArtifact[]; export type UltraKeccakHonkServerProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number]; export type UltraHonkServerProtocolArtifact = (typeof UltraHonkCircuits)[number]; diff --git a/yarn-project/bb-prover/src/prover/server/bb_prover.ts b/yarn-project/bb-prover/src/prover/server/bb_prover.ts index c33794188bc0..ab4855b0f20f 100644 --- a/yarn-project/bb-prover/src/prover/server/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/server/bb_prover.ts @@ -17,6 +17,8 @@ import { convertBlockRootEmptyTxFirstRollupPrivateInputsToWitnessMap, convertBlockRootFirstRollupOutputsFromWitnessMap, convertBlockRootFirstRollupPrivateInputsToWitnessMap, + convertBlockRootMsgsOnlyRollupOutputsFromWitnessMap, + convertBlockRootMsgsOnlyRollupPrivateInputsToWitnessMap, convertBlockRootRollupOutputsFromWitnessMap, convertBlockRootRollupPrivateInputsToWitnessMap, convertBlockRootSingleTxFirstRollupOutputsFromWitnessMap, @@ -31,10 +33,8 @@ import { convertCheckpointRootRollupPrivateInputsToWitnessMap, convertCheckpointRootSingleBlockRollupOutputsFromWitnessMap, convertCheckpointRootSingleBlockRollupPrivateInputsToWitnessMap, - convertParityBaseOutputsFromWitnessMap, - convertParityBasePrivateInputsToWitnessMap, - convertParityRootOutputsFromWitnessMap, - convertParityRootPrivateInputsToWitnessMap, + convertInboxParityOutputsFromWitnessMap, + convertInboxParityPrivateInputsToWitnessMap, convertPrivateTxBaseRollupOutputsFromWitnessMap, convertPrivateTxBaseRollupPrivateInputsToWitnessMap, convertPublicChonkVerifierOutputsFromWitnessMap, @@ -46,6 +46,7 @@ import { convertTxMergeRollupOutputsFromWitnessMap, convertTxMergeRollupPrivateInputsToWitnessMap, getServerCircuitArtifact, + inboxParityArtifactForSize, } from '@aztec/noir-protocol-circuits-types/server'; import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks'; import { mapProtocolArtifactNameToCircuitName } from '@aztec/noir-protocol-circuits-types/types'; @@ -58,13 +59,14 @@ import { type ServerCircuitProver, makePublicInputsAndRecursiveProof, } from '@aztec/stdlib/interfaces/server'; -import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import type { InboxParityPrivateInputs, ParityPublicInputs } from '@aztec/stdlib/parity'; import { Proof, RecursiveProof, makeRecursiveProofFromBinary } from '@aztec/stdlib/proofs'; import { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -138,34 +140,16 @@ export class BBNativeRollupProver implements ServerCircuitProver { * @param inputs - Inputs to the circuit. * @returns The public inputs of the parity circuit. */ - @trackSpan('BBNativeRollupProver.getBaseParityProof', { [Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-base' }) - public getBaseParityProof( - inputs: ParityBasePrivateInputs, + @trackSpan('BBNativeRollupProver.getInboxParityProof', { [Attributes.PROTOCOL_CIRCUIT_NAME]: 'inbox-parity' }) + public getInboxParityProof( + inputs: InboxParityPrivateInputs, ): Promise> { return this.createRecursiveProofAndVerify( inputs, - 'ParityBaseArtifact', + inboxParityArtifactForSize(inputs.size), RECURSIVE_PROOF_LENGTH, - convertParityBasePrivateInputsToWitnessMap, - convertParityBaseOutputsFromWitnessMap, - ); - } - - /** - * Simulates the root parity circuit from its inputs. - * @param inputs - Inputs to the circuit. - * @returns The public inputs of the parity circuit. - */ - @trackSpan('BBNativeRollupProver.getRootParityProof', { [Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-root' }) - public getRootParityProof( - inputs: ParityRootPrivateInputs, - ): Promise> { - return this.createRecursiveProofAndVerify( - inputs, - 'ParityRootArtifact', - NESTED_RECURSIVE_PROOF_LENGTH, - convertParityRootPrivateInputsToWitnessMap, - convertParityRootOutputsFromWitnessMap, + convertInboxParityPrivateInputsToWitnessMap, + outputs => convertInboxParityOutputsFromWitnessMap(outputs, inputs.size), ); } @@ -316,6 +300,18 @@ export class BBNativeRollupProver implements ServerCircuitProver { ); } + public getBlockRootMsgsOnlyRollupProof( + input: BlockRootMsgsOnlyRollupPrivateInputs, + ): Promise> { + return this.createRecursiveProofAndVerify( + input, + 'BlockRootMsgsOnlyRollupArtifact', + NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, + convertBlockRootMsgsOnlyRollupPrivateInputsToWitnessMap, + convertBlockRootMsgsOnlyRollupOutputsFromWitnessMap, + ); + } + public getBlockMergeRollupProof( input: BlockMergeRollupPrivateInputs, ): Promise> { diff --git a/yarn-project/bb-prover/src/test/delay_values.ts b/yarn-project/bb-prover/src/test/delay_values.ts index 023b6c540b5e..a7685e0676b7 100644 --- a/yarn-project/bb-prover/src/test/delay_values.ts +++ b/yarn-project/bb-prover/src/test/delay_values.ts @@ -2,10 +2,10 @@ import { ProvingRequestType } from '@aztec/stdlib/proofs'; export const WITGEN_DELAY_MS: Record = { [ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 60, - [ProvingRequestType.PARITY_BASE]: 1_600, - [ProvingRequestType.PARITY_ROOT]: 40, + [ProvingRequestType.INBOX_PARITY]: 1_600, [ProvingRequestType.BLOCK_ROOT_FIRST_ROLLUP]: 45, [ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: 18, + [ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP]: 18, [ProvingRequestType.BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP]: 27, [ProvingRequestType.CHECKPOINT_MERGE_ROLLUP]: 30, [ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 36_000, @@ -25,10 +25,10 @@ export const WITGEN_DELAY_MS: Record = { export const PROOF_DELAY_MS: Record = { [ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 16_300, - [ProvingRequestType.PARITY_BASE]: 15_300, - [ProvingRequestType.PARITY_ROOT]: 18_600, + [ProvingRequestType.INBOX_PARITY]: 15_300, [ProvingRequestType.BLOCK_ROOT_FIRST_ROLLUP]: 17_400, [ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: 4_500, + [ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP]: 4_500, [ProvingRequestType.BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP]: 9_200, [ProvingRequestType.CHECKPOINT_MERGE_ROLLUP]: 10_200, [ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 37_100, diff --git a/yarn-project/bb-prover/src/test/test_circuit_prover.ts b/yarn-project/bb-prover/src/test/test_circuit_prover.ts index 9ef5ef33cfe2..17e9b22b642d 100644 --- a/yarn-project/bb-prover/src/test/test_circuit_prover.ts +++ b/yarn-project/bb-prover/src/test/test_circuit_prover.ts @@ -15,6 +15,8 @@ import { convertBlockRootEmptyTxFirstRollupPrivateInputsToWitnessMap, convertBlockRootFirstRollupOutputsFromWitnessMap, convertBlockRootFirstRollupPrivateInputsToWitnessMap, + convertBlockRootMsgsOnlyRollupOutputsFromWitnessMap, + convertBlockRootMsgsOnlyRollupPrivateInputsToWitnessMap, convertBlockRootRollupOutputsFromWitnessMap, convertBlockRootRollupPrivateInputsToWitnessMap, convertBlockRootSingleTxFirstRollupOutputsFromWitnessMap, @@ -29,10 +31,8 @@ import { convertCheckpointRootRollupPrivateInputsToWitnessMap, convertCheckpointRootSingleBlockRollupOutputsFromWitnessMap, convertCheckpointRootSingleBlockRollupPrivateInputsToWitnessMap, - convertParityBaseOutputsFromWitnessMap, - convertParityBasePrivateInputsToWitnessMap, - convertParityRootOutputsFromWitnessMap, - convertParityRootPrivateInputsToWitnessMap, + convertInboxParityOutputsFromWitnessMap, + convertInboxParityPrivateInputsToWitnessMap, convertPrivateTxBaseRollupOutputsFromWitnessMap, convertPrivateTxBaseRollupPrivateInputsToWitnessMap, convertPublicTxBaseRollupOutputsFromWitnessMap, @@ -43,6 +43,7 @@ import { convertTxMergeRollupPrivateInputsToWitnessMap, foreignCallHandler, getSimulatedServerCircuitArtifact, + inboxParityArtifactForSize, } from '@aztec/noir-protocol-circuits-types/server'; import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks'; import { mapProtocolArtifactNameToCircuitName } from '@aztec/noir-protocol-circuits-types/types'; @@ -54,7 +55,7 @@ import { type ServerCircuitProver, makePublicInputsAndRecursiveProof, } from '@aztec/stdlib/interfaces/server'; -import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import type { InboxParityPrivateInputs, ParityPublicInputs } from '@aztec/stdlib/parity'; import { type Proof, ProvingRequestType, @@ -67,6 +68,7 @@ import { type BlockRollupPublicInputs, type BlockRootEmptyTxFirstRollupPrivateInputs, type BlockRootFirstRollupPrivateInputs, + type BlockRootMsgsOnlyRollupPrivateInputs, type BlockRootRollupPrivateInputs, type BlockRootSingleTxFirstRollupPrivateInputs, type BlockRootSingleTxRollupPrivateInputs, @@ -125,37 +127,17 @@ export class TestCircuitProver implements ServerCircuitProver { * @param inputs - Inputs to the circuit. * @returns The public inputs of the parity circuit. */ - @trackSpan('TestCircuitProver.getBaseParityProof') - public getBaseParityProof( - inputs: ParityBasePrivateInputs, + @trackSpan('TestCircuitProver.getInboxParityProof') + public getInboxParityProof( + inputs: InboxParityPrivateInputs, ): Promise> { - return this.applyDelay(ProvingRequestType.PARITY_BASE, () => + return this.applyDelay(ProvingRequestType.INBOX_PARITY, () => this.simulate( inputs, - 'ParityBaseArtifact', + inboxParityArtifactForSize(inputs.size), RECURSIVE_PROOF_LENGTH, - convertParityBasePrivateInputsToWitnessMap, - convertParityBaseOutputsFromWitnessMap, - ), - ); - } - - /** - * Simulates the root parity circuit from its inputs. - * @param inputs - Inputs to the circuit. - * @returns The public inputs of the parity circuit. - */ - @trackSpan('TestCircuitProver.getRootParityProof') - public getRootParityProof( - inputs: ParityRootPrivateInputs, - ): Promise> { - return this.applyDelay(ProvingRequestType.PARITY_ROOT, () => - this.simulate( - inputs, - 'ParityRootArtifact', - NESTED_RECURSIVE_PROOF_LENGTH, - convertParityRootPrivateInputsToWitnessMap, - convertParityRootOutputsFromWitnessMap, + convertInboxParityPrivateInputsToWitnessMap, + outputs => convertInboxParityOutputsFromWitnessMap(outputs, inputs.size), ), ); } @@ -269,6 +251,21 @@ export class TestCircuitProver implements ServerCircuitProver { ); } + @trackSpan('TestCircuitProver.getBlockRootMsgsOnlyRollupProof') + public getBlockRootMsgsOnlyRollupProof( + input: BlockRootMsgsOnlyRollupPrivateInputs, + ): Promise> { + return this.applyDelay(ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP, () => + this.simulate( + input, + 'BlockRootMsgsOnlyRollupArtifact', + NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, + convertBlockRootMsgsOnlyRollupPrivateInputsToWitnessMap, + convertBlockRootMsgsOnlyRollupOutputsFromWitnessMap, + ), + ); + } + @trackSpan('TestCircuitProver.getBlockRootRollupProof') public getBlockRootRollupProof( input: BlockRootRollupPrivateInputs, diff --git a/yarn-project/blob-lib/src/encoding/block_blob_data.test.ts b/yarn-project/blob-lib/src/encoding/block_blob_data.test.ts index cd291c70c778..c47c45d8a431 100644 --- a/yarn-project/blob-lib/src/encoding/block_blob_data.test.ts +++ b/yarn-project/blob-lib/src/encoding/block_blob_data.test.ts @@ -2,39 +2,14 @@ import { decodeBlockBlobData, encodeBlockBlobData } from './block_blob_data.js'; import { makeBlockBlobData } from './fixtures.js'; describe('block blob data', () => { - it('encode and decode first block', () => { - const isFirstBlock = true; - const numTxs = 3; - const blockBlobData = makeBlockBlobData({ isFirstBlock, numTxs }); + it('encodes and decodes a block carrying the l1-to-l2 message root', () => { + const blockBlobData = makeBlockBlobData({ numTxs: 3 }); expect(blockBlobData.txs.length).toBe(3); + // Every block carries the l1-to-l2 message tree root. expect(blockBlobData.l1ToL2MessageRoot).toBeDefined(); const encoded = encodeBlockBlobData(blockBlobData); - const decoded = decodeBlockBlobData(encoded, isFirstBlock); + const decoded = decodeBlockBlobData(encoded); expect(decoded).toEqual(blockBlobData); }); - - it('encode and decode second block', () => { - const isFirstBlock = false; - const numTxs = 3; - const blockBlobData = makeBlockBlobData({ isFirstBlock, numTxs }); - expect(blockBlobData.txs.length).toBe(3); - expect(blockBlobData.l1ToL2MessageRoot).toBeUndefined(); - - const encoded = encodeBlockBlobData(blockBlobData); - const decoded = decodeBlockBlobData(encoded, isFirstBlock); - expect(decoded).toEqual(blockBlobData); - }); - - it('does not include l1ToL2MessageRoot if not first block', () => { - const blockBlobData = makeBlockBlobData({ isFirstBlock: true, numTxs: 3 }); - const { l1ToL2MessageRoot, ...blockBlobDataWithoutL1ToL2MessageRoot } = blockBlobData; - // l1ToL2MessageRoot exists in the blob data. - expect(l1ToL2MessageRoot).toBeDefined(); - - const encoded = encodeBlockBlobData(blockBlobData); - // isFirstBlock is false. The l1ToL2MessageRoot should be ignored. - const decoded = decodeBlockBlobData(encoded, false); - expect(decoded).toEqual(blockBlobDataWithoutL1ToL2MessageRoot); - }); }); diff --git a/yarn-project/blob-lib/src/encoding/block_blob_data.ts b/yarn-project/blob-lib/src/encoding/block_blob_data.ts index 8d8d9d83ba60..fd5d6607a7df 100644 --- a/yarn-project/blob-lib/src/encoding/block_blob_data.ts +++ b/yarn-project/blob-lib/src/encoding/block_blob_data.ts @@ -17,16 +17,15 @@ import { type TxBlobData, decodeTxBlobData, encodeTxBlobData } from './tx_blob_d // Must match the implementation in `noir-protocol-circuits/crates/types/src/blob_data/block_blob_data.nr`. -export const NUM_BLOCK_END_BLOB_FIELDS = 6; -export const NUM_FIRST_BLOCK_END_BLOB_FIELDS = 7; +// Every block carries the L1-to-L2 message tree root: once any block can insert its own +// message bundle, the root is per-block, so blob-syncing nodes reconstruct each block's message-tree root from the +// blob alone. +export const NUM_BLOCK_END_BLOB_FIELDS = 7; export const NUM_CHECKPOINT_END_MARKER_FIELDS = 1; -/** - * Returns the number of blob fields used for block end data. - * @param isFirstBlockInCheckpoint - Whether this is the first block in a checkpoint. - */ -export function getNumBlockEndBlobFields(isFirstBlockInCheckpoint: boolean): number { - return isFirstBlockInCheckpoint ? NUM_FIRST_BLOCK_END_BLOB_FIELDS : NUM_BLOCK_END_BLOB_FIELDS; +/** Returns the number of blob fields used for block end data. */ +export function getNumBlockEndBlobFields(): number { + return NUM_BLOCK_END_BLOB_FIELDS; } export interface BlockEndBlobData { @@ -36,7 +35,7 @@ export interface BlockEndBlobData { noteHashRoot: Fr; nullifierRoot: Fr; publicDataRoot: Fr; - l1ToL2MessageRoot: Fr | undefined; + l1ToL2MessageRoot: Fr; } export interface BlockBlobData extends BlockEndBlobData { @@ -51,14 +50,14 @@ export function encodeBlockEndBlobData(blockEndBlobData: BlockEndBlobData): Fr[] blockEndBlobData.noteHashRoot, blockEndBlobData.nullifierRoot, blockEndBlobData.publicDataRoot, - ...(blockEndBlobData.l1ToL2MessageRoot ? [blockEndBlobData.l1ToL2MessageRoot] : []), + blockEndBlobData.l1ToL2MessageRoot, ]; } -export function decodeBlockEndBlobData(fields: Fr[] | FieldReader, isFirstBlock: boolean): BlockEndBlobData { +export function decodeBlockEndBlobData(fields: Fr[] | FieldReader): BlockEndBlobData { const reader = FieldReader.asReader(fields); - const numBlockEndData = getNumBlockEndBlobFields(isFirstBlock); + const numBlockEndData = getNumBlockEndBlobFields(); if (numBlockEndData > reader.remainingFields()) { throw new BlobDeserializationError( `Incorrect encoding of blob fields: not enough fields for block end data. Expected ${numBlockEndData} fields, only ${reader.remainingFields()} remaining.`, @@ -72,7 +71,7 @@ export function decodeBlockEndBlobData(fields: Fr[] | FieldReader, isFirstBlock: noteHashRoot: reader.readField(), nullifierRoot: reader.readField(), publicDataRoot: reader.readField(), - l1ToL2MessageRoot: isFirstBlock ? reader.readField() : undefined, + l1ToL2MessageRoot: reader.readField(), }; } @@ -80,7 +79,7 @@ export function encodeBlockBlobData(blockBlobData: BlockBlobData): Fr[] { return [...blockBlobData.txs.map(tx => encodeTxBlobData(tx)).flat(), ...encodeBlockEndBlobData(blockBlobData)]; } -export function decodeBlockBlobData(fields: Fr[] | FieldReader, isFirstBlock: boolean): BlockBlobData { +export function decodeBlockBlobData(fields: Fr[] | FieldReader): BlockBlobData { const reader = FieldReader.asReader(fields); const txs: TxBlobData[] = []; @@ -98,7 +97,7 @@ export function decodeBlockBlobData(fields: Fr[] | FieldReader, isFirstBlock: bo } } - const blockEndBlobData = decodeBlockEndBlobData(reader, isFirstBlock); + const blockEndBlobData = decodeBlockEndBlobData(reader); const blockEndMarker = blockEndBlobData.blockEndMarker; if (blockEndMarker.numTxs !== txs.length) { diff --git a/yarn-project/blob-lib/src/encoding/checkpoint_blob_data.ts b/yarn-project/blob-lib/src/encoding/checkpoint_blob_data.ts index ad786affd9db..aff4ac2b1588 100644 --- a/yarn-project/blob-lib/src/encoding/checkpoint_blob_data.ts +++ b/yarn-project/blob-lib/src/encoding/checkpoint_blob_data.ts @@ -6,7 +6,6 @@ import { type BlockBlobData, NUM_BLOCK_END_BLOB_FIELDS, NUM_CHECKPOINT_END_MARKER_FIELDS, - NUM_FIRST_BLOCK_END_BLOB_FIELDS, decodeBlockBlobData, encodeBlockBlobData, } from './block_blob_data.js'; @@ -46,7 +45,7 @@ export function decodeCheckpointBlobData(fields: Fr[] | FieldReader): Checkpoint const blocks = []; let checkpointEndMarker: CheckpointEndMarker | undefined; while (!reader.isFinished() && !checkpointEndMarker) { - blocks.push(decodeBlockBlobData(reader, blocks.length === 0 /* isFirstBlock */)); + blocks.push(decodeBlockBlobData(reader)); // After reading a block, the next item must be either a checkpoint end marker or another block. // The first field of a block is always a tx start marker. So if the provided fields are valid, it's not possible to @@ -94,8 +93,7 @@ export function getTotalNumBlobFieldsFromTxs(txsPerBlock: TxStartMarker[][]): nu } return ( - (numBlocks ? NUM_FIRST_BLOCK_END_BLOB_FIELDS - NUM_BLOCK_END_BLOB_FIELDS : 0) + // l1ToL2Messages root in the first block - numBlocks * NUM_BLOCK_END_BLOB_FIELDS + // 6 fields for each block end blob data. + numBlocks * NUM_BLOCK_END_BLOB_FIELDS + // block-end fields for each block (includes the per-block l1-to-l2 root) txsPerBlock.reduce((total, txs) => total + txs.reduce((total, tx) => total + tx.numBlobFields, 0), 0) + NUM_CHECKPOINT_END_MARKER_FIELDS // checkpoint end marker ); diff --git a/yarn-project/blob-lib/src/encoding/fixtures.ts b/yarn-project/blob-lib/src/encoding/fixtures.ts index ab146d5c5dea..c416c0e32d6a 100644 --- a/yarn-project/blob-lib/src/encoding/fixtures.ts +++ b/yarn-project/blob-lib/src/encoding/fixtures.ts @@ -131,12 +131,9 @@ export function makeBlockEndStateField({ } export function makeBlockEndBlobData({ - isFirstBlock = true, seed = 1, ...overrides -}: { seed?: number; isFirstBlock?: boolean } & Partial< - Omit -> & { +}: { seed?: number } & Partial> & { blockEndMarker?: Partial; blockEndStateField?: Partial; } = {}): BlockEndBlobData { @@ -152,18 +149,18 @@ export function makeBlockEndBlobData({ noteHashRoot: fr(seed + 0x300), nullifierRoot: fr(seed + 0x400), publicDataRoot: fr(seed + 0x500), - l1ToL2MessageRoot: isFirstBlock ? fr(seed + 0x600) : undefined, + // Every block carries the l1-to-l2 message tree root. + l1ToL2MessageRoot: fr(seed + 0x600), ...blockEndBlobDataOverrides, }; } export function makeBlockBlobData({ numTxs = 1, - isFirstBlock = true, isFullTx = false, seed = 1, ...overrides -}: { numTxs?: number; isFirstBlock?: boolean; isFullTx?: boolean; seed?: number } & Partial< +}: { numTxs?: number; isFullTx?: boolean; seed?: number } & Partial< Parameters[0] > = {}): BlockBlobData { return { @@ -173,7 +170,6 @@ export function makeBlockBlobData({ blockEndMarker: { numTxs, }, - isFirstBlock, ...overrides, }), }; @@ -193,11 +189,7 @@ export function makeCheckpointBlobData({ } & Partial = {}): CheckpointBlobData { const blocks = overrides.blocks ?? - makeTuple( - numBlocks, - i => makeBlockBlobData({ numTxs: numTxsPerBlock, isFirstBlock: i === seed, isFullTx, seed: seed + i * 0x1000 }), - seed, - ); + makeTuple(numBlocks, i => makeBlockBlobData({ numTxs: numTxsPerBlock, isFullTx, seed: seed + i * 0x1000 }), seed); const numBlobFields = overrides.checkpointEndMarker?.numBlobFields ?? diff --git a/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts b/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts index 098e033ad634..b484d886b69f 100644 --- a/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts +++ b/yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts @@ -434,12 +434,10 @@ describe('e2e_node_rpc_perf', () => { }); describe('message APIs', () => { - it('benchmarks getL1ToL2MessageCheckpoint', async () => { + it('benchmarks getL1ToL2MessageIndex', async () => { const l1ToL2Message = Fr.random(); - const { stats } = await benchmark('getL1ToL2MessageCheckpoint', () => - aztecNode.getL1ToL2MessageCheckpoint(l1ToL2Message), - ); - addResult('getL1ToL2MessageCheckpoint', stats); + const { stats } = await benchmark('getL1ToL2MessageIndex', () => aztecNode.getL1ToL2MessageIndex(l1ToL2Message)); + addResult('getL1ToL2MessageIndex', stats); expect(stats.avg).toBeLessThan(2000); }); diff --git a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts index 9990541e8dda..87cfd0da01a0 100644 --- a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts +++ b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts @@ -376,7 +376,6 @@ describe('e2e_multi_validator_node', () => { blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, indexWithinCheckpoint: number, - inHash: Fr, archive: Fr, txs: Tx[], proposerAddress: EthAddress | undefined, @@ -397,7 +396,6 @@ describe('e2e_multi_validator_node', () => { blockHeader, checkpointNumber, IndexWithinCheckpoint(indexWithinCheckpoint), - inHash, archive, txs, proposerAddress, diff --git a/yarn-project/end-to-end/src/fixtures/fixtures.ts b/yarn-project/end-to-end/src/fixtures/fixtures.ts index 217bc1ccf645..6bfd955cc976 100644 --- a/yarn-project/end-to-end/src/fixtures/fixtures.ts +++ b/yarn-project/end-to-end/src/fixtures/fixtures.ts @@ -30,8 +30,6 @@ export const PIPELINED_FEE_PADDING = TEST_FEE_PADDING; * * The preset runs the production Sequencer with the always-enforced timetable at real (wall-clock) * timing, yielding exactly 2 blocks per slot. It sets: - * - `inboxLag: 2` so the sequencer sources L1->L2 messages from checkpoint N-1 (already sealed), - * avoiding `L1ToL2MessagesNotReadyError` when building for slot N during slot N-1. * - `minTxsPerBlock: 0` so empty checkpoints land even when a tx arrives late in the build window * (otherwise the chain stalls on alternating slots). * - `aztecSlotDuration: 12` / `ethereumSlotDuration: 4` so the pipelined cycle fits inside the @@ -44,7 +42,6 @@ export const PIPELINED_FEE_PADDING = TEST_FEE_PADDING; * - `walletMinFeePadding: PIPELINED_FEE_PADDING` (30x) to absorb the wider fee evolution window. */ export const PIPELINING_SETUP_OPTS = { - inboxLag: 2, minTxsPerBlock: 0, aztecSlotDuration: 12, ethereumSlotDuration: 4, @@ -75,7 +72,6 @@ export const PIPELINING_SETUP_OPTS = { */ export const AUTOMINE_E2E_OPTS = { useAutomineSequencer: true, - inboxLag: 1, minTxsPerBlock: 0, aztecSlotDuration: 12, ethereumSlotDuration: 4, diff --git a/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts index 88c57c5d9197..4f1022ccc347 100644 --- a/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts @@ -57,7 +57,6 @@ describe('multi-node/block-production/multi_validator_node', () => { anvilSlotsInAnEpoch: 4, blockDurationMs: 2000, minTxsPerBlock: 0, - inboxLag: 2, }); // All 5 validators in a single physical node. diff --git a/yarn-project/end-to-end/src/multi-node/block-production/redistribution.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/block-production/redistribution.parallel.test.ts index d2eeb78036b8..4f3dcfe90048 100644 --- a/yarn-project/end-to-end/src/multi-node/block-production/redistribution.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/block-production/redistribution.parallel.test.ts @@ -56,7 +56,6 @@ describe('multi-node/block-production/redistribution', () => { const test = await MultiNodeTestContext.setup({ numberOfAccounts: 0, initialValidators: validators, - inboxLag: 2, mockGossipSubNetwork: true, startProverNode: true, aztecEpochDuration: 4, diff --git a/yarn-project/end-to-end/src/multi-node/block-production/setup.ts b/yarn-project/end-to-end/src/multi-node/block-production/setup.ts index 595ae29cdea5..802d3f12f2de 100644 --- a/yarn-project/end-to-end/src/multi-node/block-production/setup.ts +++ b/yarn-project/end-to-end/src/multi-node/block-production/setup.ts @@ -171,7 +171,6 @@ export async function setupBlockProductionWithProver(opts: { ...setupOpts, pxeOpts: { syncChainTip }, skipInitialSequencer: true, - inboxLag: 2, }, nodeOpts: (index: number) => ({ dontStartSequencer: true, diff --git a/yarn-project/end-to-end/src/multi-node/governance/add_rollup.test.ts b/yarn-project/end-to-end/src/multi-node/governance/add_rollup.test.ts index 59ff485e4c5d..4f6c25d556c6 100644 --- a/yarn-project/end-to-end/src/multi-node/governance/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/multi-node/governance/add_rollup.test.ts @@ -89,11 +89,8 @@ describe('multi-node/governance/add_rollup', () => { aztecTargetCommitteeSize: NUM_VALIDATORS, governanceProposerRoundSize: 10, // Allow validators to build empty checkpoints so the chain keeps advancing while we wait for - // L1->L2 messages to land in the next checkpoint's inbox tree. + // L1->L2 messages to be consumed from the streaming Inbox. minTxsPerBlock: 0, - // inboxLag: 2 sources L1->L2 messages from an already-sealed checkpoint under pipelining, avoiding - // L1ToL2MessagesNotReadyError. - inboxLag: 2, // Fund the bridging accounts (and the sponsored FPC) at genesis. Skip the hardcoded-account // fast-path so our additionallyFundedAccounts are not clobbered. skipHardcodedAccount: true, @@ -160,7 +157,6 @@ describe('multi-node/governance/add_rollup', () => { aztecTargetCommitteeSize: context.aztecNodeConfig.aztecTargetCommitteeSize, lagInEpochsForValidatorSet: context.aztecNodeConfig.lagInEpochsForValidatorSet, lagInEpochsForRandao: context.aztecNodeConfig.lagInEpochsForRandao, - inboxLag: context.aztecNodeConfig.inboxLag, aztecProofSubmissionEpochs: context.aztecNodeConfig.aztecProofSubmissionEpochs, slashingQuorum: context.aztecNodeConfig.slashingQuorum, slashingRoundSizeInEpochs: context.aztecNodeConfig.slashingRoundSizeInEpochs, diff --git a/yarn-project/end-to-end/src/multi-node/governance/upgrade_governance_proposer.test.ts b/yarn-project/end-to-end/src/multi-node/governance/upgrade_governance_proposer.test.ts index 36a6dd07bf23..d81717bb62b1 100644 --- a/yarn-project/end-to-end/src/multi-node/governance/upgrade_governance_proposer.test.ts +++ b/yarn-project/end-to-end/src/multi-node/governance/upgrade_governance_proposer.test.ts @@ -38,7 +38,6 @@ describe('multi-node/governance/upgrade_governance_proposer', () => { governanceProposerRoundSize: 10, activationThreshold: 10n ** 22n, ejectionThreshold: 5n ** 22n, - inboxLag: 2, minTxsPerBlock: 0, initialValidators: buildMockGossipValidators(NUM_VALIDATORS), }); diff --git a/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_block_proposal_slash.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_block_proposal_slash.test.ts index d1876afe573e..2a97f16d648f 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_block_proposal_slash.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_block_proposal_slash.test.ts @@ -49,7 +49,6 @@ describe('multi-node/slashing/broadcasted_invalid_block_proposal_slash', () => { sentinelEnabled: false, // reuse only the fast 8s-slot timing; this test does not use the sentinel blockDurationMs: 2000, aztecTargetCommitteeSize: COMMITTEE_SIZE, - inboxLag: 2, aztecProofSubmissionEpochs: 1024, // effectively do not reorg slashInactivityConsecutiveEpochThreshold: 32, // effectively do not slash for inactivity minTxsPerBlock: 0, // always be building diff --git a/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_checkpoint_proposal_slash.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_checkpoint_proposal_slash.parallel.test.ts index b207200e5a0a..89e9d8da96b4 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_checkpoint_proposal_slash.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/broadcasted_invalid_checkpoint_proposal_slash.parallel.test.ts @@ -240,7 +240,6 @@ describe('multi-node/slashing/broadcasted_invalid_checkpoint_proposal_slash', () aztecTargetCommitteeSize: COMMITTEE_SIZE, aztecProofSubmissionEpochs: 1024, minTxsPerBlock: 0, - inboxLag: 2, slashingQuorum: SLASHING_QUORUM, slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE / SENTINEL_TIMING.aztecEpochDuration, slashAmountSmall: slashingUnit, diff --git a/yarn-project/end-to-end/src/multi-node/slashing/data_withholding_slash.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/data_withholding_slash.test.ts index ea146ea02982..da03696d2fa2 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/data_withholding_slash.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/data_withholding_slash.test.ts @@ -91,7 +91,6 @@ describe('multi-node/slashing/data_withholding_slash', () => { slashDataWithholdingToleranceSlots: TOLERANCE_SLOTS, slashDataWithholdingPenalty: slashingAmount, minTxsPerBlock: 1, - inboxLag: 2, initialValidators: buildMockGossipValidators(NUM_VALIDATORS), }); }); diff --git a/yarn-project/end-to-end/src/multi-node/slashing/inactivity_setup.ts b/yarn-project/end-to-end/src/multi-node/slashing/inactivity_setup.ts index beec45ff503b..073e28f94955 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/inactivity_setup.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/inactivity_setup.ts @@ -48,7 +48,6 @@ export class InactivityTest { private async run(opts: { slashInactivityConsecutiveEpochThreshold: number; inactiveNodeCount: number }) { this.test = await MultiNodeTestContext.setup({ ...SLASHER_ENABLED_MULTI_VALIDATOR_OPTS, - inboxLag: 2, anvilSlotsInAnEpoch: 4, // A fake prover node is started by the context (realProofs:false); give it the multi-epoch // proving delay the inactivity scenario relied on, and keep enough broker history. diff --git a/yarn-project/end-to-end/src/multi-node/slashing/multiple_validators_sentinel.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/multiple_validators_sentinel.parallel.test.ts index 8bfb047e9d5a..df1d4cc42312 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/multiple_validators_sentinel.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/multiple_validators_sentinel.parallel.test.ts @@ -47,7 +47,6 @@ describe('multi-node/slashing/multiple_validators_sentinel', () => { minTxsPerBlock: 0, slashingRoundSizeInEpochs: 2, slashInactivityPenalty: 0n, // Set to 0 to disable - inboxLag: 2, initialValidators: buildMockGossipValidators(NUM_VALIDATORS), }); diff --git a/yarn-project/end-to-end/src/multi-node/slashing/sentinel_status_slash.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/sentinel_status_slash.parallel.test.ts index 47b64bf660f9..d2f14d5c46a5 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/sentinel_status_slash.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/sentinel_status_slash.parallel.test.ts @@ -73,7 +73,6 @@ describe('multi-node/slashing/sentinel_status_slash', () => { blockDurationMs: 2000, aztecProofSubmissionEpochs: 1024, minTxsPerBlock: 0, - inboxLag: 2, // A single proposer-fault slot in an epoch gives missed/total = 1/6 ≈ 0.167; threshold // 0.1 lets that single fault trip inactivity. slashInactivityTargetPercentage: 0.1, diff --git a/yarn-project/end-to-end/src/multi-node/slashing/slash_veto_demo.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/slash_veto_demo.test.ts index 6ab8d440b5cf..fe2c35371c34 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/slash_veto_demo.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/slash_veto_demo.test.ts @@ -71,7 +71,6 @@ describe('veto slash', () => { blockDurationMs: 2000, aztecProofSubmissionEpochs: 1024, // effectively do not reorg minTxsPerBlock: 0, - inboxLag: 2, aztecTargetCommitteeSize: NUM_VALIDATORS, slashSelfAllowed: true, slashingOffsetInRounds: SLASH_OFFSET_IN_ROUNDS, diff --git a/yarn-project/end-to-end/src/multi-node/slashing/validators_sentinel.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/slashing/validators_sentinel.parallel.test.ts index 09c9a6b1870e..fd40dafb2e8a 100644 --- a/yarn-project/end-to-end/src/multi-node/slashing/validators_sentinel.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/slashing/validators_sentinel.parallel.test.ts @@ -42,7 +42,6 @@ describe('multi-node/slashing/validators_sentinel', () => { minTxsPerBlock: 0, slashingRoundSizeInEpochs: 2, slashInactivityPenalty: 0n, // Set to 0 to disable - inboxLag: 2, initialValidators: buildMockGossipValidators(NUM_VALIDATORS), }); diff --git a/yarn-project/end-to-end/src/p2p/fee_asset_price_oracle_gossip.test.ts b/yarn-project/end-to-end/src/p2p/fee_asset_price_oracle_gossip.test.ts index 21c010085ac3..5e4b1b15fc87 100644 --- a/yarn-project/end-to-end/src/p2p/fee_asset_price_oracle_gossip.test.ts +++ b/yarn-project/end-to-end/src/p2p/fee_asset_price_oracle_gossip.test.ts @@ -46,9 +46,6 @@ describe('e2e_p2p_network', () => { slashingRoundSizeInEpochs: 2, slashingQuorum: 5, listenAddress: '127.0.0.1', - // Pipelining: target-slot is one ahead of build-slot; inboxLag sources L1->L2 - // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. - inboxLag: 2, }, }); diff --git a/yarn-project/end-to-end/src/p2p/gossip_network.test.ts b/yarn-project/end-to-end/src/p2p/gossip_network.test.ts index a1df69dce8cd..46f7409e5515 100644 --- a/yarn-project/end-to-end/src/p2p/gossip_network.test.ts +++ b/yarn-project/end-to-end/src/p2p/gossip_network.test.ts @@ -65,7 +65,6 @@ describe('e2e_p2p_network', () => { slashingRoundSizeInEpochs: 2, slashingQuorum: 5, listenAddress: '127.0.0.1', - inboxLag: 2, }, }); @@ -160,7 +159,6 @@ describe('e2e_p2p_network', () => { // Without this, no blocks are built until txs arrive, and a failed checkpoint during tx // submission causes block pruning that invalidates tx references. minTxsPerBlock: 0, - inboxLag: 2, }, }); diff --git a/yarn-project/end-to-end/src/p2p/late_prover_tx_collection.test.ts b/yarn-project/end-to-end/src/p2p/late_prover_tx_collection.test.ts index 0c46f4693c49..2baea1ce1db1 100644 --- a/yarn-project/end-to-end/src/p2p/late_prover_tx_collection.test.ts +++ b/yarn-project/end-to-end/src/p2p/late_prover_tx_collection.test.ts @@ -52,7 +52,6 @@ describe('e2e_p2p_late_prover_tx_collection', () => { // Only build blocks that actually carry txs, so the chain idles after our block is mined and // the late prover is never auto-triggered to collect for a different block. minTxsPerBlock: 1, - inboxLag: 2, }, }); diff --git a/yarn-project/end-to-end/src/p2p/preferred_gossip_network.test.ts b/yarn-project/end-to-end/src/p2p/preferred_gossip_network.test.ts index b2242e916abb..d1f1c64f21e8 100644 --- a/yarn-project/end-to-end/src/p2p/preferred_gossip_network.test.ts +++ b/yarn-project/end-to-end/src/p2p/preferred_gossip_network.test.ts @@ -136,7 +136,6 @@ describe('e2e_p2p_preferred_network', () => { // Just for testing be aggressive here, don't allow any auth handshake failures p2pMaxFailedAuthAttemptsAllowed: 0, minTxsPerBlock: 0, - inboxLag: 2, }, }); diff --git a/yarn-project/end-to-end/src/p2p/rediscovery.test.ts b/yarn-project/end-to-end/src/p2p/rediscovery.test.ts index 7eed53674dd9..f44c24eff919 100644 --- a/yarn-project/end-to-end/src/p2p/rediscovery.test.ts +++ b/yarn-project/end-to-end/src/p2p/rediscovery.test.ts @@ -33,7 +33,6 @@ describe('e2e_p2p_rediscovery', () => { aztecSlotDuration: 24, blockDurationMs: BLOCK_DURATION_MS, listenAddress: '127.0.0.1', - inboxLag: 2, }, }); await t.setup(); diff --git a/yarn-project/end-to-end/src/p2p/reqresp/utils.ts b/yarn-project/end-to-end/src/p2p/reqresp/utils.ts index e8e69cd7902c..535d884c9c14 100644 --- a/yarn-project/end-to-end/src/p2p/reqresp/utils.ts +++ b/yarn-project/end-to-end/src/p2p/reqresp/utils.ts @@ -43,9 +43,6 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise

L2 - // messages from the previous checkpoint to avoid L1ToL2MessagesNotReadyError. - inboxLag: 2, }, }); await t.setup(); diff --git a/yarn-project/end-to-end/src/shared/wait_for_l1_to_l2_message.ts b/yarn-project/end-to-end/src/shared/wait_for_l1_to_l2_message.ts index c8cc9ac455b5..a17774d3cd23 100644 --- a/yarn-project/end-to-end/src/shared/wait_for_l1_to_l2_message.ts +++ b/yarn-project/end-to-end/src/shared/wait_for_l1_to_l2_message.ts @@ -10,12 +10,12 @@ import { retryUntil } from '@aztec/foundation/retry'; * blocks afterwards to make the message consumable. */ export function waitForL1ToL2MessageSeen( - node: Pick, + node: Pick, l1ToL2MessageHash: Fr, opts: { timeoutSeconds: number }, ) { return retryUntil( - async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined, + async () => (await node.getL1ToL2MessageIndex(l1ToL2MessageHash)) !== undefined, `L1 to L2 message ${l1ToL2MessageHash.toString()} seen`, opts.timeoutSeconds, 0.25, diff --git a/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts b/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts index fcb86aab36b1..99edbf848904 100644 --- a/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts +++ b/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts @@ -59,7 +59,6 @@ describe('single-node/block-building/debug_trace', () => { // enough to reach it, where the proposer selection changes and the propose silently reverts. aztecEpochDuration: 32, aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, - inboxLag: 2, }); ({ aztecNode, logger, aztecNodeAdmin, config } = test.context); sequencer = test.context.sequencer! as TestSequencerClient; diff --git a/yarn-project/end-to-end/src/single-node/bot/bot.test.ts b/yarn-project/end-to-end/src/single-node/bot/bot.test.ts index 75a54e5b92f2..b6b55845d16d 100644 --- a/yarn-project/end-to-end/src/single-node/bot/bot.test.ts +++ b/yarn-project/end-to-end/src/single-node/bot/bot.test.ts @@ -2,7 +2,6 @@ import { getInitialTestAccountsData } from '@aztec/accounts/testing'; import { Fr } from '@aztec/aztec.js/fields'; import type { AztecNode } from '@aztec/aztec.js/node'; import { MinedTxReceipt, type TxReceipt } from '@aztec/aztec.js/tx'; -import type { CheatCodes } from '@aztec/aztec/testing'; import { AmmBot, Bot, @@ -29,15 +28,13 @@ import { NO_REORG_SUBMISSION_EPOCHS } from '../setup.js'; // Tests the transaction bot implementations (transfer bot, AMM bot, cross-chain bot). // Uses setup(0, PIPELINING_SETUP_OPTS + aztecProofSubmissionEpochs:NO_REORG_SUBMISSION_EPOCHS) with one node, production // sequencer (ethereumSlotDuration=4s, aztecSlotDuration=12s, proofSubEpochs=NO_REORG_SUBMISSION_EPOCHS, minTxsPerBlock=0; -// aztecEpochDuration is the setup() default). The bridge-resume, setup-via-bridging, and -// cross-chain-bot subsuites actively drive L1 cross-chain bridging: fee-juice portal deposits, -// advanceInboxInProgress, and L2→L1 messages via CrossChainBot. +// aztecEpochDuration is the setup() default). The bridge-resume and cross-chain-bot subsuites actively +// drive L1 cross-chain bridging: fee-juice portal deposits and L2→L1 messages via CrossChainBot. describe('single-node/bot/bot', () => { let wallet: EmbeddedWallet; let aztecNode: AztecNode; let teardown: () => Promise; let aztecNodeAdmin: AztecNodeAdmin | undefined; - let cheatCodes: CheatCodes; let config: BotConfig; let l1RpcUrls: string[]; @@ -52,7 +49,6 @@ describe('single-node/bot/bot', () => { teardown, aztecNode, aztecNodeAdmin, - cheatCodes, config: { l1RpcUrls }, } = setupResult); wallet = await testSpan('setup:wallet', () => EmbeddedWallet.create(aztecNode, { ephemeral: true })); @@ -270,30 +266,6 @@ describe('single-node/bot/bot', () => { }); }); - // Tests that Bot.create succeeds after the inbox drifts away from the rollup contract. - // Actively drives L1 via advanceInboxInProgress. - describe('setup via bridging funds cross-chain', () => { - beforeAll(() => { - config = { - ...getBotDefaultConfig(), - followChain: 'PROPOSED', - botMode: 'transfer', - senderPrivateKey: new SecretValue(Fr.random()), - l1PrivateKey: getPrivateKey(), - l1RpcUrls, - flushSetupTransactions: true, - }; - }); - - // See 'can consume L1 to L2 message in %s after inbox drifts away from the rollup' - // in end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts for context on this test. - // Advances inbox 4 slots then creates Bot; verifies it completes setup without error. - it('creates bot after inbox drift', async () => { - await cheatCodes.rollup.advanceInboxInProgress(4); - await Bot.create(config, wallet, aztecNode, aztecNodeAdmin, new BotStore(await openTmpStore('bot'))); - }, 300_000); - }); - // Tests the CrossChainBot: seeds L1→L2 messages and on each tick consumes one while seeding // a replacement. Actively drives L1 portal contracts. describe('cross-chain-bot', () => { diff --git a/yarn-project/end-to-end/src/single-node/cross-chain/cross_chain_messaging_test.ts b/yarn-project/end-to-end/src/single-node/cross-chain/cross_chain_messaging_test.ts index ed5a141d3247..73dee52ccf8c 100644 --- a/yarn-project/end-to-end/src/single-node/cross-chain/cross_chain_messaging_test.ts +++ b/yarn-project/end-to-end/src/single-node/cross-chain/cross_chain_messaging_test.ts @@ -21,6 +21,7 @@ import { TestERC20Abi, TestERC20Bytecode, TokenPortalAbi, TokenPortalBytecode } import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge'; import type { PXEConfig } from '@aztec/pxe/server'; +import type { BlockTag } from '@aztec/stdlib/block'; import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; @@ -109,6 +110,17 @@ export class CrossChainMessagingTest extends SingleNodeTestContext { this.requireEpochProven = opts.startProverNode ?? false; } + /** + * Chain tip the PXE syncs to. L1→L2 message readiness must be evaluated against this tip rather than + * the default `'latest'`: with per-block inbox insertion the proposed chain reaches a message's + * checkpoint before that checkpoint is published, so a `'latest'` readiness check flips true while a + * PXE anchored to `'checkpointed'` (or `'proven'`) has not yet synced the block the consuming tx will + * anchor to. Defaults to `'latest'` so suites that do not pin a sync tip keep their semantics. + */ + get pxeSyncChainTip(): BlockTag { + return this.pxeOpts.syncChainTip ?? 'latest'; + } + override async setup(opts: SingleNodeTestOpts = {}, pxeOpts: Partial = {}) { this.logger.info('Setting up cross chain messaging test'); // Recompute requireEpochProven from the merged options so per-call startProverNode is honored. diff --git a/yarn-project/end-to-end/src/single-node/cross-chain/l1_to_l2_inbox_drift.test.ts b/yarn-project/end-to-end/src/single-node/cross-chain/l1_to_l2_inbox_drift.test.ts index a7164ada4d0a..f936cb180be8 100644 --- a/yarn-project/end-to-end/src/single-node/cross-chain/l1_to_l2_inbox_drift.test.ts +++ b/yarn-project/end-to-end/src/single-node/cross-chain/l1_to_l2_inbox_drift.test.ts @@ -3,7 +3,6 @@ import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; import { Fr } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; -import { TxExecutionResult } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; import type { BlockNumber } from '@aztec/foundation/branded-types'; import { timesAsync } from '@aztec/foundation/collection'; @@ -19,11 +18,13 @@ import { type L1ToL2MessageScope, createL1ToL2MessageHelpers } from './message_t jest.setTimeout(300_000); -// L1→L2 messaging via Inbox: inbox checkpoint drift after a rollup reorg. Uses CrossChainMessagingTest +// L1→L2 messaging via Inbox: an L1→L2 message survives a rollup prune. Uses CrossChainMessagingTest // (prod sequencer, pipelining preset: ethSlot=4s, aztecSlot=12s, inboxLag=2, minTxsPerBlock=1, -// aztecProofSubmissionEpochs=2, aztecEpochDuration=4) with EpochTestSettler for auto-proving and -// CrossChainTestHarness for L1↔L2 token portal bridging. The drift scenario runs over private and -// public scope via it.each, all sharing one node stood up once in beforeAll. +// aztecProofSubmissionEpochs=2, aztecEpochDuration=4) with EpochTestSettler for auto-proving. Messages +// carry a compact L1-assigned index and stream in by insertion order rather than +// pinning to a checkpoint, so a message inserted while the proposed chain drifts must still be +// re-consumed with a stable index after the chain prunes back. Runs over private and public scope via +// it.each, sharing one node stood up once in beforeAll. describe('single-node/cross-chain/l1_to_l2_inbox_drift', () => { let t: CrossChainMessagingTest; @@ -35,7 +36,6 @@ describe('single-node/cross-chain/l1_to_l2_inbox_drift', () => { let sendMessageToL2: ReturnType['sendMessageToL2']; let advanceBlock: ReturnType['advanceBlock']; - let waitForMessageFetched: ReturnType['waitForMessageFetched']; let waitForMessageReady: ReturnType['waitForMessageReady']; // Whether explicit mark-as-proven calls are honored. The inbox-drift scenario flips this to @@ -73,7 +73,7 @@ describe('single-node/cross-chain/l1_to_l2_inbox_drift', () => { ({ logger: log, wallet, user1Address, aztecNode } = t); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); - ({ sendMessageToL2, advanceBlock, waitForMessageFetched, waitForMessageReady } = createL1ToL2MessageHelpers({ + ({ sendMessageToL2, advanceBlock, waitForMessageReady } = createL1ToL2MessageHelpers({ t, aztecNode, wallet, @@ -127,108 +127,100 @@ describe('single-node/cross-chain/l1_to_l2_inbox_drift', () => { } }; - // Inbox checkpoint number can drift on two scenarios: if the rollup reorgs and rolls back its own - // checkpoint number, or if the inbox receives too many messages and they are inserted faster than - // they are consumed. In this test, we mine several checkpoints without marking them as proven until - // we can trigger a reorg, and then wait until the message can be processed to consume it. - const canConsumeMessageAfterInboxDrift = async (scope: L1ToL2MessageScope) => { + // L1→L2 messages carry a compact, L1-assigned global leaf index and are streamed + // into the L2 tree in insertion order (subject to inbox lag and per-block/checkpoint caps) rather than + // being pinned to a fixed checkpoint. This scenario stresses that message state survives an L2 reorg: + // we let the proposed chain drift by mining several unproven checkpoints, insert a message during the + // drift, then force the rollup to prune back to the pre-drift block. After the prune, the message must + // still be re-consumed on the new chain and its witness leaf index must remain the L1-assigned index. + const canConsumeMessageAfterRollupPrune = async (scope: L1ToL2MessageScope) => { // Stop the background epoch test settler so the drift scenario below can proceed without // an auto-prover racing it. await t.epochTestSettler?.stop(); // Reset the L1 proof window by marking the current pending tip as proven, so L1's prune - // deadline doesn't fire mid-test before we finish mining the 4 drift checkpoints below. + // deadline doesn't fire mid-test before we finish mining the drift checkpoints below. await markAsProven(); - // Stop proving + // Snapshot the block we will prune back to, then stop proving so the proposed chain can drift. const lastProven = await aztecNode.getBlockNumber(); - const [checkpointedProvenBlock] = await aztecNode.getBlocks(lastProven, 1, { - includeL1PublishInfo: true, - includeAttestations: true, - onlyCheckpointed: true, - }); - log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); + log.warn(`Stopping proof submission at block ${lastProven} to allow drift`); markProvenEnabled = false; // Mine several checkpoints to ensure drift log.warn(`Mining blocks to allow drift`); await timesAsync(4, advanceCheckpoint); - // Generate and send the message to the L1 contract + // Generate and send the message to the L1 contract during the drift log.warn(`Sending L1 to L2 message`); const [secret, secretHash] = await generateClaimSecret(); const message = { recipient: testContract.address, content: Fr.random(), secretHash }; const { msgHash, globalLeafIndex } = await sendMessageToL2(message); - // Wait until the Aztec node has synced it - const msgCheckpointNumber = await waitForMessageFetched(msgHash); - log.warn(`Message synced for checkpoint ${msgCheckpointNumber}`); - expect(checkpointedProvenBlock.checkpointNumber + 4).toBeLessThan(msgCheckpointNumber); - - // And keep mining until we prune back to the original block number. Now the "waiting for two blocks" - // strategy for the message to be ready to use shouldn't work, since the lastProven block is more than - // two blocks behind the message block. This is the scenario we want to test. + // The drift's current L1 pending checkpoint. The node prunes its local view as soon as the proof + // window lapses, but L1 only commits the prune when the rebuilt chain proposes its first checkpoint + // on top of the pre-drift block. Wait for that on-chain commit — L1's pending tip dropping back + // below the drift — before re-enabling proving: marking proven while the drift is still the pending + // tip would pin the drift proven and wedge the rebuild forever with Rollup__InvalidArchive. + const driftPendingCheckpoint = (await t.cheatCodes.rollup.getTips()).pending; + + // Keep mining until the rollup prunes the drifted proposed chain back to the pre-drift block. L1's + // pending tip dropping below the drift is the unambiguous signal that the on-chain prune committed + // (a new checkpoint was proposed on top of the pre-drift block); the node's faster local prune is + // not, which is why we gate on L1 here rather than on the node's block number. log.warn(`Waiting until we prune back to ${lastProven}`); await retryUntil( - async () => - (await aztecNode.getBlockNumber().then(b => b === lastProven || b === lastProven + 1)) || - (await tryAdvanceBlock()), + async () => { + await tryAdvanceBlock(); + return (await t.cheatCodes.rollup.getTips()).pending < driftPendingCheckpoint; + }, 'wait for prune', 180, ); - // The drift condition has been established. Re-enable explicit proving so the catch-up blocks - // below are not pruned a second time before the message checkpoint becomes ready. + // The prune has committed on L1. Re-enable explicit proving so the catch-up chain that re-consumes + // the message is not pruned a second time before we can consume it — safe now that L1's pending tip + // is the rebuilt chain rather than the drift. markProvenEnabled = true; await markAsProven(); - // Check that there is no witness yet - expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeUndefined(); - - // Define L2 function to consume the message - const consume = () => getConsumeMethod(scope)(message.content, secret, t.ethAccount, globalLeafIndex); + // The invariant under test: the compact-indexed message survives the L2 prune and is re-consumed on the + // new chain within a reasonable window (its bucket and rolling-hash state must persist across the + // reorg), becoming consumable from the requested scope. + await waitForMessageReady(msgHash, scope); - // Wait until the message is ready to be consumed, checking that it cannot be consumed beforehand - await waitForMessageReady(msgHash, scope, async () => { - if (scope === 'private') { - // On private, we simulate the tx locally and check that we get a missing message error, then we advance to the next block - await expect(() => consume().simulate({ from: user1Address })).rejects.toThrow(/No L1 to L2 message found/); - await tryAdvanceBlock(); - } else { - // In public it is harder to determine when a message becomes consumable. - // We send a transaction, this advances the chain and the message MIGHT be consumed in the new block. - // If it does get consumed then we check that the block contains the message. - // If it fails we check that the block doesn't contain the message - const { receipt } = await consume().send({ from: user1Address, wait: { dontThrowOnRevert: true } }); - if (receipt.executionResult === TxExecutionResult.SUCCESS) { - // The consume tx must not succeed before the message checkpoint. It can land in a later - // checkpoint if the node catches up between the readiness poll and the tx being built. - const block = await aztecNode.getBlock(receipt.blockNumber!); - expect(block).toBeDefined(); - expect(block!.checkpointNumber).toBeGreaterThanOrEqual(msgCheckpointNumber); - } else { - expect(receipt.executionResult).toEqual(TxExecutionResult.REVERTED); + // The PXE is anchored to the checkpointed tip (syncChainTip: 'checkpointed'), so the re-consumed + // message only becomes visible to the consume simulation once its block is checkpointed — not merely + // proposed at 'latest'. Drive the rebuilt chain forward (advanceBlock marks each step proven so it + // is not pruned again) until the checkpointed tip covers the block that re-consumed the message. + const messageBlock = await aztecNode.getBlockNumber(); + await retryUntil( + async () => { + if ((await aztecNode.getBlockNumber('checkpointed')) >= messageBlock) { + return true; } - } - await markAsProven(); - }); + await tryAdvanceBlock(); + return false; + }, + 'wait for message block to be checkpointed', + 180, + ); - // Verify the membership witness is available for creating the tx (private-land only) - if (scope === 'private') { - const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; - expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); - // And consume the message for private, public was already consumed. - await consume().send({ from: user1Address }); - } + // The witness leaf index is the L1-assigned compact global index and must be stable across the prune. + const [messageIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; + expect(messageIndex).toEqual(globalLeafIndex.toBigInt()); + + // The message is consumable on L2 from the requested scope. + const consume = () => getConsumeMethod(scope)(message.content, secret, t.ethAccount, globalLeafIndex); + await consume().send({ from: user1Address }); }; - // Mines four checkpoints without proving, inserting an L1→L2 message after the drift, then - // triggers a rollup prune back to the pre-drift block. Verifies the message can be consumed only - // after the chain re-syncs to the message's checkpoint, not before, from both private and public - // scope (public uses a send+dontThrowOnRevert loop to probe when the message becomes consumable). + // Mines several unproven checkpoints, inserts an L1→L2 message during the drift, then triggers a + // rollup prune back to the pre-drift block and verifies the message is still re-consumed on the new + // chain — with its L1-assigned witness index intact — from both private and public scope. it.each(['private', 'public'] as const)( - 'can consume L1 to L2 message in %s after inbox drifts away from the rollup', + 'consumes an L1 to L2 message after a rollup prune drops the drifted chain (%s)', async scope => { - await canConsumeMessageAfterInboxDrift(scope); + await canConsumeMessageAfterRollupPrune(scope); }, ); }); diff --git a/yarn-project/end-to-end/src/single-node/cross-chain/message_test_helpers.ts b/yarn-project/end-to-end/src/single-node/cross-chain/message_test_helpers.ts index 4e520ed7002a..0233eaa098a4 100644 --- a/yarn-project/end-to-end/src/single-node/cross-chain/message_test_helpers.ts +++ b/yarn-project/end-to-end/src/single-node/cross-chain/message_test_helpers.ts @@ -4,7 +4,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging'; import type { AztecNode } from '@aztec/aztec.js/node'; import type { Wallet } from '@aztec/aztec.js/wallet'; -import type { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; +import type { BlockNumber } from '@aztec/foundation/branded-types'; import { retryUntil } from '@aztec/foundation/retry'; import { ExecutionPayload } from '@aztec/stdlib/tx'; @@ -33,7 +33,7 @@ export interface L1ToL2MessageHelpers { secretHash: Fr; }): ReturnType; advanceBlock(): Promise; - waitForMessageFetched(msgHash: Fr): Promise; + waitForMessageIndexed(msgHash: Fr): Promise; waitForMessageReady( msgHash: Fr, scope: L1ToL2MessageScope, @@ -72,20 +72,20 @@ export function createL1ToL2MessageHelpers(deps: L1ToL2MessageHelperDeps): L1ToL return newBlock; }; - // Waits until the message is fetched by the archiver of the node and returns the msg target checkpoint. - // Advances a block on each retry because an L1->L2 message is only indexed once further L2 blocks build. - const waitForMessageFetched = async (msgHash: Fr) => { + // Waits until the node's archiver has ingested the message from the Inbox and returns its message-tree leaf index. + // Advances a block on each retry to keep the chain moving while the archiver catches up with L1. + const waitForMessageIndexed = async (msgHash: Fr) => { log.warn(`Waiting until the message is fetched by the node`); return await retryUntil( async () => { - const checkpoint = await aztecNode.getL1ToL2MessageCheckpoint(msgHash); - if (checkpoint !== undefined) { - return checkpoint; + const messageIndex = await aztecNode.getL1ToL2MessageIndex(msgHash); + if (messageIndex !== undefined) { + return messageIndex; } await advanceBlock(); return undefined; }, - 'get msg checkpoint', + 'get msg index', 60, ); }; @@ -96,9 +96,9 @@ export function createL1ToL2MessageHelpers(deps: L1ToL2MessageHelperDeps): L1ToL scope: L1ToL2MessageScope, onNotReady?: (blockNumber: BlockNumber) => Promise, ) => { - const msgCheckpoint = await waitForMessageFetched(msgHash); + const msgIndex = await waitForMessageIndexed(msgHash); log.warn( - `Waiting until L2 reaches the first block of msg checkpoint ${msgCheckpoint} (current is ${await aztecNode.getCheckpointNumber()})`, + `Waiting until L2 consumes msg leaf index ${msgIndex} (checkpoint is ${await aztecNode.getCheckpointNumber()})`, ); await retryUntil( async () => { @@ -107,19 +107,19 @@ export function createL1ToL2MessageHelpers(deps: L1ToL2MessageHelperDeps): L1ToL aztecNode.getCheckpointNumber(), ]); const witness = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash); - const isReady = await isL1ToL2MessageReady(aztecNode, msgHash); + const isReady = await isL1ToL2MessageReady(aztecNode, msgHash, t.pxeSyncChainTip); log.info( - `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message checkpoint is ${msgCheckpoint}. Witness ${!!witness}. Ready ${isReady}.`, + `Block is ${blockNumber}, checkpoint is ${checkpointNumber}. Message leaf index is ${msgIndex}. Witness ${!!witness}. Ready ${isReady}.`, ); if (!isReady) { await (onNotReady ? onNotReady(blockNumber) : advanceBlock()); } return isReady; }, - `wait for rollup to reach msg checkpoint ${msgCheckpoint}`, + `wait for rollup to consume msg leaf index ${msgIndex}`, 240, ); }; - return { sendMessageToL2, advanceBlock, waitForMessageFetched, waitForMessageReady }; + return { sendMessageToL2, advanceBlock, waitForMessageIndexed, waitForMessageReady }; } diff --git a/yarn-project/end-to-end/src/single-node/cross-chain/streaming_inbox.test.ts b/yarn-project/end-to-end/src/single-node/cross-chain/streaming_inbox.test.ts new file mode 100644 index 000000000000..1764ceb01b72 --- /dev/null +++ b/yarn-project/end-to-end/src/single-node/cross-chain/streaming_inbox.test.ts @@ -0,0 +1,328 @@ +import type { AztecAddress } from '@aztec/aztec.js/addresses'; +import { generateClaimSecret } from '@aztec/aztec.js/ethereum'; +import { Fr } from '@aztec/aztec.js/fields'; +import type { Logger } from '@aztec/aztec.js/log'; +import type { AztecNode } from '@aztec/aztec.js/node'; +import { TxExecutionResult } from '@aztec/aztec.js/tx'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import { INBOX_LAG_SECONDS } from '@aztec/constants'; +import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { retryUntil } from '@aztec/foundation/retry'; +import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { getSlotAtTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; + +import { jest } from '@jest/globals'; + +import { L1_DIRECT_WRITE_ACCOUNT_INDEX, PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; +import { CrossChainMessagingTest } from './cross_chain_messaging_test.js'; +import { createL1ToL2MessageHelpers } from './message_test_helpers.js'; + +jest.setTimeout(600_000); + +// Streaming Inbox e2e coverage the legacy per-checkpoint suite could not express: when every L1->L2 message +// entered at the first block of the *next* checkpoint, mid-checkpoint inclusion, message-only blocks, and +// per-block streaming latency had no observable surface. Runs the production +// pipelining sequencer via CrossChainMessagingTest with a widened slot (36s / 6s blocks -> up to ~4 blocks +// per checkpoint) so a message can become lag-eligible partway through a checkpoint and land in a non-first +// block. minTxsPerBlock=0 lets a checkpoint carry a zero-tx block whose only content is a streaming bundle. +// +// Grounded on l1_to_l2.test.ts (send/wait helpers, TestContract arbitrary-sender consume) and +// cross_chain_public_message.test.ts (same-block public consume). All cases share one node stood up once. +describe('single-node/cross-chain/streaming_inbox', () => { + let t: CrossChainMessagingTest; + + let log: Logger; + let aztecNode: AztecNode; + let wallet: Wallet; + let user1Address: AztecAddress; + let testContract: TestContract; + + let sendMessageToL2: ReturnType['sendMessageToL2']; + let advanceBlock: ReturnType['advanceBlock']; + let waitForMessageReady: ReturnType['waitForMessageReady']; + + const markAsProven = () => t.cheatCodes.rollup.markAsProven(); + + beforeAll(async () => { + t = new CrossChainMessagingTest( + 'streaming_inbox', + // A 36s slot with 6s blocks yields up to ~4 blocks per checkpoint (the pipelining timing model gives + // maxBlocks = floor((36 - 0.5 - (0.5 + D)) / D) = 4 for D=6), which is what lets a message aged past + // INBOX_LAG_SECONDS land in a non-first block of the same checkpoint. minTxsPerBlock=0 permits a + // zero-tx message-only block (the FI-05 relaxation). + { ...PIPELINING_SETUP_OPTS, aztecSlotDuration: 36, blockDurationMs: 6000, minTxsPerBlock: 0 }, + { aztecProofSubmissionEpochs: 2, aztecEpochDuration: 4 }, + { syncChainTip: 'checkpointed' }, + // Pass arbitrary L1->L2 messages straight to a TestContract; no token bridge needed. + { l1HarnessAccountIndex: L1_DIRECT_WRITE_ACCOUNT_INDEX, deployTokenBridge: false }, + ); + await t.setup(); + + ({ logger: log, wallet, user1Address, aztecNode } = t); + ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: user1Address })); + + ({ sendMessageToL2, advanceBlock, waitForMessageReady } = createL1ToL2MessageHelpers({ + t, + aztecNode, + wallet, + user1Address, + log, + markAsProven, + })); + }, 600_000); + + afterAll(async () => { + await t.teardown(); + }); + + /** The L1 block timestamp at which an L1->L2 message was inserted; equals the message's Inbox bucket key. */ + const getMessageL1Timestamp = async (l1BlockNumber: bigint): Promise => { + const block = await t.harnessL1Client.getBlock({ blockNumber: l1BlockNumber }); + return block.timestamp; + }; + + /** + * Finds the L2 block that inserted `msgHash` into the L1-to-L2 message tree by scanning forward from + * `fromBlock` for the first block whose committed tree resolves a membership witness. Under the streaming + * Inbox a message enters the tree at the block that consumes its Inbox bucket, which need not be the first + * block of a checkpoint. Returns the block-data (checkpoint number + index within checkpoint) of that block. + */ + const findInsertingBlock = (msgHash: Fr, fromBlock: BlockNumber) => { + return retryUntil( + async () => { + const tip = await aztecNode.getBlockNumber(); + for (let n = fromBlock; n <= tip; n = BlockNumber(n + 1)) { + const witness = await aztecNode.getL1ToL2MessageMembershipWitness(n, msgHash); + if (witness !== undefined) { + const data = await aztecNode.getBlockData(n); + return { blockNumber: n, checkpointNumber: data!.checkpointNumber, index: data!.indexWithinCheckpoint }; + } + } + return undefined; + }, + `find block inserting message ${msgHash.toString()}`, + 240, + 0.5, + ); + }; + + /** + * Runs `fn` while a background loop feeds empty txs, so checkpoints build multiple blocks promptly rather + * than stalling on an empty pool. advanceBlock also refreshes the L1 proof window, keeping the chain from + * pruning mid-test. Callers must pass a no-op `onNotReady` to any readiness wait so it does not send its own + * wallet txs concurrently (which would race the feeder on the wallet nonce). + */ + const withBackgroundFeeder = async (fn: () => Promise): Promise => { + let feeding = true; + const feeder = (async () => { + while (feeding) { + try { + await advanceBlock(); + } catch (err) { + log.warn(`Feeder tx failed: ${(err as Error).message}`); + } + } + })(); + try { + return await fn(); + } finally { + feeding = false; + await feeder; + } + }; + + // Test 1 (mid-checkpoint inclusion): a message sent mid-checkpoint becomes available in a *later* block of + // the same checkpoint (indexWithinCheckpoint > 0), which the legacy first-block-of-next-checkpoint flow + // could never produce. Feeds a steady tx stream so checkpoints fill to multiple blocks, times the send so + // the message ages past INBOX_LAG_SECONDS partway through a checkpoint's build, then locates the inserting + // block. Retries with fresh messages so a message that happens to age exactly at a checkpoint boundary (and + // lands at index 0) does not fail the run. + it('includes a message in a non-first block of a checkpoint (mid-checkpoint streaming)', async () => { + const { slotDuration } = t.constants; + + await withBackgroundFeeder(async () => { + let inserting: { blockNumber: BlockNumber; checkpointNumber: number; index: number } | undefined; + let insertedMsgHash: Fr | undefined; + + for (let attempt = 0; attempt < 4 && inserting === undefined; attempt++) { + // Aim the send so the message ages past the lag partway through a checkpoint's build window. The + // eligibility instant is T + INBOX_LAG_SECONDS; targeting it a few seconds into an upcoming build + // window lands it on a non-first block across the ~4-block checkpoint. The eligible window is wide + // (any block after the first whose build time exceeds T + lag), so exact timing is not required. + const nowTs = BigInt(await t.cheatCodes.eth.lastBlockTimestamp()); + const currentSlot = getSlotAtTimestamp(nowTs, t.constants); + const targetSlot = SlotNumber(Number(currentSlot) + 3); + const sendTargetTs = getTimestampForSlot(targetSlot, t.constants) - BigInt(INBOX_LAG_SECONDS) + 4n; + log.warn(`Attempt ${attempt}: waiting for L1 to reach ${sendTargetTs} before sending message`, { + currentSlot, + targetSlot, + }); + await retryUntil( + async () => BigInt(await t.cheatCodes.eth.lastBlockTimestamp()) >= sendTargetTs, + `L1 reaches ${sendTargetTs}`, + Number(slotDuration) * 6, + 0.2, + ); + + const blockAtSend = await aztecNode.getBlockNumber(); + const [, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash } = await sendMessageToL2(message); + log.warn(`Sent message ${msgHash.toString()} at block ${blockAtSend}`); + + // The background feeder drives block production; findInsertingBlock polls the committed tree without + // sending its own wallet txs (which would race the feeder on the nonce). + const found = await findInsertingBlock(msgHash, BlockNumber(blockAtSend + 1)); + log.warn(`Message ${msgHash.toString()} inserted at block ${found.blockNumber}`, { + checkpointNumber: found.checkpointNumber, + index: found.index, + }); + + if (found.index > 0) { + inserting = found; + insertedMsgHash = msgHash; + } else { + log.warn(`Message landed at index 0 (checkpoint boundary); retrying with a fresh message`); + } + } + + expect(inserting).toBeDefined(); + // A non-first block of its checkpoint carried the message: streaming placed it mid-checkpoint, which the + // legacy path (all messages at the first block of the next checkpoint) could never do. + expect(inserting!.index).toBeGreaterThan(0); + // The immediately preceding block did not yet have the message, confirming this block is the one that + // inserted it (rather than the message having been present since an earlier block of the checkpoint). + const priorWitness = await aztecNode.getL1ToL2MessageMembershipWitness( + BlockNumber(inserting!.blockNumber - 1), + insertedMsgHash!, + ); + expect(priorWitness).toBeUndefined(); + }); + }); + + // Test 2 (latency bound): the delay between a message's L1 inclusion and the L2 block that makes it + // available stays within the streaming bound. Asserted in slot-denominated terms (L1/L2 timestamps, not + // wall-clock): the including block's timestamp minus the message's L1 timestamp must be at most + // INBOX_LAG_SECONDS + 2 * slotDuration (lag + a full slot straddle + one slot of CI slack). No lower bound + // is asserted (eligibility is already enforced by L1 and the validator). The wall-clock latency is logged + // for information only. + it('makes a message available within the streaming latency bound', async () => { + const { slotDuration } = t.constants; + const maxDelaySeconds = BigInt(INBOX_LAG_SECONDS) + 2n * BigInt(slotDuration); + + await withBackgroundFeeder(async () => { + const blockAtSend = await aztecNode.getBlockNumber(); + const wallClockAtSend = Date.now(); + const [, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash, txReceipt } = await sendMessageToL2(message); + const messageL1Ts = await getMessageL1Timestamp(txReceipt.blockNumber!); + log.warn(`Sent message ${msgHash.toString()} with L1 timestamp ${messageL1Ts}`); + + // The background feeder drives block production; findInsertingBlock polls the committed tree without + // sending its own wallet txs (which would race the feeder on the nonce). + const inserting = await findInsertingBlock(msgHash, BlockNumber(blockAtSend + 1)); + const wallClockLatencyMs = Date.now() - wallClockAtSend; + const insertingBlock = (await aztecNode.getBlock(inserting.blockNumber))!; + const includingBlockTs = insertingBlock.header.globalVariables.timestamp; + const delaySeconds = includingBlockTs - messageL1Ts; + + // Informational only: the wall-clock number flakes under CI load, so it is never + // asserted on; the slot-denominated bound below is the real check. + log.warn(`Streaming latency for message ${msgHash.toString()}`, { + messageL1Ts, + includingBlockTs, + delaySeconds: Number(delaySeconds), + maxDelaySeconds: Number(maxDelaySeconds), + wallClockLatencyMs, + }); + + expect(delaySeconds).toBeGreaterThan(0n); + expect(delaySeconds).toBeLessThanOrEqual(maxDelaySeconds); + }); + }); + + // Test 3 (message-only block): on an empty tx pool, the block that consumes a message carries zero txs and a + // non-empty streaming bundle (the FI-05 shape exercised on a live chain), and the chain keeps proving past + // it. Drains the pool first, then sends a single message and asserts the inserting block has no tx effects. + it('produces a message-only block on an empty tx pool and keeps proving', async () => { + // Let the pool drain so the checkpoint that consumes the message is not padded with unrelated txs. + await retryUntil( + async () => !(await aztecNode.getPendingTxCount()), + 'tx pool drains', + Number(t.constants.slotDuration) * 3, + 0.5, + ); + + const blockAtSend = await aztecNode.getBlockNumber(); + const [, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash } = await sendMessageToL2(message); + log.warn(`Sent message ${msgHash.toString()} on an empty pool`); + + // Do not feed txs; the sequencer builds empty checkpoints until the message ages past the lag, at which + // point a zero-tx block consumes it. findInsertingBlock polls the committed tree without sending txs, so + // the pool stays empty and the block that consumes the message carries only the bundle. + const inserting = await findInsertingBlock(msgHash, BlockNumber(blockAtSend + 1)); + + const insertingBlock = (await aztecNode.getBlock(inserting.blockNumber, { includeTransactions: true }))!; + log.warn(`Message ${msgHash.toString()} inserted at block ${inserting.blockNumber}`, { + checkpointNumber: inserting.checkpointNumber, + index: inserting.index, + txCount: insertingBlock.body.txEffects.length, + }); + + // The inserting block carried the message with no txs: a message-only block. + expect(insertingBlock.body.txEffects.length).toBe(0); + // The membership witness resolving proves the block's bundle was non-empty (it inserted the message). + expect(await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash)).toBeDefined(); + + // The chain keeps proving past the message-only block. + await markAsProven(); + await retryUntil( + async () => (await aztecNode.getBlockNumber('proven')) >= inserting.blockNumber, + `proven tip reaches block ${inserting.blockNumber}`, + Number(t.constants.slotDuration) * t.epochDuration * 3, + 1, + ); + expect(await aztecNode.getBlockNumber('proven')).toBeGreaterThanOrEqual(inserting.blockNumber); + }); + + // Test 4 (send-then-consume on the streaming path): a message inserted by the streaming Inbox is consumed by + // a public L2 tx, passing the compact leaf index, and cannot be consumed twice. Same-block consumption is + // available (a block's BlockConstantData.l1_to_l2_tree_snapshot pins to that block's post-bundle + // root, so the public/AVM read sees the just-inserted message), but which block consumes the message relative + // to its insertion depends on sequencer timing under the production sequencer; the block relationship is + // logged for visibility while the robust invariants asserted are the successful compact-index consume and the + // double-spend revert. Mirrors cross_chain_public_message.test.ts. + it('consumes a streaming-inserted message by compact index and rejects double-spend', async () => { + const l1Account = t.ethAccount; + const blockAtSend = await aztecNode.getBlockNumber(); + const [secret, secretHash] = await generateClaimSecret(); + const message = { recipient: testContract.address, content: Fr.random(), secretHash }; + const { msgHash, globalLeafIndex } = await sendMessageToL2(message); + log.warn(`Sent message ${msgHash.toString()} with compact index ${globalLeafIndex}`); + + await waitForMessageReady(msgHash, 'public'); + const inserting = await findInsertingBlock(msgHash, BlockNumber(blockAtSend + 1)); + + const { receipt: txReceipt } = await testContract.methods + .consume_message_from_arbitrary_sender_public(message.content, secret, l1Account, globalLeafIndex.toBigInt()) + .send({ from: user1Address }); + expect(txReceipt.blockNumber).toBeGreaterThan(0); + // The compact leaf index from the Inbox event resolves to the same message the node inserted. + const [resolvedIndex] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash))!; + expect(resolvedIndex).toBe(globalLeafIndex.toBigInt()); + log.warn(`Consumed message ${msgHash.toString()} in block ${txReceipt.blockNumber}`, { + insertingBlock: inserting.blockNumber, + consumeBlock: txReceipt.blockNumber, + sameBlock: Number(txReceipt.blockNumber) === Number(inserting.blockNumber), + }); + + // The message was inserted and consumed; a second consume must revert (the leaf is nullified). + const { receipt: failedReceipt } = await testContract.methods + .consume_message_from_arbitrary_sender_public(message.content, secret, l1Account, globalLeafIndex.toBigInt()) + .send({ from: user1Address, wait: { dontThrowOnRevert: true } }); + expect(failedReceipt.executionResult).toBe(TxExecutionResult.REVERTED); + }); +}); diff --git a/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts b/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts index 53b062cff8ce..79bc06be39bf 100644 --- a/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts @@ -76,7 +76,6 @@ describe('single-node/fees/fee_settings', () => { // (Test-body txs explicitly call `wallet.setMinFeePadding(...)` so they don't use the wallet default.) const AZTEC_SLOT_DURATION = 12; const t = new FeesTest('fee_juice', 1, { - inboxLag: 2, minTxsPerBlock: 0, aztecSlotDuration: AZTEC_SLOT_DURATION, ethereumSlotDuration: 4, diff --git a/yarn-project/end-to-end/src/single-node/prover/server/full.test.ts b/yarn-project/end-to-end/src/single-node/prover/server/full.test.ts index 991969bc5838..a75cfa2e5dd7 100644 --- a/yarn-project/end-to-end/src/single-node/prover/server/full.test.ts +++ b/yarn-project/end-to-end/src/single-node/prover/server/full.test.ts @@ -321,7 +321,10 @@ describe('single-node/prover/full', () => { }), ); - // For the commented out circuits, run the tests in orchestrator_single_checkpoint.test.ts to generate the sample inputs. + // Regenerates the private-kernel Prover.toml sample inputs plus the transaction-base rollup + // samples, which all need real client-proved transactions. The block-root, block-merge, + // checkpoint, tx-merge, and root rollup Prover.tomls are regenerated instead by the prover-client + // suite `regenerate_rollup_sample_inputs.test.ts`, so they are intentionally not written here. ( [ 'private-kernel-init', @@ -339,17 +342,6 @@ describe('single-node/prover/full', () => { 'private-kernel-reset-tail-to-public', 'rollup-tx-base-private', 'rollup-tx-base-public', - // 'rollup-tx-merge', - 'rollup-block-root-first', - 'rollup-block-root-first-single-tx', - // 'rollup-block-root-first-empty-tx', - // 'rollup-block-root', - // 'rollup-block-root-single-tx', - // 'rollup-block-merge', - // 'rollup-checkpoint-root', - 'rollup-checkpoint-root-single-block', - 'rollup-checkpoint-merge', - 'rollup-root', ] satisfies CircuitName[] ).forEach(circuitName => { const data = getTestData(circuitName); diff --git a/yarn-project/end-to-end/src/single-node/proving/prover_restart.parallel.test.ts b/yarn-project/end-to-end/src/single-node/proving/prover_restart.parallel.test.ts index 319ffee9e94f..b8b111fdbc6f 100644 --- a/yarn-project/end-to-end/src/single-node/proving/prover_restart.parallel.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/prover_restart.parallel.test.ts @@ -33,8 +33,7 @@ const ALL_PROVING_TYPES = Object.values(ProvingRequestType).filter( (t): t is ProvingRequestType => typeof t === 'number', ); -const isParity = (type: ProvingRequestType) => - type === ProvingRequestType.PARITY_BASE || type === ProvingRequestType.PARITY_ROOT; +const isParity = (type: ProvingRequestType) => type === ProvingRequestType.INBOX_PARITY; const isTxBaseRollup = (type: ProvingRequestType) => type === ProvingRequestType.PRIVATE_TX_BASE_ROLLUP || type === ProvingRequestType.PUBLIC_TX_BASE_ROLLUP; diff --git a/yarn-project/end-to-end/src/single-node/sequencer/escape_hatch_vote_only.test.ts b/yarn-project/end-to-end/src/single-node/sequencer/escape_hatch_vote_only.test.ts index f85cd95d6f76..0fb0454b1353 100644 --- a/yarn-project/end-to-end/src/single-node/sequencer/escape_hatch_vote_only.test.ts +++ b/yarn-project/end-to-end/src/single-node/sequencer/escape_hatch_vote_only.test.ts @@ -93,7 +93,6 @@ describe('single-node/sequencer/escape_hatch_vote_only', () => { automineL1Setup: true, // Pipelining opts — exercise the §6 B5 fix (tryVoteWhenEscapeHatchOpen signing/submitting for targetSlot). // inboxLag: 2 so the sequencer sources L1->L2 messages from a sealed checkpoint when building for slot+1. - inboxLag: 2, }); ({ diff --git a/yarn-project/end-to-end/src/single-node/single_node_test_context.ts b/yarn-project/end-to-end/src/single-node/single_node_test_context.ts index 2e73c4fee273..00285605b4dc 100644 --- a/yarn-project/end-to-end/src/single-node/single_node_test_context.ts +++ b/yarn-project/end-to-end/src/single-node/single_node_test_context.ts @@ -265,7 +265,6 @@ export class SingleNodeTestContext { slasherEnabled: false, // `inboxLag: 2` is the intended value when running with pipelining (the production config // default of 1 is a separate bug). Set before `...opts` so tests can still override. - inboxLag: 2, ...opts, ...(hardcodedAccountData ? { additionallyFundedAccounts: [hardcodedAccountData], numberOfAccounts: 0 } : {}), }, diff --git a/yarn-project/end-to-end/src/single-node/sync/synching.test.ts b/yarn-project/end-to-end/src/single-node/sync/synching.test.ts index 46e1f9214fb5..e2d29d9cb840 100644 --- a/yarn-project/end-to-end/src/single-node/sync/synching.test.ts +++ b/yarn-project/end-to-end/src/single-node/sync/synching.test.ts @@ -502,6 +502,7 @@ describe('single-node/sync/synching', () => { rollupAddress: deployL1ContractsValues.l1ContractAddresses.rollupAddress, }), Signature.empty(), + 0n, ); await cheatCodes.rollup.markAsProven(CheckpointNumber(provenThrough)); diff --git a/yarn-project/ethereum/src/config.ts b/yarn-project/ethereum/src/config.ts index 8388a5c74a54..5d8fa61cceb2 100644 --- a/yarn-project/ethereum/src/config.ts +++ b/yarn-project/ethereum/src/config.ts @@ -35,8 +35,6 @@ export type L1ContractsConfig = { lagInEpochsForValidatorSet: number; /** The number of epochs to lag behind the current epoch for randao selection. */ lagInEpochsForRandao: number; - /** The number of checkpoints to lag in the inbox (prevents sequencer DOS attacks). */ - inboxLag: number; /** The number of epochs after an epoch ends that proofs are still accepted. */ aztecProofSubmissionEpochs: number; /** The deposit amount for a validator */ @@ -129,11 +127,6 @@ export const l1ContractsConfigMappings: ConfigMappingsType = description: 'The number of epochs to lag behind the current epoch for randao selection.', ...numberConfigHelper(l1ContractsDefaultEnv.AZTEC_LAG_IN_EPOCHS_FOR_RANDAO), }, - inboxLag: { - env: 'AZTEC_INBOX_LAG', - description: 'The number of checkpoints to lag in the inbox (prevents sequencer DOS attacks).', - ...numberConfigHelper(l1ContractsDefaultEnv.AZTEC_INBOX_LAG), - }, aztecProofSubmissionEpochs: { env: 'AZTEC_PROOF_SUBMISSION_EPOCHS', description: 'The number of epochs after an epoch ends that proofs are still accepted.', diff --git a/yarn-project/ethereum/src/contracts/chain_state_override.ts b/yarn-project/ethereum/src/contracts/chain_state_override.ts index 8693981098d0..b17d841b0683 100644 --- a/yarn-project/ethereum/src/contracts/chain_state_override.ts +++ b/yarn-project/ethereum/src/contracts/chain_state_override.ts @@ -21,6 +21,8 @@ export type PendingCheckpointOverrideState = { outHash?: Fr; payloadDigest?: Buffer32; slotNumber?: SlotNumber; + inboxMsgTotal?: bigint; + inboxConsumedBucket?: bigint; }; export type ChainTipsOverride = { @@ -93,11 +95,12 @@ export class SimulationOverridesBuilder { /** * Overrides one or more `tempCheckpointLogs` cell fields for the configured pending checkpoint. - * Fields are independent: any subset can be provided. The translator (`makeTempCheckpointLogOverride`) - * emits a stateDiff entry per field actually set, so unspecified fields stay at their on-chain - * values. + * Any subset can be provided. The translator (`makeTempCheckpointLogOverride`) emits a stateDiff + * entry per storage word touched, so fields in untouched words stay at their on-chain values; + * `slotNumber`, `inboxMsgTotal` and `inboxConsumedBucket` share a word, so setting any of them + * zeroes the others unless they are supplied too. * - * `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: when the simulation overrides `pending` + * `slotNumber` is required for `STFLib.canPruneAtTime`: when the simulation overrides `pending` * to a checkpoint that has no on-chain `tempCheckpointLogs` entry yet, the missing slotNumber falls * back to 0 and the contract treats the pending tip as belonging to epoch 0, triggering a phantom * prune that silently undoes the `pending` override. @@ -107,6 +110,8 @@ export class SimulationOverridesBuilder { outHash?: Fr; payloadDigest?: Buffer32; slotNumber?: SlotNumber; + inboxMsgTotal?: bigint; + inboxConsumedBucket?: bigint; }): this { this.assertPendingCheckpointNumber(); this.pendingCheckpointState = { ...(this.pendingCheckpointState ?? {}), ...fields }; @@ -174,6 +179,8 @@ export async function buildSimulationOverridesStateOverride( outHash: plan.pendingCheckpointState.outHash, payloadDigest: plan.pendingCheckpointState.payloadDigest, slotNumber: plan.pendingCheckpointState.slotNumber, + inboxMsgTotal: plan.pendingCheckpointState.inboxMsgTotal, + inboxConsumedBucket: plan.pendingCheckpointState.inboxConsumedBucket, feeHeader: plan.pendingCheckpointState.feeHeader, }), ), diff --git a/yarn-project/ethereum/src/contracts/inbox.ts b/yarn-project/ethereum/src/contracts/inbox.ts index 77bcfd1a1f15..1960962a7fc5 100644 --- a/yarn-project/ethereum/src/contracts/inbox.ts +++ b/yarn-project/ethereum/src/contracts/inbox.ts @@ -1,6 +1,6 @@ +import { asyncPool } from '@aztec/foundation/async-pool'; import { maxBigint } from '@aztec/foundation/bigint'; -import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import { Buffer16, Buffer32 } from '@aztec/foundation/buffer'; +import { Buffer32 } from '@aztec/foundation/buffer'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { InboxAbi } from '@aztec/l1-artifacts/InboxAbi'; @@ -18,12 +18,17 @@ import { checkBlockTag } from './utils.js'; export type MessageSentArgs = { index: bigint; leaf: Fr; - checkpointNumber: CheckpointNumber; - rollingHash: Buffer16; + /** Consensus rolling hash (truncated sha256 chain) after this message. */ + inboxRollingHash: Fr; + /** Sequence number of the Inbox bucket this message was absorbed into. */ + bucketSeq: bigint; }; -/** Log type for MessageSent events. */ -export type MessageSentLog = L1EventLog; +/** Log type for MessageSent events, enriched with the emitting L1 block's timestamp (the bucket recency key). */ +export type MessageSentLog = L1EventLog & { + /** Timestamp (in seconds) of the L1 block that emitted the event; the key of the message's Inbox bucket. */ + l1BlockTimestamp: bigint; +}; export class InboxContract { private readonly inbox: GetContractReturnType; @@ -60,27 +65,53 @@ export class InboxContract { return this.inbox; } - public async getLag(opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}): Promise { - await checkBlockTag(opts.blockNumber, this.client); - return await this.inbox.read.LAG(opts); - } - public async getState(opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}): Promise { await checkBlockTag(opts.blockNumber, this.client); const state = await this.inbox.read.getState(opts); return { totalMessagesInserted: state.totalMessagesInserted, - messagesRollingHash: Buffer16.fromString(state.rollingHash), - treeInProgress: state.inProgress, }; } + /** Returns the sequence number of the Inbox bucket currently accumulating messages. */ + public async getCurrentBucketSeq(opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}): Promise { + await checkBlockTag(opts.blockNumber, this.client); + return this.inbox.read.getCurrentBucketSeq(opts); + } + + /** Returns the Inbox bucket with the given sequence number. */ + public async getBucket( + seq: bigint, + opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}, + ): Promise { + await checkBlockTag(opts.blockNumber, this.client); + const bucket = await this.inbox.read.getBucket([seq], opts); + return { + rollingHash: Fr.fromString(bucket.rollingHash), + totalMsgCount: bucket.totalMsgCount, + timestamp: bucket.timestamp, + msgCount: bucket.msgCount, + }; + } + + /** + * Returns the Inbox bucket currently accumulating messages: its consensus rolling hash and cumulative message + * total are the Inbox's live chain position, used by the archiver's message sync and L1-reorg detection. + */ + public async getCurrentBucket( + opts: { blockTag?: BlockTag; blockNumber?: bigint } = {}, + ): Promise { + const seq = await this.getCurrentBucketSeq(opts); + return this.getBucket(seq, opts); + } + /** Fetches MessageSent events within the given block range. */ async getMessageSentEvents(fromBlock: bigint, toBlock: bigint): Promise { - const logs = await this.inbox.getEvents.MessageSent({}, { fromBlock, toBlock }); - return logs - .filter(log => log.blockNumber! >= fromBlock && log.blockNumber! <= toBlock) - .map(log => this.mapMessageSentLog(log)); + const logs = (await this.inbox.getEvents.MessageSent({}, { fromBlock, toBlock })).filter( + log => log.blockNumber! >= fromBlock && log.blockNumber! <= toBlock, + ); + const timestamps = await this.getBlockTimestamps(logs.map(log => log.blockHash!)); + return logs.map(log => this.mapMessageSentLog(log, timestamps.get(log.blockHash!)!)); } /** Fetches MessageSent events for a specific message hash around a specific block. */ @@ -93,24 +124,55 @@ export class InboxContract { { hash: msgHash }, { fromBlock: maxBigint(aroundL1BlockNumber - 5n, 1n), toBlock: aroundL1BlockNumber + 5n }, ); - return log && this.mapMessageSentLog(log); + if (!log) { + return log as unknown as MessageSentLog; + } + const [timestamp] = (await this.getBlockTimestamps([log.blockHash!])).values(); + return this.mapMessageSentLog(log, timestamp); } - private mapMessageSentLog(log: { - blockNumber: bigint | null; - blockHash: `0x${string}` | null; - transactionHash: `0x${string}` | null; - args: { index?: bigint; hash?: `0x${string}`; checkpointNumber?: bigint; rollingHash?: `0x${string}` }; - }): MessageSentLog { + /** + * Fetches the timestamp of each distinct L1 block, so each MessageSent log can carry its bucket key. Blocks are + * resolved by hash, which pins them to the same fork the logs were read from: resolving by number would silently + * return the same-height block of another fork if the chain reorgs between the log query and this lookup, storing a + * timestamp that never applied to the message. By hash, such a reorg fails the lookup instead, and the caller + * retries against the reorged chain. Fetched with bounded concurrency to keep a large sync batch from fanning out + * unbounded RPC requests. + */ + private async getBlockTimestamps(blockHashes: Hex[]): Promise> { + const uniqueBlockHashes = [...new Set(blockHashes)]; + const timestamps = new Map(); + await asyncPool(10, uniqueBlockHashes, async blockHash => { + const block = await this.client.getBlock({ blockHash, includeTransactions: false }); + timestamps.set(blockHash, block.timestamp); + }); + return timestamps; + } + + private mapMessageSentLog( + log: { + blockNumber: bigint | null; + blockHash: `0x${string}` | null; + transactionHash: `0x${string}` | null; + args: { + index?: bigint; + hash?: `0x${string}`; + inboxRollingHash?: `0x${string}`; + bucketSeq?: bigint; + }; + }, + l1BlockTimestamp: bigint, + ): MessageSentLog { return { l1BlockNumber: log.blockNumber!, l1BlockHash: Buffer32.fromString(log.blockHash!), l1TransactionHash: log.transactionHash!, + l1BlockTimestamp, args: { index: log.args.index!, leaf: Fr.fromString(log.args.hash!), - checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber!), - rollingHash: Buffer16.fromString(log.args.rollingHash!), + inboxRollingHash: Fr.fromString(log.args.inboxRollingHash!), + bucketSeq: log.args.bucketSeq!, }, }; } @@ -118,6 +180,16 @@ export class InboxContract { export type InboxContractState = { totalMessagesInserted: bigint; - messagesRollingHash: Buffer16; - treeInProgress: bigint; +}; + +/** A snapshot of an on-chain Inbox rolling-hash bucket. */ +export type InboxContractBucket = { + /** Consensus rolling hash (truncated sha256 chain) after the last message absorbed into this bucket. */ + rollingHash: Fr; + /** Cumulative number of messages inserted into the Inbox up to and including this bucket. */ + totalMsgCount: bigint; + /** L1 block timestamp at which this bucket was opened; its recency key, in seconds. */ + timestamp: bigint; + /** Number of messages absorbed into this bucket. */ + msgCount: number; }; diff --git a/yarn-project/ethereum/src/contracts/rollup.test.ts b/yarn-project/ethereum/src/contracts/rollup.test.ts index 0e32dc63be7a..63b1d75866b4 100644 --- a/yarn-project/ethereum/src/contracts/rollup.test.ts +++ b/yarn-project/ethereum/src/contracts/rollup.test.ts @@ -487,6 +487,26 @@ describe('Rollup', () => { ); }); + it('packs the inbox consumption counts into the slot-number word', async () => { + const checkpointNumber = CheckpointNumber(13); + const override = await rollup.makeTempCheckpointLogOverride(checkpointNumber, { + slotNumber: SlotNumber(7), + inboxMsgTotal: 300n, + inboxConsumedBucket: 5n, + }); + const { map, slotFor } = getDiffMap(checkpointNumber, override); + expect(override[0].stateDiff).toHaveLength(1); + expect(map.get(await slotFor(TempCheckpointLogField.SlotNumber))).toBe( + `0x${(7n | (300n << 32n) | (5n << 96n)).toString(16).padStart(64, '0')}`.toLowerCase(), + ); + }); + + it('throws when an inbox consumption count overflows uint64', async () => { + await expect( + rollup.makeTempCheckpointLogOverride(CheckpointNumber(3), { inboxMsgTotal: 1n << 64n }), + ).rejects.toThrow(/does not fit in uint64/); + }); + it('partial override returns an empty array when no fields are supplied', async () => { const override = await rollup.makeTempCheckpointLogOverride(CheckpointNumber(13), {}); expect(override).toEqual([]); diff --git a/yarn-project/ethereum/src/contracts/rollup.ts b/yarn-project/ethereum/src/contracts/rollup.ts index e08e0085339c..ba41242c3e5f 100644 --- a/yarn-project/ethereum/src/contracts/rollup.ts +++ b/yarn-project/ethereum/src/contracts/rollup.ts @@ -68,6 +68,10 @@ export type EpochProofPublicInputArgs = { previousArchive: `0x${string}`; endArchive: `0x${string}`; outHash: `0x${string}`; + /** Inbox rolling hash before the epoch's first checkpoint's messages. */ + previousInboxRollingHash: `0x${string}`; + /** Inbox rolling hash after the epoch's last checkpoint's messages. */ + endInboxRollingHash: `0x${string}`; proverId: `0x${string}`; }; @@ -75,7 +79,7 @@ export type ViemHeader = { lastArchiveRoot: `0x${string}`; blockHeadersHash: `0x${string}`; blobsHash: `0x${string}`; - inHash: `0x${string}`; + inboxRollingHash: `0x${string}`; outHash: `0x${string}`; slotNumber: bigint; timestamp: bigint; @@ -134,7 +138,10 @@ export type L1FeeData = { blobFee: bigint; }; -/** Field offsets within the CompressedTempCheckpointLog struct in Solidity storage. */ +/** + * Field offsets within the CompressedTempCheckpointLog struct in Solidity storage. The `SlotNumber` + * word also packs the inbox consumption counts, which Solidity places in the same slot. + */ export enum TempCheckpointLogField { HeaderHash = 0, BlobCommitmentsHash = 1, @@ -143,6 +150,7 @@ export enum TempCheckpointLogField { PayloadDigest = 4, SlotNumber = 5, FeeHeader = 6, + InboxRollingHash = 7, } /** @@ -150,12 +158,19 @@ export enum TempCheckpointLogField { * `propose()` path actually reads back. `payloadDigest` is `Buffer32` because it carries an * arbitrary `bytes32` value rather than a BN254 scalar. `slotNumber` carries the uint32 portion * of the on-chain `CompressedSlot`. + * + * `slotNumber`, `inboxMsgTotal` and `inboxConsumedBucket` share a single storage word, so supplying + * any one of them rewrites all three; the ones left out land as zero. */ export type TempCheckpointLogOverrideFields = { headerHash?: Fr; outHash?: Fr; payloadDigest?: Buffer32; slotNumber?: SlotNumber; + /** Cumulative Inbox message count consumed as of this checkpoint. */ + inboxMsgTotal?: bigint; + /** Inbox bucket sequence number this checkpoint's rolling hash corresponds to. */ + inboxConsumedBucket?: bigint; feeHeader?: FeeHeader; }; @@ -261,6 +276,13 @@ function isHexString(value: unknown): value is Hex { return typeof value === 'string' && value.startsWith('0x'); } +function requireUintFits(value: bigint, bits: number, name: string): bigint { + if (value < 0n || value >= 1n << BigInt(bits)) { + throw new Error(`${name} ${value} does not fit in uint${bits}`); + } + return value; +} + export class RollupContract { private readonly rollup: GetContractReturnType; private readonly logger = createLogger('ethereum:rollup'); @@ -941,6 +963,9 @@ export class RollupContract { * * `blobCommitmentsHash` and `attestationsHash` are intentionally not exposed here — the propose path * never asserts against them, so leaving them at storage zero is harmless. + * + * One diff entry is emitted per storage word touched, so words left out keep their on-chain values. + * `slotNumber` and the two inbox consumption counts share a word: any of them rewrites all three. */ public async makeTempCheckpointLogOverride( checkpointNumber: CheckpointNumber, @@ -965,14 +990,22 @@ export class RollupContract { value: fields.payloadDigest.toString() as `0x${string}`, }); } - if (fields.slotNumber !== undefined) { - // CompressedSlot is uint32 on L1 (SafeCast.toUint32 reverts on overflow). Match that behavior here - // so a malformed override surfaces immediately rather than silently truncating into a wrong slot. - const slotNumber = BigInt(fields.slotNumber); - if (slotNumber < 0n || slotNumber > 0xffffffffn) { - throw new Error(`slotNumber ${slotNumber} does not fit in uint32`); - } - stateDiff.push({ slot: slotAt(TempCheckpointLogField.SlotNumber), value: word(slotNumber) }); + if ( + fields.slotNumber !== undefined || + fields.inboxMsgTotal !== undefined || + fields.inboxConsumedBucket !== undefined + ) { + // The L1 struct packs the slot number and the two inbox consumption counts into one word, so this + // diff always writes all three. Widths are enforced here because the L1 writers cast through + // SafeCast and revert on overflow; a malformed override must surface rather than silently truncate + // into a neighbouring field. + const slotNumber = requireUintFits(BigInt(fields.slotNumber ?? 0), 32, 'slotNumber'); + const inboxMsgTotal = requireUintFits(fields.inboxMsgTotal ?? 0n, 64, 'inboxMsgTotal'); + const inboxConsumedBucket = requireUintFits(fields.inboxConsumedBucket ?? 0n, 64, 'inboxConsumedBucket'); + stateDiff.push({ + slot: slotAt(TempCheckpointLogField.SlotNumber), + value: word(slotNumber | (inboxMsgTotal << 32n) | (inboxConsumedBucket << 96n)), + }); } if (fields.feeHeader) { stateDiff.push({ diff --git a/yarn-project/ethereum/src/deploy_aztec_l1_contracts.ts b/yarn-project/ethereum/src/deploy_aztec_l1_contracts.ts index f62c005c0949..df59d422a678 100644 --- a/yarn-project/ethereum/src/deploy_aztec_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_aztec_l1_contracts.ts @@ -581,7 +581,6 @@ export function getDeployRollupForUpgradeEnvVars( AZTEC_TARGET_COMMITTEE_SIZE: args.aztecTargetCommitteeSize.toString(), AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: args.lagInEpochsForValidatorSet.toString(), AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: args.lagInEpochsForRandao.toString(), - AZTEC_INBOX_LAG: args.inboxLag?.toString(), AZTEC_PROOF_SUBMISSION_EPOCHS: args.aztecProofSubmissionEpochs.toString(), AZTEC_LOCAL_EJECTION_THRESHOLD: args.localEjectionThreshold.toString(), AZTEC_SLASHING_LIFETIME_IN_ROUNDS: args.slashingLifetimeInRounds.toString(), diff --git a/yarn-project/ethereum/src/queries.ts b/yarn-project/ethereum/src/queries.ts index fde4ceb0561d..be3ea3663823 100644 --- a/yarn-project/ethereum/src/queries.ts +++ b/yarn-project/ethereum/src/queries.ts @@ -5,7 +5,6 @@ import { BaseError, type Block } from 'viem'; import { DefaultL1ContractsConfig, type L1ContractsConfig } from './config.js'; import { ReadOnlyGovernanceContract } from './contracts/governance.js'; import { GovernanceProposerContract } from './contracts/governance_proposer.js'; -import { InboxContract } from './contracts/inbox.js'; import { RollupContract } from './contracts/rollup.js'; import type { ViemClient, ViemPublicClient } from './types.js'; @@ -92,8 +91,6 @@ export async function getL1ContractsConfig( const rollup = new RollupContract(publicClient, rollupAddress.toString()); const slasherProposer = await rollup.getSlashingProposer(); const slasher = await rollup.getSlasherContract(); - const rollupAddresses = await rollup.getRollupAddresses(); - const inboxContract = new InboxContract(publicClient, rollupAddresses.inboxAddress.toString()); const [ l1StartBlock, @@ -104,7 +101,6 @@ export async function getL1ContractsConfig( aztecTargetCommitteeSize, lagInEpochsForValidatorSet, lagInEpochsForRandao, - inboxLag, activationThreshold, ejectionThreshold, localEjectionThreshold, @@ -132,7 +128,6 @@ export async function getL1ContractsConfig( rollup.getTargetCommitteeSize(), rollup.getLagInEpochsForValidatorSet(), rollup.getLagInEpochsForRandao(), - inboxContract.getLag(), rollup.getActivationThreshold(), rollup.getEjectionThreshold(), rollup.getLocalEjectionThreshold(), @@ -162,7 +157,6 @@ export async function getL1ContractsConfig( aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize), lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet), lagInEpochsForRandao: Number(lagInEpochsForRandao), - inboxLag: Number(inboxLag), governanceProposerQuorum: Number(governanceProposerQuorum), governanceProposerRoundSize: Number(governanceProposerRoundSize), governanceVotingDuration: DefaultL1ContractsConfig.governanceVotingDuration, diff --git a/yarn-project/ethereum/src/test/rollup_cheat_codes.test.ts b/yarn-project/ethereum/src/test/rollup_cheat_codes.test.ts deleted file mode 100644 index 454549dfe680..000000000000 --- a/yarn-project/ethereum/src/test/rollup_cheat_codes.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { getPublicClient } from '@aztec/ethereum/client'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { createLogger } from '@aztec/foundation/log'; -import { DateProvider } from '@aztec/foundation/timer'; -import { InboxAbi } from '@aztec/l1-artifacts/InboxAbi'; - -import { foundry } from 'viem/chains'; - -import { DefaultL1ContractsConfig } from '../config.js'; -import { deployAztecL1Contracts } from '../deploy_aztec_l1_contracts.js'; -import type { ViemClient } from '../types.js'; -import { EthCheatCodes } from './eth_cheat_codes.js'; -import { RollupCheatCodes } from './rollup_cheat_codes.js'; -import type { Anvil } from './start_anvil.js'; -import { startAnvil } from './start_anvil.js'; - -describe('RollupCheatCodes', () => { - let anvil: Anvil; - let rpcUrl: string; - let privateKey: `0x${string}`; - let publicClient: ViemClient; - let cheatCodes: EthCheatCodes; - let rollupCheatCodes: RollupCheatCodes; - - let vkTreeRoot: Fr; - let protocolContractsHash: Fr; - let deployedL1Contracts: Awaited>; - - beforeAll(async () => { - // this is the 6th address that gets funded by the junk mnemonic - privateKey = '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba'; - vkTreeRoot = Fr.random(); - protocolContractsHash = Fr.random(); - - ({ anvil, rpcUrl } = await startAnvil()); - - publicClient = getPublicClient({ l1RpcUrls: [rpcUrl], l1ChainId: 31337 }); - cheatCodes = new EthCheatCodes([rpcUrl], new DateProvider()); - - deployedL1Contracts = await deployAztecL1Contracts(rpcUrl, privateKey, foundry.id, { - ...DefaultL1ContractsConfig, - vkTreeRoot, - protocolContractsHash, - genesisArchiveRoot: Fr.random(), - realVerifier: false, - }); - - rollupCheatCodes = RollupCheatCodes.create([rpcUrl], deployedL1Contracts.l1ContractAddresses, new DateProvider()); - }); - - afterAll(async () => { - await cheatCodes.setIntervalMining(0); - await anvil?.stop().catch(err => createLogger('cleanup').error(err)); - }); - - describe('advanceInboxInProgress', () => { - it('should advance the inbox inProgress field correctly', async () => { - const inboxAddress = deployedL1Contracts.l1ContractAddresses.inboxAddress.toString(); - - // Read initial state directly from contract - const initialState = await publicClient.readContract({ - address: inboxAddress as `0x${string}`, - abi: InboxAbi, - functionName: 'getState', - }); - - const initialInProgress = initialState.inProgress; - const initialRollingHash = initialState.rollingHash; - const initialTotalMessagesInserted = initialState.totalMessagesInserted; - - // Advance the inbox inProgress by a large amount - const advanceBy = 1000n; - const newInProgress = await rollupCheatCodes.advanceInboxInProgress(advanceBy); - - // Read state after advancement - const finalState = await publicClient.readContract({ - address: inboxAddress as `0x${string}`, - abi: InboxAbi, - functionName: 'getState', - }); - - const finalInProgress = finalState.inProgress; - const finalRollingHash = finalState.rollingHash; - const finalTotalMessagesInserted = finalState.totalMessagesInserted; - - // Check that the advancement worked - expect(newInProgress).toBe(initialInProgress + advanceBy); - expect(finalInProgress).toBe(initialInProgress + advanceBy); - - // Check that all other fields remain unchanged - expect(finalRollingHash).toBe(initialRollingHash); - expect(finalTotalMessagesInserted).toBe(initialTotalMessagesInserted); - }); - }); -}); diff --git a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts index 9aa17c44994d..e2823cd86c2c 100644 --- a/yarn-project/ethereum/src/test/rollup_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/rollup_cheat_codes.ts @@ -295,47 +295,6 @@ export class RollupCheatCodes { ); } - /** - * Overrides the inProgress field of the Inbox contract state - * @param howMuch - How many checkpoints to move it forward - */ - public advanceInboxInProgress(howMuch: number | bigint): Promise { - return this.ethCheatCodes.execWithPausedAnvil(async () => { - // Storage slot 2 contains the InboxState struct - const inboxStateSlot = 2n; - - // Get inbox and its current state values - const inboxAddress = await this.rollup.read.getInbox(); - const currentStateValue = await this.ethCheatCodes.load(EthAddress.fromString(inboxAddress), inboxStateSlot); - - // Extract current values from the packed storage slot - // Storage layout: rollingHash (128 bits) | totalMessagesInserted (64 bits) | inProgress (64 bits) - const currentRollingHash = currentStateValue & ((1n << 128n) - 1n); - const currentTotalMessages = (currentStateValue >> 128n) & ((1n << 64n) - 1n); - const currentInProgress = currentStateValue >> 192n; - const newInProgress = currentInProgress + BigInt(howMuch); - - // Pack new values: rollingHash (low 128 bits) | totalMessages (middle 64 bits) | inProgress (high 64 bits) - const newValue = (BigInt(newInProgress) << 192n) | (currentTotalMessages << 128n) | currentRollingHash; - - await this.ethCheatCodes.store(EthAddress.fromString(inboxAddress), inboxStateSlot, newValue, { - silent: true, - }); - - this.logger.warn(`Inbox inProgress advanced from ${currentInProgress} to ${newInProgress}`, { - inbox: inboxAddress, - oldValue: '0x' + currentStateValue.toString(16), - newValue: '0x' + newValue.toString(16), - rollingHash: currentRollingHash, - totalMessages: currentTotalMessages, - oldInProgress: currentInProgress, - newInProgress, - }); - - return newInProgress; - }); - } - public insertOutbox(epoch: EpochNumber, numCheckpointsInEpoch: number, outHash: bigint) { return this.ethCheatCodes.execWithPausedAnvil(async () => { const outboxAddress = await this.rollup.read.getOutbox(); diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 09c3eacc19cc..418950675b78 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -323,7 +323,6 @@ export type EnvVar = | 'AZTEC_TARGET_COMMITTEE_SIZE' | 'AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET' | 'AZTEC_LAG_IN_EPOCHS_FOR_RANDAO' - | 'AZTEC_INBOX_LAG' | 'AZTEC_PROOF_SUBMISSION_EPOCHS' | 'AZTEC_ACTIVATION_THRESHOLD' | 'AZTEC_EJECTION_THRESHOLD' diff --git a/yarn-project/foundation/src/testing/files/index.ts b/yarn-project/foundation/src/testing/files/index.ts index 424936b283f5..bf86a6a47015 100644 --- a/yarn-project/foundation/src/testing/files/index.ts +++ b/yarn-project/foundation/src/testing/files/index.ts @@ -51,8 +51,10 @@ export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: s /** * Updates the sample Prover.toml files in noir-projects/noir-protocol-circuits/crates/. - * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 to be set - * To re-gen, run 'AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn test:e2e e2e_prover/full.test' + * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 to be set. The block-root, block-merge, checkpoint, + * tx-merge, and root rollup samples are regenerated by the prover-client + * `regenerate_rollup_sample_inputs.test.ts` suite; the private-kernel and transaction-base rollup + * samples by the e2e 'AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn test:e2e single-node/prover/server/full.test' dump. */ export function updateProtocolCircuitSampleInputs(circuitName: string, value: string) { const logger = createConsoleLogger('aztec:testing:test_data'); diff --git a/yarn-project/ivc-integration/src/base_parity_inputs.test.ts b/yarn-project/ivc-integration/src/base_parity_inputs.test.ts index 523e12618bad..278ed58ca3a7 100644 --- a/yarn-project/ivc-integration/src/base_parity_inputs.test.ts +++ b/yarn-project/ivc-integration/src/base_parity_inputs.test.ts @@ -1,57 +1,87 @@ /** - * Generates base parity circuit inputs (bytecode + witness) for UltraHonk benchmarks. + * Generates parity circuit inputs (bytecode + witness) for UltraHonk benchmarks. * Only runs when BASE_PARITY_BENCH_DIR env var is set by the UltraHonk benchmark input generator. * * Run with: BASE_PARITY_BENCH_DIR=./bench-out yarn workspace @aztec/ivc-integration test src/base_parity_inputs.test.ts + * + * The parity base/root circuits were replaced by the single variable-size InboxParity circuit; this benchmark now + * targets the 256-message rung (`InboxParity256`), matching the old base-parity circuit's size. The + * output files keep their legacy `parity_base.json` / `witness.gz` names because `ci_benchmark_ultrahonk_circuits.sh` + * locates inputs as `${circuit_name}.json` with `circuit_name=parity_base`. */ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; +import { INBOX_PARITY_SIZE_MEDIUM } from '@aztec/constants'; import { Fr } from '@aztec/foundation/curves/bn254'; import { createLogger } from '@aztec/foundation/log'; import { Noir } from '@aztec/noir-noir_js'; import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; -import { ParityBasePrivateInputs } from '@aztec/stdlib/parity'; +import { L1ToL2MessageSponge } from '@aztec/stdlib/messaging'; +import { InboxParityPrivateInputs } from '@aztec/stdlib/parity'; import { jest } from '@jest/globals'; import * as fs from 'fs/promises'; import * as path from 'path'; -const logger = createLogger('bench:base-parity'); +const logger = createLogger('bench:inbox-parity'); jest.setTimeout(120_000); -describe('Base Parity Benchmark Inputs', () => { - it('generates bytecode and witness files for base parity benchmarking', async () => { +describe('Inbox Parity Benchmark Inputs', () => { + it('generates bytecode and witness files for parity benchmarking', async () => { const outputDir = process.env.BASE_PARITY_BENCH_DIR; if (!outputDir) { - logger.info('Skipping base parity bench input generation (BASE_PARITY_BENCH_DIR not set)'); + logger.info('Skipping parity bench input generation (BASE_PARITY_BENCH_DIR not set)'); return; } - logger.info(`Generating base parity bench inputs to ${outputDir}`); + logger.info(`Generating parity bench inputs to ${outputDir}`); await fs.mkdir(outputDir, { recursive: true }); - // Generate random L1-to-L2 messages - logger.info(`Generating ${NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP} random L1-to-L2 messages...`); - const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(null).map(() => Fr.random()); + // Generate random L1-to-L2 messages that fill the 256-message rung. + logger.info(`Generating ${INBOX_PARITY_SIZE_MEDIUM} random L1-to-L2 messages...`); + const l1ToL2Messages = new Array(INBOX_PARITY_SIZE_MEDIUM).fill(null).map(() => Fr.random()); - // Create base parity inputs for the first slice + // Create InboxParity inputs (picks the 256 rung for 256 messages). const vkTreeRoot = getVKTreeRoot(); - const baseParityInputs = ParityBasePrivateInputs.fromSlice(l1ToL2Messages, 0, vkTreeRoot, Fr.random()); - logger.info('Created base parity inputs'); + const inputs = InboxParityPrivateInputs.fromMessages( + l1ToL2Messages, + Fr.ZERO, + L1ToL2MessageSponge.empty(), + vkTreeRoot, + Fr.random(), + ); + logger.info('Created inbox parity inputs'); // Convert inputs to Noir format (inline the mapping since it's simple) + const startSponge = inputs.startSponge; const noirInputs = { - msgs: baseParityInputs.msgs.map(m => m.toString()), + msgs: inputs.messages.map(m => m.toString()), + // eslint-disable-next-line camelcase + num_msgs: inputs.numMessages, + // eslint-disable-next-line camelcase + start_rolling_hash: inputs.startRollingHash.toString(), + // eslint-disable-next-line camelcase + start_sponge: { + sponge: { + cache: startSponge.sponge.cache.map(f => f.toString()), + state: startSponge.sponge.state.map(f => f.toString()), + // eslint-disable-next-line camelcase + cache_size: startSponge.sponge.cacheSize, + // eslint-disable-next-line camelcase + squeeze_mode: startSponge.sponge.squeezeMode, + }, + // eslint-disable-next-line camelcase + num_absorbed: startSponge.numAbsorbed, + }, // eslint-disable-next-line camelcase - vk_tree_root: baseParityInputs.vkTreeRoot.toString(), + vk_tree_root: inputs.vkTreeRoot.toString(), // eslint-disable-next-line camelcase - prover_id: baseParityInputs.proverId.toString(), + prover_id: inputs.proverId.toString(), }; logger.info('Converted inputs to Noir format'); // Get the circuit artifact - const artifact = ServerCircuitArtifacts.ParityBaseArtifact; + const artifact = ServerCircuitArtifacts.InboxParity256Artifact; // Execute the circuit with Noir to generate witness logger.info('Executing circuit with Noir to generate witness...'); @@ -59,7 +89,7 @@ describe('Base Parity Benchmark Inputs', () => { const { witness } = await program.execute({ inputs: noirInputs }); logger.info('Witness generated'); - // Save bytecode as JSON (bb expects the full JSON artifact) + // Save bytecode as JSON (bb expects the full JSON artifact). Filename is the harness's legacy contract. const bytecodeOutputPath = path.join(outputDir, 'parity_base.json'); await fs.writeFile(bytecodeOutputPath, JSON.stringify(artifact)); logger.info(`Wrote bytecode to ${bytecodeOutputPath}`); @@ -69,7 +99,7 @@ describe('Base Parity Benchmark Inputs', () => { await fs.writeFile(witnessOutputPath, witness); logger.info(`Wrote witness to ${witnessOutputPath}`); - logger.info('Base parity bench inputs generated successfully'); + logger.info('Inbox parity bench inputs generated successfully'); logger.info(`Output directory: ${outputDir}`); logger.info('Files:'); logger.info(` - ${bytecodeOutputPath} (circuit bytecode)`); diff --git a/yarn-project/ivc-integration/src/bb_js_debug.test.ts b/yarn-project/ivc-integration/src/bb_js_debug.test.ts index b7d6c2c4ea1f..9ce6333f5fcb 100644 --- a/yarn-project/ivc-integration/src/bb_js_debug.test.ts +++ b/yarn-project/ivc-integration/src/bb_js_debug.test.ts @@ -6,13 +6,14 @@ */ import { BBJsInstance, type BBJsProofResult } from '@aztec/bb-prover'; import { DebugBBJsInstance } from '@aztec/bb-prover/debug'; -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; +import { INBOX_PARITY_SIZE_MEDIUM } from '@aztec/constants'; import { Fr } from '@aztec/foundation/curves/bn254'; import { createLogger } from '@aztec/foundation/log'; import { Noir } from '@aztec/noir-noir_js'; import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; -import { ParityBasePrivateInputs } from '@aztec/stdlib/parity'; +import { L1ToL2MessageSponge } from '@aztec/stdlib/messaging'; +import { InboxParityPrivateInputs } from '@aztec/stdlib/parity'; import { jest } from '@jest/globals'; import * as proc from 'child_process'; @@ -54,20 +55,44 @@ describe('BB.js Debug Wrapper', () => { // Create a temporary debug output directory debugDir = await fs.mkdtemp(path.join(process.env.BB_WORKING_DIRECTORY || '/tmp', 'bb-debug-test-')); - // Generate base parity inputs (same approach as base_parity_inputs.test.ts) - const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(null).map(() => Fr.random()); + // Generate inbox parity inputs (same approach as base_parity_inputs.test.ts) + const l1ToL2Messages = new Array(INBOX_PARITY_SIZE_MEDIUM).fill(null).map(() => Fr.random()); const vkTreeRoot = getVKTreeRoot(); - const baseParityInputs = ParityBasePrivateInputs.fromSlice(l1ToL2Messages, 0, vkTreeRoot, Fr.random()); + const inboxParityInputs = InboxParityPrivateInputs.fromMessages( + l1ToL2Messages, + Fr.ZERO, + L1ToL2MessageSponge.empty(), + vkTreeRoot, + Fr.random(), + ); + const startSponge = inboxParityInputs.startSponge; const noirInputs = { - msgs: baseParityInputs.msgs.map(m => m.toString()), + msgs: inboxParityInputs.messages.map(m => m.toString()), + // eslint-disable-next-line camelcase + num_msgs: inboxParityInputs.numMessages, + // eslint-disable-next-line camelcase + start_rolling_hash: inboxParityInputs.startRollingHash.toString(), + // eslint-disable-next-line camelcase + start_sponge: { + sponge: { + cache: startSponge.sponge.cache.map(f => f.toString()), + state: startSponge.sponge.state.map(f => f.toString()), + // eslint-disable-next-line camelcase + cache_size: startSponge.sponge.cacheSize, + // eslint-disable-next-line camelcase + squeeze_mode: startSponge.sponge.squeezeMode, + }, + // eslint-disable-next-line camelcase + num_absorbed: startSponge.numAbsorbed, + }, // eslint-disable-next-line camelcase - vk_tree_root: baseParityInputs.vkTreeRoot.toString(), + vk_tree_root: inboxParityInputs.vkTreeRoot.toString(), // eslint-disable-next-line camelcase - prover_id: baseParityInputs.proverId.toString(), + prover_id: inboxParityInputs.proverId.toString(), }; - const artifact = ServerCircuitArtifacts.ParityBaseArtifact; + const artifact = ServerCircuitArtifacts.InboxParity256Artifact; // Execute circuit with Noir JS to generate witness logger.info('Generating witness via Noir JS...'); @@ -85,7 +110,7 @@ describe('BB.js Debug Wrapper', () => { const debug = new DebugBBJsInstance(raw, debugDir, BB_PATH, logger); try { - bbJsResult = await debug.generateProof('ParityBase', bytecode, vkBytes, witness, 'ultra_honk'); + bbJsResult = await debug.generateProof('InboxParity256', bytecode, vkBytes, witness, 'ultra_honk'); logger.info( `bb.js proof generated: ${bbJsResult.proofFields.length} proof fields, ${bbJsResult.publicInputFields.length} public input fields`, ); @@ -102,12 +127,12 @@ describe('BB.js Debug Wrapper', () => { }); it('writes correct debug files and command.sh', async () => { - const opDir = path.join(debugDir, 'ParityBase-001'); + const opDir = path.join(debugDir, 'InboxParity256-001'); // Check all expected files exist const files = await fs.readdir(opDir); - expect(files).toContain('ParityBase-bytecode.gz'); - expect(files).toContain('ParityBase-vk'); + expect(files).toContain('InboxParity256-bytecode.gz'); + expect(files).toContain('InboxParity256-vk'); expect(files).toContain('partial-witness.gz'); expect(files).toContain('proof'); expect(files).toContain('public_inputs'); @@ -126,15 +151,15 @@ describe('BB.js Debug Wrapper', () => { }); it('CLI bb prove reproduces the same proof as bb.js', async () => { - const opDir = path.join(debugDir, 'ParityBase-001'); + const opDir = path.join(debugDir, 'InboxParity256-001'); // Create a separate output directory for the CLI proof const cliOutputDir = path.join(debugDir, 'cli-prove-output'); await fs.mkdir(cliOutputDir, { recursive: true }); // Run the bb prove command using the same input files - const bytecodePath = path.join(opDir, 'ParityBase-bytecode.gz'); - const vkPath = path.join(opDir, 'ParityBase-vk'); + const bytecodePath = path.join(opDir, 'InboxParity256-bytecode.gz'); + const vkPath = path.join(opDir, 'InboxParity256-vk'); const witnessPath = path.join(opDir, 'partial-witness.gz'); const logFn = (msg: string) => logger.verbose(`bb-cli - ${msg}`); @@ -175,7 +200,7 @@ describe('BB.js Debug Wrapper', () => { }); it('CLI bb verify succeeds with debug output files', async () => { - const opDir = path.join(debugDir, 'ParityBase-001'); + const opDir = path.join(debugDir, 'InboxParity256-001'); // We need the VK produced by the prover (not the input VK). // The prove command writes a VK only with --write_vk. Instead, we write_vk separately @@ -185,7 +210,7 @@ describe('BB.js Debug Wrapper', () => { const vkDir = path.join(debugDir, 'cli-vk-output'); await fs.mkdir(vkDir, { recursive: true }); - const bytecodePath = path.join(opDir, 'ParityBase-bytecode.gz'); + const bytecodePath = path.join(opDir, 'InboxParity256-bytecode.gz'); // Generate VK via CLI const logFn = (msg: string) => logger.verbose(`bb-cli - ${msg}`); diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts index c2c2fea39c78..b0e00e56b414 100644 --- a/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts @@ -1,8 +1,9 @@ import type { NoirCompiledCircuit, NoirCompiledCircuitWithName } from '@aztec/stdlib/noir'; import PublicChonkVerifierJson from '../../artifacts/chonk_verifier_public.json' with { type: 'json' }; -import ParityBaseJson from '../../artifacts/parity_base.json' with { type: 'json' }; -import ParityRootJson from '../../artifacts/parity_root.json' with { type: 'json' }; +import InboxParity64Json from '../../artifacts/inbox_parity_64.json' with { type: 'json' }; +import InboxParity256Json from '../../artifacts/inbox_parity_256.json' with { type: 'json' }; +import InboxParity1024Json from '../../artifacts/inbox_parity_1024.json' with { type: 'json' }; import BlockMergeRollupJson from '../../artifacts/rollup_block_merge.json' with { type: 'json' }; import BlockRootRollupJson from '../../artifacts/rollup_block_root.json' with { type: 'json' }; import BlockRootFirstRollupJson from '../../artifacts/rollup_block_root_first.json' with { type: 'json' }; @@ -10,6 +11,7 @@ import BlockRootEmptyTxFirstRollupJson from '../../artifacts/rollup_block_root_f import BlockRootFirstRollupSimulatedJson from '../../artifacts/rollup_block_root_first_simulated.json' with { type: 'json' }; import BlockRootSingleTxFirstRollupJson from '../../artifacts/rollup_block_root_first_single_tx.json' with { type: 'json' }; import BlockRootSingleTxFirstRollupSimulatedJson from '../../artifacts/rollup_block_root_first_single_tx_simulated.json' with { type: 'json' }; +import BlockRootMsgsOnlyRollupJson from '../../artifacts/rollup_block_root_msgs_only.json' with { type: 'json' }; import BlockRootRollupSimulatedJson from '../../artifacts/rollup_block_root_simulated.json' with { type: 'json' }; import BlockRootSingleTxRollupJson from '../../artifacts/rollup_block_root_single_tx.json' with { type: 'json' }; import BlockRootSingleTxRollupSimulatedJson from '../../artifacts/rollup_block_root_single_tx_simulated.json' with { type: 'json' }; @@ -28,8 +30,9 @@ import TxMergeRollupJson from '../../artifacts/rollup_tx_merge.json' with { type import type { ServerProtocolArtifact } from './types.js'; export const ServerCircuitArtifacts: Record = { - ParityBaseArtifact: ParityBaseJson as NoirCompiledCircuit, - ParityRootArtifact: ParityRootJson as NoirCompiledCircuit, + InboxParity64Artifact: InboxParity64Json as NoirCompiledCircuit, + InboxParity256Artifact: InboxParity256Json as NoirCompiledCircuit, + InboxParity1024Artifact: InboxParity1024Json as NoirCompiledCircuit, PublicChonkVerifier: PublicChonkVerifierJson as NoirCompiledCircuit, PrivateTxBaseRollupArtifact: PrivateTxBaseRollupJson as NoirCompiledCircuit, PublicTxBaseRollupArtifact: PublicTxBaseRollupJson as NoirCompiledCircuit, @@ -39,6 +42,7 @@ export const ServerCircuitArtifacts: Record = { - ParityBaseArtifact: ParityBaseJson as NoirCompiledCircuit, - ParityRootArtifact: ParityRootJson as NoirCompiledCircuit, + // No separate simulated build for the inbox parity ladder: they verify no child proofs, so the constrained + // artifacts are used for simulation too. + InboxParity64Artifact: InboxParity64Json as NoirCompiledCircuit, + InboxParity256Artifact: InboxParity256Json as NoirCompiledCircuit, + InboxParity1024Artifact: InboxParity1024Json as NoirCompiledCircuit, PublicChonkVerifier: PublicChonkVerifierJson as NoirCompiledCircuit, PrivateTxBaseRollupArtifact: PrivateTxBaseRollupSimulatedJson as NoirCompiledCircuit, PublicTxBaseRollupArtifact: PublicTxBaseRollupSimulatedJson as NoirCompiledCircuit, @@ -59,6 +66,9 @@ export const SimulatedServerCircuitArtifacts: Record = { - ParityBaseArtifact: abiToVKData(ParityBase), - ParityRootArtifact: abiToVKData(ParityRoot), + InboxParity64Artifact: abiToVKData(InboxParity64), + InboxParity256Artifact: abiToVKData(InboxParity256), + InboxParity1024Artifact: abiToVKData(InboxParity1024), PublicChonkVerifier: abiToVKData(PublicChonkVerifier), PrivateTxBaseRollupArtifact: abiToVKData(PrivateTxBaseRollup), PublicTxBaseRollupArtifact: abiToVKData(PublicTxBaseRollup), @@ -68,6 +73,7 @@ export const ServerCircuitVks: Record = { HidingKernelToRollup: HIDING_KERNEL_TO_ROLLUP_VK_INDEX, HidingKernelToPublic: HIDING_KERNEL_TO_PUBLIC_VK_INDEX, PublicChonkVerifier: PUBLIC_CHONK_VERIFIER_VK_INDEX, - ParityBaseArtifact: PARITY_BASE_VK_INDEX, - ParityRootArtifact: PARITY_ROOT_VK_INDEX, + InboxParity64Artifact: INBOX_PARITY_64_VK_INDEX, + InboxParity256Artifact: INBOX_PARITY_256_VK_INDEX, + InboxParity1024Artifact: INBOX_PARITY_1024_VK_INDEX, PrivateTxBaseRollupArtifact: PRIVATE_TX_BASE_ROLLUP_VK_INDEX, PublicTxBaseRollupArtifact: PUBLIC_TX_BASE_ROLLUP_VK_INDEX, TxMergeRollupArtifact: TX_MERGE_ROLLUP_VK_INDEX, @@ -102,6 +109,7 @@ export const ProtocolCircuitVkIndexes: Record = { BlockRootEmptyTxFirstRollupArtifact: BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP_VK_INDEX, BlockRootRollupArtifact: BLOCK_ROOT_ROLLUP_VK_INDEX, BlockRootSingleTxRollupArtifact: BLOCK_ROOT_SINGLE_TX_ROLLUP_VK_INDEX, + BlockRootMsgsOnlyRollupArtifact: BLOCK_ROOT_MSGS_ONLY_ROLLUP_VK_INDEX, BlockMergeRollupArtifact: BLOCK_MERGE_ROLLUP_VK_INDEX, CheckpointRootRollupArtifact: CHECKPOINT_ROOT_ROLLUP_VK_INDEX, CheckpointRootSingleBlockRollupArtifact: CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP_VK_INDEX, diff --git a/yarn-project/noir-protocol-circuits-types/src/conversion/server.ts b/yarn-project/noir-protocol-circuits-types/src/conversion/server.ts index af399f11fbfd..0e32f920b309 100644 --- a/yarn-project/noir-protocol-circuits-types/src/conversion/server.ts +++ b/yarn-project/noir-protocol-circuits-types/src/conversion/server.ts @@ -12,6 +12,7 @@ import { CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH, MAX_CHECKPOINTS_PER_EPOCH, + MAX_L1_TO_L2_MSGS_PER_BLOCK, type NULLIFIER_TREE_HEIGHT, ULTRA_VK_LENGTH_IN_FIELDS, } from '@aztec/constants'; @@ -32,7 +33,8 @@ import { PrivateToPublicKernelCircuitPublicInputs, } from '@aztec/stdlib/kernel'; import type { FlatPublicLogs } from '@aztec/stdlib/logs'; -import { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import { L1ToL2MessageBundle, L1ToL2MessageSponge } from '@aztec/stdlib/messaging'; +import { InboxParityPrivateInputs, ParityPublicInputs } from '@aztec/stdlib/parity'; import type { ProofData, ProofDataForFixedVk, RecursiveProof } from '@aztec/stdlib/proofs'; import { BlockConstantData, @@ -40,6 +42,7 @@ import { BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -76,6 +79,7 @@ import type { BlockRollupPublicInputs as BlockRollupPublicInputsNoir, BlockRootEmptyTxFirstRollupPrivateInputs as BlockRootEmptyTxFirstRollupPrivateInputsNoir, BlockRootFirstRollupPrivateInputs as BlockRootFirstRollupPrivateInputsNoir, + BlockRootMsgsOnlyRollupPrivateInputs as BlockRootMsgsOnlyRollupPrivateInputsNoir, BlockRootRollupPrivateInputs as BlockRootRollupPrivateInputsNoir, BlockRootSingleTxFirstRollupPrivateInputs as BlockRootSingleTxFirstRollupPrivateInputsNoir, BlockRootSingleTxRollupPrivateInputs as BlockRootSingleTxRollupPrivateInputsNoir, @@ -90,10 +94,9 @@ import type { FinalBlobAccumulator as FinalBlobAccumulatorNoir, FinalBlobBatchingChallenges as FinalBlobBatchingChallengesNoir, FixedLengthArray, + L1ToL2MessageSponge as L1ToL2MessageSpongeNoir, Field as NoirField, - ParityBasePrivateInputs as ParityBasePrivateInputsNoir, ParityPublicInputs as ParityPublicInputsNoir, - ParityRootPrivateInputs as ParityRootPrivateInputsNoir, Poseidon2Sponge as Poseidon2SpongeNoir, PrivateToAvmAccumulatedDataArrayLengths as PrivateToAvmAccumulatedDataArrayLengthsNoir, PrivateToAvmAccumulatedData as PrivateToAvmAccumulatedDataNoir, @@ -265,6 +268,17 @@ function mapSpongeBlobFromNoir(spongeBlob: SpongeBlobNoir): SpongeBlob { ); } +function mapL1ToL2MessageSpongeToNoir(sponge: L1ToL2MessageSponge): L1ToL2MessageSpongeNoir { + return { + sponge: mapPoseidon2SpongeToNoir(sponge.sponge), + num_absorbed: mapNumberToNoir(sponge.numAbsorbed), + }; +} + +function mapL1ToL2MessageSpongeFromNoir(sponge: L1ToL2MessageSpongeNoir): L1ToL2MessageSponge { + return new L1ToL2MessageSponge(mapPoseidon2SpongeFromNoir(sponge.sponge), mapNumberFromNoir(sponge.num_absorbed)); +} + /** * Maps blob challenges to noir. * @param challenges - The stdlib challenges. @@ -467,8 +481,11 @@ export function mapAvmProofDataToNoir( function mapParityPublicInputsToNoir(parityPublicInputs: ParityPublicInputs): ParityPublicInputsNoir { return { - sha_root: mapFieldToNoir(parityPublicInputs.shaRoot), - converted_root: mapFieldToNoir(parityPublicInputs.convertedRoot), + start_rolling_hash: mapFieldToNoir(parityPublicInputs.startRollingHash), + end_rolling_hash: mapFieldToNoir(parityPublicInputs.endRollingHash), + start_sponge: mapL1ToL2MessageSpongeToNoir(parityPublicInputs.startSponge), + end_sponge: mapL1ToL2MessageSpongeToNoir(parityPublicInputs.endSponge), + num_msgs: mapNumberToNoir(parityPublicInputs.numMsgs), vk_tree_root: mapFieldToNoir(parityPublicInputs.vkTreeRoot), prover_id: mapFieldToNoir(parityPublicInputs.proverId), }; @@ -486,6 +503,8 @@ export function mapRootRollupPublicInputsFromNoir( mapFieldFromNoir(rootRollupPublicInputs.previous_archive_root), mapFieldFromNoir(rootRollupPublicInputs.new_archive_root), mapFieldFromNoir(rootRollupPublicInputs.out_hash), + mapFieldFromNoir(rootRollupPublicInputs.previous_inbox_rolling_hash), + mapFieldFromNoir(rootRollupPublicInputs.end_inbox_rolling_hash), mapTupleFromNoir(rootRollupPublicInputs.checkpoint_header_hashes, MAX_CHECKPOINTS_PER_EPOCH, mapFieldFromNoir), mapTupleFromNoir(rootRollupPublicInputs.fees, MAX_CHECKPOINTS_PER_EPOCH, mapFeeRecipientFromNoir), mapEpochConstantDataFromNoir(rootRollupPublicInputs.constants), @@ -500,8 +519,11 @@ export function mapRootRollupPublicInputsFromNoir( */ export function mapParityPublicInputsFromNoir(parityPublicInputs: ParityPublicInputsNoir): ParityPublicInputs { return new ParityPublicInputs( - mapFieldFromNoir(parityPublicInputs.sha_root), - mapFieldFromNoir(parityPublicInputs.converted_root), + mapFieldFromNoir(parityPublicInputs.start_rolling_hash), + mapFieldFromNoir(parityPublicInputs.end_rolling_hash), + mapL1ToL2MessageSpongeFromNoir(parityPublicInputs.start_sponge), + mapL1ToL2MessageSpongeFromNoir(parityPublicInputs.end_sponge), + mapNumberFromNoir(parityPublicInputs.num_msgs), mapFieldFromNoir(parityPublicInputs.vk_tree_root), mapFieldFromNoir(parityPublicInputs.prover_id), ); @@ -608,7 +630,9 @@ export function mapBlockRollupPublicInputsFromNoir(inputs: BlockRollupPublicInpu mapSpongeBlobFromNoir(inputs.end_sponge_blob), mapU64FromNoir(inputs.timestamp), mapFieldFromNoir(inputs.block_headers_hash), - mapFieldFromNoir(inputs.in_hash), + inputs.is_first_block, + mapL1ToL2MessageSpongeFromNoir(inputs.start_msg_sponge), + mapL1ToL2MessageSpongeFromNoir(inputs.end_msg_sponge), mapFieldFromNoir(inputs.out_hash), mapFieldFromNoir(inputs.accumulated_fees), mapFieldFromNoir(inputs.accumulated_mana_used), @@ -626,7 +650,9 @@ export function mapBlockRollupPublicInputsToNoir(inputs: BlockRollupPublicInputs end_sponge_blob: mapSpongeBlobToNoir(inputs.endSpongeBlob), timestamp: mapU64ToNoir(inputs.timestamp), block_headers_hash: mapFieldToNoir(inputs.blockHeadersHash), - in_hash: mapFieldToNoir(inputs.inHash), + is_first_block: inputs.isFirstBlock, + start_msg_sponge: mapL1ToL2MessageSpongeToNoir(inputs.startMsgSponge), + end_msg_sponge: mapL1ToL2MessageSpongeToNoir(inputs.endMsgSponge), out_hash: mapFieldToNoir(inputs.outHash), accumulated_fees: mapFieldToNoir(inputs.accumulatedFees), accumulated_mana_used: mapFieldToNoir(inputs.accumulatedManaUsed), @@ -640,6 +666,8 @@ export function mapCheckpointRollupPublicInputsFromNoir(inputs: CheckpointRollup mapAppendOnlyTreeSnapshotFromNoir(inputs.new_archive), mapAppendOnlyTreeSnapshotFromNoir(inputs.previous_out_hash), mapAppendOnlyTreeSnapshotFromNoir(inputs.new_out_hash), + mapFieldFromNoir(inputs.start_inbox_rolling_hash), + mapFieldFromNoir(inputs.end_inbox_rolling_hash), mapTupleFromNoir(inputs.checkpoint_header_hashes, MAX_CHECKPOINTS_PER_EPOCH, mapFieldFromNoir), mapTupleFromNoir(inputs.fees, MAX_CHECKPOINTS_PER_EPOCH, mapFeeRecipientFromNoir), mapBlobAccumulatorFromNoir(inputs.start_blob_accumulator), @@ -657,6 +685,8 @@ export function mapCheckpointRollupPublicInputsToNoir( new_archive: mapAppendOnlyTreeSnapshotToNoir(inputs.newArchive), previous_out_hash: mapAppendOnlyTreeSnapshotToNoir(inputs.previousOutHash), new_out_hash: mapAppendOnlyTreeSnapshotToNoir(inputs.newOutHash), + start_inbox_rolling_hash: mapFieldToNoir(inputs.startInboxRollingHash), + end_inbox_rolling_hash: mapFieldToNoir(inputs.endInboxRollingHash), checkpoint_header_hashes: mapTuple(inputs.checkpointHeaderHashes, mapFieldToNoir), fees: mapTuple(inputs.fees, mapFeeRecipientToNoir), start_blob_accumulator: mapBlobAccumulatorToNoir(inputs.startBlobAccumulator), @@ -699,22 +729,19 @@ function mapTreeSnapshotDiffHintsToNoir(hints: TreeSnapshotDiffHints): TreeSnaps }; } -export function mapParityBasePrivateInputsToNoir(inputs: ParityBasePrivateInputs): ParityBasePrivateInputsNoir { +// Maps the size-generic InboxParity inputs to the Noir struct. The `messages` array length already equals the chosen +// ladder size, so the same object satisfies whichever size-specific artifact ABI is selected by `inputs.size`. +export function mapInboxParityPrivateInputsToNoir(inputs: InboxParityPrivateInputs) { return { - msgs: mapTuple(inputs.msgs, mapFieldToNoir), + msgs: mapFieldArrayToNoir(inputs.messages), + num_msgs: mapNumberToNoir(inputs.numMessages), + start_rolling_hash: mapFieldToNoir(inputs.startRollingHash), + start_sponge: mapL1ToL2MessageSpongeToNoir(inputs.startSponge), vk_tree_root: mapFieldToNoir(inputs.vkTreeRoot), prover_id: mapFieldToNoir(inputs.proverId), }; } -export function mapParityRootPrivateInputsToNoir(inputs: ParityRootPrivateInputs): ParityRootPrivateInputsNoir { - return { - children: mapTuple(inputs.children, c => - mapProofDataToNoir(c, mapParityPublicInputsToNoir, ULTRA_VK_LENGTH_IN_FIELDS), - ), - }; -} - export function mapPublicChonkVerifierPrivateInputsToNoir( inputs: PublicChonkVerifierPrivateInputs, ): PublicChonkVerifierPrivateInputsNoir { @@ -800,20 +827,26 @@ export function mapRevertCodeToNoir(revertCode: RevertCode): NoirField { return mapFieldToNoir(revertCode.toField()); } +function mapL1ToL2MessageBundleToNoir(bundle: L1ToL2MessageBundle) { + return { + // `messages` is a plain `Fr[]` (padded to the cap) rather than a fixed tuple, so pass the length explicitly to + // get the fixed-length `FixedLengthArray` the generated `L1ToL2MessageBundle.messages` type requires. + messages: mapFieldArrayToNoir(bundle.messages, MAX_L1_TO_L2_MSGS_PER_BLOCK), + num_msgs: mapNumberToNoir(bundle.numMsgs), + }; +} + export function mapBlockRootFirstRollupPrivateInputsToNoir( inputs: BlockRootFirstRollupPrivateInputs, ): BlockRootFirstRollupPrivateInputsNoir { return { - parity_root: mapProofDataToNoir(inputs.l1ToL2Roots, mapParityPublicInputsToNoir), previous_rollups: [ mapProofDataToNoir(inputs.previousRollups[0], mapTxRollupPublicInputsToNoir), mapProofDataToNoir(inputs.previousRollups[1], mapTxRollupPublicInputsToNoir), ], + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), previous_l1_to_l2: mapAppendOnlyTreeSnapshotToNoir(inputs.previousL1ToL2), - new_l1_to_l2_message_subtree_root_sibling_path: mapTuple( - inputs.newL1ToL2MessageSubtreeRootSiblingPath, - mapFieldToNoir, - ), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), }; } @@ -822,13 +855,10 @@ export function mapBlockRootSingleTxFirstRollupPrivateInputsToNoir( inputs: BlockRootSingleTxFirstRollupPrivateInputs, ): BlockRootSingleTxFirstRollupPrivateInputsNoir { return { - parity_root: mapProofDataToNoir(inputs.l1ToL2Roots, mapParityPublicInputsToNoir), previous_rollup: mapProofDataToNoir(inputs.previousRollup, mapTxRollupPublicInputsToNoir), + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), previous_l1_to_l2: mapAppendOnlyTreeSnapshotToNoir(inputs.previousL1ToL2), - new_l1_to_l2_message_subtree_root_sibling_path: mapTuple( - inputs.newL1ToL2MessageSubtreeRootSiblingPath, - mapFieldToNoir, - ), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), }; } @@ -837,15 +867,28 @@ export function mapBlockRootEmptyTxFirstRollupPrivateInputsToNoir( inputs: BlockRootEmptyTxFirstRollupPrivateInputs, ): BlockRootEmptyTxFirstRollupPrivateInputsNoir { return { - parity_root: mapProofDataToNoir(inputs.l1ToL2Roots, mapParityPublicInputsToNoir), previous_archive: mapAppendOnlyTreeSnapshotToNoir(inputs.previousArchive), previous_state: mapStateReferenceToNoir(inputs.previousState), constants: mapCheckpointConstantDataToNoir(inputs.constants), timestamp: mapU64ToNoir(inputs.timestamp), - new_l1_to_l2_message_subtree_root_sibling_path: mapTuple( - inputs.newL1ToL2MessageSubtreeRootSiblingPath, - mapFieldToNoir, - ), + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), + new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), + }; +} + +export function mapBlockRootMsgsOnlyRollupPrivateInputsToNoir( + inputs: BlockRootMsgsOnlyRollupPrivateInputs, +): BlockRootMsgsOnlyRollupPrivateInputsNoir { + return { + previous_archive: mapAppendOnlyTreeSnapshotToNoir(inputs.previousArchive), + previous_state: mapStateReferenceToNoir(inputs.previousState), + constants: mapCheckpointConstantDataToNoir(inputs.constants), + timestamp: mapU64ToNoir(inputs.timestamp), + start_sponge_blob: mapSpongeBlobToNoir(inputs.startSpongeBlob), + start_msg_sponge: mapL1ToL2MessageSpongeToNoir(inputs.startMsgSponge), + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), }; } @@ -858,6 +901,10 @@ export function mapBlockRootRollupPrivateInputsToNoir( mapProofDataToNoir(inputs.previousRollups[0], mapTxRollupPublicInputsToNoir), mapProofDataToNoir(inputs.previousRollups[1], mapTxRollupPublicInputsToNoir), ], + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), + previous_l1_to_l2: mapAppendOnlyTreeSnapshotToNoir(inputs.previousL1ToL2), + start_msg_sponge: mapL1ToL2MessageSpongeToNoir(inputs.startMsgSponge), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), }; } @@ -867,6 +914,10 @@ export function mapBlockRootSingleTxRollupPrivateInputsToNoir( ): BlockRootSingleTxRollupPrivateInputsNoir { return { previous_rollup: mapProofDataToNoir(inputs.previousRollup, mapTxRollupPublicInputsToNoir), + message_bundle: mapL1ToL2MessageBundleToNoir(inputs.messageBundle), + previous_l1_to_l2: mapAppendOnlyTreeSnapshotToNoir(inputs.previousL1ToL2), + start_msg_sponge: mapL1ToL2MessageSpongeToNoir(inputs.startMsgSponge), + l1_to_l2_message_frontier_hint: mapTuple(inputs.l1ToL2MessageFrontierHint, mapFieldToNoir), new_archive_sibling_path: mapTuple(inputs.newArchiveSiblingPath, mapFieldToNoir), }; } @@ -904,6 +955,7 @@ export function mapCheckpointRootRollupPrivateInputsToNoir( mapProofDataToNoir(inputs.previousRollups[0], mapBlockRollupPublicInputsToNoir), mapProofDataToNoir(inputs.previousRollups[1], mapBlockRollupPublicInputsToNoir), ], + inbox_parity: mapProofDataToNoir(inputs.inboxParity, mapParityPublicInputsToNoir, ULTRA_VK_LENGTH_IN_FIELDS), hints: mapCheckpointRootRollupHintsToNoir(inputs.hints), }; } @@ -913,6 +965,7 @@ export function mapCheckpointRootSingleBlockRollupPrivateInputsToNoir( ): CheckpointRootSingleBlockRollupPrivateInputsNoir { return { previous_rollup: mapProofDataToNoir(inputs.previousRollup, mapBlockRollupPublicInputsToNoir), + inbox_parity: mapProofDataToNoir(inputs.inboxParity, mapParityPublicInputsToNoir, ULTRA_VK_LENGTH_IN_FIELDS), hints: mapCheckpointRootRollupHintsToNoir(inputs.hints), }; } diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/server.ts b/yarn-project/noir-protocol-circuits-types/src/execution/server.ts index a2719392b148..b30e84876ebf 100644 --- a/yarn-project/noir-protocol-circuits-types/src/execution/server.ts +++ b/yarn-project/noir-protocol-circuits-types/src/execution/server.ts @@ -1,12 +1,14 @@ +import { INBOX_PARITY_SIZE_LARGE, INBOX_PARITY_SIZE_MEDIUM, INBOX_PARITY_SIZE_SMALL } from '@aztec/constants'; import { pushTestData } from '@aztec/foundation/testing'; import type { WitnessMap } from '@aztec/noir-acvm_js'; import { abiDecode, abiEncode } from '@aztec/noir-noirc_abi'; -import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import type { InboxParityPrivateInputs, ParityPublicInputs } from '@aztec/stdlib/parity'; import type { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -32,6 +34,7 @@ import { mapBlockRollupPublicInputsFromNoir, mapBlockRootEmptyTxFirstRollupPrivateInputsToNoir, mapBlockRootFirstRollupPrivateInputsToNoir, + mapBlockRootMsgsOnlyRollupPrivateInputsToNoir, mapBlockRootRollupPrivateInputsToNoir, mapBlockRootSingleTxFirstRollupPrivateInputsToNoir, mapBlockRootSingleTxRollupPrivateInputsToNoir, @@ -39,9 +42,8 @@ import { mapCheckpointRollupPublicInputsFromNoir, mapCheckpointRootRollupPrivateInputsToNoir, mapCheckpointRootSingleBlockRollupPrivateInputsToNoir, - mapParityBasePrivateInputsToNoir, + mapInboxParityPrivateInputsToNoir, mapParityPublicInputsFromNoir, - mapParityRootPrivateInputsToNoir, mapPrivateTxBaseRollupPrivateInputsToNoir, mapPublicChonkVerifierPrivateInputsToNoir, mapPublicChonkVerifierPublicInputsFromNoir, @@ -53,12 +55,12 @@ import { } from '../conversion/server.js'; import type { ChonkVerifierPublicReturnType, - ParityBaseReturnType, - ParityRootReturnType, + InboxParity64ReturnType, RollupBlockMergeReturnType, RollupBlockRootFirstEmptyTxReturnType, RollupBlockRootFirstReturnType, RollupBlockRootFirstSingleTxReturnType, + RollupBlockRootMsgsOnlyReturnType, RollupBlockRootReturnType, RollupBlockRootSingleTxReturnType, RollupCheckpointMergeReturnType, @@ -74,27 +76,33 @@ import type { DecodedInputs } from '../utils/decoded_inputs.js'; export { mapAvmCircuitPublicInputsToNoir } from '../conversion/server.js'; /** - * Converts the inputs of the base parity circuit into a witness map. - * @param inputs - The base parity inputs. + * Converts the inputs of the inbox parity circuit into a witness map. + * @param inputs - The inbox parity inputs. * @returns The witness map */ -export function convertParityBasePrivateInputsToWitnessMap( - inputs: ParityBasePrivateInputs, +export function convertInboxParityPrivateInputsToWitnessMap( + inputs: InboxParityPrivateInputs, simulated = false, ): WitnessMap { - return convertPrivateInputsToWitnessMap('ParityBaseArtifact', mapParityBasePrivateInputsToNoir(inputs), simulated); + return convertPrivateInputsToWitnessMap( + inboxParityArtifactForSize(inputs.size), + mapInboxParityPrivateInputsToNoir(inputs), + simulated, + ); } -/** - * Converts the inputs of the root parity circuit into a witness map. - * @param inputs - The root parity inputs. - * @returns The witness map - */ -export function convertParityRootPrivateInputsToWitnessMap( - inputs: ParityRootPrivateInputs, - simulated = false, -): WitnessMap { - return convertPrivateInputsToWitnessMap('ParityRootArtifact', mapParityRootPrivateInputsToNoir(inputs), simulated); +/** Maps an InboxParity ladder size to its server artifact. */ +export function inboxParityArtifactForSize(size: number): ServerProtocolArtifact { + switch (size) { + case INBOX_PARITY_SIZE_SMALL: + return 'InboxParity64Artifact'; + case INBOX_PARITY_SIZE_MEDIUM: + return 'InboxParity256Artifact'; + case INBOX_PARITY_SIZE_LARGE: + return 'InboxParity1024Artifact'; + default: + throw new Error(`No InboxParity artifact for size ${size}`); + } } export function convertPublicChonkVerifierPrivateInputsToWitnessMap( @@ -201,6 +209,17 @@ export function convertBlockRootSingleTxRollupPrivateInputsToWitnessMap( ); } +export function convertBlockRootMsgsOnlyRollupPrivateInputsToWitnessMap( + inputs: BlockRootMsgsOnlyRollupPrivateInputs, + simulated = false, +): WitnessMap { + return convertPrivateInputsToWitnessMap( + 'BlockRootMsgsOnlyRollupArtifact', + mapBlockRootMsgsOnlyRollupPrivateInputsToNoir(inputs), + simulated, + ); +} + export function convertBlockMergeRollupPrivateInputsToWitnessMap( inputs: BlockMergeRollupPrivateInputs, simulated = false, @@ -370,6 +389,18 @@ export function convertBlockRootSingleTxRollupOutputsFromWitnessMap( return mapBlockRollupPublicInputsFromNoir(publicInputs); } +export function convertBlockRootMsgsOnlyRollupOutputsFromWitnessMap( + outputs: WitnessMap, + simulated = false, +): BlockRollupPublicInputs { + const publicInputs = convertOutputsFromWitnessMap( + 'BlockRootMsgsOnlyRollupArtifact', + outputs, + simulated, + ); + return mapBlockRollupPublicInputsFromNoir(publicInputs); +} + export function convertBlockMergeRollupOutputsFromWitnessMap( outputs: WitnessMap, simulated = false, @@ -441,22 +472,21 @@ export function convertRootRollupOutputsFromWitnessMap(outputs: WitnessMap, simu } /** - * Converts the outputs of the base parity circuit from a witness map. - * @param outputs - The base parity outputs as a witness map. + * Converts the outputs of the inbox parity circuit from a witness map. + * @param outputs - The inbox parity outputs as a witness map. * @returns The public inputs. */ -export function convertParityBaseOutputsFromWitnessMap(outputs: WitnessMap, simulated = false): ParityPublicInputs { - const publicInputs = convertOutputsFromWitnessMap('ParityBaseArtifact', outputs, simulated); - return mapParityPublicInputsFromNoir(publicInputs); -} - -/** - * Converts the outputs of the root parity circuit from a witness map. - * @param outputs - The root parity outputs as a witness map. - * @returns The public inputs. - */ -export function convertParityRootOutputsFromWitnessMap(outputs: WitnessMap, simulated = false): ParityPublicInputs { - const publicInputs = convertOutputsFromWitnessMap('ParityRootArtifact', outputs, simulated); +export function convertInboxParityOutputsFromWitnessMap( + outputs: WitnessMap, + size: number, + simulated = false, +): ParityPublicInputs { + // Every ladder size shares the same `ParityPublicInputs` return ABI, so the decode is identical across sizes. + const publicInputs = convertOutputsFromWitnessMap( + inboxParityArtifactForSize(size), + outputs, + simulated, + ); return mapParityPublicInputsFromNoir(publicInputs); } diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 8cca923f21ef..79a3ba4f4b00 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -8,8 +8,9 @@ import { promises as fs } from 'fs'; const log = createConsoleLogger('autogenerate'); const circuits = [ - 'parity_base', - 'parity_root', + 'inbox_parity_64', + 'inbox_parity_256', + 'inbox_parity_1024', 'private_kernel_init', 'private_kernel_init_2', 'private_kernel_init_3', @@ -34,6 +35,7 @@ const circuits = [ 'rollup_block_root_first', 'rollup_block_root_first_single_tx', 'rollup_block_root_first_empty_tx', + 'rollup_block_root_msgs_only', 'rollup_block_merge', 'rollup_checkpoint_root', 'rollup_checkpoint_root_single_block', diff --git a/yarn-project/p2p/src/client/factory.ts b/yarn-project/p2p/src/client/factory.ts index 1175be199df8..2172e68847db 100644 --- a/yarn-project/p2p/src/client/factory.ts +++ b/yarn-project/p2p/src/client/factory.ts @@ -81,7 +81,10 @@ export async function createP2PClient( const store = deps.store ?? (await createStore(P2P_STORE_NAME, 4, config, bindings)); const archive = await createStore(P2P_ARCHIVE_STORE_NAME, 1, config, bindings); const peerStore = await createStore(P2P_PEER_STORE_NAME, 1, config, bindings); - const attestationStore = await createStore(P2P_ATTESTATION_STORE_NAME, 2, config, bindings); + // Attestation store version 3: persisted proposal/attestation buffers embed the checkpoint header (which lost + // `inHash`) and the block-proposal wire format (which dropped its zeroed `inHash`), so pre-Fast-Inbox bytes no + // longer decode. Bumped to wipe stale pools; same no-migration policy as the archiver store. + const attestationStore = await createStore(P2P_ATTESTATION_STORE_NAME, 3, config, bindings); const l1Constants = await archiver.getL1Constants(); const rollupAddress = inputConfig.rollupAddress.toString().toLowerCase().replace(/^0x/, ''); diff --git a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts index 3c163f0fe551..30ea05fe0d31 100644 --- a/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts +++ b/yarn-project/p2p/src/services/libp2p/libp2p_service.test.ts @@ -20,7 +20,7 @@ import { makeCheckpointProposal, mockTx, } from '@aztec/stdlib/testing'; -import { TxArray, TxHashArray } from '@aztec/stdlib/tx'; +import { TxArray, TxHash, TxHashArray } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import { ServerWorldStateSynchronizer } from '@aztec/world-state'; @@ -809,8 +809,8 @@ describe('LibP2PService', () => { }); // Regression for A-1013: payloads sharing (slot, position, archive) but differing on another - // signed field (e.g. inHash) used to dedup by archive only and silently drop the second one. - // The pool now dedups by signed-payload hash, so the equivocation surfaces. + // signed field (e.g. the transaction set) used to dedup by archive only and silently drop the + // second one. The pool now dedups by signed-payload hash, so the equivocation surfaces. it('same archive but different signed payload triggers slash callback', async () => { const blockHeader = makeBlockHeader(1, { slotNumber: targetSlot }); const indexWithinCheckpoint = IndexWithinCheckpoint(0); @@ -820,7 +820,7 @@ describe('LibP2PService', () => { signer, blockHeader, indexWithinCheckpoint, - inHash: Fr.fromString('0x1'), + txHashes: [TxHash.fromField(new Fr(1))], archiveRoot: sharedArchive, }); await service.processBlockFromPeer(proposal1.toBuffer(), 'msg-1', mockPeerId); @@ -830,7 +830,7 @@ describe('LibP2PService', () => { signer, blockHeader, indexWithinCheckpoint, - inHash: Fr.fromString('0x2'), + txHashes: [TxHash.fromField(new Fr(2))], archiveRoot: sharedArchive, }); expect(proposal2.archive.toString()).toBe(proposal1.archive.toString()); diff --git a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.bench.test.ts b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.bench.test.ts index a12f1f88723b..670fb97b4d22 100644 --- a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.bench.test.ts +++ b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.bench.test.ts @@ -146,18 +146,18 @@ describe('LightweightCheckpointBuilder benchmarks', () => { const constants = makeCheckpointConstants(slotNumber); const fork = await worldState.fork(); - const builder = await LightweightCheckpointBuilder.startNewCheckpoint( + const builder = LightweightCheckpointBuilder.startNewCheckpoint( CheckpointNumber(1), constants, [], - [], + Fr.ZERO, fork, ); const globalVariables = makeGlobalVariables(blockNumber, slotNumber); const txs = await timesAsync(numTxs, i => makeTx(globalVariables, 5000 + i)); - const { timings } = await builder.addBlock(globalVariables, txs, { insertTxsEffects: true }); + const { timings } = await builder.addBlock(globalVariables, txs, [], { insertTxsEffects: true }); const prefix = `addBlock/${label}/${numTxs} txs`; for (const [step, ms] of Object.entries(timings)) { diff --git a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.test.ts b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.test.ts index b10d906cd0e7..04d532654705 100644 --- a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.test.ts +++ b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.test.ts @@ -97,23 +97,22 @@ describe('LightweightCheckpointBuilder', () => { const blockNumber = BlockNumber(1); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); // Use LightweightCheckpointBuilder directly - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); // Build empty block const globalVariables = makeGlobalVariables(blockNumber, slotNumber); - const { block } = await checkpointBuilder.addBlock(globalVariables, [], { insertTxsEffects: true }); + const { block } = await checkpointBuilder.addBlock(globalVariables, [], [], { insertTxsEffects: true }); expect(block.header.globalVariables.blockNumber).toEqual(blockNumber); @@ -137,17 +136,16 @@ describe('LightweightCheckpointBuilder', () => { const blockNumber = BlockNumber(1); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; // There are two checkpoints before this one. const previousCheckpointOutHashes = [Fr.random(), Fr.random()]; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -159,7 +157,7 @@ describe('LightweightCheckpointBuilder', () => { tx.txEffect.l2ToL1Msgs.push(...msgs); // Build block with tx - insertTxsEffects will handle inserting side effects - const { block } = await checkpointBuilder.addBlock(globalVariables, [tx], { + const { block } = await checkpointBuilder.addBlock(globalVariables, [tx], [], { insertTxsEffects: true, }); @@ -188,16 +186,15 @@ describe('LightweightCheckpointBuilder', () => { const blockNumber = BlockNumber(1); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -206,7 +203,7 @@ describe('LightweightCheckpointBuilder', () => { const txs = await timesAsync(3, i => makeProcessedTx(globalVariables, 1000 + i)); // Build block with txs - insertTxsEffects will handle inserting side effects - const { block } = await checkpointBuilder.addBlock(globalVariables, txs, { + const { block } = await checkpointBuilder.addBlock(globalVariables, txs, [], { insertTxsEffects: true, }); @@ -227,16 +224,15 @@ describe('LightweightCheckpointBuilder', () => { const slotNumber = SlotNumber(15); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -252,7 +248,7 @@ describe('LightweightCheckpointBuilder', () => { const txs = await timesAsync(txsPerBlock, j => makeProcessedTx(globalVariables, 2000 + i * 10 + j)); // Build block - insertTxsEffects will handle inserting side effects - const { block } = await checkpointBuilder.addBlock(globalVariables, txs, { + const { block } = await checkpointBuilder.addBlock(globalVariables, txs, [], { insertTxsEffects: true, }); @@ -280,16 +276,15 @@ describe('LightweightCheckpointBuilder', () => { const slotNumber = SlotNumber(15); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -304,29 +299,28 @@ describe('LightweightCheckpointBuilder', () => { const slotNumber = SlotNumber(15); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); // Add first block with txs - insertTxsEffects will handle inserting side effects const globalVariables1 = makeGlobalVariables(BlockNumber(1), slotNumber); const txs1 = await timesAsync(2, i => makeProcessedTx(globalVariables1, 3000 + i)); - await checkpointBuilder.addBlock(globalVariables1, txs1, { + await checkpointBuilder.addBlock(globalVariables1, txs1, [], { insertTxsEffects: true, }); // Try to add second block with no txs - this should fail const globalVariables2 = makeGlobalVariables(BlockNumber(2), slotNumber); - await expect(checkpointBuilder.addBlock(globalVariables2, [], { insertTxsEffects: true })).rejects.toThrow( + await expect(checkpointBuilder.addBlock(globalVariables2, [], [], { insertTxsEffects: true })).rejects.toThrow( /first block/, ); @@ -338,16 +332,15 @@ describe('LightweightCheckpointBuilder', () => { const slotNumber = SlotNumber(15); const constants = makeCheckpointConstants(slotNumber); - const l1ToL2Messages: Fr[] = []; const previousCheckpointOutHashes: Fr[] = []; const fork = await worldState.fork(); - const checkpointBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const checkpointBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -356,7 +349,7 @@ describe('LightweightCheckpointBuilder', () => { const wrongBlockNumber = BlockNumber(5); const globalVariables = makeGlobalVariables(wrongBlockNumber, slotNumber); - await expect(checkpointBuilder.addBlock(globalVariables, [], { insertTxsEffects: true })).rejects.toThrow( + await expect(checkpointBuilder.addBlock(globalVariables, [], [], { insertTxsEffects: true })).rejects.toThrow( /Archive tree next leaf index mismatch/, ); diff --git a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.ts b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.ts index 10a2865cda4b..e2481445632b 100644 --- a/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.ts +++ b/yarn-project/prover-client/src/light/lightweight_checkpoint_builder.ts @@ -8,9 +8,9 @@ import { Checkpoint } from '@aztec/stdlib/checkpoint'; import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server'; import { accumulateCheckpointOutHashes, + accumulateInboxRollingHash, appendL1ToL2MessagesToTree, computeCheckpointOutHash, - computeInHashFromL1ToL2Messages, } from '@aztec/stdlib/messaging'; import { CheckpointHeader, computeBlockHeadersHash } from '@aztec/stdlib/rollup'; import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees'; @@ -30,7 +30,7 @@ import { /** * Builds a checkpoint and its header and the blocks in it from a set of processed tx without running any circuits. * - * It updates the l1-to-l2 message tree when starting a new checkpoint, and then updates the archive tree when each block is added. + * Each added block inserts its own L1-to-L2 message bundle into the message tree and then updates the archive tree. * Finally completes the checkpoint by computing its header. */ export class LightweightCheckpointBuilder { @@ -47,6 +47,8 @@ export class LightweightCheckpointBuilder { public feeAssetPriceModifier: bigint, public readonly l1ToL2Messages: Fr[], private readonly previousCheckpointOutHashes: Fr[], + // Inbox rolling hash of the previous checkpoint (this checkpoint's chain start); genesis is zero. + private readonly previousInboxRollingHash: Fr, public readonly db: MerkleTreeWriteOperations, bindings?: LoggerBindings, ) { @@ -58,24 +60,26 @@ export class LightweightCheckpointBuilder { this.logger.debug('Starting new checkpoint', { constants, l1ToL2Messages, feeAssetPriceModifier }); } - static async startNewCheckpoint( + /** + * Starts a fresh checkpoint. The checkpoint's L1-to-L2 messages are not supplied here: every block brings its own + * bundle to {@link addBlock}, which inserts it into the tree and accumulates it into the checkpoint's message list. + */ + static startNewCheckpoint( checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, - l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, db: MerkleTreeWriteOperations, bindings?: LoggerBindings, feeAssetPriceModifier: bigint = 0n, - ): Promise { - // Insert l1-to-l2 messages into the tree. - await appendL1ToL2MessagesToTree(db, l1ToL2Messages); - + ): LightweightCheckpointBuilder { return new LightweightCheckpointBuilder( checkpointNumber, constants, feeAssetPriceModifier, - l1ToL2Messages, + [], previousCheckpointOutHashes, + previousInboxRollingHash, db, bindings, ); @@ -84,8 +88,8 @@ export class LightweightCheckpointBuilder { /** * Resumes building a checkpoint from existing blocks. This is used for validator re-execution * where blocks have already been built and their effects are already in the database. - * Unlike startNewCheckpoint, this does NOT append l1ToL2Messages to the tree since they - * were already added when the blocks were originally built. + * `l1ToL2Messages` is the whole checkpoint's message list as consumed by the existing blocks: it seeds the + * checkpoint's rolling hash and is not inserted into the tree, since the blocks already inserted it. */ static async resumeCheckpoint( checkpointNumber: CheckpointNumber, @@ -93,6 +97,7 @@ export class LightweightCheckpointBuilder { feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, db: MerkleTreeWriteOperations, existingBlocks: L2Block[], bindings?: LoggerBindings, @@ -103,6 +108,7 @@ export class LightweightCheckpointBuilder { feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, db, bindings, ); @@ -161,18 +167,21 @@ export class LightweightCheckpointBuilder { /** * Adds a new block to the checkpoint. The tx effects must have already been inserted into the db if * this is called after tx processing, if that's not the case, then set `insertTxsEffects` to true. + * @param l1ToL2Messages - The message leaves this block consumes from the Inbox, in insertion order. */ public async addBlock( globalVariables: GlobalVariables, txs: ProcessedTx[], + l1ToL2Messages: Fr[], opts: { insertTxsEffects?: boolean; expectedEndState?: StateReference } = {}, ): Promise<{ block: L2Block; timings: Record }> { const timings: Record = {}; const isFirstBlock = this.blocks.length === 0; - // Empty blocks are only allowed as the first block in a checkpoint - if (!isFirstBlock && txs.length === 0) { - throw new Error('Cannot add empty block that is not the first block in the checkpoint.'); + // A non-first block with no txs is only allowed when it inserts a non-empty L1-to-L2 message bundle: the + // message-only block shape, proven by the msgs-only block root. + if (!isFirstBlock && txs.length === 0 && l1ToL2Messages.length === 0) { + throw new Error('Cannot add an empty non-first block that carries no L1-to-L2 messages.'); } if (isFirstBlock) { @@ -196,6 +205,13 @@ export class LightweightCheckpointBuilder { timings.insertSideEffects = msInsertSideEffects; } + // Streaming Inbox: insert this block's L1-to-L2 message bundle before reading the end state, + // so the block header's L1-to-L2 tree snapshot reflects it. Bundles are appended compactly (unpadded, at the + // tree's current next-available index). The logical messages are accumulated only once the block is fully built + // (below), so a mid-build failure does not pollute the checkpoint's rolling hash; the rolling hash is recomputed + // over them at checkpoint completion. + await appendL1ToL2MessagesToTree(this.db, l1ToL2Messages); + const [msGetEndState, endState] = await elapsed(() => this.db.getStateReference()); timings.getEndState = msGetEndState; @@ -209,7 +225,7 @@ export class LightweightCheckpointBuilder { } const [msBuildHeaderAndBody, { header, body, blockBlobFields }] = await elapsed(() => - buildHeaderAndBodyFromTxs(txs, lastArchive, endState, globalVariables, this.spongeBlob, isFirstBlock), + buildHeaderAndBodyFromTxs(txs, lastArchive, endState, globalVariables, this.spongeBlob), ); timings.buildHeaderAndBody = msBuildHeaderAndBody; @@ -231,6 +247,10 @@ export class LightweightCheckpointBuilder { const block = new L2Block(newArchive, header, body, this.checkpointNumber, indexWithinCheckpoint); this.blocks.push(block); + // Accumulate the streaming bundle now that the block is fully built, so a mid-build throw above leaves the + // checkpoint's message list (and thus its rolling hash) consistent with the blocks actually built. + this.l1ToL2Messages.push(...l1ToL2Messages); + const [msSpongeAbsorb] = await elapsed(() => this.spongeBlob.absorb(blockBlobFields)); timings.spongeAbsorb = msSpongeAbsorb; this.blobFields.push(...blockBlobFields); @@ -263,7 +283,7 @@ export class LightweightCheckpointBuilder { const blobs = await getBlobsPerL1Block(this.blobFields); const blobsHash = computeBlobsHashFromBlobs(blobs); - const inHash = computeInHashFromL1ToL2Messages(this.l1ToL2Messages); + const inboxRollingHash = accumulateInboxRollingHash(this.previousInboxRollingHash, this.l1ToL2Messages); const { slotNumber, coinbase, feeRecipient, gasFees } = this.constants; const checkpointOutHash = computeCheckpointOutHash( @@ -280,7 +300,7 @@ export class LightweightCheckpointBuilder { const header = CheckpointHeader.from({ lastArchiveRoot: this.lastArchives[0].root, blobsHash, - inHash, + inboxRollingHash, epochOutHash, blockHeadersHash, slotNumber, @@ -310,6 +330,7 @@ export class LightweightCheckpointBuilder { this.feeAssetPriceModifier, [...this.l1ToL2Messages], [...this.previousCheckpointOutHashes], + this.previousInboxRollingHash, this.db, this.logger.getBindings(), ); diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index 5c709bdbf8e4..08bf74daabcf 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -1,8 +1,7 @@ import type { BBProverConfig } from '@aztec/bb-prover'; import { TestCircuitProver } from '@aztec/bb-prover'; -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; -import { padArrayEnd, times, timesAsync } from '@aztec/foundation/collection'; +import { times, timesAsync } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { Logger } from '@aztec/foundation/log'; import { SerialQueue } from '@aztec/foundation/queue'; @@ -60,6 +59,10 @@ export class TestContext { private nextBlockNumber = 1; private epochNumber = 1; private feePayerBalance: Fr; + // Running inbox rolling hash across the checkpoints built by this context (never resets: the protocol threads it + // from genesis). Each checkpoint's builder starts from it, and it advances by the checkpoint's messages, so a + // checkpoint built after a message-carrying one commits the correct continuation in its header. + private currentInboxRollingHash = Fr.ZERO; constructor( public worldState: MerkleTreeAdminDatabase, @@ -194,12 +197,10 @@ export class TestContext { const fork = await this.worldState.fork(); - // Build l1 to l2 messages. + // Build l1 to l2 messages. Appended unpadded at compact indices; the mock assigns them all to + // the checkpoint's first block, matching how the per-block driver slices them. const l1ToL2Messages = times(numL1ToL2Messages, i => new Fr(slotNumber * 100 + i)); - await fork.appendLeaves( - MerkleTreeId.L1_TO_L2_MESSAGE_TREE, - padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), - ); + await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); const newL1ToL2Snapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, fork); const startBlockNumber = this.nextBlockNumber; @@ -244,11 +245,12 @@ export class TestContext { const cleanFork = await this.worldState.fork(); const previousCheckpointOutHashes = this.checkpointOutHashes; - const builder = await LightweightCheckpointBuilder.startNewCheckpoint( + const startInboxRollingHash = this.currentInboxRollingHash; + const builder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, { ...constants, timestamp }, - l1ToL2Messages, previousCheckpointOutHashes, + startInboxRollingHash, cleanFork, ); @@ -258,7 +260,7 @@ export class TestContext { const txs = blockTxs[i]; const state = blockEndStates[i]; - const { block } = await builder.addBlock(blockGlobalVariables[i], txs, { + const { block } = await builder.addBlock(blockGlobalVariables[i], txs, i === 0 ? l1ToL2Messages : [], { expectedEndState: state, insertTxsEffects: true, }); @@ -275,6 +277,132 @@ export class TestContext { const checkpoint = await builder.completeCheckpoint(); this.checkpoints.push(checkpoint); this.checkpointOutHashes.push(checkpoint.getCheckpointOutHash()); + this.currentInboxRollingHash = checkpoint.header.inboxRollingHash; + + return { + constants, + checkpoint, + header: checkpoint.header, + blocks, + l1ToL2Messages, + previousBlockHeader, + startInboxRollingHash, + }; + } + + /** + * Like {@link makeCheckpoint} but distributes the L1-to-L2 message bundle across the checkpoint's blocks + * (streaming Inbox): `l1ToL2MessagesPerBlock[i]` is block `i`'s own message slice, + * appended at compact indices in insertion order. Lets tests exercise checkpoints whose messages span more + * than one block, including a non-first block carrying a bundle — the single-block-per-checkpoint + * `makeCheckpoint` puts every message in the first block. `numTxsPerBlock` defaults to 1 because the builder + * rejects a non-first block with neither txs nor messages; a zero-tx entry whose slice is non-empty is valid + * and produces a message-only block. + */ + public async makeCheckpointWithMessagesPerBlock( + l1ToL2MessagesPerBlock: Fr[][], + { + numTxsPerBlock = 1, + makeProcessedTxOpts = () => ({}), + ...constantOpts + }: { + numTxsPerBlock?: number | number[]; + makeProcessedTxOpts?: ( + blockGlobalVariables: GlobalVariables, + txIndex: number, + ) => Partial[0]>; + } & Partial> = {}, + ) { + const numBlocks = l1ToL2MessagesPerBlock.length; + if (numBlocks === 0) { + throw new Error('Cannot make a checkpoint with 0 blocks.'); + } + + const checkpointIndex = this.nextCheckpointIndex++; + const checkpointNumber = this.nextCheckpointNumber; + this.nextCheckpointNumber++; + const slotNumber = checkpointNumber * 15; + + const constants = makeCheckpointConstants(slotNumber, constantOpts); + const l1ToL2Messages = l1ToL2MessagesPerBlock.flat(); + + const fork = await this.worldState.fork(); + + const startBlockNumber = this.nextBlockNumber; + const previousBlockHeader = this.getBlockHeader(BlockNumber(startBlockNumber - 1)); + const timestamp = BigInt(slotNumber * 26); + + const blockGlobalVariables = times(numBlocks, i => + makeGlobals(startBlockNumber + i, slotNumber, { + coinbase: constants.coinbase, + feeRecipient: constants.feeRecipient, + gasFees: constants.gasFees, + timestamp, + }), + ); + this.nextBlockNumber += numBlocks; + + // Build txs per block. Append the block's message slice to the fork before its txs so the per-block end + // state matches the builder's (message-tree and tx-effect trees are independent, so append order does not + // matter, but the cumulative message tree must reflect the slices already inserted). + let totalTxs = 0; + const blockEndStates: StateReference[] = []; + const blockTxs = await timesAsync(numBlocks, async blockIndex => { + await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPerBlock[blockIndex]); + const newL1ToL2Snapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, fork); + + const txIndexOffset = totalTxs; + const numTxs = typeof numTxsPerBlock === 'number' ? numTxsPerBlock : numTxsPerBlock[blockIndex]; + totalTxs += numTxs; + const txs = await timesAsync(numTxs, txIndex => + this.makeProcessedTx({ + seed: (txIndexOffset + txIndex + 1) * 321 + (checkpointIndex + 1) * 123456 + this.epochNumber * 0x99999, + globalVariables: blockGlobalVariables[blockIndex], + anchorBlockHeader: previousBlockHeader, + newL1ToL2Snapshot, + ...makeProcessedTxOpts(blockGlobalVariables[blockIndex], txIndexOffset + txIndex), + }), + ); + + const endState = await this.updateTrees(txs, fork); + blockEndStates.push(endState); + + return txs; + }); + + const cleanFork = await this.worldState.fork(); + const previousCheckpointOutHashes = this.checkpointOutHashes; + const startInboxRollingHash = this.currentInboxRollingHash; + const builder = LightweightCheckpointBuilder.startNewCheckpoint( + checkpointNumber, + { ...constants, timestamp }, + previousCheckpointOutHashes, + startInboxRollingHash, + cleanFork, + ); + + const blocks = []; + for (let i = 0; i < numBlocks; i++) { + const txs = blockTxs[i]; + const state = blockEndStates[i]; + + const { block } = await builder.addBlock(blockGlobalVariables[i], txs, l1ToL2MessagesPerBlock[i], { + expectedEndState: state, + insertTxsEffects: true, + }); + + const header = block.header; + this.headers.set(block.number, header); + + await this.worldState.handleL2BlockAndMessages(block, l1ToL2MessagesPerBlock[i]); + + blocks.push({ header, txs }); + } + + const checkpoint = await builder.completeCheckpoint(); + this.checkpoints.push(checkpoint); + this.checkpointOutHashes.push(checkpoint.getCheckpointOutHash()); + this.currentInboxRollingHash = checkpoint.header.inboxRollingHash; return { constants, @@ -282,7 +410,9 @@ export class TestContext { header: checkpoint.header, blocks, l1ToL2Messages, + l1ToL2MessagesPerBlock, previousBlockHeader, + startInboxRollingHash, }; } diff --git a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts index 01c0726d70bb..1c340afa73cc 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -312,7 +312,6 @@ export const buildHeaderAndBodyFromTxs = runInSpan( endState: StateReference, globalVariables: GlobalVariables, startSpongeBlob: SpongeBlob, - isFirstBlock: boolean, ) => { span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber); @@ -341,7 +340,8 @@ export const buildHeaderAndBodyFromTxs = runInSpan( noteHashRoot: partial.noteHashTree.root, nullifierRoot: partial.nullifierTree.root, publicDataRoot: partial.publicDataTree.root, - l1ToL2MessageRoot: isFirstBlock ? l1ToL2MessageTree.root : undefined, + // Every block carries its own post-bundle l1-to-l2 message tree root. + l1ToL2MessageRoot: l1ToL2MessageTree.root, txs: body.toTxBlobData(), }); @@ -399,6 +399,15 @@ export async function getSubtreeSiblingPath( return fullSiblingPath.getSubtreeSiblingPath(subtreeHeight).toFields(); } +/** + * Returns the full-height frontier (left-sibling path) at a tree's next-available leaf index — the hint the append + * circuits re-hash against the snapshot root when appending leaves at a compact (unaligned) index. + */ +export async function getFrontierSiblingPath(treeId: MerkleTreeId, db: MerkleTreeReadOperations): Promise { + const nextAvailableLeafIndex = await db.getTreeInfo(treeId).then(t => t.size); + return (await db.getSiblingPath(treeId, nextAvailableLeafIndex)).toFields(); +} + // Scan a tree searching for a specific value and return a membership witness proof for it export async function getMembershipWitnessFor( value: Fr, diff --git a/yarn-project/prover-client/src/orchestrator/block-proving-state.ts b/yarn-project/prover-client/src/orchestrator/block-proving-state.ts index 53c7a594db82..f94fc06b7889 100644 --- a/yarn-project/prover-client/src/orchestrator/block-proving-state.ts +++ b/yarn-project/prover-client/src/orchestrator/block-proving-state.ts @@ -1,22 +1,21 @@ import { type BlockBlobData, type BlockEndBlobData, type SpongeBlob, encodeBlockEndBlobData } from '@aztec/blob-lib'; -import { - type ARCHIVE_HEIGHT, - type L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - NESTED_RECURSIVE_PROOF_LENGTH, - type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, - NUM_BASE_PARITY_PER_ROOT_PARITY, +import type { + ARCHIVE_HEIGHT, + L1_TO_L2_MSG_TREE_HEIGHT, + NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; -import { type Tuple, assertLength } from '@aztec/foundation/serialize'; +import type { Tuple } from '@aztec/foundation/serialize'; import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees'; import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server'; -import { type ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import { L1ToL2MessageBundle, type L1ToL2MessageSponge, makeL1ToL2MessageBundle } from '@aztec/stdlib/messaging'; import type { RollupHonkProofData } from '@aztec/stdlib/proofs'; import { BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -38,6 +37,18 @@ export type ProofState = { isProving?: boolean; }; +/** + * The block-root rollup flavor a block proves with and its private inputs, discriminated by circuit name so callers + * can dispatch to the matching prover entrypoint with the correctly-typed inputs. + */ +export type BlockRootRollupTypeAndInputs = + | { rollupType: 'rollup-block-root-first'; inputs: BlockRootFirstRollupPrivateInputs } + | { rollupType: 'rollup-block-root-first-single-tx'; inputs: BlockRootSingleTxFirstRollupPrivateInputs } + | { rollupType: 'rollup-block-root-first-empty-tx'; inputs: BlockRootEmptyTxFirstRollupPrivateInputs } + | { rollupType: 'rollup-block-root-msgs-only'; inputs: BlockRootMsgsOnlyRollupPrivateInputs } + | { rollupType: 'rollup-block-root-single-tx'; inputs: BlockRootSingleTxRollupPrivateInputs } + | { rollupType: 'rollup-block-root'; inputs: BlockRootRollupPrivateInputs }; + /** * The current state of the proving schedule for a given block. Managed by ProvingState. * Contains the raw inputs and intermediate state to generate every constituent proof in the tree. @@ -46,11 +57,6 @@ export class BlockProvingState { private baseOrMergeProofs: UnbalancedTreeStore< ProofState > = new UnbalancedTreeStore(0); - private baseParityProofs: (ProofState | undefined)[] = - Array.from({ - length: NUM_BASE_PARITY_PER_ROOT_PARITY, - }).map(_ => undefined); - private rootParityProof: ProofState | undefined; private blockRootProof: | ProofState | undefined; @@ -70,24 +76,42 @@ export class BlockProvingState { private readonly timestamp: UInt64, public readonly lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot, private readonly lastArchiveSiblingPath: Tuple, - private readonly lastL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, - private readonly lastL1ToL2MessageSubtreeRootSiblingPath: Tuple< - Fr, - typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH - >, + // The full state reference of the previous block, before this block's bundle is appended. Feeds the msgs-only + // block root, whose zero-tx block has no tx constants to pin the previous state. + private readonly previousState: StateReference, + // This block's L1-to-L2 message tree snapshot before and after its own bundle. The start is + // the previous block's end (block-merge continuity); the end is this block's own post-bundle snapshot. + private readonly startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, public readonly newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + // Full-height frontier (left-sibling path) at the block's start index, pinning the append at a compact index. + private readonly l1ToL2MessageFrontierHint: Tuple, + // This block's own real L1-to-L2 message leaves (unpadded slice). + private readonly l1ToL2Messages: Fr[], + // Message sponge threaded across the checkpoint's blocks: the start is the previous block's + // end sponge (empty for the first block), the end absorbs this block's own slice. Block merges assert the + // continuity, so the end is exposed for the next block to inherit. + private readonly startMsgSponge: L1ToL2MessageSponge, + private readonly endMsgSponge: L1ToL2MessageSponge, private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader, private readonly startSpongeBlob: SpongeBlob, public parentCheckpoint: CheckpointProvingState, ) { this.isFirstBlock = index === 0; - if (!totalNumTxs && !this.isFirstBlock) { - throw new Error(`Cannot create a block with 0 txs, unless it's the first block.`); + if (!totalNumTxs && !this.isFirstBlock && l1ToL2Messages.length === 0) { + throw new Error( + `Cannot create a non-first block with 0 txs and no L1-to-L2 messages (block ${blockNumber}). ` + + `A zero-tx non-first block must carry a message bundle (the msgs-only block root).`, + ); } this.baseOrMergeProofs = new UnbalancedTreeStore(totalNumTxs); } + /** The message sponge after absorbing this block's slice; inherited by the next block as its start sponge. */ + public getEndMsgSponge(): L1ToL2MessageSponge { + return this.endMsgSponge; + } + public get epochNumber(): number { return this.parentCheckpoint.epochNumber; } @@ -148,38 +172,6 @@ export class BlockProvingState { this.baseOrMergeProofs.setNode(location, { provingOutput }); } - public tryStartProvingBaseParity(index: number) { - if (this.baseParityProofs[index]?.isProving) { - return false; - } else { - this.baseParityProofs[index] = { isProving: true }; - return true; - } - } - - // Stores a set of root parity inputs at the given index - public setBaseParityProof(index: number, provingOutput: PublicInputsAndRecursiveProof) { - if (index >= NUM_BASE_PARITY_PER_ROOT_PARITY) { - throw new Error( - `Unable to set a base parity proofs at index ${index}. Expected at most ${NUM_BASE_PARITY_PER_ROOT_PARITY} proofs.`, - ); - } - this.baseParityProofs[index] = { provingOutput }; - } - - public tryStartProvingRootParity() { - if (this.rootParityProof?.isProving) { - return false; - } else { - this.rootParityProof = { isProving: true }; - return true; - } - } - - public setRootParityProof(provingOutput: PublicInputsAndRecursiveProof) { - this.rootParityProof = { provingOutput }; - } - public tryStartProvingBlockRoot() { if (this.blockRootProof?.isProving) { return false; @@ -288,7 +280,8 @@ export class BlockProvingState { noteHashRoot: partial.noteHashTree.root, nullifierRoot: partial.nullifierTree.root, publicDataRoot: partial.publicDataTree.root, - l1ToL2MessageRoot: this.isFirstBlock ? this.newL1ToL2MessageTreeSnapshot.root : undefined, + // Every block carries its own post-bundle l1-to-l2 message tree root. + l1ToL2MessageRoot: this.newL1ToL2MessageTreeSnapshot.root, }; } @@ -316,7 +309,7 @@ export class BlockProvingState { return new TxMergeRollupPrivateInputs([toProofData(left), toProofData(right)]); } - public getBlockRootRollupTypeAndInputs() { + public getBlockRootRollupTypeAndInputs(): BlockRootRollupTypeAndInputs { const provingOutputs = this.#getChildProvingOutputsForBlockRoot(); if (!provingOutputs.every(p => !!p)) { throw new Error('At least one child is not ready for the block root rollup.'); @@ -328,36 +321,73 @@ export class BlockProvingState { return this.#getFirstBlockRootRollupTypeAndInputs(previousRollups); } + const messageBundle = this.#getMessageBundle(); + const frontierHint = this.#getFrontierHint(); + const startMsgSponge = this.startMsgSponge; + + // A non-first block with no txs exists solely to insert its message bundle (the constructor rejects an empty one). + if (this.totalNumTxs === 0) { + return { + rollupType: 'rollup-block-root-msgs-only' satisfies CircuitName, + inputs: new BlockRootMsgsOnlyRollupPrivateInputs( + this.lastArchiveTreeSnapshot, + this.previousState, + this.constants, + this.timestamp, + this.startSpongeBlob, + startMsgSponge, + messageBundle, + frontierHint, + this.lastArchiveSiblingPath, + ), + }; + } + const [leftRollup, rightRollup] = previousRollups; if (!rightRollup) { return { rollupType: 'rollup-block-root-single-tx' satisfies CircuitName, - inputs: new BlockRootSingleTxRollupPrivateInputs(leftRollup, this.lastArchiveSiblingPath), + inputs: new BlockRootSingleTxRollupPrivateInputs( + leftRollup, + messageBundle, + this.startL1ToL2MessageTreeSnapshot, + startMsgSponge, + frontierHint, + this.lastArchiveSiblingPath, + ), }; } else { return { rollupType: 'rollup-block-root' satisfies CircuitName, - inputs: new BlockRootRollupPrivateInputs([leftRollup, rightRollup], this.lastArchiveSiblingPath), + inputs: new BlockRootRollupPrivateInputs( + [leftRollup, rightRollup], + messageBundle, + this.startL1ToL2MessageTreeSnapshot, + startMsgSponge, + frontierHint, + this.lastArchiveSiblingPath, + ), }; } } - #getFirstBlockRootRollupTypeAndInputs([leftRollup, rightRollup]: RollupHonkProofData[]) { - if (!this.rootParityProof?.provingOutput) { - throw new Error('Root parity is not ready.'); - } - const l1ToL2Roots = toProofData(this.rootParityProof.provingOutput); + #getFirstBlockRootRollupTypeAndInputs([ + leftRollup, + rightRollup, + ]: RollupHonkProofData[]): BlockRootRollupTypeAndInputs { + const messageBundle = this.#getMessageBundle(); + const frontierHint = this.#getFrontierHint(); if (!leftRollup) { return { rollupType: 'rollup-block-root-first-empty-tx' satisfies CircuitName, inputs: new BlockRootEmptyTxFirstRollupPrivateInputs( - l1ToL2Roots, this.lastArchiveTreeSnapshot, this.headerOfLastBlockInPreviousCheckpoint.state, this.constants, this.timestamp, - this.lastL1ToL2MessageSubtreeRootSiblingPath, + messageBundle, + frontierHint, this.lastArchiveSiblingPath, ), }; @@ -365,10 +395,10 @@ export class BlockProvingState { return { rollupType: 'rollup-block-root-first-single-tx' satisfies CircuitName, inputs: new BlockRootSingleTxFirstRollupPrivateInputs( - l1ToL2Roots, leftRollup, - this.lastL1ToL2MessageTreeSnapshot, - this.lastL1ToL2MessageSubtreeRootSiblingPath, + messageBundle, + this.startL1ToL2MessageTreeSnapshot, + frontierHint, this.lastArchiveSiblingPath, ), }; @@ -376,24 +406,32 @@ export class BlockProvingState { return { rollupType: 'rollup-block-root-first' satisfies CircuitName, inputs: new BlockRootFirstRollupPrivateInputs( - l1ToL2Roots, [leftRollup, rightRollup], - this.lastL1ToL2MessageTreeSnapshot, - this.lastL1ToL2MessageSubtreeRootSiblingPath, + messageBundle, + this.startL1ToL2MessageTreeSnapshot, + frontierHint, this.lastArchiveSiblingPath, ), }; } } - public getParityRootInputs() { - const baseParityProvingOutputs = this.baseParityProofs.filter(p => !!p?.provingOutput).map(p => p!.provingOutput!); - if (baseParityProvingOutputs.length !== this.baseParityProofs.length) { - throw new Error('At lease one base parity is not ready.'); - } + /** + * The real-count message bundle this block appends: the block's own message slice, inserted at + * compact indices and absorbed into its block-root message sponge. + */ + #getMessageBundle(): L1ToL2MessageBundle { + return this.l1ToL2Messages.length === 0 + ? L1ToL2MessageBundle.empty() + : makeL1ToL2MessageBundle(this.l1ToL2Messages); + } - const children = baseParityProvingOutputs.map(p => toProofData(p)); - return new ParityRootPrivateInputs(assertLength(children, NUM_BASE_PARITY_PER_ROOT_PARITY)); + /** + * Full-height frontier hint for the bundle append: the left-sibling path at the block's compact start index, which + * the block-root circuit re-hashes against its start snapshot root. + */ + #getFrontierHint(): Tuple { + return this.l1ToL2MessageFrontierHint; } // Returns a specific transaction proving state @@ -413,15 +451,11 @@ export class BlockProvingState { return !!this.baseOrMergeProofs.getSibling(location)?.provingOutput; } - // Returns true if we have sufficient inputs to execute the block root rollup + // Returns true if we have sufficient inputs to execute the block root rollup. Parity no longer gates the block root + // (it moved to the checkpoint root), so the block root is ready once its child tx proofs land. public isReadyForBlockRootRollup() { const childProofs = this.#getChildProvingOutputsForBlockRoot(); - return (!this.isFirstBlock || !!this.rootParityProof?.provingOutput) && childProofs.every(p => !!p); - } - - // Returns true if we have sufficient root parity inputs to execute the root parity circuit - public isReadyForRootParity() { - return this.baseParityProofs.every(p => !!p?.provingOutput); + return childProofs.every(p => !!p); } public isComplete() { diff --git a/yarn-project/prover-client/src/orchestrator/checkpoint-proving-state.ts b/yarn-project/prover-client/src/orchestrator/checkpoint-proving-state.ts index af04c8ebd55d..98d3d9946ac3 100644 --- a/yarn-project/prover-client/src/orchestrator/checkpoint-proving-state.ts +++ b/yarn-project/prover-client/src/orchestrator/checkpoint-proving-state.ts @@ -1,20 +1,20 @@ import { SpongeBlob } from '@aztec/blob-lib'; -import { - type ARCHIVE_HEIGHT, - type L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, - NUM_MSGS_PER_BASE_PARITY, +import type { + ARCHIVE_HEIGHT, + L1_TO_L2_MSG_TREE_HEIGHT, + NESTED_RECURSIVE_PROOF_LENGTH, + NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; -import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { Tuple } from '@aztec/foundation/serialize'; import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees'; import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server'; -import { ParityBasePrivateInputs } from '@aztec/stdlib/parity'; +import { L1ToL2MessageSponge } from '@aztec/stdlib/messaging'; +import { InboxParityPrivateInputs, type ParityPublicInputs } from '@aztec/stdlib/parity'; import { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, CheckpointConstantData } from '@aztec/stdlib/rollup'; import type { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees'; -import type { BlockHeader } from '@aztec/stdlib/tx'; +import type { BlockHeader, StateReference } from '@aztec/stdlib/tx'; import type { UInt64 } from '@aztec/stdlib/types'; import { toProofData } from './block-building-helpers.js'; @@ -24,6 +24,10 @@ export class CheckpointProvingState { private blockProofs: UnbalancedTreeStore< ProofState >; + // The checkpoint's single InboxParity proof. Parity gates the checkpoint root, not the first block root: one + // variable-size proof per checkpoint replaces the former base + root parity fan-in. Surfaced as part of the + // sub-tree result. + private inboxParityProof: ProofState | undefined; private blocks: (BlockProvingState | undefined)[] = []; private error: string | undefined; public readonly firstBlockNumber: BlockNumber; @@ -35,18 +39,9 @@ export class CheckpointProvingState { private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader, private readonly lastArchiveSiblingPath: Tuple, private readonly l1ToL2Messages: Fr[], - // The snapshot and sibling path before the new l1 to l2 message subtree is inserted. - private readonly lastL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, - private readonly lastL1ToL2MessageSubtreeRootSiblingPath: Tuple< - Fr, - typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH - >, - // The snapshot and sibling path after the new l1 to l2 message subtree is inserted. - private readonly newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, - private readonly newL1ToL2MessageSubtreeRootSiblingPath: Tuple< - Fr, - typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH - >, + // Inbox rolling hash before this checkpoint's messages (the previous checkpoint's end value; genesis is zero). + // Threaded into the InboxParity circuit so the resulting checkpoint header rolling hash matches the proposer's. + private readonly startInboxRollingHash: Fr, public readonly epochNumber: number, /** Owner's liveness check. `verifyState()` returns false once this returns false. */ private readonly isAlive: () => boolean, @@ -57,26 +52,32 @@ export class CheckpointProvingState { this.firstBlockNumber = BlockNumber(headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1); } - public startNewBlock( + /** The checkpoint's real L1-to-L2 messages (unpadded), consumed across its blocks. */ + public getL1ToL2Messages(): Fr[] { + return this.l1ToL2Messages; + } + + public async startNewBlock( blockNumber: BlockNumber, timestamp: UInt64, totalNumTxs: number, lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot, lastArchiveSiblingPath: Tuple, - ): BlockProvingState { + // The full state reference of the previous block (before this block's message bundle is appended). Feeds the + // msgs-only block root, whose zero-tx block carries no tx constants to pin the previous state. + previousState: StateReference, + // Per-block L1-to-L2 message state: the block's start snapshot (its parent's end), its own + // post-bundle end snapshot, the full-height frontier at the start index, and its own real message slice. + startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + endL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + l1ToL2MessageFrontierHint: Tuple, + l1ToL2Messages: Fr[], + ): Promise { const index = Number(blockNumber) - Number(this.firstBlockNumber); if (index >= this.totalNumBlocks) { throw new Error(`Unable to start a new block at index ${index}. Expected at most ${this.totalNumBlocks} blocks.`); } - // If this is the first block, we use the snapshot and sibling path before the new l1 to l2 messages are inserted. - // Otherwise, we use the snapshot and sibling path after the new l1 to l2 messages are inserted, which will always - // happen in the first block. - const lastL1ToL2MessageTreeSnapshot = - index === 0 ? this.lastL1ToL2MessageTreeSnapshot : this.newL1ToL2MessageTreeSnapshot; - const lastL1ToL2MessageSubtreeRootSiblingPath = - index === 0 ? this.lastL1ToL2MessageSubtreeRootSiblingPath : this.newL1ToL2MessageSubtreeRootSiblingPath; - const startSpongeBlob = index === 0 ? SpongeBlob.init() : this.blocks[index - 1]?.getEndSpongeBlob(); if (!startSpongeBlob) { throw new Error( @@ -84,6 +85,19 @@ export class CheckpointProvingState { ); } + // Thread the message sponge across the checkpoint's blocks: each block starts from the + // previous block's end sponge (empty for the first block) and absorbs its own real slice. The block merge and + // checkpoint root circuits assert exactly this continuity (`right.start_msg_sponge == left.end_msg_sponge`, first + // block starts empty, merged end equals the InboxParity sponge), so the end sponge is computed eagerly here for + // the next block to inherit. Blocks must therefore be started in order, which the sequential per-block message + // appends already require. + const startMsgSponge = index === 0 ? L1ToL2MessageSponge.empty() : this.blocks[index - 1]?.getEndMsgSponge(); + if (!startMsgSponge) { + throw new Error('Cannot start a new block before the previous block in the checkpoint has been started.'); + } + const endMsgSponge = startMsgSponge.clone(); + await endMsgSponge.absorb(l1ToL2Messages); + const block = new BlockProvingState( index, blockNumber, @@ -92,9 +106,13 @@ export class CheckpointProvingState { timestamp, lastArchiveTreeSnapshot, lastArchiveSiblingPath, - lastL1ToL2MessageTreeSnapshot, - lastL1ToL2MessageSubtreeRootSiblingPath, - this.newL1ToL2MessageTreeSnapshot, + previousState, + startL1ToL2MessageTreeSnapshot, + endL1ToL2MessageTreeSnapshot, + l1ToL2MessageFrontierHint, + l1ToL2Messages, + startMsgSponge, + endMsgSponge, this.headerOfLastBlockInPreviousCheckpoint, startSpongeBlob, this, @@ -138,16 +156,37 @@ export class CheckpointProvingState { this.blockProofs.setNode(location, { provingOutput }); } - public getBaseParityInputs(baseParityIndex: number) { - const messages = padArrayEnd( - this.l1ToL2Messages.slice( - baseParityIndex * NUM_MSGS_PER_BASE_PARITY, - (baseParityIndex + 1) * NUM_MSGS_PER_BASE_PARITY, - ), - Fr.ZERO, - NUM_MSGS_PER_BASE_PARITY, + // ---------------- inbox parity proof orchestration ---------------- + + /** + * Builds the checkpoint's single InboxParity input. The circuit is sized to the smallest ladder rung that fits the + * message count; the rolling hash starts from the previous checkpoint's end and the message sponge starts empty (it + * resets per checkpoint). + */ + public getInboxParityInputs(): InboxParityPrivateInputs { + return InboxParityPrivateInputs.fromMessages( + this.l1ToL2Messages, + this.startInboxRollingHash, + L1ToL2MessageSponge.empty(), + this.constants.vkTreeRoot, + this.constants.proverId, ); - return new ParityBasePrivateInputs(messages, this.constants.vkTreeRoot, this.constants.proverId); + } + + public tryStartProvingInboxParity() { + if (this.inboxParityProof?.isProving) { + return false; + } + this.inboxParityProof = { isProving: true }; + return true; + } + + public setInboxParityProof(provingOutput: PublicInputsAndRecursiveProof) { + this.inboxParityProof = { provingOutput }; + } + + public getInboxParityProof() { + return this.inboxParityProof?.provingOutput; } public getParentLocation(location: TreeNodeLocation) { diff --git a/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.test.ts b/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.test.ts index e0b48d2559b6..554a8754cbc9 100644 --- a/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.test.ts +++ b/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.test.ts @@ -1,9 +1,10 @@ import { MAX_L2_TO_L1_MSGS_PER_TX } from '@aztec/constants'; import { EpochNumber } from '@aztec/foundation/branded-types'; -import { padArrayEnd } from '@aztec/foundation/collection'; +import { padArrayEnd, sum } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { createLogger } from '@aztec/foundation/log'; -import { ScopedL2ToL1Message, computeBlockOutHash } from '@aztec/stdlib/messaging'; +import { L1ToL2MessageSponge, ScopedL2ToL1Message, computeBlockOutHash } from '@aztec/stdlib/messaging'; import { makeScopedL2ToL1Message } from '@aztec/stdlib/testing'; import { TestContext, makeTestDeferredJobQueue } from '../mocks/test_context.js'; @@ -50,15 +51,16 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { makeTestDeferredJobQueue(), constants, l1ToL2Messages, + Fr.ZERO, numBlocks, previousBlockHeader, ); try { const resultPromise = subTree.getSubTreeResult(); - for (const block of blocks) { + for (const [blockIndex, block] of blocks.entries()) { const { blockNumber, timestamp } = block.header.globalVariables; - await subTree.startNewBlock(blockNumber, timestamp, block.txs.length); + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, blockIndex === 0 ? l1ToL2Messages : []); if (block.txs.length > 0) { await subTree.addTxs(block.txs); } @@ -68,6 +70,10 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { const result = await resultPromise; expect(result.blockProofOutputs).toHaveLength(1); expect(result.blockProofOutputs[0].proof).toBeDefined(); + // Parity gates the checkpoint root: the sub-tree proves it once per checkpoint and surfaces it for the top tree + // to feed into the checkpoint root rollup. + expect(result.inboxParityProof).toBeDefined(); + expect(result.inboxParityProof.proof).toBeDefined(); expect(result.previousArchiveSiblingPath).toBeDefined(); } finally { await subTree.stop(); @@ -91,15 +97,16 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { makeTestDeferredJobQueue(), constants, l1ToL2Messages, + Fr.ZERO, numBlocks, previousBlockHeader, ); try { const resultPromise = subTree.getSubTreeResult(); - for (const block of blocks) { + for (const [blockIndex, block] of blocks.entries()) { const { blockNumber, timestamp } = block.header.globalVariables; - await subTree.startNewBlock(blockNumber, timestamp, block.txs.length); + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, blockIndex === 0 ? l1ToL2Messages : []); if (block.txs.length > 0) { await subTree.addTxs(block.txs); } @@ -108,6 +115,8 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { const result = await resultPromise; expect(result.blockProofOutputs).toHaveLength(2); + // A single parity root proof covers the whole checkpoint, regardless of block count. + expect(result.inboxParityProof).toBeDefined(); } finally { await subTree.stop(); } @@ -133,15 +142,16 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { makeTestDeferredJobQueue(), constants, l1ToL2Messages, + Fr.ZERO, numBlocks, previousBlockHeader, ); try { const resultPromise = subTree.getSubTreeResult(); - for (const block of blocks) { + for (const [blockIndex, block] of blocks.entries()) { const { blockNumber, timestamp } = block.header.globalVariables; - await subTree.startNewBlock(blockNumber, timestamp, block.txs.length); + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, blockIndex === 0 ? l1ToL2Messages : []); if (block.txs.length > 0) { await subTree.addTxs(block.txs); } @@ -180,15 +190,16 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { makeTestDeferredJobQueue(), constants, l1ToL2Messages, + Fr.ZERO, numBlocks, previousBlockHeader, ); try { const resultPromise = subTree.getSubTreeResult(); - for (const block of blocks) { + for (const [blockIndex, block] of blocks.entries()) { const { blockNumber, timestamp } = block.header.globalVariables; - await subTree.startNewBlock(blockNumber, timestamp, block.txs.length); + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, blockIndex === 0 ? l1ToL2Messages : []); if (block.txs.length > 0) { await subTree.addTxs(block.txs); } @@ -208,4 +219,98 @@ describe('prover/orchestrator/checkpoint-sub-tree', () => { await subTree.stop(); } }); + + it('slices L1-to-L2 messages per block across a multi-block checkpoint', async () => { + // A checkpoint whose messages span more than one block: the first block carries a bundle, a middle block + // carries none (txs only), and the last block carries a bundle with zero txs (a message-only block, proven by + // the msgs-only block root). The sub-tree must append each block's own slice at compact indices with + // contiguous, non-overlapping per-block snapshots, and thread the message sponge across the blocks. + // The sub-tree result surfaces post-merge top-level nodes (at most two, for the binary + // checkpoint root), not one output per block. + const l1ToL2MessagesPerBlock = [[new Fr(1001), new Fr(1002)], [], [new Fr(1003), new Fr(1004), new Fr(1005)]]; + const numBlocks = l1ToL2MessagesPerBlock.length; + const { constants, blocks, l1ToL2Messages, previousBlockHeader } = await context.makeCheckpointWithMessagesPerBlock( + l1ToL2MessagesPerBlock, + { numTxsPerBlock: [1, 1, 0] }, + ); + expect(l1ToL2Messages.length).toBe(5); + + const subTree = await CheckpointSubTreeOrchestrator.start( + context.worldState, + context.prover, + EthAddress.ZERO, + chonkCache, + EpochNumber(1), + false, + makeTestDeferredJobQueue(), + constants, + l1ToL2Messages, + Fr.ZERO, + numBlocks, + previousBlockHeader, + ); + try { + const resultPromise = subTree.getSubTreeResult(); + + for (const [blockIndex, block] of blocks.entries()) { + const { blockNumber, timestamp } = block.header.globalVariables; + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, l1ToL2MessagesPerBlock[blockIndex]); + if (block.txs.length > 0) { + await subTree.addTxs(block.txs); + } + await subTree.setBlockCompleted(blockNumber, block.header); + } + + const result = await resultPromise; + // Three block roots reduce to two top-level outputs: a block-merge over blocks 0-1 and block 2's msgs-only + // root. Merge public inputs span their range: is_first_block propagates from the left child, the start + // sponge/state come from the left child and the end sponge/state from the right. + const expectedOutputBlockRanges = [[0, 1], [2]]; + expect(result.blockProofOutputs).toHaveLength(expectedOutputBlockRanges.length); + + // Order the outputs by position in the checkpoint (the archive tree grows by one leaf per block). + const ordered = [...result.blockProofOutputs].sort( + (a, b) => a.inputs.previousArchive.nextAvailableLeafIndex - b.inputs.previousArchive.nextAvailableLeafIndex, + ); + + // Walk the outputs in order, asserting the L1-to-L2 message tree partitions cleanly into per-output slices, + // with each output's start snapshot equal to the previous output's end snapshot (the "threaded" per-block + // L1-to-L2 tree state). + const baseLeaf = ordered[0].inputs.startState.l1ToL2MessageTree.nextAvailableLeafIndex; + let expectedStartLeaf = baseLeaf; + // The message sponge threads across the checkpoint's blocks: the first block starts from the empty sponge and + // each block absorbs exactly its own slice (the block merge and checkpoint root circuits assert this + // continuity against the InboxParity sponge). + const expectedSponge = L1ToL2MessageSponge.empty(); + for (const [i, output] of ordered.entries()) { + const inputs = output.inputs; + const blockIndexes = expectedOutputBlockRanges[i]; + const startLeaf = inputs.startState.l1ToL2MessageTree.nextAvailableLeafIndex; + const endLeaf = inputs.endState.l1ToL2MessageTree.nextAvailableLeafIndex; + const sliceLen = sum(blockIndexes.map(b => l1ToL2MessagesPerBlock[b].length)); + + // Only the output covering the checkpoint's first block flags isFirstBlock. + expect(inputs.isFirstBlock).toBe(blockIndexes.includes(0)); + // Contiguous, non-overlapping slices: this output starts where the previous one ended (no gap/overlap). + expect(startLeaf).toBe(expectedStartLeaf); + // The tree grows by exactly the covered blocks' bundle sizes. + expect(endLeaf - startLeaf).toBe(sliceLen); + expectedStartLeaf = endLeaf; + + // Sponge continuity: this output starts from the previous one's end sponge and absorbs its blocks' slices. + expect(inputs.startMsgSponge.toBuffer()).toEqual(expectedSponge.toBuffer()); + for (const blockIndex of blockIndexes) { + await expectedSponge.absorb(l1ToL2MessagesPerBlock[blockIndex]); + } + expect(inputs.endMsgSponge.toBuffer()).toEqual(expectedSponge.toBuffer()); + } + + // Every message is accounted for with no gap or overlap across the checkpoint's blocks. + expect(expectedStartLeaf - baseLeaf).toBe(l1ToL2Messages.length); + // The last block's end sponge equals the checkpoint's InboxParity end sponge. + expect(result.inboxParityProof.inputs.endSponge.toBuffer()).toEqual(expectedSponge.toBuffer()); + } finally { + await subTree.stop(); + } + }); }); diff --git a/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.ts b/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.ts index c3d0c0e39806..21fe9ec47c81 100644 --- a/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/checkpoint-sub-tree-orchestrator.ts @@ -1,10 +1,8 @@ import type { SpongeBlob } from '@aztec/blob-lib/types'; import { type ARCHIVE_HEIGHT, - L1_TO_L2_MSG_SUBTREE_HEIGHT, - L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, + L1_TO_L2_MSG_TREE_HEIGHT, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, - NUM_BASE_PARITY_PER_ROOT_PARITY, } from '@aztec/constants'; import { BlockNumber, type EpochNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -23,13 +21,10 @@ import type { ServerCircuitProver, } from '@aztec/stdlib/interfaces/server'; import { appendL1ToL2MessagesToTree } from '@aztec/stdlib/messaging'; +import type { ParityPublicInputs } from '@aztec/stdlib/parity'; import { type BaseRollupHints, type BlockRollupPublicInputs, - BlockRootEmptyTxFirstRollupPrivateInputs, - BlockRootFirstRollupPrivateInputs, - BlockRootSingleTxFirstRollupPrivateInputs, - BlockRootSingleTxRollupPrivateInputs, CheckpointConstantData, PrivateTxBaseRollupPrivateInputs, type PublicChonkVerifierPublicInputs, @@ -51,10 +46,10 @@ import { inspect } from 'util'; import { buildHeaderFromCircuitOutputs, + getFrontierSiblingPath, getLastSiblingPath, getPublicChonkVerifierPrivateInputsFromTx, getRootTreeSiblingPath, - getSubtreeSiblingPath, getTreeSnapshot, insertSideEffectsAndBuildBaseRollupHints, validatePartialState, @@ -79,9 +74,20 @@ export type SubTreeResult = { BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH >[]; + /** + * The checkpoint's single InboxParity proof. Parity gates the checkpoint root rather than the first block root, so + * the sub-tree proves it and hands it to the top tree, which feeds it into the checkpoint root rollup. + */ + inboxParityProof: PublicInputsAndRecursiveProof; previousArchiveSiblingPath: Tuple; }; +/** + * The proofs a checkpoint's sub-tree hands to the top tree: the per-block rollup proofs plus the checkpoint's single + * variable-size InboxParity proof. + */ +export type CheckpointSubTreeProofs = Pick; + type TreeSnapshots = Map; /** @@ -192,6 +198,7 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { deferredJobQueue: SerialQueue, checkpointConstants: CheckpointConstantData, l1ToL2Messages: Fr[], + startInboxRollingHash: Fr, totalNumBlocks: number, headerOfLastBlockInPreviousCheckpoint: BlockHeader, telemetryClient: TelemetryClient = getTelemetryClient(), @@ -212,6 +219,7 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { await subTree.startCheckpoint( checkpointConstants, l1ToL2Messages, + startInboxRollingHash, totalNumBlocks, headerOfLastBlockInPreviousCheckpoint, ); @@ -256,7 +264,7 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { @trackSpan('CheckpointSubTreeOrchestrator.startNewBlock', blockNumber => ({ [Attributes.BLOCK_NUMBER]: blockNumber, })) - public async startNewBlock(blockNumber: BlockNumber, timestamp: UInt64, totalNumTxs: number) { + public async startNewBlock(blockNumber: BlockNumber, timestamp: UInt64, totalNumTxs: number, l1ToL2Messages: Fr[]) { if (!this.provingState) { throw new Error('Empty proving state. The checkpoint sub-tree has not been started.'); } @@ -280,21 +288,33 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db); const lastArchiveSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE, db); - const blockProvingState = this.provingState.startNewBlock( + // The previous block's full state reference, captured before this block's message bundle is appended. Feeds the + // msgs-only block root, whose zero-tx block carries no tx constants to pin the previous state. + const previousState = await db.getStateReference(); + + // Streaming Inbox: insert this block's own real message slice at compact indices, capturing + // the start snapshot + full-height frontier before the append and the block's own post-bundle end snapshot after. + const startL1ToL2Snapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db); + const l1ToL2FrontierHint = assertLength( + await getFrontierSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db), + L1_TO_L2_MSG_TREE_HEIGHT, + ); + await appendL1ToL2MessagesToTree(db, l1ToL2Messages); + const endL1ToL2Snapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db); + + const blockProvingState = await this.provingState.startNewBlock( blockNumber, timestamp, totalNumTxs, lastArchiveTreeSnapshot, lastArchiveSiblingPath, + previousState, + startL1ToL2Snapshot, + endL1ToL2Snapshot, + l1ToL2FrontierHint, + l1ToL2Messages, ); - // Enqueue base parity circuits for the first block in the checkpoint. - if (blockProvingState.index === 0) { - for (let i = 0; i < NUM_BASE_PARITY_PER_ROOT_PARITY; i++) { - this.enqueueBaseParityCircuit(this.provingState, blockProvingState, i); - } - } - // Because `addTxs` won't be called for a block without txs, and that's where the sponge blob state is computed, // set its end sponge blob here. This becomes the start sponge blob for the next block. if (totalNumTxs === 0) { @@ -305,6 +325,12 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { const blockEndBlobFields = blockProvingState.getBlockEndBlobFields(); await endSpongeBlob.absorb(blockEndBlobFields); blockProvingState.setEndSpongeBlob(endSpongeBlob); + + // A block with no txs has no base or merge proof whose completion would enqueue its block root, + // and parity now gates the checkpoint root rather than the first block root, so no other callback + // fires it. Enqueue it here. This drives the empty-tx first block root, or the msgs-only block root + // for a non-first zero-tx block carrying a message bundle. + this.checkAndEnqueueBlockRootRollup(blockProvingState); } } @@ -493,6 +519,7 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { private async startCheckpoint( constants: CheckpointConstantData, l1ToL2Messages: Fr[], + startInboxRollingHash: Fr, totalNumBlocks: number, headerOfLastBlockInPreviousCheckpoint: BlockHeader, ): Promise { @@ -510,14 +537,9 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { // Get archive sibling path before any block in this checkpoint lands. const lastArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, db); - // Insert all the l1 to l2 messages into the db. Get the states before and after the insertion. - const { - lastL1ToL2MessageTreeSnapshot, - lastL1ToL2MessageSubtreeRootSiblingPath, - newL1ToL2MessageTreeSnapshot, - newL1ToL2MessageSubtreeRootSiblingPath, - } = await this.updateL1ToL2MessageTree(l1ToL2Messages, db); - + // Streaming Inbox: messages are inserted per block in `startNewBlock`, not the whole + // checkpoint up front. The message sponge is likewise threaded per block (each block's start sponge is the + // previous block's end), so the last block's end sponge matches the checkpoint's single InboxParity proof. this.provingState = new CheckpointProvingState( /* index */ 0, constants, @@ -525,42 +547,19 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { headerOfLastBlockInPreviousCheckpoint, lastArchiveSiblingPath, l1ToL2Messages, - lastL1ToL2MessageTreeSnapshot, - lastL1ToL2MessageSubtreeRootSiblingPath, - newL1ToL2MessageTreeSnapshot, - newL1ToL2MessageSubtreeRootSiblingPath, + startInboxRollingHash, Number(this.epochNumber), /* isAlive */ () => !this.cancelled, /* onReject */ reason => this.subTreeResult.reject(new Error(reason)), ); + + // Parity now gates the checkpoint root (not the first block root); prove the single sized InboxParity per + // checkpoint up front. + this.enqueueInboxParityCircuit(this.provingState); } // ---------------- private: per-block proof orchestration ---------------- - private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) { - const lastL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db); - const lastL1ToL2MessageSubtreeRootSiblingPath = assertLength( - await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db), - L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - ); - - // Update the local trees to include the new l1 to l2 messages. - await appendL1ToL2MessagesToTree(db, l1ToL2Messages); - - const newL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db); - const newL1ToL2MessageSubtreeRootSiblingPath = assertLength( - await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db), - L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, - ); - - return { - lastL1ToL2MessageTreeSnapshot, - lastL1ToL2MessageSubtreeRootSiblingPath, - newL1ToL2MessageTreeSnapshot, - newL1ToL2MessageSubtreeRootSiblingPath, - }; - } - // Updates the merkle trees for a transaction. The first enqueued job for a transaction. @trackSpan('CheckpointSubTreeOrchestrator.prepareBaseRollupInputs', tx => ({ [Attributes.TX_HASH]: tx.hash.toString(), @@ -730,7 +729,9 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { return; } - const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs(); + // Kept whole (not destructured) so the switch on the `rollupType` discriminant narrows `inputs` per case. + const rollup = provingState.getBlockRootRollupTypeAndInputs(); + const rollupType = rollup.rollupType; this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`); @@ -739,16 +740,19 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { this.wrapCircuitCall( 'getBlockRootRollupProof', signal => { - if (inputs instanceof BlockRootFirstRollupPrivateInputs) { - return this.prover.getBlockRootFirstRollupProof(inputs, signal, provingState.epochNumber); - } else if (inputs instanceof BlockRootSingleTxFirstRollupPrivateInputs) { - return this.prover.getBlockRootSingleTxFirstRollupProof(inputs, signal, provingState.epochNumber); - } else if (inputs instanceof BlockRootEmptyTxFirstRollupPrivateInputs) { - return this.prover.getBlockRootEmptyTxFirstRollupProof(inputs, signal, provingState.epochNumber); - } else if (inputs instanceof BlockRootSingleTxRollupPrivateInputs) { - return this.prover.getBlockRootSingleTxRollupProof(inputs, signal, provingState.epochNumber); - } else { - return this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber); + switch (rollup.rollupType) { + case 'rollup-block-root-first': + return this.prover.getBlockRootFirstRollupProof(rollup.inputs, signal, provingState.epochNumber); + case 'rollup-block-root-first-single-tx': + return this.prover.getBlockRootSingleTxFirstRollupProof(rollup.inputs, signal, provingState.epochNumber); + case 'rollup-block-root-first-empty-tx': + return this.prover.getBlockRootEmptyTxFirstRollupProof(rollup.inputs, signal, provingState.epochNumber); + case 'rollup-block-root-msgs-only': + return this.prover.getBlockRootMsgsOnlyRollupProof(rollup.inputs, signal, provingState.epochNumber); + case 'rollup-block-root-single-tx': + return this.prover.getBlockRootSingleTxRollupProof(rollup.inputs, signal, provingState.epochNumber); + case 'rollup-block-root': + return this.prover.getBlockRootRollupProof(rollup.inputs, signal, provingState.epochNumber); } }, { [Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType }, @@ -776,70 +780,32 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { ); } - // Executes the base parity circuit. Enqueues the root parity circuit if all inputs are available. - private enqueueBaseParityCircuit( - checkpointProvingState: CheckpointProvingState, - provingState: BlockProvingState, - baseParityIndex: number, - ) { - if (!provingState.verifyState()) { - this.logger.debug('Not running base parity. State no longer valid.'); + // Runs the checkpoint's single InboxParity circuit and stores the output. The proof feeds the checkpoint root (in + // the top tree), so completing it may resolve the sub-tree rather than a block root. + private enqueueInboxParityCircuit(checkpointProvingState: CheckpointProvingState) { + if (!checkpointProvingState.verifyState()) { + this.logger.debug('Not running inbox parity. State no longer valid.'); return; } - if (!provingState.tryStartProvingBaseParity(baseParityIndex)) { - this.logger.warn(`Base parity ${baseParityIndex} already started.`); + if (!checkpointProvingState.tryStartProvingInboxParity()) { + this.logger.debug('Inbox parity already started.'); return; } - const inputs = checkpointProvingState.getBaseParityInputs(baseParityIndex); + const inputs = checkpointProvingState.getInboxParityInputs(); + const circuitName = `inbox-parity-${inputs.size}` satisfies CircuitName; this.deferredProving( - provingState, + checkpointProvingState, this.wrapCircuitCall( - 'getBaseParityProof', - signal => this.prover.getBaseParityProof(inputs, signal, provingState.epochNumber), - { [Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-base' satisfies CircuitName }, - ), - provingOutput => { - provingState.setBaseParityProof(baseParityIndex, provingOutput); - this.checkAndEnqueueRootParityCircuit(provingState); - }, - ); - } - - private checkAndEnqueueRootParityCircuit(provingState: BlockProvingState) { - if (!provingState.isReadyForRootParity()) { - return; - } - this.enqueueRootParityCircuit(provingState); - } - - // Runs the root parity circuit and stores the outputs. - // Enqueues the block root rollup if all inputs are available. - private enqueueRootParityCircuit(provingState: BlockProvingState) { - if (!provingState.verifyState()) { - this.logger.debug('Not running root parity. State no longer valid.'); - return; - } - - if (!provingState.tryStartProvingRootParity()) { - this.logger.debug('Root parity already started.'); - return; - } - - const inputs = provingState.getParityRootInputs(); - - this.deferredProving( - provingState, - this.wrapCircuitCall( - 'getRootParityProof', - signal => this.prover.getRootParityProof(inputs, signal, provingState.epochNumber), - { [Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-root' satisfies CircuitName }, + 'getInboxParityProof', + signal => this.prover.getInboxParityProof(inputs, signal, checkpointProvingState.epochNumber), + { [Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName }, ), result => { - provingState.setRootParityProof(result); - this.checkAndEnqueueBlockRootRollup(provingState); + checkpointProvingState.setInboxParityProof(result); + this.checkAndEnqueueSubTreeResolution(checkpointProvingState); }, ); } @@ -923,8 +889,15 @@ export class CheckpointSubTreeOrchestrator extends ProvingScheduler { // Block merge tree not fully resolved yet — retried as more block proofs land. return; } + // The InboxParity proof gates the sub-tree result too (it feeds the checkpoint root in the top tree). + const inboxParityProof = provingState.getInboxParityProof(); + if (!inboxParityProof) { + // Parity not proven yet — retried when the inbox parity proof lands. + return; + } this.subTreeResult.resolve({ blockProofOutputs: nonEmpty, + inboxParityProof, previousArchiveSiblingPath: provingState.getLastArchiveSiblingPath(), }); } diff --git a/yarn-project/prover-client/src/orchestrator/index.ts b/yarn-project/prover-client/src/orchestrator/index.ts index 9fe9f502a7be..f2585a33f1a7 100644 --- a/yarn-project/prover-client/src/orchestrator/index.ts +++ b/yarn-project/prover-client/src/orchestrator/index.ts @@ -1,4 +1,8 @@ -export { CheckpointSubTreeOrchestrator, type SubTreeResult } from './checkpoint-sub-tree-orchestrator.js'; +export { + CheckpointSubTreeOrchestrator, + type CheckpointSubTreeProofs, + type SubTreeResult, +} from './checkpoint-sub-tree-orchestrator.js'; export { ChonkCache, type ChonkVerifierProofResult } from './chonk-cache.js'; export { TopTreeOrchestrator, diff --git a/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.test.ts b/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.test.ts index 9be914f034b2..1d7e8aab5805 100644 --- a/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.test.ts +++ b/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.test.ts @@ -1,12 +1,13 @@ import { MAX_L2_TO_L1_MSGS_PER_TX } from '@aztec/constants'; import { EpochNumber } from '@aztec/foundation/branded-types'; import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { createLogger } from '@aztec/foundation/log'; import { promiseWithResolvers } from '@aztec/foundation/promise'; import { retryUntil } from '@aztec/foundation/retry'; import { sleep } from '@aztec/foundation/sleep'; -import { ScopedL2ToL1Message, computeEpochOutHash } from '@aztec/stdlib/messaging'; +import { ScopedL2ToL1Message, accumulateInboxRollingHash, computeEpochOutHash } from '@aztec/stdlib/messaging'; import { makeScopedL2ToL1Message } from '@aztec/stdlib/testing'; import { TestContext, makeTestDeferredJobQueue } from '../mocks/test_context.js'; @@ -41,20 +42,14 @@ describe('prover/orchestrator/top-tree', () => { await context.cleanup(); }); + /** The checkpoint fixture shape shared by `makeCheckpoint` and `makeCheckpointWithMessagesPerBlock`. */ + type CheckpointFixture = Awaited>; + /** - * Drives a single checkpoint through `CheckpointSubTreeOrchestrator` and returns - * the assembled `CheckpointTopTreeData` plus the originating checkpoint metadata. + * Drives a checkpoint fixture through `CheckpointSubTreeOrchestrator`, feeding block `i` the message slice + * `messagesPerBlock[i]`, and returns the assembled `CheckpointTopTreeData` plus the originating fixture. */ - async function driveSubTree(numBlocks: number, numTxsPerBlock: number, numL1ToL2Messages = 0, numL2ToL1Messages = 0) { - const fixture = await context.makeCheckpoint(numBlocks, { - numTxsPerBlock, - numL1ToL2Messages, - makeProcessedTxOpts: - numL2ToL1Messages > 0 - ? () => ({ privateOnly: false, avmAccumulatedData: { l2ToL1Msgs: makeL2ToL1Messages(numL2ToL1Messages) } }) - : undefined, - }); - + async function driveFixture(fixture: CheckpointFixture, messagesPerBlock: Fr[][]) { const subTree = await CheckpointSubTreeOrchestrator.start( context.worldState, context.prover, @@ -65,14 +60,15 @@ describe('prover/orchestrator/top-tree', () => { makeTestDeferredJobQueue(), fixture.constants, fixture.l1ToL2Messages, - numBlocks, + fixture.startInboxRollingHash, + fixture.blocks.length, fixture.previousBlockHeader, ); const resultPromise = subTree.getSubTreeResult(); - for (const block of fixture.blocks) { + for (const [blockIndex, block] of fixture.blocks.entries()) { const { blockNumber, timestamp } = block.header.globalVariables; - await subTree.startNewBlock(blockNumber, timestamp, block.txs.length); + await subTree.startNewBlock(blockNumber, timestamp, block.txs.length, messagesPerBlock[blockIndex]); if (block.txs.length > 0) { await subTree.addTxs(block.txs); } @@ -83,7 +79,10 @@ describe('prover/orchestrator/top-tree', () => { await subTree.stop(); const topTreeData: CheckpointTopTreeData = { - blockProofs: Promise.resolve(result.blockProofOutputs), + subTreeProofs: Promise.resolve({ + blockProofOutputs: result.blockProofOutputs, + inboxParityProof: result.inboxParityProof, + }), l2ToL1MsgsPerBlock: fixture.blocks.map(b => b.txs.map(tx => tx.txEffect.l2ToL1Msgs)), blobFields: fixture.checkpoint.toBlobFields(), previousBlockHeader: fixture.previousBlockHeader, @@ -93,6 +92,33 @@ describe('prover/orchestrator/top-tree', () => { return { fixture, topTreeData }; } + /** + * Builds a checkpoint via `makeCheckpoint` (every message in the first block) and drives it through + * `CheckpointSubTreeOrchestrator`, returning the assembled `CheckpointTopTreeData` plus the fixture. + */ + async function driveSubTree(numBlocks: number, numTxsPerBlock: number, numL1ToL2Messages = 0, numL2ToL1Messages = 0) { + const fixture = await context.makeCheckpoint(numBlocks, { + numTxsPerBlock, + numL1ToL2Messages, + makeProcessedTxOpts: + numL2ToL1Messages > 0 + ? () => ({ privateOnly: false, avmAccumulatedData: { l2ToL1Msgs: makeL2ToL1Messages(numL2ToL1Messages) } }) + : undefined, + }); + const messagesPerBlock = fixture.blocks.map((_, i) => (i === 0 ? fixture.l1ToL2Messages : [])); + return await driveFixture(fixture, messagesPerBlock); + } + + /** + * Like {@link driveSubTree} but distributes the checkpoint's messages across its blocks (streaming Inbox): + * block `i` carries `l1ToL2MessagesPerBlock[i]` as its own slice. A zero-tx entry in `numTxsPerBlock` + * whose slice is non-empty produces a message-only block, proven by the msgs-only block root. + */ + async function driveSubTreeWithMessageSlices(l1ToL2MessagesPerBlock: Fr[][], numTxsPerBlock: number[]) { + const fixture = await context.makeCheckpointWithMessagesPerBlock(l1ToL2MessagesPerBlock, { numTxsPerBlock }); + return await driveFixture(fixture, l1ToL2MessagesPerBlock); + } + it('produces an epoch proof for a single-checkpoint, single-block, single-tx epoch', async () => { const { topTreeData } = await driveSubTree(1, 1); const challenges = await context.getFinalBlobChallenges(); @@ -159,15 +185,48 @@ describe('prover/orchestrator/top-tree', () => { } }); + it('produces an epoch proof when messages span blocks, including a message-only block', async () => { + // The streaming Inbox shapes, driven through the entire proving DAG at simulated-circuit + // fidelity: a checkpoint whose messages land in a non-first block, a zero-tx message-only block (proven by the + // msgs-only block root), a block merge above the three block roots, the two-input checkpoint root over per-block + // bundles, the single-block checkpoint root for the follow-on checkpoints, the checkpoint merge asserting inbox + // rolling-hash continuity across a message-carrying boundary, and the root rollup exposing the epoch's + // rolling-hash range. + const ckpt1Slices = [[new Fr(0x100), new Fr(0x101)], [], [new Fr(0x102), new Fr(0x103), new Fr(0x104)]]; + const a = await driveSubTreeWithMessageSlices(ckpt1Slices, [1, 1, 0]); + // A single-block checkpoint with messages after a message-carrying checkpoint: its parity chain starts from + // checkpoint 0's (non-zero) end rolling hash. + const b = await driveSubTree(1, 1, 2); + // A message-less checkpoint after message-carrying ones: the rolling hash must pass through unchanged. + const c = await driveSubTree(1, 1); + const challenges = await context.getFinalBlobChallenges(); + + const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); + try { + const result = await topTree.prove(EpochNumber(1), 3, challenges, [a.topTreeData, b.topTreeData, c.topTreeData]); + expect(result.proof).toBeDefined(); + expect(result.publicInputs).toBeDefined(); + + // The epoch's rolling-hash range binds the exact message sequence consumed, in block order, across all three + // checkpoints; L1 validates this range against the Inbox when the proof lands. + const epochMessages = [...a.fixture.l1ToL2Messages, ...b.fixture.l1ToL2Messages]; + expect(epochMessages.length).toBe(7); // sanity: the fixtures really did carry messages + expect(result.publicInputs.previousInboxRollingHash).toEqual(Fr.ZERO); + expect(result.publicInputs.endInboxRollingHash).toEqual(accumulateInboxRollingHash(Fr.ZERO, epochMessages)); + } finally { + await topTree.stop(); + } + }, 300_000); + it('pipelines: starts ckpt0 root rollup before ckpt1 sub-tree resolves', async () => { // Drive both sub-trees synchronously (still no top tree running). const a = await driveSubTree(1, 1); const b = await driveSubTree(1, 1); const challenges = await context.getFinalBlobChallenges(); - // Replace ckpt1's blockProofs with a deferred promise that resolves later. - const deferred = promiseWithResolvers ? T : never>(); - const ckpt1 = { ...b.topTreeData, blockProofs: deferred.promise } as CheckpointTopTreeData; + // Replace ckpt1's subTreeProofs with a deferred promise that resolves later. + const deferred = promiseWithResolvers ? T : never>(); + const ckpt1 = { ...b.topTreeData, subTreeProofs: deferred.promise } as CheckpointTopTreeData; const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); try { @@ -179,7 +238,7 @@ describe('prover/orchestrator/top-tree', () => { await new Promise(resolve => setTimeout(resolve, 50)); // Now resolve ckpt1 — the orchestrator should pick it up and continue. - deferred.resolve((await b.topTreeData.blockProofs) as any); + deferred.resolve((await b.topTreeData.subTreeProofs) as any); const result = await provePromise; expect(result.proof).toBeDefined(); @@ -192,9 +251,9 @@ describe('prover/orchestrator/top-tree', () => { const { topTreeData } = await driveSubTree(1, 1); const challenges = await context.getFinalBlobChallenges(); - // Block ckpt0's blockProofs forever so prove() can't finish. - const stuck = new Promise ? T : never>(() => {}); - const stuckData = { ...topTreeData, blockProofs: stuck } as CheckpointTopTreeData; + // Block ckpt0's subTreeProofs forever so prove() can't finish. + const stuck = new Promise ? T : never>(() => {}); + const stuckData = { ...topTreeData, subTreeProofs: stuck } as CheckpointTopTreeData; const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); const provePromise = topTree.prove(EpochNumber(1), 1, challenges, [stuckData]); @@ -251,7 +310,10 @@ describe('prover/orchestrator/top-tree', () => { const challenges = await context.getFinalBlobChallenges(); // A malformed block proof makes toProofData (inside buildCheckpointRootInputs) throw. - const badData = { ...topTreeData, blockProofs: Promise.resolve([{} as any]) } as CheckpointTopTreeData; + const badData = { + ...topTreeData, + subTreeProofs: Promise.resolve({ blockProofOutputs: [{} as any], inboxParityProof: {} as any }), + } as CheckpointTopTreeData; const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); try { @@ -280,23 +342,23 @@ describe('prover/orchestrator/top-tree', () => { const { topTreeData } = await driveSubTree(1, 1); const challenges = await context.getFinalBlobChallenges(); - const deferred = promiseWithResolvers ? T : never>(); - // Observe exactly when prove() attaches its blockProofs handler, so we can sequence the + const deferred = promiseWithResolvers ? T : never>(); + // Observe exactly when prove() attaches its subTreeProofs handler, so we can sequence the // genuine rejection and the cancel deterministically rather than racing a fixed timeout. let handlerAttached = false; - const observableBlockProofs = { + const observableSubTreeProofs = { then: (onF: any, onR: any) => { handlerAttached = true; return deferred.promise.then(onF, onR); }, }; - const failingData = { ...topTreeData, blockProofs: observableBlockProofs as any } as CheckpointTopTreeData; + const failingData = { ...topTreeData, subTreeProofs: observableSubTreeProofs as any } as CheckpointTopTreeData; const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); const provePromise = topTree.prove(EpochNumber(1), 1, challenges, [failingData]); - // Wait until prove() has finished its pre-loop setup and registered the blockProofs handler. - await retryUntil(() => handlerAttached, 'prove() attaches blockProofs handler', 5, 0.005); + // Wait until prove() has finished its pre-loop setup and registered the subTreeProofs handler. + await retryUntil(() => handlerAttached, 'prove() attaches subTreeProofs handler', 5, 0.005); // Register a cancel reaction on the rejection, after prove()'s own handler (registered // first, so it runs first). On rejection the ordering is: prove's handler rejects the diff --git a/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.ts b/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.ts index 5c3d9e66bc39..eccd4340328f 100644 --- a/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/top-tree-orchestrator.ts @@ -19,6 +19,7 @@ import { MerkleTreeCalculator, type TreeNodeLocation, shaMerkleHash } from '@azt import type { EthAddress } from '@aztec/stdlib/block'; import type { PublicInputsAndRecursiveProof, ServerCircuitProver } from '@aztec/stdlib/interfaces/server'; import { computeCheckpointOutHash } from '@aztec/stdlib/messaging'; +import type { ParityPublicInputs } from '@aztec/stdlib/parity'; import type { Proof } from '@aztec/stdlib/proofs'; import { type BlockRollupPublicInputs, @@ -32,19 +33,18 @@ import type { BlockHeader } from '@aztec/stdlib/tx'; import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client'; import { buildBlobHints, toProofData } from './block-building-helpers.js'; +import type { CheckpointSubTreeProofs } from './checkpoint-sub-tree-orchestrator.js'; import { ProvingScheduler } from './proving-scheduler.js'; import { TopTreeProvingState } from './top-tree-proving-state.js'; /** Per-checkpoint data fed into the top tree. */ export type CheckpointTopTreeData = { /** - * Block-rollup proof outputs from the checkpoint's sub-tree. Passed as a Promise so the - * top tree can start (compute hints, pipeline merges) while sub-trees are still proving. - * The promise resolves to 1 entry for a single-block checkpoint, 2 for multi-block. + * The checkpoint sub-tree's proofs. Passed as a Promise so the top tree can start (compute hints, pipeline merges) + * while sub-trees are still proving. `blockProofOutputs` resolves to 1 entry for a single-block checkpoint, 2 for + * multi-block; `inboxParityProof` feeds the checkpoint root rollup. */ - blockProofs: Promise< - PublicInputsAndRecursiveProof[] - >; + subTreeProofs: Promise; /** L2-to-L1 messages per block in the checkpoint, used to compute the out hash. */ l2ToL1MsgsPerBlock: Fr[][][]; /** Blob fields encoding the checkpoint's tx effects, used to compute the blob accumulator. */ @@ -84,7 +84,7 @@ type OutHashHint = { * * Pipelined start: `prove()` does not wait for block-level proving. It pre-computes the * out-hash and blob-accumulator hint chains immediately from archiver-derivable data, - * and each checkpoint's root rollup fires the moment its sub-tree's `blockProofs` + * and each checkpoint's root rollup fires the moment its sub-tree's `subTreeProofs` * promise resolves. Later checkpoints can still be block-level proving in parallel. */ export class TopTreeOrchestrator extends ProvingScheduler { @@ -166,15 +166,16 @@ export class TopTreeOrchestrator extends ProvingScheduler { for (let i = 0; i < checkpointData.length; i++) { const cd = checkpointData[i]; const checkpointIndex = i; - void cd.blockProofs.then( - blockProofs => { + void cd.subTreeProofs.then( + subTreeProofs => { if (this.cancelled || !this.state?.verifyState()) { return; } this.enqueueCheckpointRoot( this.state, checkpointIndex, - blockProofs, + subTreeProofs.blockProofOutputs, + subTreeProofs.inboxParityProof, cd, outHashHints[i], checkpointStartBlobs[i], @@ -220,15 +221,22 @@ export class TopTreeOrchestrator extends ProvingScheduler { private enqueueCheckpointRoot( state: TopTreeProvingState, checkpointIndex: number, - blockProofs: PublicInputsAndRecursiveProof< + blockProofOutputs: PublicInputsAndRecursiveProof< BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH >[], + inboxParityProof: PublicInputsAndRecursiveProof, cd: CheckpointTopTreeData, outHashHint: OutHashHint, startBlobAccumulator: BatchedBlobAccumulator, ) { - void this.buildCheckpointRootInputs(blockProofs, cd, outHashHint, startBlobAccumulator).then( + void this.buildCheckpointRootInputs( + blockProofOutputs, + inboxParityProof, + cd, + outHashHint, + startBlobAccumulator, + ).then( inputs => { this.deferredProving( state, @@ -261,10 +269,11 @@ export class TopTreeOrchestrator extends ProvingScheduler { } private async buildCheckpointRootInputs( - blockProofs: PublicInputsAndRecursiveProof< + blockProofOutputs: PublicInputsAndRecursiveProof< BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH >[], + inboxParityProof: PublicInputsAndRecursiveProof, cd: CheckpointTopTreeData, outHashHint: OutHashHint, startBlobAccumulator: BatchedBlobAccumulator, @@ -283,10 +292,11 @@ export class TopTreeOrchestrator extends ProvingScheduler { blobsHash, }); - const proofDatas = blockProofs.map(p => toProofData(p)); + const inboxParity = toProofData(inboxParityProof); + const proofDatas = blockProofOutputs.map(p => toProofData(p)); return proofDatas.length === 1 - ? new CheckpointRootSingleBlockRollupPrivateInputs(proofDatas[0], hints) - : new CheckpointRootRollupPrivateInputs([proofDatas[0], proofDatas[1]], hints); + ? new CheckpointRootSingleBlockRollupPrivateInputs(proofDatas[0], inboxParity, hints) + : new CheckpointRootRollupPrivateInputs([proofDatas[0], proofDatas[1]], inboxParity, hints); } // --- internal: top-tree proof orchestration (formerly TopTreeProvingScheduler) --- diff --git a/yarn-project/prover-client/src/prover-client/prover-client.ts b/yarn-project/prover-client/src/prover-client/prover-client.ts index f8260d704fbc..c9040b46b685 100644 --- a/yarn-project/prover-client/src/prover-client/prover-client.ts +++ b/yarn-project/prover-client/src/prover-client/prover-client.ts @@ -56,6 +56,7 @@ export interface EpochProverFactory { epochNumber: EpochNumber, checkpointConstants: CheckpointConstantData, l1ToL2Messages: Fr[], + startInboxRollingHash: Fr, totalNumBlocks: number, headerOfLastBlockInPreviousCheckpoint: BlockHeader, ): Promise; @@ -133,6 +134,7 @@ export class ProverClient implements EpochProverManager, EpochProverFactory { epochNumber: EpochNumber, checkpointConstants: CheckpointConstantData, l1ToL2Messages: Fr[], + startInboxRollingHash: Fr, totalNumBlocks: number, headerOfLastBlockInPreviousCheckpoint: BlockHeader, ): Promise { @@ -146,6 +148,7 @@ export class ProverClient implements EpochProverManager, EpochProverFactory { this.getDeferredJobQueue(), checkpointConstants, l1ToL2Messages, + startInboxRollingHash, totalNumBlocks, headerOfLastBlockInPreviousCheckpoint, this.telemetry, diff --git a/yarn-project/prover-client/src/proving_broker/broker_prover_facade.test.ts b/yarn-project/prover-client/src/proving_broker/broker_prover_facade.test.ts index c73b1789583a..ce8dd828fc29 100644 --- a/yarn-project/prover-client/src/proving_broker/broker_prover_facade.test.ts +++ b/yarn-project/prover-client/src/proving_broker/broker_prover_facade.test.ts @@ -4,7 +4,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise'; import { retryFastUntil } from '@aztec/foundation/retry'; import { type ProvingJobStatus, makePublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server'; import { makeRecursiveProof } from '@aztec/stdlib/proofs'; -import { makeParityBasePrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; +import { makeInboxParityPrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; import { VerificationKeyData } from '@aztec/stdlib/vks'; import { jest } from '@jest/globals'; @@ -40,33 +40,33 @@ describe('BrokerCircuitProverFacade', () => { }); it('sends jobs to the broker', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); jest.spyOn(broker, 'enqueueProvingJob'); - jest.spyOn(prover, 'getBaseParityProof'); + jest.spyOn(prover, 'getInboxParityProof'); jest.spyOn(errorProofStore, 'saveProofInput'); - await expect(facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42))).resolves.toBeDefined(); + await expect(facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42))).resolves.toBeDefined(); expect(broker.enqueueProvingJob).toHaveBeenCalled(); - expect(prover.getBaseParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); + expect(prover.getInboxParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); expect(errorProofStore.saveProofInput).not.toHaveBeenCalled(); }); it('handles multiple calls for the same job', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); const promises: Promise[] = []; const resultPromise = promiseWithResolvers(); jest.spyOn(broker, 'enqueueProvingJob'); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValue(resultPromise.promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValue(resultPromise.promise); // send N identical proof requests const CALLS = 50; for (let i = 0; i < CALLS; i++) { - promises.push(facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42))); + promises.push(facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42))); } // now we have 50 promises all waiting on the same result @@ -83,11 +83,11 @@ describe('BrokerCircuitProverFacade', () => { // the broker will only have been told about one of the calls expect(broker.enqueueProvingJob).toHaveBeenCalledTimes(1); - expect(prover.getBaseParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); + expect(prover.getInboxParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); // enqueue another N requests for the same jobs for (let i = 0; i < CALLS; i++) { - promises.push(facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42))); + promises.push(facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42))); } await Promise.all(promises); @@ -95,7 +95,7 @@ describe('BrokerCircuitProverFacade', () => { // the broker will have received one new request expect(broker.enqueueProvingJob).toHaveBeenCalledTimes(2); // but no new jobs where created - expect(prover.getBaseParityProof).toHaveBeenCalledTimes(1); + expect(prover.getInboxParityProof).toHaveBeenCalledTimes(1); // and all requests will have been resolved with the same result for (const promise of promises) { @@ -104,23 +104,23 @@ describe('BrokerCircuitProverFacade', () => { }); it('handles proof errors', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); const promises: Promise[] = []; const resultPromise = promiseWithResolvers(); jest.spyOn(broker, 'enqueueProvingJob'); - const getBaseParityProofSpy = jest.spyOn(prover, 'getBaseParityProof').mockReturnValue(resultPromise.promise); + const getInboxParityProofSpy = jest.spyOn(prover, 'getInboxParityProof').mockReturnValue(resultPromise.promise); jest.spyOn(errorProofStore, 'saveProofInput'); // send N identical proof requests const CALLS = 50; for (let i = 0; i < CALLS; i++) { // wrap the error in a resolved promises so that we don't have unhandled rejections - promises.push(facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err }))); + promises.push(facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err }))); } - await retryFastUntil(() => getBaseParityProofSpy.mock.calls.length > 0, 'prover to be called'); + await retryFastUntil(() => getInboxParityProofSpy.mock.calls.length > 0, 'prover to be called'); resultPromise.reject(new Error('TEST ERROR')); @@ -129,11 +129,11 @@ describe('BrokerCircuitProverFacade', () => { // the broker should only have been called once expect(broker.enqueueProvingJob).toHaveBeenCalledTimes(1); - expect(prover.getBaseParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); + expect(prover.getInboxParityProof).toHaveBeenCalledWith(inputs, expect.anything(), EpochNumber(42)); // enqueue another N requests for the same jobs for (let i = 0; i < CALLS; i++) { - promises.push(facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err }))); + promises.push(facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err }))); } // and all 2 * N requests will have been resolved with the same result @@ -144,23 +144,23 @@ describe('BrokerCircuitProverFacade', () => { // the broker will have received one new request expect(broker.enqueueProvingJob).toHaveBeenCalledTimes(2); // but no new jobs where created - expect(prover.getBaseParityProof).toHaveBeenCalledTimes(1); + expect(prover.getInboxParityProof).toHaveBeenCalledTimes(1); // and the proof input will have been backed up expect(errorProofStore.saveProofInput).toHaveBeenCalled(); }); it('handles aborts', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); const resultPromise = promiseWithResolvers(); jest.spyOn(broker, 'enqueueProvingJob'); - const getBaseParityProofSpy = jest.spyOn(prover, 'getBaseParityProof').mockReturnValue(resultPromise.promise); + const getInboxParityProofSpy = jest.spyOn(prover, 'getInboxParityProof').mockReturnValue(resultPromise.promise); jest.spyOn(errorProofStore, 'saveProofInput'); - const promise = facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err })); + const promise = facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err })); - await retryFastUntil(() => getBaseParityProofSpy.mock.calls.length > 0, 'prover to be called'); + await retryFastUntil(() => getInboxParityProofSpy.mock.calls.length > 0, 'prover to be called'); controller.abort(); @@ -169,14 +169,14 @@ describe('BrokerCircuitProverFacade', () => { }); it('rejects jobs when the facade is stopped', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); const resultPromise = promiseWithResolvers(); jest.spyOn(broker, 'enqueueProvingJob'); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValue(resultPromise.promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValue(resultPromise.promise); - const promise = facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err })); + const promise = facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42)).catch(err => ({ err })); await facade.stop(); @@ -185,13 +185,13 @@ describe('BrokerCircuitProverFacade', () => { // Regression test for #13166 it('handles stopping while sending a proof to the broker', async () => { - const inputs = makeParityBasePrivateInputs(); + const inputs = makeInboxParityPrivateInputs(); const controller = new AbortController(); // make sure the job hangs on waiting for the broker const enqueueJobPromise = promiseWithResolvers(); const enqueueProvingJobSpy = jest.spyOn(broker, 'enqueueProvingJob').mockReturnValue(enqueueJobPromise.promise); - const promise = facade.getBaseParityProof(inputs, controller.signal, EpochNumber(42)); + const promise = facade.getInboxParityProof(inputs, controller.signal, EpochNumber(42)); // now stop the facade after giving it time, which will trigger a rejection await retryFastUntil(() => enqueueProvingJobSpy.mock.calls.length > 0, 'broker to be called'); diff --git a/yarn-project/prover-client/src/proving_broker/broker_prover_facade.ts b/yarn-project/prover-client/src/proving_broker/broker_prover_facade.ts index acb80833f38f..3aa04785f558 100644 --- a/yarn-project/prover-client/src/proving_broker/broker_prover_facade.ts +++ b/yarn-project/prover-client/src/proving_broker/broker_prover_facade.ts @@ -1,6 +1,5 @@ import type { AVM_V2_PROOF_LENGTH_IN_FIELDS, - NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, RECURSIVE_PROOF_LENGTH, } from '@aztec/constants'; @@ -22,13 +21,14 @@ import { type ServerCircuitProver, makeProvingJobId, } from '@aztec/stdlib/interfaces/server'; -import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import type { InboxParityPrivateInputs, ParityPublicInputs } from '@aztec/stdlib/parity'; import { ProvingRequestType, RecursiveProof } from '@aztec/stdlib/proofs'; import type { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -406,14 +406,14 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver { ); } - getBaseParityProof( - inputs: ParityBasePrivateInputs, + getInboxParityProof( + inputs: InboxParityPrivateInputs, signal?: AbortSignal, epochNumber?: EpochNumber, ): Promise> { return this.enqueueJob( - this.generateId(ProvingRequestType.PARITY_BASE, inputs, epochNumber), - ProvingRequestType.PARITY_BASE, + this.generateId(ProvingRequestType.INBOX_PARITY, inputs, epochNumber), + ProvingRequestType.INBOX_PARITY, inputs, epochNumber, signal, @@ -478,20 +478,6 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver { ); } - getRootParityProof( - inputs: ParityRootPrivateInputs, - signal?: AbortSignal, - epochNumber?: EpochNumber, - ): Promise> { - return this.enqueueJob( - this.generateId(ProvingRequestType.PARITY_ROOT, inputs, epochNumber), - ProvingRequestType.PARITY_ROOT, - inputs, - epochNumber, - signal, - ); - } - getBlockRootFirstRollupProof( input: BlockRootFirstRollupPrivateInputs, signal?: AbortSignal, @@ -534,6 +520,20 @@ export class BrokerCircuitProverFacade implements ServerCircuitProver { ); } + getBlockRootMsgsOnlyRollupProof( + input: BlockRootMsgsOnlyRollupPrivateInputs, + signal?: AbortSignal, + epochNumber?: EpochNumber, + ): Promise> { + return this.enqueueJob( + this.generateId(ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP, input, epochNumber), + ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP, + input, + epochNumber, + signal, + ); + } + getBlockRootRollupProof( input: BlockRootRollupPrivateInputs, signal?: AbortSignal, diff --git a/yarn-project/prover-client/src/proving_broker/fixtures.ts b/yarn-project/prover-client/src/proving_broker/fixtures.ts index ac1a5e3ddc89..9dea2a5c70dd 100644 --- a/yarn-project/prover-client/src/proving_broker/fixtures.ts +++ b/yarn-project/prover-client/src/proving_broker/fixtures.ts @@ -6,7 +6,7 @@ import { ProvingRequestType } from '@aztec/stdlib/proofs'; export function makeRandomProvingJobId(epochNumber?: EpochNumber): ProvingJobId { return makeProvingJobId( epochNumber ?? EpochNumber(1), - ProvingRequestType.PARITY_BASE, + ProvingRequestType.INBOX_PARITY, randomBytes(8).toString('hex'), ); } diff --git a/yarn-project/prover-client/src/proving_broker/proving_agent.test.ts b/yarn-project/prover-client/src/proving_broker/proving_agent.test.ts index d366982152d3..9403d7793dc2 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_agent.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_agent.test.ts @@ -15,7 +15,7 @@ import { } from '@aztec/stdlib/interfaces/server'; import type { ParityPublicInputs } from '@aztec/stdlib/parity'; import { ProvingRequestType, makeRecursiveProof } from '@aztec/stdlib/proofs'; -import { makeParityBasePrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; +import { makeInboxParityPrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; import { VerificationKeyData } from '@aztec/stdlib/vks'; import { jest } from '@jest/globals'; @@ -49,7 +49,7 @@ describe('ProvingAgent', () => { saveProofOutput: jest.fn(() => Promise.resolve('' as ProofUri)), }; - allowList = [ProvingRequestType.PARITY_BASE]; + allowList = [ProvingRequestType.INBOX_PARITY]; agent = new ProvingAgent(jobSource, proofDB, prover, allowList, agentPollIntervalMs); }); @@ -59,7 +59,7 @@ describe('ProvingAgent', () => { it('polls for jobs passing the permitted list of proofs', () => { agent.start(); - expect(jobSource.getProvingJob).toHaveBeenCalledWith({ allowList: [ProvingRequestType.PARITY_BASE] }); + expect(jobSource.getProvingJob).toHaveBeenCalledWith({ allowList: [ProvingRequestType.INBOX_PARITY] }); }); it('only takes a single job from the source at a time', async () => { @@ -68,7 +68,7 @@ describe('ProvingAgent', () => { // simulate the proof taking a long time const { promise, resolve } = promiseWithResolvers>(); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValueOnce(promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValueOnce(promise); const { job, time, inputs } = makeBaseParityJob(); jobSource.getProvingJob.mockResolvedValueOnce({ job, time }); @@ -103,7 +103,7 @@ describe('ProvingAgent', () => { const { job, time, inputs } = makeBaseParityJob(); const result = makeBaseParityResult(); - jest.spyOn(prover, 'getBaseParityProof').mockResolvedValueOnce(result); + jest.spyOn(prover, 'getInboxParityProof').mockResolvedValueOnce(result); jobSource.getProvingJob.mockResolvedValueOnce({ job, time }); proofDB.getProofInput.mockResolvedValueOnce(inputs); @@ -118,7 +118,7 @@ describe('ProvingAgent', () => { it('reports errors to the job source', async () => { const { job, time, inputs } = makeBaseParityJob(); - jest.spyOn(prover, 'getBaseParityProof').mockRejectedValueOnce(new Error('test error')); + jest.spyOn(prover, 'getInboxParityProof').mockRejectedValueOnce(new Error('test error')); jobSource.getProvingJob.mockResolvedValueOnce({ job, time }); proofDB.getProofInput.mockResolvedValueOnce(inputs); @@ -133,7 +133,7 @@ describe('ProvingAgent', () => { it('sets the retry flag on when reporting an error', async () => { const { job, time, inputs } = makeBaseParityJob(); const err = new ProvingError('test error', undefined, true); - jest.spyOn(prover, 'getBaseParityProof').mockRejectedValueOnce(err); + jest.spyOn(prover, 'getInboxParityProof').mockRejectedValueOnce(err); jobSource.getProvingJob.mockResolvedValueOnce({ job, time }); proofDB.getProofInput.mockResolvedValueOnce(inputs); @@ -149,7 +149,7 @@ describe('ProvingAgent', () => { const { job, time, inputs } = makeBaseParityJob(); const { promise, resolve } = promiseWithResolvers>(); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValueOnce(promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValueOnce(promise); jobSource.getProvingJob.mockResolvedValueOnce({ job, time }); proofDB.getProofInput.mockResolvedValueOnce(inputs); @@ -157,12 +157,12 @@ describe('ProvingAgent', () => { await jest.advanceTimersByTimeAsync(agentPollIntervalMs); expect(jobSource.reportProvingJobProgress).toHaveBeenCalledWith(job.id, time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }); await jest.advanceTimersByTimeAsync(agentPollIntervalMs); expect(jobSource.reportProvingJobProgress).toHaveBeenCalledWith(job.id, time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }); resolve(makeBaseParityResult()); @@ -175,7 +175,7 @@ describe('ProvingAgent', () => { promiseWithResolvers>(); // simulate a long running proving job that can be aborted - jest.spyOn(prover, 'getBaseParityProof').mockImplementationOnce((_, signal) => { + jest.spyOn(prover, 'getInboxParityProof').mockImplementationOnce((_, signal) => { signal?.addEventListener('abort', () => { firstProof.reject(new AbortError('test abort')); firstProofAborted = true; @@ -191,7 +191,7 @@ describe('ProvingAgent', () => { await jest.advanceTimersByTimeAsync(agentPollIntervalMs); expect(jobSource.reportProvingJobProgress).toHaveBeenCalledTimes(1); expect(jobSource.reportProvingJobProgress).toHaveBeenCalledWith(firstJob.job.id, firstJob.time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }); await jest.advanceTimersByTimeAsync(agentPollIntervalMs); @@ -205,21 +205,21 @@ describe('ProvingAgent', () => { const secondProof = promiseWithResolvers>(); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValueOnce(secondProof.promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValueOnce(secondProof.promise); jobSource.reportProvingJobProgress.mockResolvedValueOnce(secondJobResponse); await jest.advanceTimersByTimeAsync(agentPollIntervalMs); expect(jobSource.reportProvingJobProgress).toHaveBeenCalledTimes(4); expect(jobSource.reportProvingJobProgress).toHaveBeenNthCalledWith(3, firstJob.job.id, firstJob.time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }); expect(jobSource.reportProvingJobProgress).toHaveBeenNthCalledWith( 4, secondJobResponse.job.id, secondJobResponse.time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }, ); expect(firstProofAborted).toBe(true); @@ -231,7 +231,7 @@ describe('ProvingAgent', () => { secondJobResponse.job.id, secondJobResponse.time, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }, ); }); @@ -241,7 +241,7 @@ describe('ProvingAgent', () => { const job2 = makeBaseParityJob(); jest - .spyOn(prover, 'getBaseParityProof') + .spyOn(prover, 'getInboxParityProof') .mockResolvedValueOnce(makeBaseParityResult()) .mockResolvedValueOnce(makeBaseParityResult()); @@ -265,7 +265,7 @@ describe('ProvingAgent', () => { const job2 = makeBaseParityJob(); jest - .spyOn(prover, 'getBaseParityProof') + .spyOn(prover, 'getInboxParityProof') .mockRejectedValueOnce(new Error('test error')) .mockResolvedValueOnce(makeBaseParityResult()); @@ -297,11 +297,11 @@ describe('ProvingAgent', () => { function makeBaseParityJob(): { job: ProvingJob; time: number; inputs: ProvingJobInputs } { const time = jest.now(); - const inputs: ProvingJobInputs = { type: ProvingRequestType.PARITY_BASE, inputs: makeParityBasePrivateInputs() }; + const inputs: ProvingJobInputs = { type: ProvingRequestType.INBOX_PARITY, inputs: makeInboxParityPrivateInputs() }; const job: ProvingJob = { id: randomBytes(8).toString('hex') as ProvingJobId, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: randomBytes(8).toString('hex') as ProofUri, }; diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts index ca5cb0be1851..79060fa85a53 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.test.ts @@ -83,7 +83,7 @@ describe.each([ await broker.enqueueProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); expect(await broker.getProvingJobStatus(id)).toEqual({ status: 'in-queue' }); @@ -105,7 +105,7 @@ describe.each([ const enqueueStatus = await broker.enqueueProvingJob({ id, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); expect(enqueueStatus).toEqual({ status: 'not-found' }); @@ -125,7 +125,7 @@ describe.each([ it('ignores duplicate jobs', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -139,7 +139,7 @@ describe.each([ it('reports correct status when enqueuing repeat jobs', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -172,14 +172,14 @@ describe.each([ await broker.enqueueProvingJob({ id, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); await expect( broker.enqueueProvingJob({ id, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ).rejects.toThrow('Duplicate proving job ID'); @@ -195,7 +195,7 @@ describe.each([ await broker.enqueueProvingJob({ id, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); await assertJobStatus(id, 'in-queue'); @@ -209,7 +209,7 @@ describe.each([ await broker.enqueueProvingJob({ id, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); await assertJobStatus(id, 'in-queue'); @@ -222,7 +222,7 @@ describe.each([ it('revives an aborted job when its producer re-requests it', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -239,7 +239,7 @@ describe.each([ // 'in-queue', and it can then be completed. await expect(broker.enqueueProvingJob(provingJob)).resolves.toEqual({ status: 'in-queue' }); await assertJobStatus(provingJob.id, 'in-queue'); - const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] }); + const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] }); expect(returnedJob?.job).toEqual(provingJob); const retryValue = makeOutputsUri(); @@ -250,7 +250,7 @@ describe.each([ it('persists the aborted state across a restart and revives on re-request', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -276,7 +276,7 @@ describe.each([ // 'in-queue' status), and it can be completed. await expect(broker.enqueueProvingJob(provingJob)).resolves.toEqual({ status: 'in-queue' }); await assertJobStatus(provingJob.id, 'in-queue'); - const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] }); + const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] }); expect(returnedJob?.job).toEqual(provingJob); const value = makeOutputsUri(); @@ -287,7 +287,7 @@ describe.each([ it('persists the revived (non-aborted) state, so a restart mid-revival stays revived', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -318,7 +318,7 @@ describe.each([ it('revives once when the producer re-requests an aborted job concurrently', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -338,10 +338,10 @@ describe.each([ expect(second).toEqual({ status: 'in-queue' }); await assertJobStatus(provingJob.id, 'in-queue'); - const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] }); + const returnedJob = await broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] }); expect(returnedJob?.job).toEqual(provingJob); await assertJobStatus(provingJob.id, 'in-progress'); - await expect(broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] })).resolves.toBeUndefined(); + await expect(broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] })).resolves.toBeUndefined(); await broker.reportProvingJobSuccess(provingJob.id, makeOutputsUri()); await assertJobStatus(provingJob.id, 'fulfilled'); @@ -350,7 +350,7 @@ describe.each([ it('returns job result if successful', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -366,7 +366,7 @@ describe.each([ it('returns job error if failed', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -382,7 +382,7 @@ describe.each([ it('correctly returns job status for concurrent writes', async () => { const job = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(0), inputsUri: makeInputsUri(), }; @@ -394,7 +394,7 @@ describe.each([ promises.push( broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(0), inputsUri: makeInputsUri(), }), @@ -403,7 +403,7 @@ describe.each([ promises.push( broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(0), inputsUri: makeInputsUri(), }), @@ -420,21 +420,21 @@ describe.each([ describe('Consumer API', () => { it('returns undefined if no jobs are available', async () => { - const provingJob = await broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] }); + const provingJob = await broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] }); expect(provingJob).toBeUndefined(); }); it('returns jobs in priority order', async () => { const provingJob1: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; const provingJob2: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }; @@ -442,13 +442,13 @@ describe.each([ await broker.enqueueProvingJob(provingJob2); await broker.enqueueProvingJob(provingJob1); - await getAndAssertNextJobId(provingJob1.id, ProvingRequestType.PARITY_BASE); + await getAndAssertNextJobId(provingJob1.id, ProvingRequestType.INBOX_PARITY); }); it('returns undefined if no jobs are available for the given allowList', async () => { await broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -462,7 +462,7 @@ describe.each([ const baseParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: baseParity1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -486,19 +486,19 @@ describe.each([ const rootParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: rootParity1, - type: ProvingRequestType.PARITY_ROOT, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); - await getAndAssertNextJobId(baseParity1, ProvingRequestType.PARITY_BASE); + await getAndAssertNextJobId(baseParity1, ProvingRequestType.INBOX_PARITY); }); it('returns the most important job if it is in the allowList', async () => { const baseParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: baseParity1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -522,24 +522,47 @@ describe.each([ const rootParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: rootParity1, - type: ProvingRequestType.PARITY_ROOT, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await getAndAssertNextJobId( baseRollup1, - ProvingRequestType.PARITY_BASE, + ProvingRequestType.INBOX_PARITY, ProvingRequestType.PRIVATE_TX_BASE_ROLLUP, - ProvingRequestType.PARITY_ROOT, + ProvingRequestType.INBOX_PARITY, ); }); + it('prefers an older epoch over a higher-priority proof type from a younger epoch', async () => { + const baseRollup2 = makeRandomProvingJobId(); + await broker.enqueueProvingJob({ + id: baseRollup2, + type: ProvingRequestType.PRIVATE_TX_BASE_ROLLUP, + epochNumber: EpochNumber(2), + inputsUri: makeInputsUri(), + }); + + const publicVm1 = makeRandomProvingJobId(); + await broker.enqueueProvingJob({ + id: publicVm1, + type: ProvingRequestType.PUBLIC_VM, + epochNumber: EpochNumber(1), + inputsUri: makeInputsUri(), + }); + + // A lower-priority type from epoch 1 wins over the higher-priority type from epoch 2: the oldest + // epoch's remaining jobs must complete rather than starve behind newer epochs' work. + await getAndAssertNextJobId(publicVm1, ProvingRequestType.PUBLIC_VM, ProvingRequestType.PRIVATE_TX_BASE_ROLLUP); + await getAndAssertNextJobId(baseRollup2, ProvingRequestType.PUBLIC_VM, ProvingRequestType.PRIVATE_TX_BASE_ROLLUP); + }); + it('returns any job if filter is empty', async () => { const baseParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: baseParity1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -563,7 +586,7 @@ describe.each([ const rootParity1 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: rootParity1, - type: ProvingRequestType.PARITY_ROOT, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -575,7 +598,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -585,12 +608,12 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await expect( - broker.reportProvingJobSuccess(id, 'result' as ProofUri, { allowList: [ProvingRequestType.PARITY_BASE] }), + broker.reportProvingJobSuccess(id, 'result' as ProofUri, { allowList: [ProvingRequestType.INBOX_PARITY] }), ).resolves.toEqual({ job: expect.objectContaining({ id: id2 }), time: expect.any(Number) }); }); @@ -598,7 +621,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -608,12 +631,12 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await expect( - broker.reportProvingJobError(id, 'result' as ProofUri, false, { allowList: [ProvingRequestType.PARITY_BASE] }), + broker.reportProvingJobError(id, 'result' as ProofUri, false, { allowList: [ProvingRequestType.INBOX_PARITY] }), ).resolves.toEqual({ job: expect.objectContaining({ id: id2 }), time: expect.any(Number) }); }); @@ -621,7 +644,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -631,12 +654,12 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await expect( - broker.reportProvingJobError(id, 'result' as ProofUri, true, { allowList: [ProvingRequestType.PARITY_BASE] }), + broker.reportProvingJobError(id, 'result' as ProofUri, true, { allowList: [ProvingRequestType.INBOX_PARITY] }), ).resolves.toEqual({ job: expect.objectContaining({ id: id2 }), time: expect.any(Number) }); }); @@ -644,7 +667,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -656,12 +679,12 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await expect( - broker.reportProvingJobProgress(id, now(), { allowList: [ProvingRequestType.PARITY_BASE] }), + broker.reportProvingJobProgress(id, now(), { allowList: [ProvingRequestType.INBOX_PARITY] }), ).resolves.toEqual({ job: expect.objectContaining({ id: id2 }), time: expect.any(Number) }); }); @@ -670,14 +693,14 @@ describe.each([ // this test simulates the broker crashing and when it comes back online it has two agents working the same job const job1: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; const job2: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }; @@ -686,7 +709,7 @@ describe.each([ await broker.enqueueProvingJob(job2); const { job: firstAgentJob, time: firstAgentStartedAt } = (await broker.getProvingJob({ - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }))!; expect(firstAgentJob).toEqual(job1); @@ -695,7 +718,7 @@ describe.each([ await sleep(jobTimeoutMs / 2); await expect( broker.reportProvingJobProgress(job1.id, firstAgentStartedAt, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }), ).resolves.toBeUndefined(); @@ -711,7 +734,7 @@ describe.each([ await assertJobStatus(job1.id, 'in-queue'); const { job: secondAgentJob, time: secondAgentStartedAt } = (await broker.getProvingJob({ - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }))!; // should be the same job! @@ -722,14 +745,14 @@ describe.each([ // and it should take over the job from the second agent await expect( broker.reportProvingJobProgress(job1.id, firstAgentStartedAt, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }), ).resolves.toBeUndefined(); // second agent should get a new job now await expect( broker.reportProvingJobProgress(job1.id, secondAgentStartedAt, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }), ).resolves.toEqual({ job: job2, time: expect.any(Number) }); }); @@ -739,14 +762,14 @@ describe.each([ // this test simulates the broker crashing and when it comes back online it has two agents working the same job const job1: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; const job2: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }; @@ -755,7 +778,7 @@ describe.each([ await broker.enqueueProvingJob(job2); const { job: firstAgentJob, time: firstAgentStartedAt } = (await broker.getProvingJob({ - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }))!; expect(firstAgentJob).toEqual(job1); @@ -776,12 +799,12 @@ describe.each([ // and it should take over the job from the second agent await expect( broker.reportProvingJobProgress(job1.id, firstAgentStartedAt, { - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }), ).resolves.toBeUndefined(); const { job: secondAgentJob } = (await broker.getProvingJob({ - allowList: [ProvingRequestType.PARITY_BASE], + allowList: [ProvingRequestType.INBOX_PARITY], }))!; // should be the same job! @@ -795,14 +818,14 @@ describe.each([ // this test simulates the broker crashing and when it comes back online it has two agents working the same job const job1: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; const job2: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }; @@ -839,13 +862,13 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }); @@ -868,13 +891,13 @@ describe.each([ const id2 = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); await broker.enqueueProvingJob({ id: id2, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(2), inputsUri: makeInputsUri(), }); @@ -906,14 +929,14 @@ describe.each([ const provingJob1: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; const provingJob2: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -956,7 +979,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -970,7 +993,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -988,7 +1011,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1010,7 +1033,7 @@ describe.each([ // epoch has advanced await broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(10), inputsUri: makeInputsUri(), }); @@ -1024,7 +1047,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1048,7 +1071,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1059,7 +1082,7 @@ describe.each([ // Advance the epoch height so epoch 1 becomes stale (oldestEpochToKeep = 3 - 1 = 2) await broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(3), inputsUri: makeInputsUri(), }); @@ -1076,7 +1099,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1114,7 +1137,7 @@ describe.each([ it('retries jobs', async () => { const provingJob: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -1133,7 +1156,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1155,7 +1178,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1173,7 +1196,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1192,7 +1215,7 @@ describe.each([ // advance the epoch height await broker.enqueueProvingJob({ id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(3), inputsUri: makeInputsUri(), }); @@ -1220,7 +1243,7 @@ describe.each([ await database.addProvingJob({ id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1238,10 +1261,10 @@ describe.each([ await expect(broker.getProvingJobStatus(id1)).resolves.toEqual({ status: 'in-queue' }); await expect(broker.getProvingJobStatus(id2)).resolves.toEqual({ status: 'in-queue' }); - await expect(broker.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] })).resolves.toEqual({ + await expect(broker.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] })).resolves.toEqual({ job: { id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: expect.any(String), }, @@ -1271,7 +1294,7 @@ describe.each([ await database.addProvingJob({ id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1305,7 +1328,7 @@ describe.each([ await database.addProvingJob({ id: id1, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1330,7 +1353,7 @@ describe.each([ await broker.start(); const job: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -1349,7 +1372,7 @@ describe.each([ await expect( broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }), @@ -1362,7 +1385,7 @@ describe.each([ const job: ProvingJob = { id: makeRandomProvingJobId(), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }; @@ -1381,7 +1404,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1397,7 +1420,7 @@ describe.each([ await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1414,7 +1437,7 @@ describe.each([ const id = makeRandomProvingJobId(); await broker.enqueueProvingJob({ id, - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, epochNumber: EpochNumber(1), inputsUri: makeInputsUri(), }); @@ -1461,7 +1484,7 @@ describe.each([ await broker.enqueueProvingJob({ id: id1, epochNumber: EpochNumber(1), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: '' as ProofUri, }); await broker.reportProvingJobSuccess(id1, '' as ProofUri); @@ -1470,7 +1493,7 @@ describe.each([ await broker.enqueueProvingJob({ id: id2, epochNumber: EpochNumber(2), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: '' as ProofUri, }); await broker.reportProvingJobSuccess(id2, '' as ProofUri); @@ -1484,7 +1507,7 @@ describe.each([ await broker.enqueueProvingJob({ id: id3, epochNumber: EpochNumber(3), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: '' as ProofUri, }); @@ -1498,7 +1521,7 @@ describe.each([ await broker.enqueueProvingJob({ id: id4, epochNumber: EpochNumber(4), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: '' as ProofUri, }); @@ -1513,7 +1536,7 @@ describe.each([ await broker.enqueueProvingJob({ id: id5, epochNumber: EpochNumber(5), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: '' as ProofUri, }); diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker.ts b/yarn-project/prover-client/src/proving_broker/proving_broker.ts index d1ab4342cf8c..c15a0da446c0 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker.ts @@ -55,6 +55,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr [ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: new PriorityMemoryQueue( provingJobComparator, ), + [ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP]: new PriorityMemoryQueue(provingJobComparator), [ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue(provingJobComparator), [ProvingRequestType.BLOCK_ROOT_SINGLE_TX_ROLLUP]: new PriorityMemoryQueue(provingJobComparator), @@ -65,8 +66,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr [ProvingRequestType.CHECKPOINT_MERGE_ROLLUP]: new PriorityMemoryQueue(provingJobComparator), [ProvingRequestType.CHECKPOINT_PADDING_ROLLUP]: new PriorityMemoryQueue(provingJobComparator), - [ProvingRequestType.PARITY_BASE]: new PriorityMemoryQueue(provingJobComparator), - [ProvingRequestType.PARITY_ROOT]: new PriorityMemoryQueue(provingJobComparator), + [ProvingRequestType.INBOX_PARITY]: new PriorityMemoryQueue(provingJobComparator), }; // holds a copy of the database in memory in order to quickly fulfill requests @@ -410,9 +410,16 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr : Object.values(ProvingRequestType).filter((x): x is ProvingRequestType => typeof x === 'number'); allowedProofs.sort(proofTypeComparator); + // Select the oldest-epoch job across the allowed queues, tie-breaking by proof-type priority: an epoch's + // remaining jobs always outrank younger epochs' work, so the oldest epoch completes instead of starving + // behind the continuous arrival of new higher-priority-type jobs. The legacy L1-to-L2 tree got this ordering + // for free (block roots waited on parity outputs); the streaming inbox parity only gates the checkpoint + // root, so a purely type-major order would leave it unscheduled under sustained block production. + let selected: { proofType: ProvingRequestType; enqueuedJob: EnqueuedProvingJob; job: ProvingJob } | undefined; for (const proofType of allowedProofs) { const queue = this.queues[proofType]; let enqueuedJob: EnqueuedProvingJob | undefined; + let candidate: { enqueuedJob: EnqueuedProvingJob; job: ProvingJob } | undefined; // exhaust the queue and make sure we're not sending a job that's already in progress // or has already been completed // this can happen if the broker crashes and restarts @@ -420,25 +427,42 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Pr while ((enqueuedJob = queue.getImmediate())) { const job = this.jobsCache.get(enqueuedJob.id); if (job && !this.inProgress.has(enqueuedJob.id) && !this.resultsCache.has(enqueuedJob.id)) { - const time = this.msTimeSource(); - this.inProgress.set(job.id, { - id: job.id, - startedAt: time, - lastUpdatedAt: time, - }); - const enqueuedAt = this.enqueuedAt.get(job.id); - if (enqueuedAt) { - this.instrumentation.recordJobWait(job.type, enqueuedAt); - // we can clear this flag now. - this.enqueuedAt.delete(job.id); - } - - return { job, time }; + candidate = { enqueuedJob, job }; + break; } } + if (!candidate) { + continue; + } + if (selected === undefined || candidate.enqueuedJob.epochNumber < selected.enqueuedJob.epochNumber) { + if (selected) { + this.queues[selected.proofType].put(selected.enqueuedJob); + } + selected = { proofType, ...candidate }; + } else { + queue.put(candidate.enqueuedJob); + } + } + + if (!selected) { + return undefined; + } + + const { job } = selected; + const time = this.msTimeSource(); + this.inProgress.set(job.id, { + id: job.id, + startedAt: time, + lastUpdatedAt: time, + }); + const enqueuedAt = this.enqueuedAt.get(job.id); + if (enqueuedAt) { + this.instrumentation.recordJobWait(job.type, enqueuedAt); + // we can clear this flag now. + this.enqueuedAt.delete(job.id); } - return undefined; + return { job, time }; } async #reportProvingJobError( @@ -784,6 +808,7 @@ export const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [ ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP, ProvingRequestType.BLOCK_ROOT_ROLLUP, ProvingRequestType.BLOCK_ROOT_SINGLE_TX_ROLLUP, + ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP, ProvingRequestType.BLOCK_MERGE_ROLLUP, ProvingRequestType.CHECKPOINT_ROOT_ROLLUP, ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP, @@ -794,6 +819,5 @@ export const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [ ProvingRequestType.PRIVATE_TX_BASE_ROLLUP, ProvingRequestType.PUBLIC_VM, ProvingRequestType.PUBLIC_CHONK_VERIFIER, - ProvingRequestType.PARITY_ROOT, - ProvingRequestType.PARITY_BASE, + ProvingRequestType.INBOX_PARITY, ]; diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker_agent_integration.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker_agent_integration.test.ts index e52e3791c04c..f023de614806 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker_agent_integration.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker_agent_integration.test.ts @@ -6,7 +6,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise'; import { sleep } from '@aztec/foundation/sleep'; import { ProvingJob, makeProvingJobId } from '@aztec/stdlib/interfaces/server'; import { ProvingRequestType } from '@aztec/stdlib/proofs'; -import { makeParityBasePrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; +import { makeInboxParityPrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; import { jest } from '@jest/globals'; @@ -63,9 +63,9 @@ describe('ProvingBroker <-> ProvingAgent integration', () => { const duplicateJobs: string[] = []; - jest.spyOn(prover, 'getBaseParityProof').mockImplementation((inputs, signal) => { + jest.spyOn(prover, 'getInboxParityProof').mockImplementation((inputs, signal) => { const inputsHash = sha256(inputs.toBuffer()); - const id = makeProvingJobId(EpochNumber(0), ProvingRequestType.PARITY_BASE, inputsHash.toString('hex')); + const id = makeProvingJobId(EpochNumber(0), ProvingRequestType.INBOX_PARITY, inputsHash.toString('hex')); // job was given to two agents if (deferreds[id]) { duplicateJobs.push(id); @@ -78,17 +78,17 @@ describe('ProvingBroker <-> ProvingAgent integration', () => { const enqueueRandomJob = async () => { while (true) { - const inputs = makeParityBasePrivateInputs(randomInt(Number.MAX_SAFE_INTEGER)); + const inputs = makeInboxParityPrivateInputs(randomInt(Number.MAX_SAFE_INTEGER)); const inputsHash = sha256(inputs.toBuffer()); - const id = makeProvingJobId(EpochNumber(0), ProvingRequestType.PARITY_BASE, inputsHash.toString('hex')); + const id = makeProvingJobId(EpochNumber(0), ProvingRequestType.INBOX_PARITY, inputsHash.toString('hex')); if (jobs[id]) { continue; } jobs[id] = { id, - type: ProvingRequestType.PARITY_BASE, - inputsUri: await store.saveProofInput(id, ProvingRequestType.PARITY_BASE, inputs), + type: ProvingRequestType.INBOX_PARITY, + inputsUri: await store.saveProofInput(id, ProvingRequestType.INBOX_PARITY, inputs), epochNumber: EpochNumber(0), }; await broker.enqueueProvingJob(jobs[id]); diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker_agent_rpc_integration.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker_agent_rpc_integration.test.ts index e71eebaf0f8b..d8b2a9ae4600 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker_agent_rpc_integration.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker_agent_rpc_integration.test.ts @@ -38,14 +38,14 @@ describe('ProvingBroker RPC', () => { const inputsUri = isSmall ? makeInputsUri() : (randomBytes(2000).toString('hex') as ProofUri); const job: ProvingJob = { id: makeRandomProvingJobId(EpochNumber(1)), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri, epochNumber: EpochNumber(1), }; await client.enqueueProvingJob(job); - const retrievedJob = await client.getProvingJob({ allowList: [ProvingRequestType.PARITY_BASE] }); + const retrievedJob = await client.getProvingJob({ allowList: [ProvingRequestType.INBOX_PARITY] }); expect(retrievedJob?.job.id).toBe(job.id); expect(retrievedJob?.job.inputsUri).toBe(inputsUri); } finally { diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker_database/broker_persisted_database.test.ts b/yarn-project/prover-client/src/proving_broker/proving_broker_database/broker_persisted_database.test.ts index 3cd951fcc6db..8f7f4b871383 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker_database/broker_persisted_database.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker_database/broker_persisted_database.test.ts @@ -52,7 +52,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ).resolves.not.toThrow(); @@ -66,7 +66,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ).resolves.not.toThrow(); @@ -79,7 +79,7 @@ describe('ProvingBrokerPersistedDatabase', () => { await db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); await expect(db.setProvingJobResult(id, 'Proof' as ProofUri)).resolves.not.toThrow(); @@ -91,7 +91,7 @@ describe('ProvingBrokerPersistedDatabase', () => { await db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); @@ -108,7 +108,7 @@ describe('ProvingBrokerPersistedDatabase', () => { await db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); @@ -121,7 +121,7 @@ describe('ProvingBrokerPersistedDatabase', () => { await db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); @@ -137,7 +137,7 @@ describe('ProvingBrokerPersistedDatabase', () => { const job: ProvingJob = { id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }; await db.addProvingJob(job); @@ -163,7 +163,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ).resolves.not.toThrow(); @@ -181,7 +181,7 @@ describe('ProvingBrokerPersistedDatabase', () => { const job: ProvingJob = { id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }; await db.addProvingJob(job); @@ -211,7 +211,7 @@ describe('ProvingBrokerPersistedDatabase', () => { await db.addProvingJob({ id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }); epochs.push(startEpoch + i); @@ -228,7 +228,7 @@ describe('ProvingBrokerPersistedDatabase', () => { const job: ProvingJob = { id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }; await db.addProvingJob(job); @@ -273,7 +273,7 @@ describe('ProvingBrokerPersistedDatabase', () => { const job: ProvingJob = { id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }; await db.addProvingJob(job); @@ -313,7 +313,7 @@ describe('ProvingBrokerPersistedDatabase', () => { const job: ProvingJob = { id, epochNumber: EpochNumber(startEpoch + i), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }; await db.addProvingJob(job); @@ -378,7 +378,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id, epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ); @@ -405,7 +405,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id: makeRandomProvingJobId(EpochNumber(42)), epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ); @@ -413,7 +413,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id: makeRandomProvingJobId(EpochNumber(42)), epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ); @@ -421,7 +421,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id: makeRandomProvingJobId(EpochNumber(42)), epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ); @@ -439,7 +439,7 @@ describe('ProvingBrokerPersistedDatabase', () => { db.addProvingJob({ id: makeRandomProvingJobId(EpochNumber(42)), epochNumber: EpochNumber(42), - type: ProvingRequestType.PARITY_BASE, + type: ProvingRequestType.INBOX_PARITY, inputsUri: makeInputsUri(), }), ); diff --git a/yarn-project/prover-client/src/proving_broker/proving_broker_database/persisted.ts b/yarn-project/prover-client/src/proving_broker/proving_broker_database/persisted.ts index 3dd2686583ed..36d764c6ce44 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_broker_database/persisted.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_broker_database/persisted.ts @@ -27,7 +27,7 @@ import type { ProverBrokerConfig } from '../config.js'; import type { ProvingBrokerDatabase } from '../proving_broker_database.js'; class SingleEpochDatabase { - public static readonly SCHEMA_VERSION = 1; + public static readonly SCHEMA_VERSION = 2; private jobs: AztecAsyncMap; private jobResults: AztecAsyncMap; diff --git a/yarn-project/prover-client/src/proving_broker/proving_job_controller.test.ts b/yarn-project/prover-client/src/proving_broker/proving_job_controller.test.ts index 3b48fe70226f..a4e4d944b35d 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_job_controller.test.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_job_controller.test.ts @@ -5,7 +5,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise'; import { sleep } from '@aztec/foundation/sleep'; import { type ProvingJobId, makePublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server'; import { ProvingRequestType, makeRecursiveProof } from '@aztec/stdlib/proofs'; -import { makeParityBasePrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; +import { makeInboxParityPrivateInputs, makeParityPublicInputs } from '@aztec/stdlib/testing'; import { VerificationKeyData } from '@aztec/stdlib/vks'; import { jest } from '@jest/globals'; @@ -24,8 +24,8 @@ describe('ProvingJobController', () => { controller = new ProvingJobController( '1' as ProvingJobId, { - type: ProvingRequestType.PARITY_BASE, - inputs: makeParityBasePrivateInputs(), + type: ProvingRequestType.INBOX_PARITY, + inputs: makeInboxParityPrivateInputs(), }, EpochNumber(0), 42, @@ -63,7 +63,7 @@ describe('ProvingJobController', () => { makeRecursiveProof(RECURSIVE_PROOF_LENGTH), VerificationKeyData.makeFakeHonk(), ); - jest.spyOn(prover, 'getBaseParityProof').mockResolvedValueOnce(resp); + jest.spyOn(prover, 'getInboxParityProof').mockResolvedValueOnce(resp); controller.start(); await sleep(1); // give promises a chance to complete @@ -73,7 +73,7 @@ describe('ProvingJobController', () => { it('calls onComplete with the error', async () => { const err = new Error('test error'); - jest.spyOn(prover, 'getBaseParityProof').mockRejectedValueOnce(err); + jest.spyOn(prover, 'getInboxParityProof').mockRejectedValueOnce(err); controller.start(); await sleep(1); @@ -95,7 +95,7 @@ describe('ProvingJobController', () => { it('calls onComplete if abort is called but result is masked', async () => { const { promise, resolve } = promiseWithResolvers(); - jest.spyOn(prover, 'getBaseParityProof').mockReturnValueOnce(promise); + jest.spyOn(prover, 'getInboxParityProof').mockReturnValueOnce(promise); controller.start(); diff --git a/yarn-project/prover-client/src/proving_broker/proving_job_controller.ts b/yarn-project/prover-client/src/proving_broker/proving_job_controller.ts index 043d0293eef5..74f3e41bfa43 100644 --- a/yarn-project/prover-client/src/proving_broker/proving_job_controller.ts +++ b/yarn-project/prover-client/src/proving_broker/proving_job_controller.ts @@ -162,6 +162,10 @@ export class ProvingJobController { return await this.circuitProver.getBlockRootEmptyTxFirstRollupProof(inputs, signal, this.epochNumber); } + case ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP: { + return await this.circuitProver.getBlockRootMsgsOnlyRollupProof(inputs, signal, this.epochNumber); + } + case ProvingRequestType.BLOCK_ROOT_ROLLUP: { return await this.circuitProver.getBlockRootRollupProof(inputs, signal, this.epochNumber); } @@ -194,12 +198,8 @@ export class ProvingJobController { return await this.circuitProver.getRootRollupProof(inputs, signal, this.epochNumber); } - case ProvingRequestType.PARITY_BASE: { - return await this.circuitProver.getBaseParityProof(inputs, signal, this.epochNumber); - } - - case ProvingRequestType.PARITY_ROOT: { - return await this.circuitProver.getRootParityProof(inputs, signal, this.epochNumber); + case ProvingRequestType.INBOX_PARITY: { + return await this.circuitProver.getInboxParityProof(inputs, signal, this.epochNumber); } default: { diff --git a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts index db00fb35bbfb..26c2b81c50bf 100644 --- a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts @@ -1,8 +1,9 @@ import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PAIRING_POINTS_SIZE } from '@aztec/constants'; +import { MAX_L1_TO_L2_MSGS_PER_BLOCK, PAIRING_POINTS_SIZE } from '@aztec/constants'; import { EpochNumber } from '@aztec/foundation/branded-types'; import { timesAsync } from '@aztec/foundation/collection'; import { parseBooleanEnv } from '@aztec/foundation/config'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; @@ -51,7 +52,8 @@ describe('prover/bb_prover/full-rollup', () => { const checkpoints = await timesAsync(numCheckpoints, () => context.makeCheckpoint(numBlockPerCheckpoint, { numTxsPerBlock, - numL1ToL2Messages: NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + // makeCheckpoint puts the whole message list into the first block, so cap at the per-block limit. + numL1ToL2Messages: MAX_L1_TO_L2_MSGS_PER_BLOCK, makeProcessedTxOpts: (_, txIndex) => ({ privateOnly: txIndex % 2 === 0 }), }), ); @@ -67,6 +69,9 @@ describe('prover/bb_prover/full-rollup', () => { for (let checkpointIndex = 0; checkpointIndex < numCheckpoints; checkpointIndex++) { const { constants, blocks, l1ToL2Messages, previousBlockHeader, checkpoint } = checkpoints[checkpointIndex]; + const previousInboxRollingHash = + checkpointIndex === 0 ? Fr.ZERO : checkpoints[checkpointIndex - 1].checkpoint.header.inboxRollingHash; + log.info(`Starting new checkpoint #${checkpointIndex}`); const subTree = await CheckpointSubTreeOrchestrator.start( context.worldState, @@ -78,6 +83,7 @@ describe('prover/bb_prover/full-rollup', () => { makeTestDeferredJobQueue(), constants, l1ToL2Messages, + previousInboxRollingHash, numBlockPerCheckpoint, previousBlockHeader, ); @@ -88,7 +94,7 @@ describe('prover/bb_prover/full-rollup', () => { const { blockNumber, timestamp } = header.globalVariables; log.info(`Starting new block #${blockNumber}`); - await subTree.startNewBlock(blockNumber, timestamp, txs.length); + await subTree.startNewBlock(blockNumber, timestamp, txs.length, i === 0 ? l1ToL2Messages : []); if (txs.length > 0) { await subTree.addTxs(txs); } @@ -98,7 +104,9 @@ describe('prover/bb_prover/full-rollup', () => { } topTreeData.push({ - blockProofs: subTree.getSubTreeResult().then(r => r.blockProofOutputs), + subTreeProofs: subTree + .getSubTreeResult() + .then(r => ({ blockProofOutputs: r.blockProofOutputs, inboxParityProof: r.inboxParityProof })), l2ToL1MsgsPerBlock: blocks.map(b => b.txs.map(tx => tx.txEffect.l2ToL1Msgs)), blobFields: checkpoint.toBlobFields(), previousBlockHeader, diff --git a/yarn-project/prover-client/src/test/bb_prover_parity.test.ts b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts index 64e98703a317..4848af4efd85 100644 --- a/yarn-project/prover-client/src/test/bb_prover_parity.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts @@ -1,26 +1,24 @@ import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; -import { - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - NUM_BASE_PARITY_PER_ROOT_PARITY, - PARITY_BASE_VK_INDEX, - RECURSIVE_PROOF_LENGTH, -} from '@aztec/constants'; -import { makeTuple } from '@aztec/foundation/array'; import { parseBooleanEnv } from '@aztec/foundation/config'; -import { randomBytes } from '@aztec/foundation/crypto/random'; import { Fr } from '@aztec/foundation/curves/bn254'; import { createLogger } from '@aztec/foundation/log'; +import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server'; import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; -import { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; -import { makeRecursiveProof } from '@aztec/stdlib/proofs'; -import { VerificationKeyData } from '@aztec/stdlib/vks'; +import { L1ToL2MessageSponge } from '@aztec/stdlib/messaging'; +import { INBOX_PARITY_SIZES, InboxParityPrivateInputs, type InboxParitySize } from '@aztec/stdlib/parity'; import { TestContext } from '../mocks/test_context.js'; -import { toProofData } from '../orchestrator/block-building-helpers.js'; const logger = createLogger('prover-client:test:bb-prover-parity'); +// Maps a ladder size to its server artifact name, mirroring the bb-prover's own selection. +const artifactForSize: Record = { + 64: 'InboxParity64Artifact', + 256: 'InboxParity256Artifact', + 1024: 'InboxParity1024Artifact', +}; + describe('prover/bb_prover/parity', () => { const FAKE_PROOFS = parseBooleanEnv(process.env.FAKE_PROOFS); @@ -29,7 +27,7 @@ describe('prover/bb_prover/parity', () => { beforeAll(async () => { const buildProver = async (bbConfig: BBProverConfig) => { - bbConfig.circuitFilter = ['ParityBaseArtifact', 'ParityRootArtifact']; + bbConfig.circuitFilter = Object.values(artifactForSize); bbProver = await BBNativeRollupProver.new(bbConfig); return bbProver; }; @@ -43,118 +41,31 @@ describe('prover/bb_prover/parity', () => { await context.cleanup(); }); - it( - 'proves the parity circuits', - async () => { - const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(null).map(() => Fr.random()); + // One InboxParity proof per checkpoint, sized to the smallest ladder rung that fits. Prove and verify each rung. + it.each(INBOX_PARITY_SIZES)( + 'proves and verifies the inbox parity circuit at size %i', + async size => { + // Fill the rung with real messages so `numMessages === size` (the largest circuit for that rung). + const messages = Array.from({ length: size }, () => Fr.random()); const proverId = Fr.random(); - const baseParityInputs = makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, i => - ParityBasePrivateInputs.fromSlice(l1ToL2Messages, i, getVKTreeRoot(), proverId), - ); - // Generate the base parity proofs - const baseParityProofsAndPublicInputs = await Promise.all( - baseParityInputs.map(baseInputs => context.prover.getBaseParityProof(baseInputs)), + const inputs = InboxParityPrivateInputs.fromMessages( + messages, + Fr.ZERO, + L1ToL2MessageSponge.empty(), + getVKTreeRoot(), + proverId, ); + expect(inputs.size).toBe(size); - const rootInputs = makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, i => { - const inputs = baseParityProofsAndPublicInputs[i]; - return toProofData(inputs); - }); + const output = await context.prover.getInboxParityProof(inputs); - // These could differ if artifacts generated by `generate_vk_json.js` are not consistent with what we do, - // which would cause the root parity proof to fail, because the proof of VK root inclusion would not match the key in the proof. - expect(ServerCircuitVks.ParityBaseArtifact.keyAsFields.hash).toEqual(rootInputs[0].vkData.vk.keyAsFields.hash); + const artifact = artifactForSize[size as InboxParitySize]; + // Sanity: the VK the proof was generated against is the one in the vk tree for this rung. + expect(ServerCircuitVks[artifact].keyAsFields.hash).toEqual(output.verificationKey.keyAsFields.hash); - // Verify the base parity proofs if (bbProver) { - await expect( - Promise.all( - baseParityProofsAndPublicInputs.map(input => - bbProver!.verifyProof('ParityBaseArtifact', input.proof.binaryProof), - ), - ), - ).resolves.not.toThrow(); - } - - // Now generate the root parity proof - const rootParityInputs = new ParityRootPrivateInputs(rootInputs); - const rootOutput = await context.prover.getRootParityProof(rootParityInputs); - - // We only test validity and negative proofs with actual proofs enabled - if (!bbProver) { - return; - } - - // Verify the root parity proof - await expect(bbProver.verifyProof('ParityRootArtifact', rootOutput.proof.binaryProof)).resolves.not.toThrow(); - - // Now test for negative cases. We will try and generate 3 invalid proofs. - // One where a single child has an invalid proof - // One where a child has incorrect public inputs - // One where a child has an invalid verification key - // In each case either the proof should fail to generate or verify - - const validVk = rootParityInputs.children[0].vkData.vk; - const validPublicInputs = rootParityInputs.children[0].publicInputs; - const validProof = rootParityInputs.children[0].proof; - - const defectiveProofInput = toProofData({ - inputs: validPublicInputs, - proof: makeRecursiveProof(RECURSIVE_PROOF_LENGTH, 0x500), - verificationKey: validVk, - }); - - const shaRoot = randomBytes(32); - shaRoot[0] = 0; - - const defectivePublicInputs = toProofData({ - inputs: new ParityPublicInputs(Fr.fromBuffer(shaRoot), Fr.random(), getVKTreeRoot(), proverId), - proof: validProof, - verificationKey: validVk, - }); - - const defectiveVerificationKey = toProofData( - { - inputs: validPublicInputs, - proof: validProof, - verificationKey: VerificationKeyData.makeFakeHonk(), - }, - PARITY_BASE_VK_INDEX, - ); - - const tupleWithDefectiveProof = makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, (i: number) => { - if (i == 0) { - return defectiveProofInput; - } - return rootParityInputs.children[i]; - }); - - const tupleWithDefectiveInputs = makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, (i: number) => { - if (i == 0) { - return defectivePublicInputs; - } - return rootParityInputs.children[i]; - }); - - const tupleWithDefectiveVK = makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, (i: number) => { - if (i == 0) { - return defectiveVerificationKey; - } - return rootParityInputs.children[i]; - }); - - // Check the invalid VK scenario with an invalid witness assertion - await expect( - context.prover.getRootParityProof(new ParityRootPrivateInputs(tupleWithDefectiveVK)), - ).rejects.toThrow('Failed to generate witness'); - - for (const t of [tupleWithDefectiveProof, tupleWithDefectiveInputs]) { - await expect(async () => { - const result = await context.prover.getRootParityProof(new ParityRootPrivateInputs(t)); - await bbProver!.verifyProof('ParityRootArtifact', result.proof.binaryProof); - fail('Proof should not be generated and verified'); - }).rejects.toThrow(/Failed to generate proof|Failed to verify proof/); + await expect(bbProver.verifyProof(artifact, output.proof.binaryProof)).resolves.not.toThrow(); } }, FAKE_PROOFS ? undefined : 600_000, diff --git a/yarn-project/prover-client/src/test/epoch_proving_sim.test.ts b/yarn-project/prover-client/src/test/epoch_proving_sim.test.ts index a83b8ced6935..2954b2e5fa3b 100644 --- a/yarn-project/prover-client/src/test/epoch_proving_sim.test.ts +++ b/yarn-project/prover-client/src/test/epoch_proving_sim.test.ts @@ -1,5 +1,4 @@ import { PROOF_DELAY_MS, WITGEN_DELAY_MS } from '@aztec/bb-prover/test'; -import { NUM_BASE_PARITY_PER_ROOT_PARITY } from '@aztec/constants'; import { insertIntoSortedArray } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { ProvingRequestType } from '@aztec/stdlib/proofs'; @@ -25,8 +24,7 @@ const PROOF_TYPES_IN_PRIORITY_ORDER: ProvingRequestType[] = [ ProvingRequestType.PRIVATE_TX_BASE_ROLLUP, ProvingRequestType.PUBLIC_VM, ProvingRequestType.PUBLIC_CHONK_VERIFIER, - ProvingRequestType.PARITY_ROOT, - ProvingRequestType.PARITY_BASE, // Lowest priority + ProvingRequestType.INBOX_PARITY, // Lowest priority ]; // Job represents a proving task with its hierarchical context @@ -66,9 +64,8 @@ type TestConfig = { // State tracking for dependency resolution type SimState = { - // Parity tracking (per checkpoint, first block only) - baseParityComplete: Map; - rootParityComplete: Map; + // Parity tracking: one InboxParity proof per checkpoint, gating the first block root. + inboxParityComplete: Map; // Public tx dependency tracking (aggregate per block) // Key format: "checkpoint-block" @@ -243,8 +240,7 @@ function getBlockTxCount(block: Block): { privateTxs: number; publicTxs: number; function initializeState(checkpoints: Checkpoint[]): SimState { const state: SimState = { - baseParityComplete: new Map(), - rootParityComplete: new Map(), + inboxParityComplete: new Map(), vmComplete: new Map(), chonkComplete: new Map(), publicBaseEnqueued: new Map(), @@ -267,8 +263,7 @@ function initializeState(checkpoints: Checkpoint[]): SimState { for (let cp = 1; cp <= checkpoints.length; cp++) { const blocks = checkpoints[cp - 1]; state.blocksPerCheckpoint.set(cp, blocks.length); - state.baseParityComplete.set(cp, 0); - state.rootParityComplete.set(cp, false); + state.inboxParityComplete.set(cp, false); state.blockRootComplete.set(cp, false); state.checkpointRootComplete.set(cp, false); @@ -300,10 +295,8 @@ function fillQueue(queues: Queues, checkpoints: Checkpoint[]): void { for (let cp = 1; cp <= checkpoints.length; cp++) { const blocks = checkpoints[cp - 1]; - // assume every checkpoint includes cross-chain messages - queues[ProvingRequestType.PARITY_BASE].push( - ...times(NUM_BASE_PARITY_PER_ROOT_PARITY, () => createJob(cp, 1, ProvingRequestType.PARITY_BASE)), - ); + // assume every checkpoint includes cross-chain messages: one InboxParity proof per checkpoint + queues[ProvingRequestType.INBOX_PARITY].push(createJob(cp, 1, ProvingRequestType.INBOX_PARITY)); for (let b = 1; b <= blocks.length; b++) { const block = blocks[b - 1]; @@ -335,18 +328,8 @@ function enqueueDependentJobs(job: Job, state: SimState, queues: Queues, checkpo const key = blockKey(checkpoint, block); switch (type) { - case ProvingRequestType.PARITY_BASE: { - const count = (state.baseParityComplete.get(checkpoint) ?? 0) + 1; - state.baseParityComplete.set(checkpoint, count); - - if (count === NUM_BASE_PARITY_PER_ROOT_PARITY) { - queues[ProvingRequestType.PARITY_ROOT].push(createJob(checkpoint, 1, ProvingRequestType.PARITY_ROOT)); - } - break; - } - - case ProvingRequestType.PARITY_ROOT: { - state.rootParityComplete.set(checkpoint, true); + case ProvingRequestType.INBOX_PARITY: { + state.inboxParityComplete.set(checkpoint, true); tryEnqueueBlockRoot(checkpoint, 1, state, queues); break; } @@ -523,8 +506,8 @@ function tryEnqueueBlockRoot(checkpoint: number, blk: number, state: SimState, q return; } - // First block also needs root parity - if (isFirst && !state.rootParityComplete.get(checkpoint)) { + // First block also needs the checkpoint's InboxParity proof + if (isFirst && !state.inboxParityComplete.get(checkpoint)) { return; } diff --git a/yarn-project/prover-client/src/test/mock_prover.ts b/yarn-project/prover-client/src/test/mock_prover.ts index 51415ebf677e..59b9d4c5a7c1 100644 --- a/yarn-project/prover-client/src/test/mock_prover.ts +++ b/yarn-project/prover-client/src/test/mock_prover.ts @@ -1,6 +1,5 @@ import { AVM_V2_PROOF_LENGTH_IN_FIELDS, - NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, RECURSIVE_PROOF_LENGTH, } from '@aztec/constants'; @@ -15,13 +14,14 @@ import { type ServerCircuitProver, makePublicInputsAndRecursiveProof, } from '@aztec/stdlib/interfaces/server'; -import type { ParityBasePrivateInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity'; +import type { InboxParityPrivateInputs } from '@aztec/stdlib/parity'; import { makeEmptyRecursiveProof, makeRecursiveProof } from '@aztec/stdlib/proofs'; import type { BlockMergeRollupPrivateInputs, BlockRollupPublicInputs, BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -107,7 +107,7 @@ export class MockProver implements ServerCircuitProver { return Promise.resolve(makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS)); } - getBaseParityProof(_inputs: ParityBasePrivateInputs, _signal?: AbortSignal, _epochNumber?: number) { + getInboxParityProof(_inputs: InboxParityPrivateInputs, _signal?: AbortSignal, _epochNumber?: number) { return Promise.resolve( makePublicInputsAndRecursiveProof( makeParityPublicInputs(), @@ -117,16 +117,6 @@ export class MockProver implements ServerCircuitProver { ); } - getRootParityProof(_inputs: ParityRootPrivateInputs, _signal?: AbortSignal, _epochNumber?: number) { - return Promise.resolve( - makePublicInputsAndRecursiveProof( - makeParityPublicInputs(), - makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH), - VerificationKeyData.makeFakeHonk(), - ), - ); - } - getPublicChonkVerifierProof( _inputs: PublicChonkVerifierPrivateInputs, _signal?: AbortSignal, @@ -227,6 +217,20 @@ export class MockProver implements ServerCircuitProver { ); } + getBlockRootMsgsOnlyRollupProof( + _input: BlockRootMsgsOnlyRollupPrivateInputs, + _signal?: AbortSignal, + _epochNumber?: number, + ): Promise> { + return Promise.resolve( + makePublicInputsAndRecursiveProof( + makeBlockRollupPublicInputs(), + makeRecursiveProof(NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH), + VerificationKeyData.makeFakeRollupHonk(), + ), + ); + } + getBlockRootRollupProof( _input: BlockRootRollupPrivateInputs, _signal?: AbortSignal, diff --git a/yarn-project/prover-client/src/test/proving_broker_testbench.test.ts b/yarn-project/prover-client/src/test/proving_broker_testbench.test.ts index 67bff56cdb43..d50aac8f3ef2 100644 --- a/yarn-project/prover-client/src/test/proving_broker_testbench.test.ts +++ b/yarn-project/prover-client/src/test/proving_broker_testbench.test.ts @@ -164,8 +164,7 @@ function getProofCounts( counts[priorityIndex(ProvingRequestType.CHECKPOINT_ROOT_ROLLUP)] = numCheckpoints; } - counts[priorityIndex(ProvingRequestType.PARITY_BASE)] = numCheckpoints * 4; - counts[priorityIndex(ProvingRequestType.PARITY_ROOT)] = numCheckpoints; + counts[priorityIndex(ProvingRequestType.INBOX_PARITY)] = numCheckpoints; if (numBlocksPerCheckpoint > 2) { counts[priorityIndex(ProvingRequestType.BLOCK_MERGE_ROLLUP)] = (numBlocksPerCheckpoint - 2) * numCheckpoints; diff --git a/yarn-project/prover-client/src/test/regenerate_rollup_sample_inputs.test.ts b/yarn-project/prover-client/src/test/regenerate_rollup_sample_inputs.test.ts new file mode 100644 index 000000000000..dc58fe5e8e90 --- /dev/null +++ b/yarn-project/prover-client/src/test/regenerate_rollup_sample_inputs.test.ts @@ -0,0 +1,234 @@ +import { MAX_L1_TO_L2_MSGS_PER_BLOCK } from '@aztec/constants'; +import { EpochNumber } from '@aztec/foundation/branded-types'; +import { times, timesAsync } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { EthAddress } from '@aztec/foundation/eth-address'; +import { type Logger, createLogger } from '@aztec/foundation/log'; +import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; +import { updateProtocolCircuitSampleInputs } from '@aztec/foundation/testing/files'; +import type { CircuitName } from '@aztec/stdlib/stats'; + +import TOML from '@iarna/toml'; + +import { TestContext, makeTestDeferredJobQueue } from '../mocks/test_context.js'; +import { CheckpointSubTreeOrchestrator } from '../orchestrator/checkpoint-sub-tree-orchestrator.js'; +import { ChonkCache } from '../orchestrator/chonk-cache.js'; +import { type CheckpointTopTreeData, TopTreeOrchestrator } from '../orchestrator/top-tree-orchestrator.js'; + +// Regenerates the committed `crates/rollup-*/Prover.toml` sample inputs that CI runs `nargo execute` +// against, for every rollup circuit at or above the transaction merge: the block-root variants, the +// block-merge, both checkpoint roots, the checkpoint-merge, the tx-merge, and the root rollup. The +// rollup circuits push their serialized inputs via `pushTestData` whenever they run through the +// prover, so driving representative epochs through the (simulated) orchestrator and then dumping +// `getTestData(circuitName)` produces fresh, ABI-current fixtures. Run with: +// AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test regenerate_rollup_sample_inputs +// Without that flag the whole suite is skipped, so it is a no-op (no prover setup) in normal CI. The +// `rollup-tx-base-private`/`rollup-tx-base-public` fixtures and the private-kernel fixtures depend on +// real client-proved transactions the simulated orchestrator cannot produce, so those are regenerated +// separately by the e2e `single-node/prover/server/full.test` dump instead. +// +// The scenarios are chosen to exercise each block-root variant the orchestrator selects (see +// BlockProvingState#getBlockRootRollupTypeAndInputs): a first block with 0 txs, with >=2 txs, and +// with 1 tx; non-first blocks with 1 tx (from the three-block checkpoint) and with >=2 txs (from the +// two-block checkpoint). The three-block checkpoint also produces a block-merge and the three- +// checkpoint epoch a checkpoint-merge; a merge node only exists above the tree root, so both merges +// need three leaves — two would pair directly at the root. Single-block checkpoints feed the +// checkpoint-root-single-block circuit and multi-block checkpoints the (two-input) checkpoint-root +// circuit. A block with three txs merges its transaction base proofs through the tx-merge circuit +// before the (two-input) block root, whereas one- or two-tx blocks feed the block root directly, so a +// dedicated three-tx scenario is what regenerates the tx-merge sample. A zero-tx non-first block that +// carries a message bundle (a message-only block) routes through the msgs-only +// block root, so that variant needs a per-block message distribution. Every scenario also produces +// the root rollup. +const describeOrSkip = isGenerateTestDataEnabled() ? describe : describe.skip; + +describeOrSkip('prover/regenerate-rollup-sample-inputs', () => { + let context: TestContext; + let log: Logger; + + interface Scenario { + numCheckpoints: number; + numBlocksPerCheckpoint: number; + numTxsPerBlock: number | number[]; + numL1ToL2Messages: number; + /** + * Per-block message distribution. When set it overrides `numL1ToL2Messages`, and a zero-tx non-first block with + * a non-empty slice routes through the msgs-only block root. + */ + l1ToL2MessagesPerBlock?: Fr[][]; + /** Circuits whose sample inputs this scenario is responsible for regenerating. */ + dump: CircuitName[]; + } + + // `makeCheckpoint` puts the scenario's whole message list into the first block, so the most a + // scenario can carry is one full per-block bundle, not the per-checkpoint cap. + const withMessages = MAX_L1_TO_L2_MSGS_PER_BLOCK; + + const scenarios: Scenario[] = [ + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 1, + numTxsPerBlock: 0, + numL1ToL2Messages: withMessages, + dump: ['rollup-block-root-first-empty-tx'], + }, + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 1, + numTxsPerBlock: 2, + numL1ToL2Messages: withMessages, + dump: ['rollup-block-root-first', 'rollup-checkpoint-root-single-block', 'rollup-root'], + }, + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 3, + numTxsPerBlock: 1, + numL1ToL2Messages: withMessages, + dump: [ + 'rollup-block-root-first-single-tx', + 'rollup-block-root-single-tx', + 'rollup-block-merge', + 'rollup-checkpoint-root', + ], + }, + // Messages split across both blocks so the non-first block-root sample carries a non-empty + // bundle, exercising the per-block sponge continuity asserts in the circuit. + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 2, + numTxsPerBlock: 2, + numL1ToL2Messages: 0, // Overridden by l1ToL2MessagesPerBlock. + l1ToL2MessagesPerBlock: [times(2, i => new Fr(0xb00 + i)), times(3, i => new Fr(0xc00 + i))], + dump: ['rollup-block-root'], + }, + // Three txs in a block force a tx-merge to pair the base proofs down to the two the block root + // takes; one- or two-tx blocks feed the block root directly and never exercise tx-merge. + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 1, + numTxsPerBlock: 3, + numL1ToL2Messages: withMessages, + dump: ['rollup-tx-merge'], + }, + // A zero-tx non-first block carrying a message bundle is a message-only block, the only shape that + // selects the msgs-only block root. + { + numCheckpoints: 1, + numBlocksPerCheckpoint: 2, + numTxsPerBlock: [1, 0], + numL1ToL2Messages: 0, // Overridden by l1ToL2MessagesPerBlock. + l1ToL2MessagesPerBlock: [times(2, i => new Fr(0x900 + i)), times(3, i => new Fr(0xa00 + i))], + dump: ['rollup-block-root-msgs-only'], + }, + // The checkpoint-merge only appears with three checkpoints. Independently-built checkpoints do + // not carry the inbox message state forward, so this scenario runs with no L1-to-L2 messages and + // a zero previous rolling hash, matching the multi-checkpoint case in top-tree-orchestrator.test. + { + numCheckpoints: 3, + numBlocksPerCheckpoint: 1, + numTxsPerBlock: 1, + numL1ToL2Messages: 0, + dump: ['rollup-checkpoint-merge'], + }, + ]; + + beforeEach(async () => { + log = createLogger('prover-client:test:regenerate-rollup-sample-inputs'); + context = await TestContext.new(log, { proverCount: 1 }); + }); + + afterEach(async () => { + await context.cleanup(); + }); + + it.each(scenarios)( + 'regenerates $dump from an epoch with $numCheckpoints checkpoints, $numBlocksPerCheckpoint blocks, $numTxsPerBlock txs', + async ({ + numCheckpoints, + numBlocksPerCheckpoint, + numTxsPerBlock, + numL1ToL2Messages, + l1ToL2MessagesPerBlock, + dump, + }) => { + const makeProcessedTxOpts = (_: unknown, txIndex: number) => ({ privateOnly: txIndex % 2 === 0 }); + const checkpoints = await timesAsync(numCheckpoints, () => + l1ToL2MessagesPerBlock + ? context.makeCheckpointWithMessagesPerBlock(l1ToL2MessagesPerBlock, { numTxsPerBlock, makeProcessedTxOpts }) + : context.makeCheckpoint(numBlocksPerCheckpoint, { numTxsPerBlock, numL1ToL2Messages, makeProcessedTxOpts }), + ); + + const finalBlobChallenges = await context.getFinalBlobChallenges(); + const chonkCache = new ChonkCache(); + const subTrees: CheckpointSubTreeOrchestrator[] = []; + const topTreeData: CheckpointTopTreeData[] = []; + + try { + for (let checkpointIndex = 0; checkpointIndex < numCheckpoints; checkpointIndex++) { + const { constants, blocks, l1ToL2Messages, previousBlockHeader, checkpoint } = checkpoints[checkpointIndex]; + + // First checkpoint starts from genesis; the multi-checkpoint scenario carries no messages, + // so every checkpoint's previous rolling hash is zero. + const previousInboxRollingHash = Fr.ZERO; + + const subTree = await CheckpointSubTreeOrchestrator.start( + context.worldState, + context.prover, + EthAddress.ZERO, + chonkCache, + EpochNumber(1), + /* cancelJobsOnStop */ false, + makeTestDeferredJobQueue(), + constants, + l1ToL2Messages, + previousInboxRollingHash, + numBlocksPerCheckpoint, + previousBlockHeader, + ); + subTrees.push(subTree); + + for (let i = 0; i < numBlocksPerCheckpoint; i++) { + const { header, txs } = blocks[i]; + const { blockNumber, timestamp } = header.globalVariables; + + const blockMessages = l1ToL2MessagesPerBlock?.[i] ?? (i === 0 ? l1ToL2Messages : []); + await subTree.startNewBlock(blockNumber, timestamp, txs.length, blockMessages); + if (txs.length > 0) { + await subTree.addTxs(txs); + } + await subTree.setBlockCompleted(blockNumber, header); + } + + topTreeData.push({ + subTreeProofs: subTree + .getSubTreeResult() + .then(r => ({ blockProofOutputs: r.blockProofOutputs, inboxParityProof: r.inboxParityProof })), + l2ToL1MsgsPerBlock: blocks.map(b => b.txs.map(tx => tx.txEffect.l2ToL1Msgs)), + blobFields: checkpoint.toBlobFields(), + previousBlockHeader, + previousArchiveSiblingPath: subTree.getPreviousArchiveSiblingPath(), + }); + } + + const topTree = new TopTreeOrchestrator(context.prover, EthAddress.ZERO, makeTestDeferredJobQueue()); + try { + await topTree.prove(EpochNumber(1), numCheckpoints, finalBlobChallenges, topTreeData); + } finally { + await topTree.stop(); + } + + for (const circuitName of dump) { + const data = getTestData(circuitName); + if (!data || data.length === 0) { + throw new Error(`No test data captured for ${circuitName}; scenario does not exercise it.`); + } + updateProtocolCircuitSampleInputs(circuitName, TOML.stringify(data[0] as any)); + log.info(`Regenerated sample inputs for ${circuitName}`); + } + } finally { + await Promise.all(subTrees.map(s => s.stop())); + } + }, + 300_000, + ); +}); diff --git a/yarn-project/prover-node/src/actions/rerun-epoch-proving-job.ts b/yarn-project/prover-node/src/actions/rerun-epoch-proving-job.ts index 1a64e5c2ccb4..d909738c118b 100644 --- a/yarn-project/prover-node/src/actions/rerun-epoch-proving-job.ts +++ b/yarn-project/prover-node/src/actions/rerun-epoch-proving-job.ts @@ -6,7 +6,7 @@ import { DateProvider } from '@aztec/foundation/timer'; import { type ProverClientConfig, createProverClient } from '@aztec/prover-client'; import { ProverBrokerConfig, createAndStartProvingBroker } from '@aztec/prover-client/broker'; import { getLastSiblingPath } from '@aztec/prover-client/helpers'; -import { ChonkCache } from '@aztec/prover-client/orchestrator'; +import { type CheckpointSubTreeProofs, ChonkCache } from '@aztec/prover-client/orchestrator'; import { AvmSimulatorPool, PublicProcessorFactory } from '@aztec/simulator/server'; import type { L2Block } from '@aztec/stdlib/block'; import { getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers'; @@ -86,7 +86,7 @@ export async function rerunCheckpointProvingJob( log: Logger, config: RerunConfig, genesis?: GenesisData, -) { +): Promise { await using ctx = await createRerunContext(localPath, log, config, genesis); const { jobData } = ctx; const checkpointNumber = jobData.checkpoints[0].number; @@ -95,9 +95,9 @@ export async function rerunCheckpointProvingJob( const prover = await buildCheckpointProver(ctx, 0, log); try { - const blockProofs = await prover.whenBlockProofsReady(); - log.info(`Completed proving for checkpoint ${checkpointNumber} with ${blockProofs.length} block proof(s)`); - return blockProofs; + const { blockProofOutputs } = await prover.whenSubTreeProofsReady(); + log.info(`Completed proving for checkpoint ${checkpointNumber} with ${blockProofOutputs.length} block proof(s)`); + return blockProofOutputs; } finally { prover.cancel({ routine: true }); await prover.whenDone(); @@ -167,6 +167,8 @@ async function buildCheckpointProver(ctx: RerunContext, index: number, log: Logg const checkpoint = jobData.checkpoints[index]; const previousBlockHeader = index === 0 ? jobData.previousBlockHeader : jobData.checkpoints[index - 1].blocks.at(-1)!.header; + const previousInboxRollingHash = + index === 0 ? jobData.previousInboxRollingHash : jobData.checkpoints[index - 1].header.inboxRollingHash; const l1ToL2Messages = jobData.l1ToL2Messages[checkpoint.number] ?? []; const previousArchiveSiblingPath = await getLastSiblingPath( MerkleTreeId.ARCHIVE, @@ -180,6 +182,7 @@ async function buildCheckpointProver(ctx: RerunContext, index: number, log: Logg attestations, previousBlockHeader, l1ToL2Messages, + previousInboxRollingHash, previousArchiveSiblingPath, }, { diff --git a/yarn-project/prover-node/src/checkpoint-store.test.ts b/yarn-project/prover-node/src/checkpoint-store.test.ts index bd823eb83847..c38a11417358 100644 --- a/yarn-project/prover-node/src/checkpoint-store.test.ts +++ b/yarn-project/prover-node/src/checkpoint-store.test.ts @@ -200,6 +200,7 @@ function makeRegisterData() { attestations: [], previousBlockHeader: {} as any, l1ToL2Messages: [], + previousInboxRollingHash: Fr.ZERO, previousArchiveSiblingPath: makeTuple(ARCHIVE_HEIGHT, () => Fr.ZERO), }; } diff --git a/yarn-project/prover-node/src/job/checkpoint-prover.test.ts b/yarn-project/prover-node/src/job/checkpoint-prover.test.ts index 288a11c3cb71..27e97300cade 100644 --- a/yarn-project/prover-node/src/job/checkpoint-prover.test.ts +++ b/yarn-project/prover-node/src/job/checkpoint-prover.test.ts @@ -134,13 +134,13 @@ describe('CheckpointProver', () => { await prover.whenDone(); }); - it('rejects whenBlockProofsReady() but does not mark the prover failed or fire onFailed', async () => { + it('rejects whenSubTreeProofsReady() but does not mark the prover failed or fire onFailed', async () => { // A cancel (reorg/prune/shutdown) is not a proving failure: isFailed() must stay false and the // onFailed callback must not fire (no post-mortem upload for a cancelled prover). const prover = makeProver(); - const blockProofs = prover.whenBlockProofsReady(); + const subTreeProofs = prover.whenSubTreeProofsReady(); prover.cancel(); - await expect(blockProofs).rejects.toThrow(/cancelled/); + await expect(subTreeProofs).rejects.toThrow(/cancelled/); expect(prover.isFailed()).toBe(false); expect(onFailed).not.toHaveBeenCalled(); await prover.whenDone(); @@ -161,11 +161,11 @@ describe('CheckpointProver', () => { it('routine cancel still aborts and rejects block proofs (only log level differs)', async () => { const prover = makeProver(); - const blockProofs = prover.whenBlockProofsReady(); + const subTreeProofs = prover.whenSubTreeProofsReady(); prover.cancel({ routine: true }); expect(prover.isCancelled()).toBe(true); expect(prover.getAbortSignal().aborted).toBe(true); - await expect(blockProofs).rejects.toThrow(/cancelled/); + await expect(subTreeProofs).rejects.toThrow(/cancelled/); await prover.whenDone(); }); }); @@ -221,7 +221,7 @@ describe('CheckpointProver', () => { // ---------------- gather failure ---------------- describe('gather failures', () => { - it('rejects whenBlockProofsReady when txProvider returns missing txs', async () => { + it('rejects whenSubTreeProofsReady when txProvider returns missing txs', async () => { const missingHash = checkpoint.blocks[0].body.txEffects[0]?.txHash; // Without a real missing hash the per-block payload would be empty and the prover // would happily proceed; only checkpoints with txs can exercise this branch. @@ -232,7 +232,7 @@ describe('CheckpointProver', () => { txProvider.getTxsForBlock.mockResolvedValue({ txs: [], missingTxs: [missingHash] }); const prover = makeProver(); - await expect(prover.whenBlockProofsReady()).rejects.toThrow(/Txs not found/); + await expect(prover.whenSubTreeProofsReady()).rejects.toThrow(/Txs not found/); await prover.whenDone(); }); @@ -245,19 +245,19 @@ describe('CheckpointProver', () => { txProvider.getTxsForBlock.mockReturnValue(gate.promise); const prover = makeProver(); - const blockProofs = prover.whenBlockProofsReady(); + const subTreeProofs = prover.whenSubTreeProofsReady(); prover.cancel(); gate.reject(new Error('gather aborted by test')); - await expect(blockProofs).rejects.toThrow(/cancelled/); + await expect(subTreeProofs).rejects.toThrow(/cancelled/); await expect(prover.whenDone()).resolves.toBeUndefined(); }); - it('lets a second whenBlockProofsReady caller observe the same rejection', async () => { + it('lets a second whenSubTreeProofsReady caller observe the same rejection', async () => { // Two callers awaiting the same promise both see the rejection — neither leaks an // unhandled rejection (the constructor pre-attaches a noop catch handler). const prover = makeProver(); - const a = prover.whenBlockProofsReady(); - const b = prover.whenBlockProofsReady(); + const a = prover.whenSubTreeProofsReady(); + const b = prover.whenSubTreeProofsReady(); prover.cancel(); await Promise.all([expect(a).rejects.toThrow(/cancelled/), expect(b).rejects.toThrow(/cancelled/)]); await prover.whenDone(); @@ -274,7 +274,7 @@ describe('CheckpointProver', () => { const prover = makeProver(); failure.resolve({ txs: [], missingTxs: [missingHash] }); - await expect(prover.whenBlockProofsReady()).rejects.toThrow(/Txs not found/); + await expect(prover.whenSubTreeProofsReady()).rejects.toThrow(/Txs not found/); // Subsequent cancel is a no-op; no throws. prover.cancel(); expect(prover.isCancelled()).toBe(true); @@ -285,10 +285,10 @@ describe('CheckpointProver', () => { // ---------------- data-plane reorg fork fault ---------------- describe('data-plane reorg fault', () => { - it('rejects whenBlockProofsReady when a world-state fork faults mid-proof', async () => { + it('rejects whenSubTreeProofsReady when a world-state fork faults mid-proof', async () => { // Models the data-plane prune race: gather succeeds and the sub-tree starts, but the // world-state synchronizer has already unwound the base block, so forking it faults inside - // executeCheckpoint. The fault must reject whenBlockProofsReady() AND mark the prover failed, so + // executeCheckpoint. The fault must reject whenSubTreeProofsReady() AND mark the prover failed, so // the SessionManager won't build (or rebuild) an EpochSession over it until a re-add replaces it. txProvider.getTxsForBlock.mockReset(); txProvider.getTxsForBlock.mockResolvedValue({ txs: [], missingTxs: [] }); @@ -310,9 +310,9 @@ describe('CheckpointProver', () => { const prover = makeProver(); - // blockProofs rejects: the fork error aborts the block loop before completion, so the sub-tree + // subTreeProofs rejects: the fork error aborts the block loop before completion, so the sub-tree // never yields proofs. (The raw fork error is logged; the promise settles as not-completed.) - await expect(prover.whenBlockProofsReady()).rejects.toThrow(/did not complete block processing/); + await expect(prover.whenSubTreeProofsReady()).rejects.toThrow(/did not complete block processing/); expect(dbProvider.fork).toHaveBeenCalled(); expect(prover.isFailed()).toBe(true); // The owner is notified exactly once, with this prover, so it can upload a checkpoint post-mortem. @@ -332,6 +332,7 @@ describe('CheckpointProver', () => { attestations: [], previousBlockHeader: {} as BlockHeader, l1ToL2Messages: [], + previousInboxRollingHash: Fr.ZERO, previousArchiveSiblingPath: makeTuple(ARCHIVE_HEIGHT, () => Fr.ZERO), ...overrides, }; diff --git a/yarn-project/prover-node/src/job/checkpoint-prover.ts b/yarn-project/prover-node/src/job/checkpoint-prover.ts index 5a04412bb85a..312a21578b5a 100644 --- a/yarn-project/prover-node/src/job/checkpoint-prover.ts +++ b/yarn-project/prover-node/src/job/checkpoint-prover.ts @@ -1,6 +1,5 @@ -import { type ARCHIVE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; +import type { ARCHIVE_HEIGHT } from '@aztec/constants'; import { BlockNumber, type EpochNumber, type SlotNumber } from '@aztec/foundation/branded-types'; -import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { EthAddress } from '@aztec/foundation/eth-address'; import type { Logger } from '@aztec/foundation/log'; @@ -10,7 +9,11 @@ import { type DateProvider, Timer } from '@aztec/foundation/timer'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; import { protocolContractsHash } from '@aztec/protocol-contracts'; import type { EpochProverFactory } from '@aztec/prover-client'; -import type { CheckpointSubTreeOrchestrator, ChonkCache, SubTreeResult } from '@aztec/prover-client/orchestrator'; +import type { + CheckpointSubTreeOrchestrator, + CheckpointSubTreeProofs, + ChonkCache, +} from '@aztec/prover-client/orchestrator'; import type { PublicProcessor, PublicProcessorFactory } from '@aztec/simulator/server'; import { PublicSimulatorConfig } from '@aztec/stdlib/avm'; import type { CommitteeAttestation, L2Block } from '@aztec/stdlib/block'; @@ -65,6 +68,8 @@ export type CheckpointProverArgs = { attestations: CommitteeAttestation[]; previousBlockHeader: BlockHeader; l1ToL2Messages: Fr[]; + /** Inbox rolling hash of the previous checkpoint (this checkpoint's chain start); genesis is zero. */ + previousInboxRollingHash: Fr; previousArchiveSiblingPath: Tuple; }; @@ -78,8 +83,8 @@ export type CheckpointProverArgs = { * predecessor but with different content, keys to a distinct prover. * * The prover eagerly starts its own tx gather and sub-tree work in the constructor, so - * callers only need to call `whenBlockProofsReady()` to obtain the resulting block-rollup - * proofs. + * callers only need to call `whenSubTreeProofsReady()` to obtain the resulting block-rollup + * and InboxParity proofs. * * A CheckpointProver does not survive a prune: its sub-tree work forks world-state per * block, and an L1 prune of a base block faults those reads. The store therefore cancels and @@ -97,19 +102,21 @@ export class CheckpointProver { readonly attestations: CommitteeAttestation[]; readonly previousBlockHeader: BlockHeader; readonly l1ToL2Messages: Fr[]; + readonly previousInboxRollingHash: Fr; readonly previousArchiveSiblingPath: Tuple; /** Per-prover tx map — populated by the internal gather. Empty until then. */ readonly txs: Map = new Map(); - /** Resolved by the sub-tree on success, rejected on cancel/failure. */ - private readonly blockProofs: PromiseWithResolvers = promiseWithResolvers(); + /** Resolved by the sub-tree on success, rejected on cancel/failure. Carries the block proofs plus the checkpoint's + * InboxParity proof (which feeds the checkpoint root in the top tree). */ + private readonly subTreeProofs: PromiseWithResolvers = promiseWithResolvers(); // Three independent lifecycle facts — deliberately not collapsed into one status enum, because several // combinations are legal and relied on: a prover can be `completed` and then `cancelled` (routine // teardown of an already-proven checkpoint), or `completed` and then `failed` (block proving was // enqueued, but the sub-tree subsequently faulted). Only `failed` + `cancelled` is excluded — a cancel - // is not a failure (enforced in `failBlockProofs`). + // is not a failure (enforced in `failSubTreeProofs`). /** Block-level proving was fully *enqueued* (a progress marker; the sub-tree may still be proving). */ private completed = false; /** Block proofs rejected for a genuine (non-cancel) reason — a sub-tree or prune-induced fork fault. */ @@ -134,11 +141,12 @@ export class CheckpointProver { this.attestations = args.attestations; this.previousBlockHeader = args.previousBlockHeader; this.l1ToL2Messages = args.l1ToL2Messages; + this.previousInboxRollingHash = args.previousInboxRollingHash; this.previousArchiveSiblingPath = args.previousArchiveSiblingPath; this.id = CheckpointProver.idFor(args.checkpoint); - // Mark blockProofs as observed so a cancel that lands before any consumer awaits + // Mark subTreeProofs as observed so a cancel that lands before any consumer awaits // does not surface as an unhandled rejection. - this.blockProofs.promise.catch(() => {}); + this.subTreeProofs.promise.catch(() => {}); deps.log.info(`Created CheckpointProver ${this.id}`, { checkpointNumber: this.checkpoint.number, epochNumber: this.epochNumber, @@ -179,9 +187,9 @@ export class CheckpointProver { return this.abortController.signal; } - /** Promise that resolves with the block-rollup proofs for this checkpoint (or rejects on cancel/failure). */ - public whenBlockProofsReady(): Promise { - return this.blockProofs.promise; + /** Promise that resolves with the block-rollup proofs and InboxParity proof for this checkpoint (or rejects). */ + public whenSubTreeProofsReady(): Promise { + return this.subTreeProofs.promise; } /** Resolves when all in-flight work for this prover has fully unwound. */ @@ -209,16 +217,16 @@ export class CheckpointProver { this.deps.log.error(`Error in CheckpointProver ${this.id}`, err, { checkpointNumber: this.checkpoint.number, }); - this.failBlockProofs(err instanceof Error ? err : new Error(String(err))); + this.failSubTreeProofs(err instanceof Error ? err : new Error(String(err))); } } /** - * Rejects the block-proof promise and, unless this is a cancellation, records the prover as failed so + * Rejects the sub-tree proof promise and, unless this is a cancellation, records the prover as failed so * the reconciler won't build an EpochSession over it. First rejection wins, so a later duplicate reject * (e.g. the executeCheckpoint `finally`) is a harmless no-op. */ - private failBlockProofs(err: Error): void { + private failSubTreeProofs(err: Error): void { if (!this.cancelled && !this.failed) { this.failed = true; // Notify the owner so it can upload a post-mortem for this checkpoint. Fire-and-forget: the @@ -229,7 +237,7 @@ export class CheckpointProver { this.deps.log.error(`Error in CheckpointProver onFailed callback for ${this.id}`, err); } } - this.blockProofs.reject(err); + this.subTreeProofs.reject(err); } private async gatherTxs(): Promise> { @@ -287,11 +295,12 @@ export class CheckpointProver { this.epochNumber, checkpointConstants, this.l1ToL2Messages, + this.previousInboxRollingHash, this.checkpoint.blocks.length, this.previousBlockHeader, ); subTreeStarted = true; - // Bridge the sub-tree's result onto blockProofs. + // Bridge the sub-tree's result onto subTreeProofs. void this.subTree.getSubTreeResult().then( result => { this.deps.log.info(`Sub-tree block proofs ready for checkpoint ${this.checkpoint.number}`, { @@ -300,9 +309,12 @@ export class CheckpointProver { }); // Spans processing + proving (from executeCheckpoint start, after tx gathering) to proofs ready. this.deps.metrics.recordCheckpointProving(checkpointTimer.ms()); - this.blockProofs.resolve(result.blockProofOutputs); + this.subTreeProofs.resolve({ + blockProofOutputs: result.blockProofOutputs, + inboxParityProof: result.inboxParityProof, + }); }, - err => this.failBlockProofs(err instanceof Error ? err : new Error(String(err))), + err => this.failSubTreeProofs(err instanceof Error ? err : new Error(String(err))), ); if (signal.aborted) { return; @@ -319,21 +331,31 @@ export class CheckpointProver { } } + // Streaming Inbox: the checkpoint's messages are consumed contiguously across its blocks; + // each block's slice runs from its parent block's L1-to-L2 leaf count to its own (compact indices make leaf + // count equal cumulative message count). + const l1ToL2LeafCount = (block: L2Block) => Number(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); + const checkpointStartLeafCount = l1ToL2LeafCount(this.checkpoint.blocks.at(-1)!) - this.l1ToL2Messages.length; + for (let blockIndex = 0; blockIndex < this.checkpoint.blocks.length; blockIndex++) { const blockTimer = new Timer(); const block = this.checkpoint.blocks[blockIndex]; const globalVariables = block.header.globalVariables; const blockTxs = this.getTxsForBlock(block, txs); - await this.subTree.startNewBlock(block.number, globalVariables.timestamp, blockTxs.length); + const prevLeafCount = + blockIndex === 0 ? checkpointStartLeafCount : l1ToL2LeafCount(this.checkpoint.blocks[blockIndex - 1]); + const blockMessages = this.l1ToL2Messages.slice( + prevLeafCount - checkpointStartLeafCount, + l1ToL2LeafCount(block) - checkpointStartLeafCount, + ); + + await this.subTree.startNewBlock(block.number, globalVariables.timestamp, blockTxs.length, blockMessages); if (signal.aborted) { return; } - const db = await this.createFork( - BlockNumber(block.number - 1), - blockIndex === 0 ? this.l1ToL2Messages : undefined, - ); + const db = await this.createFork(BlockNumber(block.number - 1), blockMessages); try { if (signal.aborted) { return; @@ -382,7 +404,7 @@ export class CheckpointProver { if (subTreeStarted) { await this.teardownSubTree(); } - this.failBlockProofs(new Error(`Checkpoint ${this.id} did not complete block processing`)); + this.failSubTreeProofs(new Error(`Checkpoint ${this.id} did not complete block processing`)); } } } @@ -415,7 +437,7 @@ export class CheckpointProver { }); } this.abortController.abort(); - this.blockProofs.reject(new Error(`Checkpoint ${this.id} cancelled`)); + this.subTreeProofs.reject(new Error(`Checkpoint ${this.id} cancelled`)); this.cancelPromise = this.runCancel().catch(() => {}); } @@ -478,19 +500,10 @@ export class CheckpointProver { return processedTxs; } - private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[] | undefined) { + private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[]) { const db = await this.deps.dbProvider.fork(blockNumber); - - if (l1ToL2Messages !== undefined) { - const l1ToL2MessagesPadded = padArrayEnd( - l1ToL2Messages, - Fr.ZERO, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - 'Too many L1 to L2 messages', - ); - await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded); - } - + // Append the block's real message leaves unpadded at compact indices. + await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); return db; } } diff --git a/yarn-project/prover-node/src/job/epoch-proving-job-data.test.ts b/yarn-project/prover-node/src/job/epoch-proving-job-data.test.ts index 6ff3ecc44fb3..58652eb13217 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job-data.test.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job-data.test.ts @@ -30,6 +30,7 @@ describe('EpochProvingJobData', () => { [CheckpointNumber(3)]: [Fr.random()], }, previousBlockHeader: BlockHeader.random(), + previousInboxRollingHash: Fr.random(), attestations: times(3, CommitteeAttestation.random), }; diff --git a/yarn-project/prover-node/src/job/epoch-proving-job-data.ts b/yarn-project/prover-node/src/job/epoch-proving-job-data.ts index 6b107b5eb411..c2ee95938d6e 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job-data.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job-data.ts @@ -12,6 +12,8 @@ export type EpochProvingJobData = { txs: Map; l1ToL2Messages: Record; previousBlockHeader: BlockHeader; + /** Inbox rolling hash of the checkpoint before the epoch's first checkpoint (its chain start); genesis is zero. */ + previousInboxRollingHash: Fr; attestations: CommitteeAttestation[]; }; @@ -48,6 +50,7 @@ export function serializeEpochProvingJobData(data: EpochProvingJobData): Buffer return serializeToBuffer( data.epochNumber, data.previousBlockHeader, + data.previousInboxRollingHash, checkpoints.length, ...checkpoints, txs.length, @@ -63,6 +66,7 @@ export function deserializeEpochProvingJobData(buf: Buffer): EpochProvingJobData const reader = BufferReader.asReader(buf); const epochNumber = EpochNumber(reader.readNumber()); const previousBlockHeader = reader.readObject(BlockHeader); + const previousInboxRollingHash = Fr.fromBuffer(reader); const checkpoints = reader.readVector(Checkpoint); const txArray = reader.readVector(Tx); @@ -78,5 +82,13 @@ export function deserializeEpochProvingJobData(buf: Buffer): EpochProvingJobData const txs = new Map(txArray.map(tx => [tx.getTxHash().toString(), tx])); - return { epochNumber, previousBlockHeader, checkpoints, txs, l1ToL2Messages, attestations }; + return { + epochNumber, + previousBlockHeader, + previousInboxRollingHash, + checkpoints, + txs, + l1ToL2Messages, + attestations, + }; } diff --git a/yarn-project/prover-node/src/job/epoch-session.test.ts b/yarn-project/prover-node/src/job/epoch-session.test.ts index 7c6512c2fd02..15281f684f92 100644 --- a/yarn-project/prover-node/src/job/epoch-session.test.ts +++ b/yarn-project/prover-node/src/job/epoch-session.test.ts @@ -282,20 +282,20 @@ describe('EpochSession', () => { // ---------------- checkpoint failure ---------------- describe('checkpoint that fails to prove', () => { - it('ends the session in "stopped" (not "failed") when a checkpoint\'s blockProofs reject', async () => { + it('ends the session in "stopped" (not "failed") when a checkpoint\'s subTreeProofs reject', async () => { // Build a prover whose block-rollup proofs are guaranteed to reject — this mirrors // the production path where CheckpointProver.executeCheckpoint catches an internal - // error (e.g. a data-plane reorg fork fault) and rejects its blockProofs promise. + // error (e.g. a data-plane reorg fork fault) and rejects its subTreeProofs promise. // The session must NOT declare the epoch failed: it ends in the non-declaring terminal // 'stopped', leaving the reconciler free to rebuild it over current canonical content. - const failingProver = makeStubProver(cp, { blockProofsError: new Error('block 7 proving failed') }); + const failingProver = makeStubProver(cp, { subTreeProofsError: new Error('block 7 proving failed') }); const session = new EpochSession( makeSpec(), [failingProver], makeDeps({ // Override mirrors what the real topTree.prove(...) does: awaits each prover's - // blockProofs and propagates the rejection up. - hooks: { topTreeProveOverride: () => failingProver.whenBlockProofsReady().then(() => synthProof) }, + // subTreeProofs and propagates the rejection up. + hooks: { topTreeProveOverride: () => failingProver.whenSubTreeProofsReady().then(() => synthProof) }, }), ); const state = await session.start(); @@ -308,12 +308,12 @@ describe('EpochSession', () => { }); it('whenDone resolves to "stopped" so callers observing the lifecycle agree with the return value', async () => { - const failingProver = makeStubProver(cp, { blockProofsError: new Error('boom') }); + const failingProver = makeStubProver(cp, { subTreeProofsError: new Error('boom') }); const session = new EpochSession( makeSpec(), [failingProver], makeDeps({ - hooks: { topTreeProveOverride: () => failingProver.whenBlockProofsReady().then(() => synthProof) }, + hooks: { topTreeProveOverride: () => failingProver.whenSubTreeProofsReady().then(() => synthProof) }, }), ); const startResult = session.start(); @@ -322,12 +322,12 @@ describe('EpochSession', () => { }); it('ends the session in "stopped" (not "failed") when a prover was cancelled by a prune (isCancelled, not isFailed)', async () => { - // A control-plane prune cancels the prover: its blockProofs reject with "cancelled" and it reports + // A control-plane prune cancels the prover: its subTreeProofs reject with "cancelled" and it reports // isCancelled()===true / isFailed()===false. If that rejection reaches start()'s catch before the // reconcile marks the session 'cancelled', it must NOT be classified 'failed' (which would trigger a // spurious full-snapshot upload) — a cancelled prover is prune-ambiguous, so classify 'stopped'. const cancelledProver = makeStubProver(cp, { - blockProofsError: new Error('Checkpoint cancelled'), + subTreeProofsError: new Error('Checkpoint cancelled'), isFailed: false, isCancelled: true, }); @@ -335,7 +335,7 @@ describe('EpochSession', () => { makeSpec(), [cancelledProver], makeDeps({ - hooks: { topTreeProveOverride: () => cancelledProver.whenBlockProofsReady().then(() => synthProof) }, + hooks: { topTreeProveOverride: () => cancelledProver.whenSubTreeProofsReady().then(() => synthProof) }, }), ); const state = await session.start(); @@ -465,24 +465,24 @@ class TestEpochSession extends EpochSession { * Minimal CheckpointProver-shaped stub: provides everything the TopTreeJob and EpochSession * read off a prover, without standing up the actual eager gather/sub-tree pipeline. * - * Pass `blockProofsError` to simulate a checkpoint that fails to prove — its - * `whenBlockProofsReady()` will reject with the supplied error, mirroring the production + * Pass `subTreeProofsError` to simulate a checkpoint that fails to prove — its + * `whenSubTreeProofsReady()` will reject with the supplied error, mirroring the production * path where CheckpointProver.executeCheckpoint catches an internal failure and rejects - * its blockProofs promise. + * its subTreeProofs promise. */ function makeStubProver( checkpoint: Checkpoint, - opts: { blockProofsError?: Error; isFailed?: boolean; isCancelled?: boolean } = {}, + opts: { subTreeProofsError?: Error; isFailed?: boolean; isCancelled?: boolean } = {}, ): CheckpointProver { const id = CheckpointProver.idFor(checkpoint); - // By default whenBlockProofsReady never resolves in these tests; the prove override + // By default whenSubTreeProofsReady never resolves in these tests; the prove override // bypasses any path that would actually await it. - const blockProofs: Promise = opts.blockProofsError - ? Promise.reject(opts.blockProofsError) + const subTreeProofs: Promise = opts.subTreeProofsError + ? Promise.reject(opts.subTreeProofsError) : new Promise(() => {}); // Suppress unhandled-rejection noise — tests that need the rejection observe it // explicitly via the proveOverride hook. - blockProofs.catch(() => {}); + subTreeProofs.catch(() => {}); return { id, checkpoint, @@ -493,11 +493,11 @@ function makeStubProver( l1ToL2Messages: [], previousArchiveSiblingPath: makeTuple(ARCHIVE_HEIGHT, () => Fr.ZERO), txs: new Map(), - whenBlockProofsReady: () => blockProofs, + whenSubTreeProofsReady: () => subTreeProofs, isCancelled: () => opts.isCancelled ?? false, - // A prover configured with a blockProofsError is one whose block proofs rejected — i.e. failed, + // A prover configured with a subTreeProofsError is one whose sub-tree proofs rejected — i.e. failed, // unless the caller decouples the two (e.g. to model a cancelled-but-not-failed prune). - isFailed: () => opts.isFailed ?? opts.blockProofsError !== undefined, + isFailed: () => opts.isFailed ?? opts.subTreeProofsError !== undefined, cancel: () => {}, whenDone: () => Promise.resolve(), getAbortSignal: () => new AbortController().signal, diff --git a/yarn-project/prover-node/src/job/top-tree-job.ts b/yarn-project/prover-node/src/job/top-tree-job.ts index 1290ea9de381..42d8b868feef 100644 --- a/yarn-project/prover-node/src/job/top-tree-job.ts +++ b/yarn-project/prover-node/src/job/top-tree-job.ts @@ -42,7 +42,7 @@ export type TopTreeJobHooks = { /** * Self-contained top-tree job. Constructed from a snapshot of `CheckpointProver`s; runs - * `topTree.prove(...)` against their pending `blockProofs` promises and exposes the + * `topTree.prove(...)` against their pending `subTreeProofs` promises and exposes the * final epoch proof via `result`. * */ @@ -185,7 +185,7 @@ export class TopTreeJob { ); const checkpointData: CheckpointTopTreeData[] = this.snapshot.map(j => ({ - blockProofs: j.whenBlockProofsReady(), + subTreeProofs: j.whenSubTreeProofsReady(), l2ToL1MsgsPerBlock: j.checkpoint.blocks.map(b => b.body.txEffects.map(tx => tx.l2ToL1Msgs)), blobFields: j.checkpoint.toBlobFields(), previousBlockHeader: j.previousBlockHeader, diff --git a/yarn-project/prover-node/src/prover-node-publisher.ts b/yarn-project/prover-node/src/prover-node-publisher.ts index 0ff328189dea..7e5cc668c091 100644 --- a/yarn-project/prover-node/src/prover-node-publisher.ts +++ b/yarn-project/prover-node/src/prover-node-publisher.ts @@ -333,6 +333,8 @@ export class ProverNodePublisher { previousArchive: args.publicInputs.previousArchiveRoot.toString(), endArchive: args.publicInputs.endArchiveRoot.toString(), outHash: args.publicInputs.outHash.toString(), + previousInboxRollingHash: args.publicInputs.previousInboxRollingHash.toString(), + endInboxRollingHash: args.publicInputs.endInboxRollingHash.toString(), proverId: EthAddress.fromField(args.publicInputs.constants.proverId).toString(), } /*_args*/, args.headers.map(header => header.toViem()) /*_headers*/, @@ -375,10 +377,12 @@ export class ProverNodePublisher { * [0] previousArchiveRoot * [1] endArchiveRoot * [2] outHash - * [3 .. 3+N-1] checkpointHeaderHashes[i] for i in 0..N-1 (N = MAX_CHECKPOINTS_PER_EPOCH) - * [3+N .. 3+3N-1] fees[i] = (recipient, value) for i in 0..N-1 - * [3+3N .. 3+3N+4] EpochConstantData (chainId, version, vkTreeRoot, protocolContractsHash, proverId) - * [3+3N+5 ..] blobPublicInputs (FinalBlobAccumulator) + * [3] previousInboxRollingHash + * [4] endInboxRollingHash + * [5 .. 5+N-1] checkpointHeaderHashes[i] for i in 0..N-1 (N = MAX_CHECKPOINTS_PER_EPOCH) + * [5+N .. 5+3N-1] fees[i] = (recipient, value) for i in 0..N-1 + * [5+3N .. 5+3N+4] EpochConstantData (chainId, version, vkTreeRoot, protocolContractsHash, proverId) + * [5+3N+5 ..] blobPublicInputs (FinalBlobAccumulator) */ async function reportPublicInputsMismatch(input: { rollupPublicInputs: readonly Fr[]; @@ -390,7 +394,8 @@ async function reportPublicInputsMismatch(input: { }): Promise { const { rollupPublicInputs, argsPublicInputs, fromCheckpoint, toCheckpoint, rollupContract, log } = input; const N = MAX_CHECKPOINTS_PER_EPOCH; - const constantsStart = 3 + 3 * N; + const headerHashesStart = 5; + const constantsStart = headerHashesStart + 3 * N; const blobStart = constantsStart + 5; const constantLabels = ['chainId', 'version', 'vkTreeRoot', 'protocolContractsHash', 'proverId']; @@ -410,11 +415,15 @@ async function reportPublicInputsMismatch(input: { label = 'endArchiveRoot'; } else if (i === 2) { label = 'outHash'; - } else if (i < 3 + N) { - checkpointIndex = i - 3; + } else if (i === 3) { + label = 'previousInboxRollingHash'; + } else if (i === 4) { + label = 'endInboxRollingHash'; + } else if (i < headerHashesStart + N) { + checkpointIndex = i - headerHashesStart; label = `checkpointHeaderHashes[${checkpointIndex}]`; - } else if (i < 3 + 3 * N) { - const feePairIndex = i - (3 + N); + } else if (i < headerHashesStart + 3 * N) { + const feePairIndex = i - (headerHashesStart + N); const feeIndex = Math.floor(feePairIndex / 2); const sub = feePairIndex % 2 === 0 ? 'recipient' : 'value'; label = `fees[${feeIndex}].${sub}`; diff --git a/yarn-project/prover-node/src/prover-node.test.ts b/yarn-project/prover-node/src/prover-node.test.ts index 24fd2b1adcda..f0760d4befd6 100644 --- a/yarn-project/prover-node/src/prover-node.test.ts +++ b/yarn-project/prover-node/src/prover-node.test.ts @@ -173,7 +173,7 @@ describe('ProverNode', () => { // getBlockData also feeds collectRegisterData when the rebuild re-registers, so it carries a header too. l2BlockSource.getBlockData.mockResolvedValue({ checkpointNumber: CheckpointNumber(2), - header: { lastArchive: { root: Fr.ZERO } }, + header: { lastArchive: { root: Fr.ZERO }, state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } } }, } as any); await proverNode.handleBlockStreamEvent({ type: 'chain-pruned', @@ -691,9 +691,9 @@ describe('ProverNode', () => { l2BlockSource.getBlockNumber.mockResolvedValue(undefined); setupRegistrationSuccess(); // getBlockData returns a header that lets isEpochFullyProven bail out as "not proven" - // and supplies a lastArchive.root for collectRegisterData. + // and supplies a lastArchive.root plus an L1-to-L2 leaf count for collectRegisterData. l2BlockSource.getBlockData.mockResolvedValue({ - header: { lastArchive: { root: Fr.ZERO } }, + header: { lastArchive: { root: Fr.ZERO }, state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } } }, } as any); } @@ -705,9 +705,8 @@ describe('ProverNode', () => { */ function setupRegistrationSuccess() { worldState.syncImmediate.mockResolvedValue(undefined as any); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); l2BlockSource.getBlockData.mockResolvedValue({ - header: { lastArchive: { root: Fr.ZERO } }, + header: { lastArchive: { root: Fr.ZERO }, state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } } }, } as any); worldState.getSnapshot.mockReturnValue({ getTreeInfo: () => Promise.resolve({ size: 1n }), @@ -723,9 +722,17 @@ describe('ProverNode', () => { ): Checkpoint { return { number: CheckpointNumber(checkpointNumber), - header: { slotNumber: SlotNumber(slot) }, + header: { slotNumber: SlotNumber(slot), inboxRollingHash: Fr.ZERO }, archive: { root: archiveRoot }, - blocks: [{ number: blockNumber, header: { hash: () => Promise.resolve('0x01') } }], + blocks: [ + { + number: blockNumber, + header: { + hash: () => Promise.resolve('0x01'), + state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } }, + }, + }, + ], hash: () => new Fr(checkpointNumber), } as unknown as Checkpoint; } @@ -745,9 +752,19 @@ describe('ProverNode', () => { */ function mineCheckpoint(checkpoint: Checkpoint): L2BlockStreamEvent { mined.set(Number(checkpoint.number), checkpoint); - l2BlockSource.getCheckpoint.mockImplementation((query: any) => - Promise.resolve('number' in query ? makeMaybePublished(mined.get(Number(query.number))) : undefined), - ); + l2BlockSource.getCheckpoint.mockImplementation((query: any) => { + if (!('number' in query)) { + return Promise.resolve(undefined); + } + const number = Number(query.number); + const found = mined.get(number); + // Ancestors below the mined window exist on chain but are irrelevant to the scenario; serve a synthetic + // parent so inbox rolling-hash sourcing for the earliest mined checkpoint resolves. + const belowWindow = number > 0 && number < Math.min(...mined.keys()); + return Promise.resolve( + makeMaybePublished(found ?? (belowWindow ? makeCheckpoint(number, number, number) : undefined)), + ); + }); l2BlockSource.getCheckpointsData.mockImplementation((query: any) => { if (!('from' in query)) { return Promise.resolve([]); diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index 5f4c59250153..d81e21929fe2 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -3,6 +3,7 @@ import type { RollupContract } from '@aztec/ethereum/contracts'; import type { Delayer } from '@aztec/ethereum/l1-tx-utils'; import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types'; import { assertRequired, compact, pick } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { memoize } from '@aztec/foundation/decorators'; import { createLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/running-promise'; @@ -349,8 +350,15 @@ export class ProverNode implements L2BlockStreamEventHandler, ProverNodeApi, Tra ): Promise { const previousBlockNumber = BlockNumber(checkpoint.blocks[0].number - 1); const previousBlockHeader = await this.gatherPreviousBlockHeader(previousBlockNumber); - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpoint.number); const lastBlock = checkpoint.blocks.at(-1)!; + // Streaming Inbox: the checkpoint's consumed messages are those between the parent + // checkpoint's consumed position and this checkpoint's last block, as a compact leaf-count range. The prover + // slices them per block. + const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2MessagesBetweenLeafCounts( + BigInt(previousBlockHeader.state.l1ToL2MessageTree.nextAvailableLeafIndex), + BigInt(lastBlock.header.state.l1ToL2MessageTree.nextAvailableLeafIndex), + ); + const previousInboxRollingHash = await this.gatherPreviousInboxRollingHash(checkpoint.number); const lastBlockHash = await lastBlock.header.hash(); await this.worldState.syncImmediate(lastBlock.number, lastBlockHash); const previousArchiveSiblingPath = await getLastSiblingPath( @@ -361,10 +369,27 @@ export class ProverNode implements L2BlockStreamEventHandler, ProverNodeApi, Tra attestations, previousBlockHeader, l1ToL2Messages, + previousInboxRollingHash, previousArchiveSiblingPath, }; } + /** + * Sources the inbox rolling hash chain-start for a checkpoint: the previous checkpoint's `inboxRollingHash`, or zero + * for the genesis checkpoint. The prover threads this into the base parity circuits so the rebuilt checkpoint header + * matches the proposer's. + */ + private async gatherPreviousInboxRollingHash(checkpointNumber: CheckpointNumber): Promise { + if (checkpointNumber <= 1) { + return Fr.ZERO; + } + const previous = await this.l2BlockSource.getCheckpoint({ number: CheckpointNumber(checkpointNumber - 1) }); + if (!previous) { + throw new Error(`Previous checkpoint ${checkpointNumber - 1} not found when sourcing inbox rolling hash`); + } + return previous.checkpoint.header.inboxRollingHash; + } + /** * Marks every prover orphaned by the prune as pruned, clamps the catch-up cursor below the prune target's * checkpoint, and notifies the session manager. Keyed off the prune target block (the highest surviving block) diff --git a/yarn-project/prover-node/src/session-manager.ts b/yarn-project/prover-node/src/session-manager.ts index 3a42a59e74dc..300173c436eb 100644 --- a/yarn-project/prover-node/src/session-manager.ts +++ b/yarn-project/prover-node/src/session-manager.ts @@ -453,6 +453,7 @@ export class SessionManager { txs, l1ToL2Messages, previousBlockHeader: checkpoints[0].previousBlockHeader, + previousInboxRollingHash: checkpoints[0].previousInboxRollingHash, attestations: [], }; } diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json index ae0aeba8bf19..c919b85f457b 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json @@ -16,7 +16,7 @@ "pxe_l2_tip_checkpoints": [ { "key": "utf8:checkpointed", - "value": "{\"number\":47,\"hash\":\"0x00e66a45cc6583f772f44bdb5ae6535cf821a59a3d832702a125f0c57f6228ef\"}" + "value": "{\"number\":47,\"hash\":\"0x00407c60c560276f14936ea39b073d155bc34a485e8a83c0439c9b8ef83f737e\"}" }, { "key": "utf8:proven", diff --git a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts index a8561507d41d..c1802c49f19b 100644 --- a/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts +++ b/yarn-project/pxe/src/storage/backwards_compatibility_tests/schema_tests.ts @@ -276,7 +276,7 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [ new Fr(5n), new Fr(7n), new Fr(11n), - new Fr(13n), + new Fr(15n), new Fr(17n), SlotNumber(19), 23n, diff --git a/yarn-project/sequencer-client/README.md b/yarn-project/sequencer-client/README.md index 5b709095ce54..d9145611c527 100644 --- a/yarn-project/sequencer-client/README.md +++ b/yarn-project/sequencer-client/README.md @@ -142,7 +142,7 @@ Inside `execute()`: - Transitions to `INITIALIZING_CHECKPOINT`. If there is a pending invalidation, enqueue it. - Builds **pipelined-parent simulation overrides**: when building on top of a parent that hasn't landed on L1 yet, the fee-asset price modifier must be computed against the parent fee header we predicted (not the L1 one), so all in-flight checkpoints in the pipeline agree on the same modifier. - Asks the global variables builder for the slot's `CheckpointGlobalVariables` (`coinbase`, `feeRecipient`, `timestamp`, `gasFees`, `chainId`, `version`, `slotNumber`). These are shared across every block within the checkpoint — only `blockNumber` increments. - - Computes `inHash` from the L1→L2 messages for the checkpoint, and collects `previousCheckpointOutHashes` for prior checkpoints in the same epoch. + - Resolves the streaming Inbox consumption cursor (the parent checkpoint's last-consumed bucket, from the fork's L1→L2 leaf count), and collects `previousCheckpointOutHashes` for prior checkpoints in the same epoch. Each block then selects its own message bundle against the cursor (AZIP-22 Fast Inbox). - Forks world state at the parent (`closeDelayMs: 12 s`) and asks `FullNodeCheckpointsBuilder` for a `CheckpointBuilder` bound to that fork. - Runs `buildBlocksForCheckpoint()` — the per-block loop, described below. - Transitions to `ASSEMBLING_CHECKPOINT`, asks the builder to `completeCheckpoint()`, validates it against the configured caps, and asks the validator client to sign the `CheckpointProposal` (which bundles the final block proposal so the two travel together). @@ -206,7 +206,7 @@ See the [Block Building Timetable Spec](../stdlib/src/timetable/README.md) for t Key entry points: - `canProposeAt(archive, msgSender, simulationOverridesPlan?)` — eth_call simulation of `Rollup.canProposeAt`. The sequencer runs this before deciding to build. -- `enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, opts)` — adds the propose call, with a `preCheck` that re-validates the proposal against real L1 state when it is finally sent (catches drift between build time and submit time). +- `enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, bucketHint, opts)` — adds the propose call, with a `preCheck` that re-validates the proposal against real L1 state when it is finally sent (catches drift between build time and submit time). - `enqueueInvalidateCheckpoint`, `enqueueGovernanceCastSignal`, `enqueueSlashingActions` — the rest of the actions a proposer may bundle. - `sendRequests(targetSlot?)` — immediately flushes the queue as one Multicall3 transaction. Used by the `AutomineSequencer` for synchronous in-slot publishing. - `sendRequestsAt(targetSlot)` — the production (pipelined) path: sleeps (cancellable) until the ideal L1 send time, runs each request's `preCheck` (dropping those that fail), and then calls `sendRequests(targetSlot)`, which filters expired requests, sorts the remainder, and submits one Multicall3 that mines inside the target slot. diff --git a/yarn-project/sequencer-client/src/index.ts b/yarn-project/sequencer-client/src/index.ts index 2375b9013a90..c88e2a5f5d74 100644 --- a/yarn-project/sequencer-client/src/index.ts +++ b/yarn-project/sequencer-client/src/index.ts @@ -6,3 +6,10 @@ export { Sequencer, SequencerState, type SequencerEvents } from './sequencer/ind // Used by the node to simulate public parts of transactions. Should these be moved to a shared library? // ISSUE(#9832) export * from './global_variable_builder/index.js'; +export { + type ConsumedBucketCursor, + type InboxBucketSelection, + type InboxBucketSource, + type SelectInboxBucketInput, + selectInboxBucketForBlock, +} from './sequencer/inbox_bucket_selector.js'; diff --git a/yarn-project/sequencer-client/src/publisher/l1_publisher.integration.test.ts b/yarn-project/sequencer-client/src/publisher/l1_publisher.integration.test.ts index 2742610426b5..a2b482cf14a2 100644 --- a/yarn-project/sequencer-client/src/publisher/l1_publisher.integration.test.ts +++ b/yarn-project/sequencer-client/src/publisher/l1_publisher.integration.test.ts @@ -1,4 +1,5 @@ import type { ArchiverDataSource } from '@aztec/archiver'; +import { MockL1ToL2MessageSource } from '@aztec/archiver/test'; import { AztecAddress } from '@aztec/aztec.js/addresses'; import { Fr } from '@aztec/aztec.js/fields'; import { createLogger } from '@aztec/aztec.js/log'; @@ -13,10 +14,12 @@ import { } from '@aztec/blob-lib'; import { GENESIS_ARCHIVE_ROOT, + INBOX_LAG_SECONDS, + MAX_L1_TO_L2_MSGS_PER_BLOCK, + MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, MAX_NULLIFIERS_PER_TX, MAX_PROCESSABLE_L2_GAS, MAX_TX_DA_GAS, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, } from '@aztec/constants'; import { EpochCache } from '@aztec/epoch-cache'; import { createEthereumChain } from '@aztec/ethereum/chain'; @@ -47,7 +50,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { sleep } from '@aztec/foundation/sleep'; import { hexToBuffer } from '@aztec/foundation/string'; import { TestDateProvider } from '@aztec/foundation/timer'; -import { RollupAbi } from '@aztec/l1-artifacts'; +import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree'; import { ProtocolContractsList, protocolContractsHash } from '@aztec/protocol-contracts'; import { LightweightCheckpointBuilder } from '@aztec/prover-client/light'; @@ -86,11 +89,12 @@ import { NativeWorldStateService, ServerWorldStateSynchronizer, type WorldStateC import { beforeEach, describe, expect, it, jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { type Address, encodeFunctionData, getAbiItem, getAddress, multicall3Abi } from 'viem'; +import { type Address, encodeFunctionData, getAbiItem, getAddress, getContract, multicall3Abi } from 'viem'; import { type PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts'; import { foundry } from 'viem/chains'; import { type SequencerClientConfig, getConfigEnvVars } from '../config.js'; +import { selectInboxBucketForBlock } from '../sequencer/inbox_bucket_selector.js'; import { sendL1ToL2Message } from './l1_to_l2_messaging.js'; import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js'; import { SequencerPublisher } from './sequencer-publisher.js'; @@ -111,7 +115,8 @@ const logger = createLogger('integration_l1_publisher'); // depending on @aztec/aztec-node, which would create a sequencer-client <-> aztec-node cycle. const config: SequencerClientConfig & L1ContractsConfig = { ...getL1ContractsConfigEnvVars(), ...getConfigEnvVars() }; -// Must exceed the inbox lag (network default 2) so at least one checkpoint consumes a real L1->L2 message. +// Several consecutive checkpoints, each consuming the L1->L2 messages sent while it was being built, so real +// messages are genuinely consumed and validated on L1. const numberOfConsecutiveBlocks = 3; jest.setTimeout(1000000); @@ -138,6 +143,11 @@ describe('L1Publisher integration', () => { let builderDb: NativeWorldStateService; + // Backs the blockSource mock's streaming L1->L2 message queries. The world-state synchronizer reconstructs each + // block's consumed message bundle from Inbox buckets when it syncs a block back, so the test + // registers one bucket per published block here (see buildAndPublishBlock). + let messageSource: MockL1ToL2MessageSource; + // The header of the last block let prevHeader: BlockHeader; @@ -274,6 +284,20 @@ describe('L1Publisher integration', () => { checkpointNumber: CheckpointNumber.ZERO, indexWithinCheckpoint: IndexWithinCheckpoint(0), }; + // Seed the genesis sentinel bucket (seq 0, no messages) so the world-state synchronizer can resolve a + // totalMsgCount of 0 to a bucket when reconstructing the first block's message bundle. + messageSource = new MockL1ToL2MessageSource(0); + messageSource.setInboxBucket( + { + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }, + [], + ); blockSource = mock({ getBlocks(query: BlocksQuery) { if (!('from' in query)) { @@ -349,6 +373,14 @@ describe('L1Publisher integration', () => { getBlockNumber(): Promise { return Promise.resolve(BlockNumber(blocks.at(-1)?.number ?? BlockNumber.ZERO)); }, + // Streaming L1->L2 message reconstruction: the world-state synchronizer resolves each + // block's consumed message bundle from the Inbox buckets registered per published block in buildAndPublishBlock. + getInboxBucketByTotalMsgCount(totalMsgCount: bigint) { + return messageSource.getInboxBucketByTotalMsgCount(totalMsgCount); + }, + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint) { + return messageSource.getL1ToL2MessagesBetweenBuckets(fromExclusive, toInclusive); + }, }); const worldStateConfig: WorldStateConfig = { @@ -444,13 +476,16 @@ describe('L1Publisher integration', () => { /** * Build a checkpoint with a single block using the LightweightCheckpointBuilder. - * This properly computes all checkpoint header fields (blobsHash, blockHeadersHash, inHash, epochOutHash, etc.) + * This properly computes all checkpoint header fields (blobsHash, blockHeadersHash, inboxRollingHash, + * epochOutHash, etc.). `previousInboxRollingHash` is the previous checkpoint's rolling hash (zero at genesis), so + * the header's `inboxRollingHash` continues the on-chain Inbox chain over `l1ToL2Messages`. */ const buildCheckpoint = async ( globalVariables: GlobalVariables, txs: ProcessedTx[], l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[] = [], + previousInboxRollingHash: Fr = Fr.ZERO, ): Promise => { await worldStateSynchronizer.syncImmediate(); const tempFork = await worldStateSynchronizer.fork(BlockNumber(globalVariables.blockNumber - 1)); @@ -467,15 +502,15 @@ describe('L1Publisher integration', () => { // Test uses 1-block-per-checkpoint const checkpointNumber = CheckpointNumber.fromBlockNumber(globalVariables.blockNumber); - const builder = await LightweightCheckpointBuilder.startNewCheckpoint( + const builder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, checkpointConstants, - l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, tempFork, ); - await builder.addBlock(globalVariables, txs, { insertTxsEffects: true }); + await builder.addBlock(globalVariables, txs, l1ToL2Messages, { insertTxsEffects: true }); const checkpoint = await builder.completeCheckpoint(); await tempFork.close(); @@ -485,7 +520,8 @@ describe('L1Publisher integration', () => { const buildSingleCheckpoint = async ( opts: { l1ToL2Messages?: Fr[]; blockNumber?: BlockNumber; slot?: SlotNumber } = {}, ) => { - const l1ToL2Messages = opts.l1ToL2Messages ?? new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(Fr.ZERO); + // By default a single checkpoint consumes no Inbox messages (bucketHint 0 against the genesis bucket). + const l1ToL2Messages = opts.l1ToL2Messages ?? []; const txs = await Promise.all([makeProcessedTx(0x1000), makeProcessedTx(0x2000)]); const ts = (await l1Client.getBlock()).timestamp; @@ -502,7 +538,6 @@ describe('L1Publisher integration', () => { new GasFees(0, await rollup.getManaMinFeeAt(timestamp, true)), ); const checkpoint = await buildCheckpoint(globalVariables, txs, l1ToL2Messages); - blockSource.getL1ToL2Messages.mockResolvedValueOnce(l1ToL2Messages); return { checkpoint, l1ToL2Messages }; }; @@ -516,10 +551,8 @@ describe('L1Publisher integration', () => { describe('block building', () => { beforeEach(async () => { - // This suite proposes consecutive checkpoints and models the inbox lag by hand (a checkpoint - // consumes the L1->L2 messages sent inboxLag checkpoints earlier -- see the shift register in - // buildAndPublishBlock). It inherits the network default lag and proposes enough checkpoints - // that a real message is actually consumed and validated on L1. + // This suite proposes consecutive checkpoints, each consuming the streaming-Inbox messages sent while it was + // being built, so real messages are genuinely consumed and validated on L1. await setup(); }); @@ -534,29 +567,60 @@ describe('L1Publisher integration', () => { '0x1647b194c649f5dd01d7c832f89b0f496043c9150797923ea89e93d5ac619a93', ); - // The deployed rollup consumes L1->L2 messages with a lag of `inboxLag` checkpoints: a message - // inserted while building checkpoint N is only consumable at checkpoint N + inboxLag. Model that - // with a shift register so a real message is genuinely consumed and validated on L1. - const inboxLag = getL1ContractsConfigEnvVars().inboxLag; - const messagesInFlight: Fr[][] = Array.from({ length: inboxLag }, () => []); + // Streaming Inbox consumption: the L1 Rollup only lets a checkpoint consume Inbox buckets + // that have aged past the censorship cutoff (`toTimestamp(slot - 1) - INBOX_LAG_SECONDS`), measured in L1 time, + // not whole checkpoints. Each checkpoint mirrors the real Inbox buckets into messageSource, then reuses the + // production `selectInboxBucketForBlock` (which mirrors `ProposeLib.validateInboxConsumption`) to pick exactly + // the buckets it must consume, deriving the consumed bundle, the propose bucket hint, and the header rolling + // hash from that one selection so header, world state, and L1 agree by construction. + const inbox = getContract({ + address: getAddress(l1ContractAddresses.inboxAddress.toString()), + abi: InboxAbi, + client: l1Client, + }); + // Every message sent to the Inbox, in insertion order, so each bucket's leaves can be mirrored into messageSource. + const allSentMessages: Fr[] = []; + let mirroredThroughSeq = 0n; + let mirroredThroughTotal = 0n; + // The last Inbox bucket this checkpoint chain has consumed through; genesis sentinel to start. + let parent = { seq: 0n, totalMsgCount: 0n }; + let previousInboxRollingHash = Fr.ZERO; const blobFieldsPerCheckpoint: Fr[][] = []; // The below batched blob is used for testing different epochs with 1..numberOfConsecutiveBlocks blocks on L1. // For real usage, always collect ALL epoch blobs first then call .batch(). let currentBatch: BatchedBlob | undefined; for (let i = 0; i < numberOfConsecutiveBlocks; i++) { - // With just one l1 client (serial sending) this takes too much time to send NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP + // With just one l1 client (serial sending) this takes too much time to send MAX_L1_TO_L2_MSGS_PER_CHECKPOINT // and causes a chain prune - const l1ToL2Content = range(Math.min(16, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), 128 * i + 1 + 0x400).map(fr); + const l1ToL2Content = range(Math.min(16, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT), 128 * i + 1 + 0x400).map(fr); const sentThisCheckpoint: Fr[] = []; for (let j = 0; j < l1ToL2Content.length; j++) { sentThisCheckpoint.push(await sendToL2(l1ToL2Content[j], recipientAddress)); } - - // Consume the messages sent inboxLag checkpoints ago, then enqueue this checkpoint's messages. - const currentL1ToL2Messages = messagesInFlight.shift()!; - messagesInFlight.push(sentThisCheckpoint); + allSentMessages.push(...sentThisCheckpoint); + + // Mirror the Inbox's new buckets (seq, timestamp, rolling hash, totals) and their leaves into messageSource, + // so the selector, the world-state synchronizer, and L1 all read the same bucket state. + const currentBucketSeq = await inbox.read.getCurrentBucketSeq(); + for (let seq = mirroredThroughSeq + 1n; seq <= currentBucketSeq; seq++) { + const bucket = await inbox.read.getBucket([seq]); + const bucketMessages = allSentMessages.slice(Number(mirroredThroughTotal), Number(bucket.totalMsgCount)); + messageSource.setInboxBucket( + { + seq, + inboxRollingHash: Fr.fromString(bucket.rollingHash), + totalMsgCount: bucket.totalMsgCount, + timestamp: bucket.timestamp, + msgCount: Number(bucket.msgCount), + lastMessageIndex: bucket.totalMsgCount - 1n, + }, + bucketMessages, + ); + mirroredThroughTotal = bucket.totalMsgCount; + } + mirroredThroughSeq = currentBucketSeq; // Ensure that each transaction has unique (non-intersecting nullifier values) const totalNullifiersPerBlock = 4 * MAX_NULLIFIERS_PER_TX; @@ -579,14 +643,42 @@ describe('L1Publisher integration', () => { new GasFees(0, await rollup.getManaMinFeeAt(timestamp, true)), ); - const checkpoint = await buildCheckpoint(globalVariables, txs, currentL1ToL2Messages); + // Reuse the production streaming selector to pick the buckets this single-block (hence last-block) checkpoint + // must consume, then derive the consumed bundle, the propose bucket hint, and the rolling-hash cursor from + // that one selection so the header, world state, and L1 all agree. + const buildFrameStart = await rollup.getTimestampForSlot(SlotNumber(slot - 1)); + const cutoffTimestamp = buildFrameStart - BigInt(INBOX_LAG_SECONDS); + const selection = await selectInboxBucketForBlock({ + messageSource, + now: buildFrameStart, + lagSeconds: BigInt(INBOX_LAG_SECONDS), + parent, + checkpointStartTotalMsgCount: parent.totalMsgCount, + perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + isLastBlock: true, + cutoffTimestamp, + }); + const currentL1ToL2Messages = selection.consume ? selection.bundle : []; + const bucketHint = selection.consume ? selection.bucket.seq : parent.seq; + + const checkpoint = await buildCheckpoint( + globalVariables, + txs, + currentL1ToL2Messages, + [], + previousInboxRollingHash, + ); + previousInboxRollingHash = checkpoint.header.inboxRollingHash; const block = checkpoint.blocks[0]; + if (selection.consume) { + parent = { seq: selection.bucket.seq, totalMsgCount: selection.bucket.totalMsgCount }; + } const totalManaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.billedGas.l2Gas)), Fr.ZERO); expect(totalManaUsed.toBigInt()).toEqual(block.header.totalManaUsed.toBigInt()); prevHeader = block.header; - blockSource.getL1ToL2Messages.mockResolvedValueOnce(currentL1ToL2Messages); const checkpointBlobFields = checkpoint.toBlobFields(); const blockBlobs = await getBlobsPerL1Block(checkpointBlobFields); @@ -614,6 +706,7 @@ describe('L1Publisher integration', () => { checkpoint, CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), + bucketHint, ); // Align chain time so the bundle simulate and the L1 send both run at the header's slot. await progressToSlot(BigInt(checkpoint.header.slotNumber)); @@ -659,6 +752,7 @@ describe('L1Publisher integration', () => { oracleInput: { feeAssetPriceModifier: 0n, }, + bucketHint, }, CommitteeAttestationsAndSigners.packAttestations([]), [], @@ -722,6 +816,7 @@ describe('L1Publisher integration', () => { checkpoint, new CommitteeAttestationsAndSigners(attestations, getSignatureContext()), signature, + 0n, ); // Align chain time so the bundle simulate and the L1 send both run at the header's slot. await progressToSlot(BigInt(checkpoint.header.slotNumber)); @@ -767,7 +862,7 @@ describe('L1Publisher integration', () => { // warn log carrying the on-chain revert reason (raw hex selector since the propose request // has no ABI attached). const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); - await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty()); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, Signature.empty(), 0n); await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result).toBeUndefined(); @@ -804,6 +899,7 @@ describe('L1Publisher integration', () => { checkpoint, attestationsAndSigners, flipSignature(attestationsAndSignersSignature), + 0n, ); await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); @@ -843,7 +939,7 @@ describe('L1Publisher integration', () => { // Enqueue no longer simulates — the bundle simulate at send time drops the failing propose // and sendRequests returns undefined. const loggerWarnSpy = jest.spyOn((publisher as any).log, 'warn'); - await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, wrongSig, 0n); await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result).toBeUndefined(); @@ -927,7 +1023,7 @@ describe('L1Publisher integration', () => { // Invalidate and propose logger.warn('Enqueuing requests to invalidate and propose the checkpoint'); publisher.enqueueInvalidateCheckpoint(invalidateRequest); - await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature); + await publisher.enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, 0n); await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result!.successfulActions).toEqual(['invalidate-by-insufficient-attestations', 'propose']); @@ -948,6 +1044,7 @@ describe('L1Publisher integration', () => { checkpoint, CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), + 0n, ); await publisher.enqueueGovernanceCastSignal( l1ContractAddresses.rollupAddress, @@ -963,10 +1060,9 @@ describe('L1Publisher integration', () => { }); it(`shows propose custom errors if tx simulation fails`, async () => { - // Set up different l1-to-l2 messages than the ones on the inbox, so this submission reverts because the - // INBOX.consume does not match the header.inHash and we get a Rollup__BlobHash that is not caught by - // validateHeader before. - const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(1n)); + // Set up different l1-to-l2 messages than the ones on the inbox, so the checkpoint's inboxRollingHash does not + // match the referenced Inbox bucket and the submission reverts at the streaming-consumption check. + const l1ToL2Messages = new Array(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT).fill(new Fr(1n)); const { checkpoint } = await buildSingleCheckpoint({ l1ToL2Messages }); // Enqueue no longer simulates per action — the bundle simulate at send time drops the @@ -976,16 +1072,17 @@ describe('L1Publisher integration', () => { checkpoint, CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), + 0n, ); await progressToSlot(BigInt(checkpoint.header.slotNumber)); const result = await publisher.sendRequests(); expect(result).toBeUndefined(); - // 0xcd6f4233 == Rollup__InvalidInHash selector + // 0xed1f7bb5 == Rollup__InvalidInboxRollingHash selector expect(loggerWarnSpy).toHaveBeenCalledWith( 'Bundle entry dropped: action reverted in sim', expect.objectContaining({ action: 'propose', - returnData: expect.stringMatching(/^0xcd6f4233/), + returnData: expect.stringMatching(/^0xed1f7bb5/), }), ); }); @@ -1032,6 +1129,7 @@ describe('L1Publisher integration', () => { checkpoint, CommitteeAttestationsAndSigners.empty(getSignatureContext()), Signature.empty(), + 0n, { txTimeoutAt: getProposeTxTimeoutAt(checkpoint) }, ); }; diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts index 4221bf07219e..e5058d08c326 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.test.ts @@ -259,6 +259,7 @@ describe('SequencerPublisher', () => { checkpoint, CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const { govPayload, voteSig } = mockGovernancePayload(); @@ -292,6 +293,7 @@ describe('SequencerPublisher', () => { oracleInput: { feeAssetPriceModifier: 0n, }, + bucketHint: 0n, }, CommitteeAttestationsAndSigners.packAttestations([]), [], @@ -347,6 +349,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const result = await publisher.sendRequests(); expect(result).toEqual(undefined); @@ -421,6 +424,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const result = await rotatingPublisher.sendRequests(); @@ -457,6 +461,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); // TimeoutError propagates to the outer catch in sendRequests which returns undefined const result = await rotatingPublisher.sendRequests(); @@ -476,6 +481,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const result = await rotatingPublisher.sendRequests(); @@ -490,6 +496,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, { txTimeoutAt: pastTimeout }, ); const result = await rotatingPublisher.sendRequests(); @@ -522,6 +529,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, { txTimeoutAt: futureTimeout }, ); const result = await rotatingPublisher.sendRequests(); @@ -544,6 +552,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const result = await rotatingPublisher.sendRequests(); @@ -558,6 +567,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); // Simulate the bundle-level validate returning a failed entry for the propose call. @@ -776,6 +786,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); publisher.interrupt(); const resultPromise = publisher.sendRequests(); @@ -1161,6 +1172,7 @@ describe('SequencerPublisher', () => { new Checkpoint(l2Block.archive, header, [l2Block], l2Block.checkpointNumber), CommitteeAttestationsAndSigners.empty(testSignatureContext), Signature.empty(), + 0n, ); const result = await storedPublisher.sendRequests(); diff --git a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts index 4c122580fe98..688e02db2978 100644 --- a/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/sequencer-publisher.ts @@ -113,6 +113,8 @@ type L1ProcessArgs = { attestationsAndSignersSignature: Signature; /** The fee asset price modifier in basis points (from oracle) */ feeAssetPriceModifier: bigint; + /** Sequence number of the Inbox bucket the header's rolling hash corresponds to. */ + bucketHint: bigint; }; export const Actions = [ @@ -1404,6 +1406,7 @@ export class SequencerPublisher { checkpoint: Checkpoint, attestationsAndSigners: CommitteeAttestationsAndSigners, attestationsAndSignersSignature: Signature, + bucketHint: bigint, opts: EnqueueProposeCheckpointOpts = {}, ): Promise { const checkpointHeader = checkpoint.header; @@ -1418,6 +1421,7 @@ export class SequencerPublisher { attestationsAndSigners, attestationsAndSignersSignature, feeAssetPriceModifier: checkpoint.feeAssetPriceModifier, + bucketHint, }; this.log.verbose(`Enqueuing checkpoint propose transaction`, { @@ -1588,6 +1592,7 @@ export class SequencerPublisher { oracleInput: { feeAssetPriceModifier: encodedData.feeAssetPriceModifier, }, + bucketHint: encodedData.bucketHint, }, encodedData.attestationsAndSigners.getPackedAttestations(), signers, diff --git a/yarn-project/sequencer-client/src/publisher/write_json.ts b/yarn-project/sequencer-client/src/publisher/write_json.ts index 7e07dc7bc028..e3a2b74e1603 100644 --- a/yarn-project/sequencer-client/src/publisher/write_json.ts +++ b/yarn-project/sequencer-client/src/publisher/write_json.ts @@ -55,7 +55,7 @@ export async function writeJson( lastArchiveRoot: asHex(checkpointHeader.lastArchiveRoot), blockHeadersHash: asHex(checkpointHeader.blockHeadersHash), blobsHash: asHex(checkpointHeader.blobsHash), - inHash: asHex(checkpointHeader.inHash), + inboxRollingHash: asHex(checkpointHeader.inboxRollingHash), outHash: asHex(checkpointHeader.epochOutHash), slotNumber: Number(checkpointHeader.slotNumber), timestamp: Number(checkpointHeader.timestamp), diff --git a/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts index ef1c5455768a..58fe374d0eb7 100644 --- a/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/automine/automine_sequencer.ts @@ -1,7 +1,9 @@ import type { Archiver } from '@aztec/archiver'; +import { INBOX_LAG_SECONDS, MAX_L1_TO_L2_MSGS_PER_BLOCK, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT } from '@aztec/constants'; import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils'; import { type EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test'; import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; import type { EthAddress } from '@aztec/foundation/eth-address'; import { Signature } from '@aztec/foundation/eth-signature'; import { type Logger, createLogger } from '@aztec/foundation/log'; @@ -13,7 +15,7 @@ import type { P2PClient as ConcreteP2PClient, P2P } from '@aztec/p2p'; import { settleEpochOutbox } from '@aztec/prover-client/test'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CommitteeAttestationsAndSigners, type L2Block, type L2BlockSource } from '@aztec/stdlib/block'; -import { getPreviousCheckpointOutHashes } from '@aztec/stdlib/checkpoint'; +import { getPreviousCheckpointInboxRollingHash, getPreviousCheckpointOutHashes } from '@aztec/stdlib/checkpoint'; import type { ChainConfig } from '@aztec/stdlib/config'; import { type L1RollupConstants, @@ -22,8 +24,9 @@ import { getTimestampForSlot, } from '@aztec/stdlib/epoch-helpers'; import { InsufficientValidTxsError, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import { type L1ToL2MessageSource, getInboxCutoffTimestamp } from '@aztec/stdlib/messaging'; import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p'; +import { MerkleTreeId } from '@aztec/stdlib/trees'; import type { FailedTx, Tx } from '@aztec/stdlib/tx'; import type { BuildBlockInCheckpointResult, @@ -35,6 +38,7 @@ import type { GlobalVariableBuilder } from '../../global_variable_builder/global import type { SequencerPublisherFactory } from '../../publisher/sequencer-publisher-factory.js'; import type { SequencerPublisher } from '../../publisher/sequencer-publisher.js'; import type { SequencerConfig } from '../config.js'; +import { selectInboxBucketForBlock } from '../inbox_bucket_selector.js'; /** * L1 rollup constants needed by the AutomineSequencer. Same as SequencerRollupConstants @@ -447,8 +451,6 @@ export class AutomineSequencer { SlotNumber(targetSlot), ); - const l1ToL2Messages = await this.deps.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); - const previousCheckpointOutHashes = await getPreviousCheckpointOutHashes({ blockSource: this.deps.l2BlockSource, epoch: targetEpoch, @@ -458,16 +460,46 @@ export class AutomineSequencer { log: this.log, }); + const previousInboxRollingHash = await getPreviousCheckpointInboxRollingHash({ + blockSource: this.deps.l2BlockSource, + checkpointNumber, + log: this.log, + }); + const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier(); await using fork = await this.deps.worldState.fork(syncedToBlockNumber, { closeDelayMs: 0 }); + // Streaming Inbox: automine builds a single-block checkpoint, so its one block is the + // checkpoint's final block; select its bundle from the newest lag-eligible bucket with the last-block censorship + // floor. The parent total is the fork's L1-to-L2 leaf count (compact indexing), which resolves the parent bucket. + const parentInfo = await fork.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE); + const parentTotalMsgCount = parentInfo.size; + const parentBucket = await this.deps.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(parentTotalMsgCount); + if (parentBucket === undefined) { + this.log.warn(`Automine streaming inbox: parent bucket for total ${parentTotalMsgCount} not synced; skipping`); + return undefined; + } + const selection = await selectInboxBucketForBlock({ + messageSource: this.deps.l1ToL2MessageSource, + now: BigInt(Math.floor(this.deps.dateProvider.now() / 1000)), + lagSeconds: BigInt(INBOX_LAG_SECONDS), + parent: { seq: parentBucket.seq, totalMsgCount: parentBucket.totalMsgCount }, + checkpointStartTotalMsgCount: parentTotalMsgCount, + perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + isLastBlock: true, + cutoffTimestamp: getInboxCutoffTimestamp(SlotNumber(targetSlot), this.deps.l1Constants, INBOX_LAG_SECONDS), + }); + const streamingBundle = selection.consume ? selection.bundle : []; + const bucketHint = selection.consume ? selection.bucket.seq : parentBucket.seq; + const checkpointBuilder = await this.deps.checkpointsBuilder.startCheckpoint( checkpointNumber, checkpointGlobals, feeAssetPriceModifier, - l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, this.log.getBindings(), ); @@ -482,6 +514,7 @@ export class AutomineSequencer { checkpointGlobals.timestamp, allowEmpty, checkpointNumber, + streamingBundle, ); if (!buildResult) { return undefined; @@ -509,7 +542,12 @@ export class AutomineSequencer { feeAssetPriceModifier, }); - await this.publisher.enqueueProposeCheckpoint(checkpoint, emptyAttestations, emptyAttestationsSignature); + await this.publisher.enqueueProposeCheckpoint( + checkpoint, + emptyAttestations, + emptyAttestationsSignature, + bucketHint, + ); // Automine publishes synchronously in the current slot via `sendRequests`. It must NOT use the // production `sendRequestsAt` (or `canProposeAt`), which always apply the one-slot pipelining // offset — automine is the deliberate non-pipelined exception and builds/publishes in place. @@ -749,16 +787,19 @@ export class AutomineSequencer { timestamp: bigint, allowEmpty: boolean, checkpointNumber: CheckpointNumber, + l1ToL2Messages: Fr[], ): Promise { let buildResult: BuildBlockInCheckpointResult; try { buildResult = await checkpointBuilder.buildBlock(pendingTxs, nextBlockNumber, timestamp, { maxTransactions: this.deps.config.maxTxsPerBlock, - // Allow empty for explicit-empty builds; require at least 1 valid tx otherwise. - minValidTxs: allowEmpty ? 0 : 1, + // Allow empty for explicit-empty builds; a message-only block (non-empty streaming bundle) also builds + // with zero txs. + minValidTxs: allowEmpty || l1ToL2Messages.length > 0 ? 0 : 1, isBuildingProposal: true, maxBlocksPerCheckpoint: 1, perBlockAllocationMultiplier: 1, + l1ToL2Messages, }); } catch (err) { // Mirrors production's checkpoint_proposal_job: if every pending tx failed execution and diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts index bac6571e1b66..27af8fd3cf2d 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts @@ -38,9 +38,10 @@ import { InsufficientValidTxsError, type MerkleTreeWriteOperations, type ResolvedSequencerConfig, + type TreeInfo, type WorldStateSynchronizer, } from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { BlockProposal, CheckpointProposal, type CoordinationSignatureContext } from '@aztec/stdlib/p2p'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import type { ProposerTimetable, SubslotSelection } from '@aztec/stdlib/timetable'; @@ -229,6 +230,9 @@ describe('CheckpointProposalJob', () => { const mockFork = mock({ [Symbol.asyncDispose]: jest.fn().mockReturnValue(Promise.resolve()) as () => Promise, }); + // The streaming Inbox cursor resolves the parent bucket from the fork's L1-to-L2 tree leaf count; default to + // an empty tree so checkpoints start at the genesis bucket unless a test seeds buckets. + mockFork.getTreeInfo.mockResolvedValue({ size: 0n } as TreeInfo); worldState.fork.mockResolvedValue(mockFork); // Create fake CheckpointsBuilder and CheckpointBuilder @@ -245,10 +249,24 @@ describe('CheckpointProposalJob', () => { checkpointBuilder = checkpointsBuilder.createCheckpointBuilder(checkpointConstants, checkpointNumber); l1ToL2MessageSource = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue(Array(4).fill(Fr.ZERO)); + // Genesis bucket for the empty-tree cursor above; with no newer synced buckets mocked, block bundle + // selection consumes nothing by default. + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue({ + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }); l2BlockSource = mock(); l2BlockSource.getCheckpointsData.mockResolvedValue([]); + // The job sources the parent checkpoint's inboxRollingHash; serve an empty parent header so jobs beyond + // the genesis checkpoint resolve their chain start. + l2BlockSource.getCheckpointData.mockImplementation(query => + Promise.resolve('number' in query ? ({ header: CheckpointHeader.empty() } as CheckpointData) : undefined), + ); // The (always-on) pipelined submission path waits for the archiver to confirm the parent // checkpoint on L1 before enqueuing the proposal. For the default job (checkpoint 1, no // proposed parent), the parent is genesis (cp 0), so a synced archiver reporting a @@ -278,12 +296,11 @@ describe('CheckpointProposalJob', () => { validatorClient = mock(); validatorClient.collectAttestations.mockImplementation(() => Promise.resolve([])); validatorClient.createBlockProposal.mockImplementation( - async (blockHeader, _checkpointNumber, indexWithinCheckpoint, inHash, archiveRoot, txs) => { + async (blockHeader, _checkpointNumber, indexWithinCheckpoint, archiveRoot, txs) => { const txHashes = await Promise.all((txs ?? []).map((tx: Tx) => tx.getTxHash())); return new BlockProposal( blockHeader, IndexWithinCheckpoint(indexWithinCheckpoint), - inHash, archiveRoot, txHashes, mockedSig, @@ -432,6 +449,7 @@ describe('CheckpointProposalJob', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 0n, }, }); @@ -631,6 +649,7 @@ describe('CheckpointProposalJob', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 0n, }; job = createCheckpointProposalJob({ @@ -678,6 +697,7 @@ describe('CheckpointProposalJob', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 0n, }; job = createCheckpointProposalJob({ targetSlot, targetEpoch, proposedCheckpointData }); @@ -829,6 +849,7 @@ describe('CheckpointProposalJob', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 0n, }; let mismatchEvents: { slot: SlotNumber; checkpointNumber: CheckpointNumber; reason: string }[]; @@ -1389,6 +1410,129 @@ describe('CheckpointProposalJob', () => { }); }); + describe('streaming inbox', () => { + beforeEach(() => { + job.setTimetable(makeProposerTimetable({ l1Constants, blockDurationMs: 3000 })); + }); + + it('streams per-block bucket bundles, advances the reference, and skips the bulk message fetch', async () => { + jest + .spyOn(job.getTimetable(), 'selectNextSubslot') + .mockReturnValueOnce(subslot(10, 0, false)) + .mockReturnValueOnce(subslot(18, 1, true)) + .mockReturnValue(noSubslot()); + + // The archiver returns the newest synced bucket (seq 2) for any lag/cutoff lookup, so the first block + // consumes through it and the second block (cursor already at seq 2) consumes nothing and reuses the ref. + const bucket: InboxBucket = { + seq: 2n, + inboxRollingHash: new Fr(99), + totalMsgCount: 5n, + timestamp: 0n, + msgCount: 2, + lastMessageIndex: 4n, + }; + const bundle = Array.from({ length: 5 }, (_, i) => new Fr(i + 1)); + l1ToL2MessageSource.getLatestInboxBucketAtOrBefore.mockResolvedValue(bucket); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue(bundle); + + const { lastBlock } = await setupMultipleBlocks(2, [2, 1]); + validatorClient.collectAttestations.mockResolvedValue(getAttestations(lastBlock)); + + const checkpoint = await job.executeAndAwait(); + + expect(checkpoint).toBeDefined(); + + // Streaming has no bulk per-checkpoint list; every message reaches the builder through a block. + expect(checkpointsBuilder.startCheckpointCalls).toHaveLength(1); + + // The first block consumes the selected bundle; the second consumes nothing. + expect(checkpointBuilder.buildBlockCalls).toHaveLength(2); + expect(checkpointBuilder.buildBlockCalls[0].opts.l1ToL2Messages).toEqual(bundle); + expect(checkpointBuilder.buildBlockCalls[1].opts.l1ToL2Messages).toEqual([]); + + // Both block proposals carry the selected bucket reference (the second reuses the first's). + const bucketRefArgs = validatorClient.createBlockProposal.mock.calls.map(call => call[7]); + expect(bucketRefArgs).toHaveLength(2); + expect(bucketRefArgs[0]?.bucketSeq).toBe(2n); + expect(bucketRefArgs[1]?.bucketSeq).toBe(2n); + }); + + it('produces a message-only block when a non-empty bundle is selected and no txs are pending', async () => { + jest + .spyOn(job.getTimetable(), 'selectNextSubslot') + .mockReturnValueOnce(subslot(10, 0, true)) + .mockReturnValue(noSubslot()); + + const bucket: InboxBucket = { + seq: 2n, + inboxRollingHash: new Fr(99), + totalMsgCount: 5n, + timestamp: 0n, + msgCount: 2, + lastMessageIndex: 4n, + }; + const bundle = Array.from({ length: 5 }, (_, i) => new Fr(i + 1)); + l1ToL2MessageSource.getLatestInboxBucketAtOrBefore.mockResolvedValue(bucket); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue(bundle); + + // Empty tx pool with the min-txs threshold at its default of one and no empty-checkpoint building: the + // non-empty bundle alone must count as work, producing a zero-tx (message-only) block. + const { lastBlock } = await setupMultipleBlocks(1, [0]); + validatorClient.collectAttestations.mockResolvedValue(getAttestations(lastBlock)); + + job.updateConfig({ minTxsPerBlock: 1, buildCheckpointIfEmpty: false }); + const checkpoint = await job.executeAndAwait(); + + expect(checkpoint).toBeDefined(); + expect(checkpointBuilder.buildBlockCalls).toHaveLength(1); + expect(checkpointBuilder.buildBlockCalls[0].opts.l1ToL2Messages).toEqual(bundle); + expect(publisher.enqueueProposeCheckpoint).toHaveBeenCalledTimes(1); + }); + + it('carries the consumed bucket hint when the final block fails to build after earlier consumption', async () => { + // Two sub-slots. The first block consumes the pending bucket (seq 2) as a message-only block. The final + // sub-slot block has no txs and nothing left to consume (the cursor already sits at seq 2), so it fails to + // build and is not held for broadcast. The L1 propose bucket hint must still be the bucket the checkpoint + // header committed to (seq 2), not fall back to genesis bucket 0 — otherwise L1 rejects the proposal with an + // inbox-rolling-hash mismatch (the hint's bucket rolling hash would not match the header's). + jest + .spyOn(job.getTimetable(), 'selectNextSubslot') + .mockReturnValueOnce(subslot(10, 0, false)) + .mockReturnValueOnce(subslot(18, 1, true)) + .mockReturnValue(noSubslot()); + + const bucket: InboxBucket = { + seq: 2n, + inboxRollingHash: new Fr(99), + totalMsgCount: 5n, + timestamp: 0n, + msgCount: 2, + lastMessageIndex: 4n, + }; + const bundle = Array.from({ length: 5 }, (_, i) => new Fr(i + 1)); + l1ToL2MessageSource.getLatestInboxBucketAtOrBefore.mockResolvedValue(bucket); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue(bundle); + + // Seed a single message-only block; the second sub-slot has no seeded block, no txs, and no new bucket to + // consume, so it fails the min-work threshold and no block is held for broadcast. + const { lastBlock } = await setupMultipleBlocks(1, [0]); + validatorClient.collectAttestations.mockResolvedValue(getAttestations(lastBlock)); + + job.updateConfig({ minTxsPerBlock: 1, buildCheckpointIfEmpty: false }); + const checkpoint = await job.executeAndAwait(); + + expect(checkpoint).toBeDefined(); + // Only the first (message-only) block built and consumed through bucket 2; the final block did not build. + expect(checkpointBuilder.buildBlockCalls).toHaveLength(1); + expect(publisher.enqueueProposeCheckpoint).toHaveBeenCalledTimes(1); + + // No held last block, yet the bucket hint (4th positional arg) is the consumed bucket seq 2, matching the + // checkpoint header's rolling hash. Before the fix this fell back to genesis bucket 0n. + expect(publisher.enqueueProposeCheckpoint.mock.calls[0][3]).toBe(2n); + }); + }); + describe('build single block', () => { it('does not build a block if not enough valid txs are collected', async () => { // We have enough txs, but not enough valid ones diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts index 6088fb1579e6..a11d3f131727 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts @@ -16,6 +16,7 @@ import type { BlockBuilderOptions, MerkleTreeWriteOperations, ResolvedSequencerConfig, + TreeInfo, WorldStateSynchronizer, } from '@aztec/stdlib/interfaces/server'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; @@ -448,10 +449,20 @@ describe('CheckpointProposalJob Timing Tests', () => { const mockFork = mock({ [Symbol.asyncDispose]: jest.fn().mockReturnValue(Promise.resolve()) as () => Promise, }); + // Streaming inbox: the checkpoint job resolves the parent Inbox bucket from the fork's + // L1-to-L2 tree leaf count. Default to an empty tree so it starts at the genesis bucket. + mockFork.getTreeInfo.mockResolvedValue({ size: 0n } as TreeInfo); worldState.fork.mockResolvedValue(mockFork); l1ToL2MessageSource = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue(Array(4).fill(Fr.ZERO)); + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue({ + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }); l2BlockSource = mock(); l2BlockSource.getCheckpointsData.mockResolvedValue([]); diff --git a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts index 729aa8039b87..036a23166e0f 100644 --- a/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts +++ b/yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts @@ -1,3 +1,4 @@ +import { INBOX_LAG_SECONDS, MAX_L1_TO_L2_MSGS_PER_BLOCK, MAX_L1_TO_L2_MSGS_PER_CHECKPOINT } from '@aztec/constants'; import { type EpochCache, PROPOSER_PIPELINING_SLOT_OFFSET } from '@aztec/epoch-cache'; import type { SimulationOverridesPlan } from '@aztec/ethereum/contracts'; import { @@ -39,6 +40,7 @@ import { type Checkpoint, type ProposedCheckpointData, buildCheckpointSimulationOverridesPlan, + getPreviousCheckpointInboxRollingHash, getPreviousCheckpointOutHashes, validateCheckpoint, } from '@aztec/stdlib/checkpoint'; @@ -47,10 +49,11 @@ import { Gas } from '@aztec/stdlib/gas'; import { type BlockBuilderOptions, InsufficientValidTxsError, + type MerkleTreeWriteOperations, type ResolvedSequencerConfig, type WorldStateSynchronizer, } from '@aztec/stdlib/interfaces/server'; -import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; +import { InboxBucketRef, type L1ToL2MessageSource, getInboxCutoffTimestamp } from '@aztec/stdlib/messaging'; import type { BlockProposal, BlockProposalOptions, @@ -62,6 +65,7 @@ import type { import { orderAttestations, trimAttestations } from '@aztec/stdlib/p2p'; import type { L2BlockBuiltStats } from '@aztec/stdlib/stats'; import type { ProposerTimetable } from '@aztec/stdlib/timetable'; +import { MerkleTreeId } from '@aztec/stdlib/trees'; import { type FailedTx, Tx } from '@aztec/stdlib/tx'; import { AttestationTimeoutError } from '@aztec/stdlib/validators'; import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client'; @@ -74,6 +78,11 @@ import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal import { CheckpointVoter } from './checkpoint_voter.js'; import { SequencerInterruptedError } from './errors.js'; import type { SequencerEvents } from './events.js'; +import { + type ConsumedBucketCursor, + type InboxBucketSelection, + selectInboxBucketForBlock, +} from './inbox_bucket_selector.js'; import type { SequencerMetrics } from './metrics.js'; import type { RequestsTracker } from './requests_tracker.js'; import type { SequencerRollupConstants } from './types.js'; @@ -88,6 +97,13 @@ type CheckpointProposalBroadcast = { checkpoint: Checkpoint; proposal: CheckpointProposal; blockProposedAt: number; + /** + * Sequence number of the last Inbox bucket the checkpoint consumed through — the L1 `propose` lookup aid, which + * must resolve to the bucket whose rolling hash the checkpoint header committed to. Taken from the streaming + * consumption cursor rather than the held last-block proposal, which is absent when the checkpoint's final block + * fails to build after earlier blocks already consumed messages. + */ + bucketHint: bigint; }; /** Result after attestation collection and signing, ready for L1 submission. */ @@ -95,6 +111,21 @@ type CheckpointProposalResult = { checkpoint: Checkpoint; attestations: CommitteeAttestationsAndSigners; attestationsSignature: Signature; + /** Sequence number of the Inbox bucket the checkpoint's rolling hash corresponds to; the L1 `propose` lookup aid. */ + bucketHint: bigint; +}; + +/** + * Running state of streaming Inbox message selection across the blocks of one checkpoint. + * Consumption starts from the parent checkpoint's last-consumed bucket and advances one block at a time. + */ +type StreamingCheckpointState = { + /** Cumulative Inbox message count consumed as of the parent checkpoint; the per-checkpoint cap origin (fixed). */ + checkpointStartTotalMsgCount: bigint; + /** The last bucket consumed so far (parent checkpoint's at the first block); advances as blocks consume. */ + parent: ConsumedBucketCursor; + /** Reference to the last consumed bucket; reused by blocks that consume nothing. */ + lastBucketRef: InboxBucketRef; }; /** @@ -286,6 +317,11 @@ export class CheckpointProposalJob implements Traceable { votesPromises: Promise[], ): Promise { const { checkpoint } = broadcast; + // The bucket the checkpoint consumed through, from the streaming cursor. Sourcing it from the held last-block + // proposal is wrong: when the checkpoint's final block fails to build after earlier blocks already consumed + // messages, no block is held, so the hint would fall back to genesis bucket 0 while the header commits to a + // non-genesis rolling hash, which L1 rejects with Rollup__InvalidInboxRollingHash. + const bucketHint = broadcast.bucketHint; try { // Wait for all votes actions, enqueued at the beginning, to resolve @@ -297,7 +333,7 @@ export class CheckpointProposalJob implements Traceable { // Wait for the previous checkpoint to land on L1 before submitting, so we can check it // matches the proposed checkpoint we used as parent, and has valid attestations. if (signedAttestations && (await this.waitForValidParentCheckpointOnL1())) { - await this.enqueueCheckpointForSubmission({ checkpoint, ...signedAttestations }); + await this.enqueueCheckpointForSubmission({ checkpoint, ...signedAttestations, bucketHint }); } // If we failed to collect attestations, at least check if we need to issue an invalidation @@ -368,7 +404,7 @@ export class CheckpointProposalJob implements Traceable { /** Enqueues the checkpoint for L1 submission. Called after pipeline sleep in execute(). */ private async enqueueCheckpointForSubmission(result: CheckpointProposalResult): Promise { - const { checkpoint, attestations, attestationsSignature } = result; + const { checkpoint, attestations, attestationsSignature, bucketHint } = result; this.setState(SequencerState.PUBLISHING_CHECKPOINT); // Latest L1 block the propose can still land in for the target slot: the last Ethereum block inside @@ -397,7 +433,9 @@ export class CheckpointProposalJob implements Traceable { } } - await this.publisher.enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, { txTimeoutAt }); + await this.publisher.enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, bucketHint, { + txTimeoutAt, + }); } /** @@ -610,10 +648,6 @@ export class CheckpointProposalJob implements Traceable { this.checkpointSimulationOverridesPlan, ); - // Collect L1 to L2 messages for the checkpoint and compute their hash - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(this.checkpointNumber); - const inHash = computeInHashFromL1ToL2Messages(l1ToL2Messages); - // Collect the out hashes of all the checkpoints before this one in the same epoch. // Under pipelining the parent checkpoint may not be on L1 yet at build time, so the helper // splices in the parent's checkpointOutHash from the locally-known proposed checkpoint so @@ -629,6 +663,16 @@ export class CheckpointProposalJob implements Traceable { log: this.log, }); + // Chain start for this checkpoint's inbox rolling hash: the parent checkpoint's `inboxRollingHash`. Unlike the + // epoch out-hash tree, the chain is continuous across epochs, so this is always the immediately preceding + // checkpoint's value (or zero at genesis). + const previousInboxRollingHash = await getPreviousCheckpointInboxRollingHash({ + blockSource: this.l2BlockSource, + checkpointNumber: this.checkpointNumber, + proposedCheckpointData: this.proposedCheckpointData, + log: this.log, + }); + // Anchor the modifier to the predicted parent fee header: L1 will apply it against // that, not against the latest published checkpoint (which lags by one under pipelining). const predictedParentEthPerFeeAssetE12 = @@ -638,13 +682,18 @@ export class CheckpointProposalJob implements Traceable { // Create a long-lived forked world state for the checkpoint builder await using fork = await this.worldState.fork(this.syncedToBlockNumber, { closeDelayMs: 12_000 }); + // Streaming Inbox: the consumption cursor starts at the parent state this checkpoint builds on. The fork's + // L1-to-L2 tree leaf count is the parent's cumulative consumed total (compact indexing), which resolves the + // parent's last-consumed bucket. + const streamingState = await this.resolveStreamingCheckpointStart(fork); + // Create checkpoint builder for the entire slot const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint( this.checkpointNumber, checkpointGlobalVariables, feeAssetPriceModifier, - l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, this.log.getBindings(), ); @@ -670,8 +719,8 @@ export class CheckpointProposalJob implements Traceable { const result = await this.buildBlocksForCheckpoint( checkpointBuilder, checkpointGlobalVariables.timestamp, - inHash, blockProposalOptions, + streamingState, ); blocksInCheckpoint = result.blocksInCheckpoint; blockPendingBroadcast = result.blockPendingBroadcast; @@ -787,7 +836,12 @@ export class CheckpointProposalJob implements Traceable { ); this.metrics.recordCheckpointSuccess(); // Return a broadcast result with a dummy proposal — fisherman mode skips attestation collection - return { checkpoint, proposal: undefined!, blockProposedAt: this.dateProvider.now() }; + return { + checkpoint, + proposal: undefined!, + blockProposedAt: this.dateProvider.now(), + bucketHint: streamingState.lastBucketRef.bucketSeq, + }; } // Validate the header against L1 state before broadcasting. @@ -841,8 +895,10 @@ export class CheckpointProposalJob implements Traceable { this.checkpointMetrics.noteCheckpointBroadcast(this.dateProvider.now()); } - // Return immediately after broadcast — attestation collection happens in the background - return { checkpoint, proposal, blockProposedAt }; + // Return immediately after broadcast — attestation collection happens in the background. The bucket hint is + // the streaming cursor's final consumed bucket, which matches the header's rolling hash whether or not a last + // block was held for broadcast. + return { checkpoint, proposal, blockProposedAt, bucketHint: streamingState.lastBucketRef.bucketSeq }; } catch (err) { if (err && (err instanceof DutyAlreadySignedError || err instanceof SlashingProtectionError)) { // swallow this error. It's already been logged by a function deeper in the stack @@ -861,8 +917,8 @@ export class CheckpointProposalJob implements Traceable { private async buildBlocksForCheckpoint( checkpointBuilder: CheckpointBuilder, timestamp: bigint, - inHash: Fr, blockProposalOptions: BlockProposalOptions, + streamingState?: StreamingCheckpointState, ): Promise<{ blocksInCheckpoint: L2Block[]; blockPendingBroadcast: BlockProposal | undefined; @@ -900,6 +956,18 @@ export class CheckpointProposalJob implements Traceable { break; } + // Streaming Inbox: select this block's message bundle against the current (not-yet-advanced) consumption + // cursor. The state is only advanced once the block builds successfully, so a failed build (retried in a + // later sub-slot) re-derives the bundle rather than losing it. The builder inserts the bundle and rolls it + // back with the fork on failure. The censorship cutoff floor must apply on whichever block ends the + // checkpoint, which includes the block that reaches the per-checkpoint block cap, not just the timetable's + // last sub-slot. + const isCheckpointFinalBlock = timingInfo.isLastBlock || blocksBuilt + 1 >= this.config.maxBlocksPerCheckpoint; + const selection = streamingState + ? await this.selectStreamingBundle(streamingState, isCheckpointFinalBlock, nowSeconds) + : undefined; + const streamingBundle = streamingState ? (selection && selection.consume ? selection.bundle : []) : undefined; + const buildResult = await this.buildSingleBlock(checkpointBuilder, { // Create all blocks with the same timestamp blockTimestamp: timestamp, @@ -909,6 +977,7 @@ export class CheckpointProposalJob implements Traceable { blockNumber, indexWithinCheckpoint, txHashesAlreadyIncluded, + l1ToL2Messages: streamingBundle, }); // If we failed to build the block due to insufficient txs, we try again if there is still time left in the slot @@ -944,13 +1013,29 @@ export class CheckpointProposalJob implements Traceable { blocksInCheckpoint.push(block); usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString())); + // Streaming Inbox: the block built successfully, so advance the consumption cursor and carry this block's + // rolling-hash bucket reference. A block that consumed nothing reuses the parent bucket reference. + let blockBucketRef: InboxBucketRef | undefined = undefined; + if (streamingState && selection) { + if (selection.consume) { + streamingState.parent = { seq: selection.bucket.seq, totalMsgCount: selection.bucket.totalMsgCount }; + streamingState.lastBucketRef = InboxBucketRef.fromBucket(selection.bucket); + } + blockBucketRef = streamingState.lastBucketRef; + } + // Sign the block proposal. This will throw if HA signing fails. - const proposal = await this.createBlockProposal(block, inHash, usedTxs, { - ...blockProposalOptions, - broadcastInvalidBlockProposal: - blockProposalOptions.broadcastInvalidBlockProposal || - block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint, - }); + const proposal = await this.createBlockProposal( + block, + usedTxs, + { + ...blockProposalOptions, + broadcastInvalidBlockProposal: + blockProposalOptions.broadcastInvalidBlockProposal || + block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint, + }, + blockBucketRef, + ); // Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal, // so we avoid polluting our archive with a block that would fail. @@ -990,9 +1075,9 @@ export class CheckpointProposalJob implements Traceable { /** Creates a block proposal for a given block via the validator client (unless in fisherman mode) */ private createBlockProposal( block: L2Block, - inHash: Fr, usedTxs: Tx[], blockProposalOptions: BlockProposalOptions, + bucketRef?: InboxBucketRef, ): Promise { if (this.config.fishermanMode) { this.log.info(`Skipping block proposal for block ${block.number} in fisherman mode`); @@ -1002,14 +1087,61 @@ export class CheckpointProposalJob implements Traceable { block.header, this.checkpointNumber, block.indexWithinCheckpoint, - inHash, block.archive.root, usedTxs, this.proposer, blockProposalOptions, + bucketRef, ); } + /** + * Resolves where a streaming-Inbox checkpoint's consumption starts: the parent checkpoint's last-consumed bucket. + * The parent's cumulative consumed total is the L1-to-L2 message tree leaf count of the fork + * this checkpoint builds on (compact indexing makes leaf count equal cumulative message count), which resolves the + * parent bucket by total. Genesis is the `total = 0` case, resolving the genesis bucket 0. + */ + private async resolveStreamingCheckpointStart(fork: MerkleTreeWriteOperations): Promise { + const parentInfo = await fork.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE); + const parentTotalMsgCount = parentInfo.size; + const parentBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(parentTotalMsgCount); + if (parentBucket === undefined) { + throw new Error( + `Streaming inbox: cannot resolve parent Inbox bucket for cumulative total ${parentTotalMsgCount} ` + + `(checkpoint ${this.checkpointNumber}); local Inbox view has not synced it`, + ); + } + return { + checkpointStartTotalMsgCount: parentTotalMsgCount, + parent: { seq: parentBucket.seq, totalMsgCount: parentBucket.totalMsgCount }, + lastBucketRef: InboxBucketRef.fromBucket(parentBucket), + }; + } + + /** + * Selects this block's streaming-Inbox message bundle against the current consumption cursor, mirroring the L1 + * predicate in `ProposeLib.validateInboxConsumption`. Does not mutate the cursor; the caller + * advances it only after the block builds successfully. + */ + private selectStreamingBundle( + state: StreamingCheckpointState, + isLastBlock: boolean, + nowSeconds: number, + ): Promise { + const cutoffTimestamp = getInboxCutoffTimestamp(this.targetSlot, this.l1Constants, INBOX_LAG_SECONDS); + return selectInboxBucketForBlock({ + messageSource: this.l1ToL2MessageSource, + now: BigInt(Math.floor(nowSeconds)), + lagSeconds: BigInt(INBOX_LAG_SECONDS), + parent: state.parent, + checkpointStartTotalMsgCount: state.checkpointStartTotalMsgCount, + perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + isLastBlock, + cutoffTimestamp, + }); + } + /** * Sleeps until it is time to produce the next block in the slot. * @param nextSubslotStart - Absolute wall-clock timestamp in seconds of the previous sub-slot deadline. @@ -1034,12 +1166,21 @@ export class CheckpointProposalJob implements Traceable { indexWithinCheckpoint: IndexWithinCheckpoint; buildDeadline: Date | undefined; txHashesAlreadyIncluded: Set; + /** Streaming Inbox message bundle for this block's L1-to-L2 tree; undefined when it consumes nothing. */ + l1ToL2Messages?: Fr[]; }, ): Promise< { block: L2Block; usedTxs: Tx[] } | { failure: 'insufficient-txs' | 'insufficient-valid-txs' } | { error: Error } > { - const { blockTimestamp, forceCreate, blockNumber, indexWithinCheckpoint, buildDeadline, txHashesAlreadyIncluded } = - opts; + const { + blockTimestamp, + forceCreate, + blockNumber, + indexWithinCheckpoint, + buildDeadline, + txHashesAlreadyIncluded, + l1ToL2Messages, + } = opts; this.log.verbose( `Preparing block ${blockNumber} index ${indexWithinCheckpoint} at checkpoint ${this.checkpointNumber} for slot ${this.targetSlot}`, @@ -1106,6 +1247,7 @@ export class CheckpointProposalJob implements Traceable { maxBlocksPerCheckpoint: this.timetable.getMaxBlocksPerCheckpoint(), perBlockAllocationMultiplier: this.config.perBlockAllocationMultiplier, perBlockDAAllocationMultiplier: this.config.perBlockDAAllocationMultiplier, + l1ToL2Messages, }; // Actually build the block by executing txs. The builder throws InsufficientValidTxsError @@ -1239,11 +1381,21 @@ export class CheckpointProposalJob implements Traceable { blockNumber: BlockNumber; indexWithinCheckpoint: IndexWithinCheckpoint; buildDeadline: Date | undefined; + /** Streaming Inbox message bundle this block consumes; a non-empty bundle permits a zero-tx (message-only) block. */ + l1ToL2Messages?: Fr[]; }): Promise<{ canStartBuilding: boolean; minTxs: number }> { const { indexWithinCheckpoint, blockNumber, buildDeadline, forceCreate } = opts; - // We only allow a block with 0 txs in the first block of the checkpoint - const minTxs = indexWithinCheckpoint > 0 && this.config.minTxsPerBlock === 0 ? 1 : this.config.minTxsPerBlock; + // A non-empty streaming Inbox bundle is work on its own: the block must be produced even with zero txs, + // regardless of minTxsPerBlock, so the messages get inserted (message-only block). + // Without a bundle, a non-first block needs at least one tx to avoid empty filler blocks even when + // minTxsPerBlock is zero. + const hasStreamingBundle = (opts.l1ToL2Messages?.length ?? 0) > 0; + const minTxs = hasStreamingBundle + ? 0 + : indexWithinCheckpoint > 0 && this.config.minTxsPerBlock === 0 + ? 1 + : this.config.minTxsPerBlock; // Latest time to keep waiting for txs: wait_for_txs_deadline = block_build_deadline(k) - min_block_duration. const startBuildingDeadline = buildDeadline diff --git a/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.test.ts b/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.test.ts new file mode 100644 index 000000000000..4ccd4d9b0eaa --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.test.ts @@ -0,0 +1,275 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; +import type { InboxBucket } from '@aztec/stdlib/messaging'; + +import { type InboxBucketSource, selectInboxBucketForBlock } from './inbox_bucket_selector.js'; + +/** A test bucket: its cumulative totals and leaves are derived from a running message count. */ +type TestBucketSpec = { seq: bigint; timestamp: bigint; msgCount: number }; + +/** + * Builds an in-memory {@link InboxBucketSource} from a list of bucket specs, mirroring the archiver's dense, + * timestamp-ordered buckets. Bucket seq 0 is the genesis sentinel (never a real bucket); real buckets start at 1. + */ +function makeSource(specs: TestBucketSpec[]): { + source: InboxBucketSource; + buckets: Map; + leaves: Fr[]; +} { + const leaves: Fr[] = []; + const buckets = new Map(); + let total = 0n; + for (const spec of specs) { + for (let i = 0; i < spec.msgCount; i++) { + leaves.push(new Fr(spec.seq * 1000n + BigInt(i))); + } + total += BigInt(spec.msgCount); + buckets.set(spec.seq, { + seq: spec.seq, + inboxRollingHash: new Fr(spec.seq), + totalMsgCount: total, + timestamp: spec.timestamp, + msgCount: spec.msgCount, + lastMessageIndex: total - 1n, + }); + } + + const ordered = [...buckets.values()].sort((a, b) => Number(a.seq - b.seq)); + const source: InboxBucketSource = { + getInboxBucket: (seq: bigint) => Promise.resolve(buckets.get(seq)), + getLatestInboxBucketAtOrBefore: (timestamp: bigint) => { + const eligible = ordered.filter(b => b.timestamp <= timestamp); + return Promise.resolve(eligible.length === 0 ? undefined : eligible[eligible.length - 1]); + }, + getL1ToL2MessagesBetweenBuckets: (fromExclusive: bigint, toInclusive: bigint) => { + const toBucket = buckets.get(toInclusive); + if (toBucket === undefined) { + return Promise.resolve([]); + } + let startIndex = 0n; + if (fromExclusive > 0n) { + const fromBucket = buckets.get(fromExclusive); + if (fromBucket === undefined) { + return Promise.resolve([]); + } + startIndex = fromBucket.lastMessageIndex + 1n; + } + return Promise.resolve(leaves.slice(Number(startIndex), Number(toBucket.lastMessageIndex + 1n))); + }, + }; + + return { source, buckets, leaves }; +} + +const GENESIS_PARENT = { seq: 0n, totalMsgCount: 0n }; + +// Pinned cross-layer values shared with the L1 Foundry harness: genesisTime=100000, slotDuration=36, +// INBOX_LAG_SECONDS=12. +const GENESIS_TIME = 100000n; +const SLOT_DURATION = 36n; +const LAG = 12n; +const cutoffForSlot = (slot: bigint) => GENESIS_TIME + (slot - 1n) * SLOT_DURATION - LAG; + +describe('selectInboxBucketForBlock', () => { + const baseInput = { + lagSeconds: LAG, + checkpointStartTotalMsgCount: 0n, + perBlockCap: 1024, + perCheckpointCap: 1024, + isLastBlock: false, + cutoffTimestamp: 0n, + }; + + it('consumes nothing from an empty Inbox', async () => { + const { source } = makeSource([]); + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 1_000_000n, + parent: GENESIS_PARENT, + }); + expect(result.consume).toBe(false); + }); + + it('picks the newest lag-eligible bucket and derives its bundle from genesis', async () => { + const { source } = makeSource([ + { seq: 1n, timestamp: 100n, msgCount: 3 }, + { seq: 2n, timestamp: 200n, msgCount: 2 }, + { seq: 3n, timestamp: 300n, msgCount: 4 }, + ]); + // now - lag = 250 -> newest bucket at-or-before 250 is seq 2. + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 250n + LAG, + parent: GENESIS_PARENT, + }); + expect(result).toMatchObject({ consume: true }); + if (result.consume) { + expect(result.bucket.seq).toBe(2n); + expect(result.bundle).toHaveLength(5); // buckets 1 (3) + 2 (2) + } + }); + + it('treats a bucket exactly lagSeconds old as eligible (inclusive lag boundary)', async () => { + const { source } = makeSource([{ seq: 1n, timestamp: 500n, msgCount: 1 }]); + // Bucket age exactly == lag: timestamp == now - lag. + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 500n + LAG, + parent: GENESIS_PARENT, + }); + expect(result.consume).toBe(true); + + // One second younger than the lag boundary: not yet eligible. + const tooYoung = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 500n + LAG - 1n, + parent: GENESIS_PARENT, + }); + expect(tooYoung.consume).toBe(false); + }); + + it('walks back to the newest bucket that fits the per-block cap', async () => { + const { source } = makeSource([ + { seq: 1n, timestamp: 100n, msgCount: 200 }, + { seq: 2n, timestamp: 200n, msgCount: 200 }, + { seq: 3n, timestamp: 300n, msgCount: 200 }, + ]); + // Newest eligible is seq 3 (600 msgs from genesis), but perBlockCap=400 only fits through seq 2. + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 300n + LAG, + parent: GENESIS_PARENT, + perBlockCap: 400, + }); + expect(result).toMatchObject({ consume: true }); + if (result.consume) { + expect(result.bucket.seq).toBe(2n); + expect(result.bundle).toHaveLength(400); + } + }); + + it('accumulates the per-checkpoint cap across blocks', async () => { + const { source, buckets } = makeSource([ + { seq: 1n, timestamp: 100n, msgCount: 600 }, + { seq: 2n, timestamp: 200n, msgCount: 600 }, + ]); + // Block 1 already consumed bucket 1 (600 msgs). perCheckpointCap=1000 leaves only 400 headroom, but bucket 2 + // would bring the checkpoint total to 1200 > 1000, so block 2 consumes nothing (cap-escape). + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 200n + LAG, + parent: { seq: 1n, totalMsgCount: buckets.get(1n)!.totalMsgCount }, + checkpointStartTotalMsgCount: 0n, + perCheckpointCap: 1000, + }); + expect(result.consume).toBe(false); + }); + + it('advances across sub-slots as buckets arrive', async () => { + const { source } = makeSource([ + { seq: 1n, timestamp: 100n, msgCount: 2 }, + { seq: 2n, timestamp: 260n, msgCount: 3 }, + ]); + // Block 1 at now-lag=150: only bucket 1 eligible. + const first = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 150n + LAG, + parent: GENESIS_PARENT, + }); + expect(first).toMatchObject({ consume: true }); + if (!first.consume) { + return; + } + expect(first.bucket.seq).toBe(1n); + + // Block 2, later sub-slot (now-lag=300): bucket 2 has now aged in; parent is block 1's bucket. + const second = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 300n + LAG, + parent: { seq: first.bucket.seq, totalMsgCount: first.bucket.totalMsgCount }, + checkpointStartTotalMsgCount: 0n, + }); + expect(second).toMatchObject({ consume: true }); + if (second.consume) { + expect(second.bucket.seq).toBe(2n); + expect(second.bundle).toHaveLength(3); // only bucket 2's messages, not bucket 1's + expect(second.bundle).toEqual(await source.getL1ToL2MessagesBetweenBuckets(1n, 2n)); + } + }); + + it('applies the cutoff as a consumption floor on the last block', async () => { + // Bucket sits at the cutoff for slot 10 but is younger than now-lag, so a non-last block skips it. + const cutoff = cutoffForSlot(10n); + const { source } = makeSource([{ seq: 1n, timestamp: cutoff, msgCount: 5 }]); + + const nonLast = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: cutoff + LAG - 1n, // bucket is one second too young for lag eligibility + parent: GENESIS_PARENT, + isLastBlock: false, + cutoffTimestamp: cutoff, + }); + expect(nonLast.consume).toBe(false); + + const last = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: cutoff + LAG - 1n, + parent: GENESIS_PARENT, + isLastBlock: true, + cutoffTimestamp: cutoff, + }); + expect(last).toMatchObject({ consume: true }); + if (last.consume) { + expect(last.bucket.seq).toBe(1n); + } + }); + + it('makes a bucket exactly at the cutoff mandatory and one past it optional (§13 boundary)', async () => { + const cutoff = cutoffForSlot(10n); // 100312 + // A bucket AT the cutoff must be consumed by the last block; a bucket one second past it need not be. + const atCutoff = makeSource([{ seq: 1n, timestamp: cutoff, msgCount: 1 }]); + const pastCutoff = makeSource([{ seq: 1n, timestamp: cutoff + 1n, msgCount: 1 }]); + + const mustConsume = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: atCutoff.source, + now: cutoff, // before lag would make it eligible, forcing reliance on the cutoff floor + parent: GENESIS_PARENT, + isLastBlock: true, + cutoffTimestamp: cutoff, + }); + expect(mustConsume.consume).toBe(true); + + const mayskip = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: pastCutoff.source, + now: cutoff, + parent: GENESIS_PARENT, + isLastBlock: true, + cutoffTimestamp: cutoff, + }); + expect(mayskip.consume).toBe(false); + }); + + it('consumes nothing when even the first bucket past the parent exceeds the per-checkpoint cap (cap-escape)', async () => { + const { source } = makeSource([{ seq: 1n, timestamp: 100n, msgCount: 2000 }]); + const result = await selectInboxBucketForBlock({ + ...baseInput, + messageSource: source, + now: 100n + LAG, + parent: GENESIS_PARENT, + perBlockCap: 4096, + perCheckpointCap: 1024, + }); + expect(result.consume).toBe(false); + }); +}); diff --git a/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.ts b/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.ts new file mode 100644 index 000000000000..b8a984bcb89a --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/inbox_bucket_selector.ts @@ -0,0 +1,122 @@ +import type { Fr } from '@aztec/foundation/curves/bn254'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; + +/** The subset of the archiver's Inbox-bucket queries the selector needs. */ +export type InboxBucketSource = Pick< + L1ToL2MessageSource, + 'getInboxBucket' | 'getLatestInboxBucketAtOrBefore' | 'getL1ToL2MessagesBetweenBuckets' +>; + +/** + * The last-consumed Inbox bucket a block streams from. Only the sequence number and cumulative message count are + * needed: the sequence number bounds the derived bundle, and the count is the per-block/per-checkpoint cap origin. + * At a checkpoint's first block this is the parent checkpoint's last-consumed bucket; the genesis base case is + * `{ seq: 0, totalMsgCount: 0 }` (bundles derive from the start of the Inbox). + */ +export type ConsumedBucketCursor = Pick; + +/** Inputs to a single block's streaming Inbox-bucket selection. */ +export type SelectInboxBucketInput = { + /** Archiver Inbox-bucket queries. */ + messageSource: InboxBucketSource; + /** Wall-clock time of this sub-slot, in seconds; the lag-eligibility anchor. */ + now: bigint; + /** Minimum bucket age in seconds (`INBOX_LAG_SECONDS`) for a bucket to be lag-eligible this sub-slot. */ + lagSeconds: bigint; + /** The last bucket consumed by this checkpoint so far (parent checkpoint's at the first block). */ + parent: ConsumedBucketCursor; + /** Cumulative Inbox message count consumed as of the parent checkpoint; the per-checkpoint cap origin. */ + checkpointStartTotalMsgCount: bigint; + /** Maximum number of messages this block may consume. */ + perBlockCap: number; + /** Maximum number of messages the checkpoint may consume in total. */ + perCheckpointCap: number; + /** True on the checkpoint's final block, where the censorship cutoff becomes a consumption floor. */ + isLastBlock: boolean; + /** + * Censorship cutoff timestamp, `toTimestamp(slot - 1) - lagSeconds` (mirrors `ProposeLib.validateInboxConsumption`). + * Buckets opened at or before it are mandatory to consume by the checkpoint's last block. + */ + cutoffTimestamp: bigint; +}; + +/** Result of a block's streaming Inbox-bucket selection. */ +export type InboxBucketSelection = + | { + /** The block consumes messages, advancing to `bucket`. */ + consume: true; + /** The newest bucket this block consumes through. */ + bucket: InboxBucket; + /** The message leaves consumed this block, in insertion order (may be empty for an empty bucket). */ + bundle: Fr[]; + } + | { + /** The block consumes nothing; it reuses the parent bucket reference. */ + consume: false; + }; + +/** + * Selects the newest Inbox bucket a block streams from, mirroring the L1 consumption predicate in + * `ProposeLib.validateInboxConsumption`. The policy, per block: + * + * 1. Pick the newest lag-eligible bucket: the newest bucket opened at or before `now - lagSeconds`. On the + * checkpoint's last block, also consider the cutoff bucket (newest opened at or before `cutoffTimestamp`) and take + * whichever is newer, so the checkpoint reaches the censorship floor even if the sub-slot lag preferred less. + * 2. If nothing is newer than the parent bucket, consume nothing. + * 3. Otherwise walk back from the candidate to the newest bucket whose consumption fits both the per-block cap + * (`bucket.totalMsgCount - parent.totalMsgCount`) and the per-checkpoint cap + * (`bucket.totalMsgCount - checkpointStartTotalMsgCount`). If even the first bucket past the parent overshoots the + * per-checkpoint cap, consume nothing — the L1 cap-escape (`ProposeLib` allows leaving a bucket unconsumed when + * consuming through it would exceed the per-checkpoint cap). + * + * The `<=` comparisons make a bucket exactly `lagSeconds` old lag-eligible and a bucket exactly at the cutoff + * mandatory, matching the strict `>` "past cutoff" test on L1 (`next.timestamp > cutoff` leaves it optional). + * + * A single bucket never exceeds the per-block cap by construction (the Inbox bucket size is at most the per-block cap), + * so per-block walk-back always lands on at least one bucket; only the per-checkpoint cap can force consuming nothing. + */ +export async function selectInboxBucketForBlock(input: SelectInboxBucketInput): Promise { + const { + messageSource, + now, + lagSeconds, + parent, + checkpointStartTotalMsgCount, + perBlockCap, + perCheckpointCap, + isLastBlock, + cutoffTimestamp, + } = input; + + let candidate = await messageSource.getLatestInboxBucketAtOrBefore(now - lagSeconds); + + if (isLastBlock) { + const cutoffBucket = await messageSource.getLatestInboxBucketAtOrBefore(cutoffTimestamp); + if (cutoffBucket !== undefined && (candidate === undefined || cutoffBucket.seq > candidate.seq)) { + candidate = cutoffBucket; + } + } + + if (candidate === undefined || candidate.seq <= parent.seq) { + return { consume: false }; + } + + const perBlockCapBig = BigInt(perBlockCap); + const perCheckpointCapBig = BigInt(perCheckpointCap); + + let selected: InboxBucket | undefined = candidate; + while (selected !== undefined && selected.seq > parent.seq) { + const blockCount = selected.totalMsgCount - parent.totalMsgCount; + const checkpointCount = selected.totalMsgCount - checkpointStartTotalMsgCount; + if (blockCount <= perBlockCapBig && checkpointCount <= perCheckpointCapBig) { + const bundle = await messageSource.getL1ToL2MessagesBetweenBuckets(parent.seq, selected.seq); + return { consume: true, bucket: selected, bundle }; + } + if (selected.seq - 1n <= parent.seq) { + break; + } + selected = await messageSource.getInboxBucket(selected.seq - 1n); + } + + return { consume: false }; +} diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index fb95eafd1485..c3ca4b8b3f00 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -1,4 +1,3 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; import { type EpochCache, type EpochCommitteeInfo, PROPOSER_PIPELINING_SLOT_OFFSET } from '@aztec/epoch-cache'; import { NoCommitteeError, type RollupContract } from '@aztec/ethereum/contracts'; import { @@ -35,7 +34,9 @@ import type { ChainConfig } from '@aztec/stdlib/config'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import { GasFees } from '@aztec/stdlib/gas'; import { + type MerkleTreeWriteOperations, type SequencerConfig, + type TreeInfo, WorldStateRunningState, type WorldStateSyncStatus, type WorldStateSynchronizer, @@ -166,6 +167,8 @@ describe('sequencer', () => { expect.any(Checkpoint), attestationsAndSigners, getSignatures()[0].signature, + // Streaming inbox: the checkpoint job passes the parent bucket hint (genesis => 0n). + 0n, expect.objectContaining({ txTimeoutAt: expect.any(Date), }), @@ -285,6 +288,13 @@ describe('sequencer', () => { }, } satisfies WorldStateSynchronizerStatus), }); + // Streaming inbox: the checkpoint job forks world state and resolves the parent Inbox bucket + // from the fork's L1-to-L2 tree leaf count. Default to an empty tree so it starts at the genesis bucket. + const mockFork = mock({ + [Symbol.asyncDispose]: jest.fn().mockReturnValue(Promise.resolve()) as () => Promise, + }); + mockFork.getTreeInfo.mockResolvedValue({ size: 0n } as TreeInfo); + worldState.fork.mockResolvedValue(mockFork); // Create fake CheckpointsBuilder and CheckpointBuilder // Uses blockProvider to return the current `block` variable (set per-test) @@ -338,7 +348,6 @@ describe('sequencer', () => { }); l1ToL2MessageSource = mock({ - getL1ToL2Messages: () => Promise.resolve(Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(Fr.ZERO)), getL2Tips: mockFn().mockResolvedValue({ proposed: { number: lastBlockNumber, hash }, checkpointed: { @@ -355,6 +364,14 @@ describe('sequencer', () => { }, }), }); + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue({ + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }); validatorClient = mock(); validatorClient.collectAttestations.mockImplementation(() => Promise.resolve(getCheckpointAttestations())); @@ -839,6 +856,8 @@ describe('sequencer', () => { expect.any(Checkpoint), attestationsAndSigners, getSignatures()[0].signature, + // Streaming inbox: the checkpoint job passes the parent bucket hint (genesis => 0n). + 0n, expect.objectContaining({ txTimeoutAt: expect.any(Date), }), @@ -1554,6 +1573,7 @@ describe('sequencer', () => { blockCount: 1, totalManaUsed: 0n, feeAssetPriceModifier: 0n, + inboxMsgTotal: 0n, }); await sequencer.work(); @@ -1679,6 +1699,7 @@ describe('sequencer', () => { blockCount: 1, totalManaUsed: 0n, feeAssetPriceModifier: 0n, + inboxMsgTotal: 0n, }); await sequencer.work(); @@ -1808,6 +1829,7 @@ describe('sequencer', () => { blockCount: 1, totalManaUsed: 0n, feeAssetPriceModifier: 0n, + inboxMsgTotal: 0n, }, }); diff --git a/yarn-project/sequencer-client/src/test/mock_checkpoint_builder.ts b/yarn-project/sequencer-client/src/test/mock_checkpoint_builder.ts index f0a6afca82cc..f53af34fc862 100644 --- a/yarn-project/sequencer-client/src/test/mock_checkpoint_builder.ts +++ b/yarn-project/sequencer-client/src/test/mock_checkpoint_builder.ts @@ -1,5 +1,6 @@ import { type BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; +import type { LoggerBindings } from '@aztec/foundation/log'; import { unfreeze } from '@aztec/foundation/types'; import { L2Block } from '@aztec/stdlib/block'; import { Checkpoint } from '@aztec/stdlib/checkpoint'; @@ -203,7 +204,6 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder { public startCheckpointCalls: Array<{ checkpointNumber: CheckpointNumber; constants: CheckpointGlobalVariables; - l1ToL2Messages: Fr[]; previousCheckpointOutHashes: Fr[]; feeAssetPriceModifier: bigint; }> = []; @@ -261,14 +261,14 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder { checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, - l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + _previousInboxRollingHash: Fr, _fork: MerkleTreeWriteOperations, + _bindings?: LoggerBindings, ): Promise { this.startCheckpointCalls.push({ checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, feeAssetPriceModifier, }); @@ -289,6 +289,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder { feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + _previousInboxRollingHash: Fr, _fork: MerkleTreeWriteOperations, existingBlocks: L2Block[] = [], ): Promise { diff --git a/yarn-project/sequencer-client/src/test/utils.ts b/yarn-project/sequencer-client/src/test/utils.ts index 4bee7eb50f2d..484ef4a1e401 100644 --- a/yarn-project/sequencer-client/src/test/utils.ts +++ b/yarn-project/sequencer-client/src/test/utils.ts @@ -114,7 +114,7 @@ export function createMockSignatures(signer: Secp256k1Signer): CommitteeAttestat /** * Creates a CheckpointHeader from an L2Block for testing purposes. - * Uses mock values for blockHeadersHash, blobsHash and inHash since L2Block doesn't have these fields. + * Uses mock values for blockHeadersHash and blobsHash since L2Block doesn't have these fields. */ function createCheckpointHeaderFromBlock(block: L2Block): CheckpointHeader { const gv = block.header.globalVariables; @@ -122,7 +122,7 @@ function createCheckpointHeaderFromBlock(block: L2Block): CheckpointHeader { block.header.lastArchive.root, Fr.random(), // blockHeadersHash - mock value for testing Fr.random(), // blobsHash - mock value for testing - Fr.random(), // inHash - mock value for testing + Fr.random(), // inboxRollingHash - mock value for testing Fr.random(), // outHash - mock value for testing gv.slotNumber, gv.timestamp, @@ -142,7 +142,6 @@ export function createBlockProposal(block: L2Block, signature: Signature): Block return new BlockProposal( block.header, block.indexWithinCheckpoint, - Fr.ZERO, // inHash - using zero for testing block.archive.root, txHashes, signature, diff --git a/yarn-project/stdlib/src/block/l2_block.ts b/yarn-project/stdlib/src/block/l2_block.ts index e7c78f332a1d..0d9975bee049 100644 --- a/yarn-project/stdlib/src/block/l2_block.ts +++ b/yarn-project/stdlib/src/block/l2_block.ts @@ -116,7 +116,6 @@ export class L2Block { } public toBlockBlobData(): BlockBlobData { - const isFirstBlock = this.indexWithinCheckpoint === 0; return { blockEndMarker: { numTxs: this.body.txEffects.length, @@ -134,7 +133,8 @@ export class L2Block { noteHashRoot: this.header.state.partial.noteHashTree.root, nullifierRoot: this.header.state.partial.nullifierTree.root, publicDataRoot: this.header.state.partial.publicDataTree.root, - l1ToL2MessageRoot: isFirstBlock ? this.header.state.l1ToL2MessageTree.root : undefined, + // Every block carries its own post-bundle l1-to-l2 message tree root. + l1ToL2MessageRoot: this.header.state.l1ToL2MessageTree.root, txs: this.body.toTxBlobData(), }; } @@ -155,7 +155,6 @@ export class L2Block { * @param txsPerBlock - The number of transactions to include in the block. * @param numPublicCallsPerTx - The number of public function calls to include in each transaction. * @param numPublicLogsPerCall - The number of public logs per 1 public function invocation. - * @param inHash - The hash of the L1 to L2 messages subtree which got inserted in this block. * @returns The L2 block. */ static async random( diff --git a/yarn-project/stdlib/src/checkpoint/checkpoint_data.ts b/yarn-project/stdlib/src/checkpoint/checkpoint_data.ts index b8ce95fd1231..f8ef256a686c 100644 --- a/yarn-project/stdlib/src/checkpoint/checkpoint_data.ts +++ b/yarn-project/stdlib/src/checkpoint/checkpoint_data.ts @@ -42,6 +42,18 @@ export type ProposedOnlyCheckpointData = { feeAssetPriceModifier: bigint; }; +/** Inbox consumption record of a proposed checkpoint, mirroring what `propose` writes for it on L1. */ +export type ProposedInboxConsumption = { + /** + * Cumulative Inbox message count consumed as of this checkpoint: its last block's L1-to-L2 message tree leaf count + * under compact indexing. L1 records this per checkpoint and reads it back as the parent total + * when validating the next checkpoint's consumption, so a simulation against a not-yet-mined parent must override + * the parent's cell with it — otherwise the parent reads as having consumed nothing and the child's consumption + * looks larger than it is. + */ + inboxMsgTotal: bigint; +}; + /** Lightweight checkpoint metadata without full block data. */ export type CheckpointData = CommonCheckpointData & StorageEnrichedCheckpointData & L1EnrichedCheckpointData; @@ -51,7 +63,7 @@ export type ProposedCheckpointInput = CommonCheckpointData & ProposedOnlyCheckpo /** Full data for a proposed checkpoint (proposed but not yet L1-confirmed). * Includes fee-relevant fields used during pipelining to compute the fee header override. */ -export type ProposedCheckpointData = ProposedCheckpointInput & StorageEnrichedCheckpointData; +export type ProposedCheckpointData = ProposedCheckpointInput & StorageEnrichedCheckpointData & ProposedInboxConsumption; export const ProposedCheckpointDataSchema = z.object({ checkpointNumber: CheckpointNumberSchema, @@ -62,6 +74,7 @@ export const ProposedCheckpointDataSchema = z.object({ blockCount: z.number(), totalManaUsed: schemas.BigInt, feeAssetPriceModifier: schemas.BigInt, + inboxMsgTotal: schemas.BigInt, }); export const CheckpointDataSchema = z diff --git a/yarn-project/stdlib/src/checkpoint/index.ts b/yarn-project/stdlib/src/checkpoint/index.ts index 8a0432995659..76c5eda642c3 100644 --- a/yarn-project/stdlib/src/checkpoint/index.ts +++ b/yarn-project/stdlib/src/checkpoint/index.ts @@ -3,6 +3,7 @@ export * from './checkpoint_data.js'; export * from './checkpoint_info.js'; export * from './checkpoint_reexecution_tracker.js'; export * from './digest.js'; +export * from './previous_checkpoint_inbox_rolling_hash.js'; export * from './previous_checkpoint_out_hashes.js'; export * from './published_checkpoint.js'; export * from './simulation_overrides.js'; diff --git a/yarn-project/stdlib/src/checkpoint/previous_checkpoint_inbox_rolling_hash.ts b/yarn-project/stdlib/src/checkpoint/previous_checkpoint_inbox_rolling_hash.ts new file mode 100644 index 000000000000..0e54bf0f5d6a --- /dev/null +++ b/yarn-project/stdlib/src/checkpoint/previous_checkpoint_inbox_rolling_hash.ts @@ -0,0 +1,46 @@ +import { CheckpointNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import type { Logger } from '@aztec/foundation/log'; + +import type { L2BlockSource } from '../block/l2_block_source.js'; +import type { ProposedCheckpointData } from './checkpoint_data.js'; + +/** + * Returns the inbox rolling hash chain-start for `checkpointNumber`: the `inboxRollingHash` of the immediately + * preceding checkpoint. Unlike the epoch out-hash tree, the rolling-hash chain is continuous across epoch boundaries, + * so the parent is always `checkpointNumber - 1` regardless of epoch. The genesis checkpoint (and the first checkpoint + * built on it) starts the chain at zero. + * + * Under proposer pipelining the parent may not be confirmed on L1 yet, so the locally-known proposed checkpoint is + * preferred when it is the parent, mirroring `getPreviousCheckpointOutHashes`. + */ +export async function getPreviousCheckpointInboxRollingHash(input: { + blockSource: Pick; + checkpointNumber: CheckpointNumber; + proposedCheckpointData?: ProposedCheckpointData; + log?: Logger; +}): Promise { + const { blockSource, checkpointNumber, proposedCheckpointData, log } = input; + if (checkpointNumber <= 1) { + return Fr.ZERO; + } + + const parent = CheckpointNumber(checkpointNumber - 1); + + if (proposedCheckpointData?.checkpointNumber === parent) { + log?.debug(`Using pipelined parent cp ${parent} inbox rolling hash for cp ${checkpointNumber}`); + return proposedCheckpointData.header.inboxRollingHash; + } + + const confirmed = await blockSource.getCheckpointData({ number: parent }); + if (confirmed) { + return confirmed.header.inboxRollingHash; + } + + const proposed = await blockSource.getProposedCheckpointData({ number: parent }); + if (proposed) { + return proposed.header.inboxRollingHash; + } + + throw new Error(`Cannot source inbox rolling hash for parent checkpoint ${parent} of checkpoint ${checkpointNumber}`); +} diff --git a/yarn-project/stdlib/src/checkpoint/previous_checkpoint_out_hashes.test.ts b/yarn-project/stdlib/src/checkpoint/previous_checkpoint_out_hashes.test.ts index b3994742b7b5..5256cf7e5302 100644 --- a/yarn-project/stdlib/src/checkpoint/previous_checkpoint_out_hashes.test.ts +++ b/yarn-project/stdlib/src/checkpoint/previous_checkpoint_out_hashes.test.ts @@ -37,6 +37,7 @@ function proposedParent(number: number, slot: number, outHash: Fr): ProposedChec blockCount: 1, totalManaUsed: 0n, feeAssetPriceModifier: 0n, + inboxMsgTotal: 0n, }; } diff --git a/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts b/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts index 0d30e9492eb1..3c7e5bea83d8 100644 --- a/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts +++ b/yarn-project/stdlib/src/checkpoint/simulation_overrides.test.ts @@ -31,6 +31,7 @@ describe('computePipelinedParentFeeHeader', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 0n, }; const grandparentFeeHeader: FeeHeader = { @@ -157,6 +158,7 @@ describe('buildCheckpointSimulationOverridesPlan', () => { blockCount: 1, totalManaUsed: 5000n, feeAssetPriceModifier: 100n, + inboxMsgTotal: 1500n, }; } @@ -194,6 +196,8 @@ describe('buildCheckpointSimulationOverridesPlan', () => { expect(plan?.pendingCheckpointState?.outHash).toEqual(proposedData.checkpointOutHash); expect(plan?.pendingCheckpointState?.payloadDigest).toBeDefined(); expect(plan?.pendingCheckpointState?.feeHeader).toBeDefined(); + // Without this the parent reads as having consumed no Inbox messages, inflating the child's consumed count. + expect(plan?.pendingCheckpointState?.inboxMsgTotal).toEqual(proposedData.inboxMsgTotal); }); it('throws when the pipelined parent does not match the expected parent checkpoint', async () => { diff --git a/yarn-project/stdlib/src/checkpoint/simulation_overrides.ts b/yarn-project/stdlib/src/checkpoint/simulation_overrides.ts index 937413b1d518..162603b1bfc5 100644 --- a/yarn-project/stdlib/src/checkpoint/simulation_overrides.ts +++ b/yarn-project/stdlib/src/checkpoint/simulation_overrides.ts @@ -73,21 +73,25 @@ export async function buildCheckpointSimulationOverridesPlan( builder.withChainTips({ pending: overridenChainTip, proven: overridenChainTip }); if (input.proposedCheckpointData) { - const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData; + const { header, archive, checkpointOutHash, feeAssetPriceModifier, inboxMsgTotal } = input.proposedCheckpointData; builder.withPendingArchive(archive.root); // Override every locally-derivable `tempCheckpointLogs[parent]` field that L1 will eventually - // write. `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: without it the cell reads + // write. `slotNumber` is required by `STFLib.canPruneAtTime`: without it the cell reads // slotNumber 0, the contract treats the pending tip as belonging to an expired epoch, and // `getEffectivePendingCheckpointNumber` silently collapses pending back to proven — producing - // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. The other fields - // (headerHash, outHash, payloadDigest) are not strictly load-bearing for `canProposeAt` / - // `validateBlockHeader`, but mirroring the full cell keeps the simulation byte-faithful with - // what the actual `propose()` send will observe, which is a defense against future reads - // taking dependencies on them. + // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. `inboxMsgTotal` is + // read by `ProposeLib.validateInboxConsumption` as the parent's consumed total: left at zero it + // makes our consumption look like the Inbox's entire history and trips + // `Rollup__TooManyInboxMessagesConsumed`. The remaining fields (headerHash, outHash, + // payloadDigest) are not read by `canProposeAt` / `validateBlockHeader`, but mirroring the full + // cell keeps the simulation byte-faithful with what the actual `propose()` send will observe, + // which is a defense against future reads taking dependencies on them. The parent's + // `inboxConsumedBucket` shares the word and stays zero: no contract path reads it back. builder.withPendingTempCheckpointLogFields({ headerHash: header.hash(), outHash: checkpointOutHash, slotNumber: header.slotNumber, + inboxMsgTotal, payloadDigest: computeCheckpointPayloadDigest({ header, archiveRoot: archive.root, diff --git a/yarn-project/stdlib/src/config/network-consensus-config.ts b/yarn-project/stdlib/src/config/network-consensus-config.ts index 152f29ed836c..c0fbeb13bb99 100644 --- a/yarn-project/stdlib/src/config/network-consensus-config.ts +++ b/yarn-project/stdlib/src/config/network-consensus-config.ts @@ -47,7 +47,6 @@ export const NETWORK_CONSENSUS_ENV_VARS = [ 'AZTEC_EJECTION_THRESHOLD', 'AZTEC_LOCAL_EJECTION_THRESHOLD', 'AZTEC_EXIT_DELAY_SECONDS', - 'AZTEC_INBOX_LAG', 'AZTEC_PROOF_SUBMISSION_EPOCHS', 'AZTEC_MANA_TARGET', 'AZTEC_PROVING_COST_PER_MANA', diff --git a/yarn-project/stdlib/src/deserialization/deserialization.test.ts b/yarn-project/stdlib/src/deserialization/deserialization.test.ts index 274953c9af19..85482da68ba4 100644 --- a/yarn-project/stdlib/src/deserialization/deserialization.test.ts +++ b/yarn-project/stdlib/src/deserialization/deserialization.test.ts @@ -1,7 +1,6 @@ import { NUM_BLOCK_END_BLOB_FIELDS, NUM_CHECKPOINT_END_MARKER_FIELDS, - NUM_FIRST_BLOCK_END_BLOB_FIELDS, getNumTxBlobFields, } from '@aztec/blob-lib/encoding'; import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB } from '@aztec/constants'; @@ -23,13 +22,14 @@ describe('MAX_CAPACITY_BLOCKS_PER_CHECKPOINT', () => { }); // Largest checkpoint that fits in the blob budget with the most compact construction: - // one (possibly empty) first block + (N - 1) single-nullifier blocks + a checkpoint-end marker. + // one (possibly empty) first block + (N - 1) single-nullifier blocks + a checkpoint-end marker. Every block + // spends the same block-end overhead, including the per-block l1-to-l2 root. // This is the real ceiling the proving system / L1 enforce — there is no explicit block-count cap. const blobBudget = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB; const maxBlocksThatFitInBlobs = 1 + Math.floor( - (blobBudget - NUM_CHECKPOINT_END_MARKER_FIELDS - NUM_FIRST_BLOCK_END_BLOB_FIELDS) / + (blobBudget - NUM_CHECKPOINT_END_MARKER_FIELDS - NUM_BLOCK_END_BLOB_FIELDS) / (NUM_BLOCK_END_BLOB_FIELDS + MIN_TX_BLOB_FIELDS), ); @@ -42,7 +42,7 @@ describe('MAX_CAPACITY_BLOCKS_PER_CHECKPOINT', () => { it('matches the documented ceiling for the current blob constants', () => { // Pins the arithmetic so a change to BLOBS_PER_CHECKPOINT / FIELDS_PER_BLOB / block-field counts // is noticed and the constant + its comment get revisited. - expect(maxBlocksThatFitInBlobs).toBe(2457); - expect(MAX_CAPACITY_BLOCKS_PER_CHECKPOINT).toBe(2457); + expect(maxBlocksThatFitInBlobs).toBe(2234); + expect(MAX_CAPACITY_BLOCKS_PER_CHECKPOINT).toBe(2234); }); }); diff --git a/yarn-project/stdlib/src/deserialization/index.ts b/yarn-project/stdlib/src/deserialization/index.ts index fc5e693d9357..0448f0733ca8 100644 --- a/yarn-project/stdlib/src/deserialization/index.ts +++ b/yarn-project/stdlib/src/deserialization/index.ts @@ -22,23 +22,23 @@ export const MAX_COMMITTEE_SIZE = 2048; * * budget = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB = 6 * 4096 = 24,576 fields * - * per-block minimal blob footprint: - * first block (may be empty) = 7 fields (NUM_FIRST_BLOCK_END_BLOB_FIELDS) - * every other (needs >= 1 tx) = 6 + 4 = 10 fields + * per-block minimal blob footprint (every block carries a per-block l1-to-l2 root): + * first block (may be empty) = 7 fields (NUM_BLOCK_END_BLOB_FIELDS) + * every other (needs >= 1 tx) = 7 + 4 = 11 fields * (NUM_BLOCK_END_BLOB_FIELDS + a 4-field minimal tx: * tx start marker + tx hash + fee + 1 mandatory nullifier) * + 1 checkpoint-end marker (NUM_CHECKPOINT_END_MARKER_FIELDS) * - * max N: 7 + 10*(N - 1) + 1 <= 24,576 => 10*(N - 1) <= 24,568 => N <= 2,457 + * max N: 7 + 11*(N - 1) + 1 <= 24,576 => 11*(N - 1) <= 24,568 => N <= 2,234 * * Only the first block may be empty; every other block needs >= 1 tx (the circuits have no empty-tx - * variant for non-first blocks), so 2457 is the largest provable checkpoint. The blob format can encode - * more blocks than this (up to ~4095 with all-empty blocks), but such a checkpoint is unprovable and + * variant for non-first blocks), so 2234 is the largest provable checkpoint. The blob format can encode + * more blocks than this (up to ~3510 with all-empty blocks), but such a checkpoint is unprovable and * can only reach L1 with a malicious committee supermajority — a terminal network compromise where a * wedged archiver is an acceptable outcome. We therefore bound ingest to the provable maximum. * Invariant checked by the unit test in deserialization.test.ts. */ -export const MAX_CAPACITY_BLOCKS_PER_CHECKPOINT = 2457; +export const MAX_CAPACITY_BLOCKS_PER_CHECKPOINT = 2234; /** * Max blocks per checkpoint we are willing to build or attest to (conservative client policy, and the diff --git a/yarn-project/stdlib/src/gas/tx_gas_limits.test.ts b/yarn-project/stdlib/src/gas/tx_gas_limits.test.ts index a6621bf28fef..0624244922a6 100644 --- a/yarn-project/stdlib/src/gas/tx_gas_limits.test.ts +++ b/yarn-project/stdlib/src/gas/tx_gas_limits.test.ts @@ -37,8 +37,7 @@ describe('computeNetworkTxGasLimits', () => { DA_GAS_PER_FIELD, ); const firstBlockBlobFieldCap = Math.ceil( - ((BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS - getNumBlockEndBlobFields(true)) / - b) * + ((BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS - getNumBlockEndBlobFields()) / b) * MIN_PER_BLOCK_DA_ALLOCATION_MULTIPLIER, ); expect(admittedBlobFields).toBeLessThanOrEqual(firstBlockBlobFieldCap); diff --git a/yarn-project/stdlib/src/gas/tx_gas_limits.ts b/yarn-project/stdlib/src/gas/tx_gas_limits.ts index 17c00bfb8548..e73d8ed79c4c 100644 --- a/yarn-project/stdlib/src/gas/tx_gas_limits.ts +++ b/yarn-project/stdlib/src/gas/tx_gas_limits.ts @@ -1,8 +1,4 @@ -import { - NUM_BLOCK_END_BLOB_FIELDS, - NUM_CHECKPOINT_END_MARKER_FIELDS, - NUM_FIRST_BLOCK_END_BLOB_FIELDS, -} from '@aztec/blob-lib/encoding'; +import { NUM_BLOCK_END_BLOB_FIELDS, NUM_CHECKPOINT_END_MARKER_FIELDS } from '@aztec/blob-lib/encoding'; import { BLOBS_PER_CHECKPOINT, DA_GAS_PER_FIELD, @@ -38,9 +34,8 @@ export const MIN_PER_BLOCK_DA_ALLOCATION_MULTIPLIER = 1.5; * raw blob capacity (`BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB * DA_GAS_PER_FIELD`) minus the fields the blob * encoding reserves for overhead that no tx pays DA gas for: * - * - one checkpoint-end marker field (`NUM_CHECKPOINT_END_MARKER_FIELDS`), - * - the first block's block-end fields (`NUM_FIRST_BLOCK_END_BLOB_FIELDS`, 7), and - * - `NUM_BLOCK_END_BLOB_FIELDS` (6) for each of the `blocks - 1` subsequent blocks. + * - one checkpoint-end marker field (`NUM_CHECKPOINT_END_MARKER_FIELDS`), and + * - `NUM_BLOCK_END_BLOB_FIELDS` (7, including the per-block l1-to-l2 root) for each of the `blocks` blocks. * * Subtracting the overhead for every block (not just the first) keeps the network DA admission limit at or * below the builder's first-block blob-field cap at every geometry. The builder is the MOST generous for the @@ -57,10 +52,7 @@ export function getDaCheckpointBudgetForTxs(maxBlocksPerCheckpoint: number): num // raw blob capacity, which would otherwise yield a negative advertised DA budget. const fields = Math.max( 0, - BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - - NUM_CHECKPOINT_END_MARKER_FIELDS - - NUM_FIRST_BLOCK_END_BLOB_FIELDS - - (blocks - 1) * NUM_BLOCK_END_BLOB_FIELDS, + BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS - blocks * NUM_BLOCK_END_BLOB_FIELDS, ); return fields * DA_GAS_PER_FIELD; } diff --git a/yarn-project/stdlib/src/interfaces/archiver.test.ts b/yarn-project/stdlib/src/interfaces/archiver.test.ts index 5ace4e328afe..06ef09d352e3 100644 --- a/yarn-project/stdlib/src/interfaces/archiver.test.ts +++ b/yarn-project/stdlib/src/interfaces/archiver.test.ts @@ -36,6 +36,7 @@ import { type LogResult, randomLogResult } from '../logs/log_result.js'; import type { PrivateLogsQuery, PublicLogsQuery } from '../logs/logs_query.js'; import { SiloedTag } from '../logs/siloed_tag.js'; import { Tag } from '../logs/tag.js'; +import type { InboxBucket } from '../messaging/inbox_bucket.js'; import { CheckpointHeader } from '../rollup/checkpoint_header.js'; import { getTokenContractArtifact } from '../tests/fixtures.js'; import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js'; @@ -203,16 +204,36 @@ describe('ArchiverApiSchema', () => { expect(result).toEqual([expect.any(Fr)]); }); - it('getL1ToL2Messages', async () => { - const result = await context.client.getL1ToL2Messages(CheckpointNumber(1)); - expect(result).toEqual([expect.any(Fr)]); - }); - it('getL1ToL2MessageIndex', async () => { const result = await context.client.getL1ToL2MessageIndex(Fr.random()); expect(result).toBe(1n); }); + it('getLatestInboxBucketAtOrBefore', async () => { + const result = await context.client.getLatestInboxBucketAtOrBefore(123n); + expect(result).toMatchObject({ seq: 1n, msgCount: 3, totalMsgCount: 3n }); + }); + + it('getInboxBucket', async () => { + const result = await context.client.getInboxBucket(2n); + expect(result).toMatchObject({ seq: 2n, msgCount: 3 }); + }); + + it('getInboxBucketByTotalMsgCount', async () => { + const result = await context.client.getInboxBucketByTotalMsgCount(3n); + expect(result).toMatchObject({ seq: 2n, totalMsgCount: 3n, msgCount: 3 }); + }); + + it('getL1ToL2MessagesBetweenBuckets', async () => { + const result = await context.client.getL1ToL2MessagesBetweenBuckets(0n, 3n); + expect(result).toEqual([expect.any(Fr)]); + }); + + it('getL1ToL2MessagesBetweenLeafCounts', async () => { + const result = await context.client.getL1ToL2MessagesBetweenLeafCounts(0n, 3n); + expect(result).toEqual([expect.any(Fr)]); + }); + it('registerContractFunctionSignatures', async () => { await context.client.registerContractFunctionSignatures(['test()']); }); @@ -258,6 +279,7 @@ describe('ArchiverApiSchema', () => { startBlock: 1, totalManaUsed: 1n, feeAssetPriceModifier: 1n, + inboxMsgTotal: 1n, }); }); @@ -379,6 +401,7 @@ class MockArchiver implements ArchiverApi { startBlock: BlockNumber(1), totalManaUsed: 1n, feeAssetPriceModifier: 1n, + inboxMsgTotal: 1n, }); } syncImmediate() { @@ -543,14 +566,53 @@ class MockArchiver implements ArchiverApi { expect(Array.isArray(signatures)).toBe(true); return Promise.resolve(); } - getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise { - expect(checkpointNumber).toEqual(CheckpointNumber(1)); - return Promise.resolve([Fr.random()]); - } getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise { expect(l1ToL2Message).toBeInstanceOf(Fr); return Promise.resolve(1n); } + getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise { + expect(typeof timestamp).toEqual('bigint'); + return Promise.resolve({ + seq: 1n, + inboxRollingHash: Fr.random(), + totalMsgCount: 3n, + timestamp: 100n, + msgCount: 3, + lastMessageIndex: 2n, + }); + } + getInboxBucket(seq: bigint): Promise { + expect(typeof seq).toEqual('bigint'); + return Promise.resolve({ + seq, + inboxRollingHash: Fr.random(), + totalMsgCount: 3n, + timestamp: 100n, + msgCount: 3, + lastMessageIndex: 2n, + }); + } + getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + expect(typeof totalMsgCount).toEqual('bigint'); + return Promise.resolve({ + seq: 2n, + inboxRollingHash: Fr.random(), + totalMsgCount, + timestamp: 100n, + msgCount: 3, + lastMessageIndex: 2n, + }); + } + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + expect(typeof fromExclusive).toEqual('bigint'); + expect(typeof toInclusive).toEqual('bigint'); + return Promise.resolve([Fr.random()]); + } + getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise { + expect(typeof startLeafCount).toEqual('bigint'); + expect(typeof endLeafCount).toEqual('bigint'); + return Promise.resolve([Fr.random()]); + } getL1Constants(): Promise { return Promise.resolve(EmptyL1RollupConstants); } diff --git a/yarn-project/stdlib/src/interfaces/archiver.ts b/yarn-project/stdlib/src/interfaces/archiver.ts index 362da31e3a88..a1a55af686fb 100644 --- a/yarn-project/stdlib/src/interfaces/archiver.ts +++ b/yarn-project/stdlib/src/interfaces/archiver.ts @@ -25,6 +25,7 @@ import { import { L1RollupConstantsSchema } from '../epoch-helpers/index.js'; import { LogResultSchema } from '../logs/log_result.js'; import { PrivateLogsQuerySchema, PublicLogsQuerySchema } from '../logs/logs_query.js'; +import { InboxBucketSchema } from '../messaging/inbox_bucket.js'; import type { L1ToL2MessageSource } from '../messaging/l1_to_l2_message_source.js'; import { L2ToL1MembershipWitnessSchema } from '../messaging/l2_to_l1_membership.js'; import { optional, schemas } from '../schemas/schemas.js'; @@ -135,8 +136,24 @@ export const ArchiverApiSchema: ApiSchemaFor = { }), getContractClassIds: z.function({ input: z.tuple([]), output: z.array(schemas.Fr) }), registerContractFunctionSignatures: z.function({ input: z.tuple([z.array(z.string())]), output: z.void() }), - getL1ToL2Messages: z.function({ input: z.tuple([CheckpointNumberSchema]), output: z.array(schemas.Fr) }), getL1ToL2MessageIndex: z.function({ input: z.tuple([schemas.Fr]), output: schemas.BigInt.optional() }), + getLatestInboxBucketAtOrBefore: z.function({ + input: z.tuple([schemas.BigInt]), + output: InboxBucketSchema.optional(), + }), + getInboxBucket: z.function({ input: z.tuple([schemas.BigInt]), output: InboxBucketSchema.optional() }), + getInboxBucketByTotalMsgCount: z.function({ + input: z.tuple([schemas.BigInt]), + output: InboxBucketSchema.optional(), + }), + getL1ToL2MessagesBetweenBuckets: z.function({ + input: z.tuple([schemas.BigInt, schemas.BigInt]), + output: z.array(schemas.Fr), + }), + getL1ToL2MessagesBetweenLeafCounts: z.function({ + input: z.tuple([schemas.BigInt, schemas.BigInt]), + output: z.array(schemas.Fr), + }), getDebugFunctionName: z.function({ input: z.tuple([schemas.AztecAddress, schemas.FunctionSelector]), output: optional(z.string()), diff --git a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts index 0a177636020f..934ea3d0cde4 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node.test.ts @@ -154,9 +154,9 @@ describe('AztecNodeApiSchema', () => { expect(response).toEqual([1n, expect.any(SiblingPath)]); }); - it('getL1ToL2MessageCheckpoint', async () => { - const response = await context.client.getL1ToL2MessageCheckpoint(Fr.random()); - expect(response).toEqual(5); + it('getL1ToL2MessageIndex', async () => { + const response = await context.client.getL1ToL2MessageIndex(Fr.random()); + expect(response).toEqual(5n); }); it('getL2ToL1Messages', async () => { @@ -710,9 +710,9 @@ class MockAztecNode implements AztecNode { expect(noteHash).toBeInstanceOf(Fr); return Promise.resolve(MembershipWitness.random(NOTE_HASH_TREE_HEIGHT)); } - getL1ToL2MessageCheckpoint(l1ToL2Message: Fr): Promise { + getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise { expect(l1ToL2Message).toBeInstanceOf(Fr); - return Promise.resolve(CheckpointNumber(5)); + return Promise.resolve(5n); } getL2ToL1Messages(_epoch: EpochNumber): Promise { return Promise.resolve( diff --git a/yarn-project/stdlib/src/interfaces/aztec-node.ts b/yarn-project/stdlib/src/interfaces/aztec-node.ts index 644ba4de71ea..6e5881f50ec7 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node.ts @@ -200,8 +200,12 @@ export interface AztecNode { l1ToL2Message: Fr, ): Promise<[bigint, SiblingPath] | undefined>; - /** Returns the L2 checkpoint number in which this L1 to L2 message becomes available, or undefined if not found. */ - getL1ToL2MessageCheckpoint(l1ToL2Message: Fr): Promise; + /** + * Returns the compact leaf index assigned to this L1 to L2 message as soon as the node has ingested it from L1, + * before any L2 block consumes it. Returns undefined if the node has not yet seen the message. The message becomes + * consumable once a block's L1-to-L2 message tree grows past this index. + */ + getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise; /** * Returns all the L2 to L1 messages in an epoch. @@ -609,7 +613,7 @@ export const AztecNodeApiSchema: ApiSchemaFor = { output: z.tuple([schemas.BigInt, SiblingPath.schemaFor(L1_TO_L2_MSG_TREE_HEIGHT)]).optional(), }), - getL1ToL2MessageCheckpoint: z.function({ input: z.tuple([schemas.Fr]), output: CheckpointNumberSchema.optional() }), + getL1ToL2MessageIndex: z.function({ input: z.tuple([schemas.Fr]), output: schemas.BigInt.optional() }), getL2ToL1Messages: z.function({ input: z.tuple([EpochNumberSchema]), diff --git a/yarn-project/stdlib/src/interfaces/block-builder.ts b/yarn-project/stdlib/src/interfaces/block-builder.ts index 7c39955d78dd..6d10698dab4d 100644 --- a/yarn-project/stdlib/src/interfaces/block-builder.ts +++ b/yarn-project/stdlib/src/interfaces/block-builder.ts @@ -56,6 +56,11 @@ export type PublicProcessorLimits = { type BlockBuilderOptionsBase = PublicProcessorLimits & { /** Minimum number of successfully processed txs required. Block is rejected if fewer succeed. */ minValidTxs: number; + /** + * L1-to-L2 message leaves this block consumes, inserted into the fork's L1-to-L2 message tree before the block + * header is built. Omitted when the block consumes nothing from the Inbox. + */ + l1ToL2Messages?: Fr[]; }; /** Proposer mode: redistribution params are required. */ @@ -150,12 +155,16 @@ export interface ICheckpointsBuilder { */ getFork(blockNumber: BlockNumber, blockHash?: BlockHash): Promise; + /** + * Opens a fresh checkpoint. The checkpoint's L1-to-L2 messages are not passed here: each block carries its own + * bundle in `buildBlock`'s `l1ToL2Messages`. + */ startCheckpoint( checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, - l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, fork: MerkleTreeWriteOperations, bindings?: LoggerBindings, ): Promise; diff --git a/yarn-project/stdlib/src/interfaces/proving-job-source.test.ts b/yarn-project/stdlib/src/interfaces/proving-job-source.test.ts index f37a4832f708..9dcf9d2ec8aa 100644 --- a/yarn-project/stdlib/src/interfaces/proving-job-source.test.ts +++ b/yarn-project/stdlib/src/interfaces/proving-job-source.test.ts @@ -1,16 +1,19 @@ import { NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH } from '@aztec/constants'; import { EpochNumber } from '@aztec/foundation/branded-types'; +import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc'; import { type JsonRpcTestContext, createJsonRpcTestSetup } from '@aztec/foundation/json-rpc/test'; import { ProvingRequestType } from '../proofs/proving_request_type.js'; import { makeRecursiveProof } from '../proofs/recursive_proof.js'; +import { BlockRollupPublicInputs } from '../rollup/block_rollup_public_inputs.js'; import { TxRollupPublicInputs } from '../rollup/tx_rollup_public_inputs.js'; +import { makeBlockRollupPublicInputs } from '../tests/factories.js'; import { VerificationKeyData } from '../vks/verification_key.js'; import { type ProvingJobSource, ProvingJobSourceSchema } from './proving-job-source.js'; import { type ProofUri, type ProvingJob, - type ProvingJobResult, + ProvingJobResult, type ProvingRequestResultFor, makePublicInputsAndRecursiveProof, } from './proving-job.js'; @@ -63,6 +66,28 @@ describe('ProvingJobSourceSchema', () => { }); }); +describe('ProvingJobResult', () => { + it('round-trips a message-only block-root rollup result through the schema', () => { + // The message-only block-root proof type must survive serialization: a checkpoint that builds a message-only + // block produces this result, and the proof store decodes it via the ProvingJobResult schema. Omitting it from + // the union throws "Invalid discriminator value" and stalls proving. + const result: ProvingJobResult = { + type: ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP, + result: makePublicInputsAndRecursiveProof< + BlockRollupPublicInputs, + typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH + >( + makeBlockRollupPublicInputs(), + makeRecursiveProof(NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH), + VerificationKeyData.makeFakeRollupHonk(), + ), + }; + + const roundTripped = jsonParseWithSchema(jsonStringify(result), ProvingJobResult); + expect(roundTripped.type).toEqual(ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP); + }); +}); + class MockProvingJobSource implements ProvingJobSource { getProvingJob(): Promise { return Promise.resolve({ diff --git a/yarn-project/stdlib/src/interfaces/proving-job.ts b/yarn-project/stdlib/src/interfaces/proving-job.ts index a84e82b9af2b..b7e31df2f5b3 100644 --- a/yarn-project/stdlib/src/interfaces/proving-job.ts +++ b/yarn-project/stdlib/src/interfaces/proving-job.ts @@ -11,9 +11,8 @@ import { z } from 'zod'; import { AvmCircuitInputs } from '../avm/avm.js'; import { AvmProvingRequestSchema } from '../avm/avm_proving_request.js'; -import { ParityBasePrivateInputs } from '../parity/parity_base_private_inputs.js'; +import { InboxParityPrivateInputs } from '../parity/inbox_parity_private_inputs.js'; import { ParityPublicInputs } from '../parity/parity_public_inputs.js'; -import { ParityRootPrivateInputs } from '../parity/parity_root_private_inputs.js'; import { ProvingRequestType } from '../proofs/proving_request_type.js'; import { RecursiveProof } from '../proofs/recursive_proof.js'; import { BlockMergeRollupPrivateInputs } from '../rollup/block_merge_rollup_private_inputs.js'; @@ -21,6 +20,7 @@ import { BlockRollupPublicInputs } from '../rollup/block_rollup_public_inputs.js import { BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -81,8 +81,7 @@ export function makePublicInputsAndRecursiveProof; export type ProvingJobResultsMap = { @@ -348,6 +354,10 @@ export type ProvingJobResultsMap = { BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH >; + [ProvingRequestType.BLOCK_ROOT_MSGS_ONLY_ROLLUP]: PublicInputsAndRecursiveProof< + BlockRollupPublicInputs, + typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH + >; [ProvingRequestType.BLOCK_ROOT_ROLLUP]: PublicInputsAndRecursiveProof< BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH @@ -377,11 +387,7 @@ export type ProvingJobResultsMap = { typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH >; [ProvingRequestType.ROOT_ROLLUP]: PublicInputsAndRecursiveProof; - [ProvingRequestType.PARITY_BASE]: PublicInputsAndRecursiveProof; - [ProvingRequestType.PARITY_ROOT]: PublicInputsAndRecursiveProof< - ParityPublicInputs, - typeof NESTED_RECURSIVE_PROOF_LENGTH - >; + [ProvingRequestType.INBOX_PARITY]: PublicInputsAndRecursiveProof; }; export type ProvingRequestResultFor = { type: T; result: ProvingJobResultsMap[T] }; diff --git a/yarn-project/stdlib/src/interfaces/server_circuit_prover.ts b/yarn-project/stdlib/src/interfaces/server_circuit_prover.ts index 21f1ea48f2d5..48b4514b7f6b 100644 --- a/yarn-project/stdlib/src/interfaces/server_circuit_prover.ts +++ b/yarn-project/stdlib/src/interfaces/server_circuit_prover.ts @@ -6,15 +6,15 @@ import type { } from '@aztec/constants'; import type { AvmCircuitInputs } from '../avm/avm.js'; -import type { ParityBasePrivateInputs } from '../parity/parity_base_private_inputs.js'; +import type { InboxParityPrivateInputs } from '../parity/inbox_parity_private_inputs.js'; import type { ParityPublicInputs } from '../parity/parity_public_inputs.js'; -import type { ParityRootPrivateInputs } from '../parity/parity_root_private_inputs.js'; import type { RecursiveProof } from '../proofs/recursive_proof.js'; import type { BlockMergeRollupPrivateInputs } from '../rollup/block_merge_rollup_private_inputs.js'; import type { BlockRollupPublicInputs } from '../rollup/block_rollup_public_inputs.js'; import type { BlockRootEmptyTxFirstRollupPrivateInputs, BlockRootFirstRollupPrivateInputs, + BlockRootMsgsOnlyRollupPrivateInputs, BlockRootRollupPrivateInputs, BlockRootSingleTxFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, @@ -42,25 +42,16 @@ import type { PublicInputsAndRecursiveProof } from './proving-job.js'; */ export interface ServerCircuitProver { /** - * Creates a proof for the given input. - * @param input - Input to the circuit. + * Creates the checkpoint's single InboxParity proof. The circuit variant (ladder size) is selected from + * `inputs.size`. + * @param inputs - Input to the circuit. */ - getBaseParityProof( - inputs: ParityBasePrivateInputs, + getInboxParityProof( + inputs: InboxParityPrivateInputs, signal?: AbortSignal, epochNumber?: number, ): Promise>; - /** - * Creates a proof for the given input. - * @param input - Input to the circuit. - */ - getRootParityProof( - inputs: ParityRootPrivateInputs, - signal?: AbortSignal, - epochNumber?: number, - ): Promise>; - getPublicChonkVerifierProof( inputs: PublicChonkVerifierPrivateInputs, signal?: AbortSignal, @@ -129,6 +120,12 @@ export interface ServerCircuitProver { epochNumber?: number, ): Promise>; + getBlockRootMsgsOnlyRollupProof( + input: BlockRootMsgsOnlyRollupPrivateInputs, + signal?: AbortSignal, + epochNumber?: number, + ): Promise>; + /** * Creates a proof for the given input. * @param input - Input to the circuit. diff --git a/yarn-project/stdlib/src/interfaces/validator.ts b/yarn-project/stdlib/src/interfaces/validator.ts index f17e96e2a475..17903fdbe645 100644 --- a/yarn-project/stdlib/src/interfaces/validator.ts +++ b/yarn-project/stdlib/src/interfaces/validator.ts @@ -153,7 +153,6 @@ export interface Validator { blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, indexWithinCheckpoint: number, - inHash: Fr, archive: Fr, txs: Tx[], proposerAddress: EthAddress | undefined, diff --git a/yarn-project/stdlib/src/messaging/append_l1_to_l2_messages.ts b/yarn-project/stdlib/src/messaging/append_l1_to_l2_messages.ts index 31f53fd47c03..fd42d32097cd 100644 --- a/yarn-project/stdlib/src/messaging/append_l1_to_l2_messages.ts +++ b/yarn-project/stdlib/src/messaging/append_l1_to_l2_messages.ts @@ -1,21 +1,13 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; -import { padArrayEnd } from '@aztec/foundation/collection'; -import { Fr } from '@aztec/foundation/curves/bn254'; +import type { Fr } from '@aztec/foundation/curves/bn254'; import type { MerkleTreeWriteOperations } from '../interfaces/merkle_tree_operations.js'; import { MerkleTreeId } from '../trees/merkle_tree_id.js'; /** - * Pads `l1ToL2Messages` to `NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP` and appends them to the - * L1→L2 message tree of `db`. Use whenever a fork at "state before the first block of a - * checkpoint" needs to mirror what the world-state synchronizer inserts at sync time. + * Appends a block's real L1→L2 message leaves (unpadded, at compact indices) to the L1→L2 message tree of `db`. + * Use whenever a fork at "state before a block" needs to mirror what the world-state + * synchronizer inserts at sync time. */ export async function appendL1ToL2MessagesToTree(db: MerkleTreeWriteOperations, l1ToL2Messages: Fr[]): Promise { - const padded = padArrayEnd( - l1ToL2Messages, - Fr.ZERO, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - 'Too many L1 to L2 messages', - ); - await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, padded); + await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); } diff --git a/yarn-project/stdlib/src/messaging/in_hash.ts b/yarn-project/stdlib/src/messaging/in_hash.ts deleted file mode 100644 index 52833bf937fe..000000000000 --- a/yarn-project/stdlib/src/messaging/in_hash.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; -import { padArrayEnd } from '@aztec/foundation/collection'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { computeBalancedShaRoot } from '@aztec/foundation/trees'; - -/** - * Computes the inHash for a checkpoint (or the first block in a checkpoint) given its l1 to l2 messages. - */ -export function computeInHashFromL1ToL2Messages(unpaddedL1ToL2Messages: Fr[]): Fr { - const l1ToL2Messages = padArrayEnd(unpaddedL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); - return new Fr(computeBalancedShaRoot(l1ToL2Messages.map(msg => msg.toBuffer()))); -} diff --git a/yarn-project/stdlib/src/messaging/inbox_bucket.test.ts b/yarn-project/stdlib/src/messaging/inbox_bucket.test.ts new file mode 100644 index 000000000000..4211aebbf9b7 --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_bucket.test.ts @@ -0,0 +1,49 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; +import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc'; + +import type { InboxBucket } from './inbox_bucket.js'; +import { InboxBucketRef } from './inbox_bucket.js'; + +describe('InboxBucketRef', () => { + it('serializes and deserializes round-trip', () => { + const ref = new InboxBucketRef(42n, 1_700_000_000n, Fr.random()); + const deserialized = InboxBucketRef.fromBuffer(ref.toBuffer()); + expect(deserialized).toEqual(ref); + expect(deserialized.equals(ref)).toBe(true); + }); + + it('serializes to the fixed advertised size', () => { + const ref = InboxBucketRef.random(); + expect(ref.toBuffer().length).toBe(InboxBucketRef.SIZE); + expect(ref.getSize()).toBe(InboxBucketRef.SIZE); + }); + + it('equals distinguishes each component', () => { + const ref = new InboxBucketRef(7n, 100n, new Fr(9n)); + expect(ref.equals(new InboxBucketRef(8n, 100n, new Fr(9n)))).toBe(false); + expect(ref.equals(new InboxBucketRef(7n, 101n, new Fr(9n)))).toBe(false); + expect(ref.equals(new InboxBucketRef(7n, 100n, new Fr(10n)))).toBe(false); + expect(ref.equals(new InboxBucketRef(7n, 100n, new Fr(9n)))).toBe(true); + }); + + it('derives from a bucket snapshot', () => { + const bucket: InboxBucket = { + seq: 12n, + inboxRollingHash: new Fr(0xabcn), + totalMsgCount: 30n, + timestamp: 1_650_000_000n, + msgCount: 3, + lastMessageIndex: 29n, + }; + const ref = InboxBucketRef.fromBucket(bucket); + expect(ref.bucketSeq).toBe(bucket.seq); + expect(ref.bucketTimestamp).toBe(bucket.timestamp); + expect(ref.inboxRollingHash).toEqual(bucket.inboxRollingHash); + }); + + it('round-trips through its zod schema', () => { + const ref = InboxBucketRef.random(); + const parsed = jsonParseWithSchema(jsonStringify(ref), InboxBucketRef.schema); + expect(parsed).toEqual(ref); + }); +}); diff --git a/yarn-project/stdlib/src/messaging/inbox_bucket.ts b/yarn-project/stdlib/src/messaging/inbox_bucket.ts new file mode 100644 index 000000000000..e7700882c587 --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_bucket.ts @@ -0,0 +1,125 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; +import { type ZodFor, schemas } from '@aztec/foundation/schemas'; +import { BufferReader, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize'; +import type { FieldsOf } from '@aztec/foundation/types'; + +import { z } from 'zod'; + +/** + * Snapshot of an Inbox rolling-hash bucket as tracked by the archiver. + * + * A bucket accumulates the message leaves inserted into the Inbox within a single L1 block (up to a per-bucket + * maximum, after which further messages in the same block spill into the next bucket). Buckets are identified by + * a dense, monotonically increasing sequence number and keyed for recency lookups by the L1 block timestamp at + * which they were opened. Mirrors the on-chain `InboxBucket` struct plus the fields the archiver derives while + * syncing. + */ +export type InboxBucket = { + /** Dense, monotonically increasing sequence number of this bucket in the Inbox ring. */ + seq: bigint; + /** Consensus rolling hash (truncated sha256 chain) after the last message absorbed into this bucket. */ + inboxRollingHash: Fr; + /** Cumulative number of messages inserted into the Inbox up to and including this bucket. */ + totalMsgCount: bigint; + /** L1 block timestamp at which this bucket was opened; the recency key for lag/cutoff comparisons, in seconds. */ + timestamp: bigint; + /** Number of messages absorbed into this bucket. */ + msgCount: number; + /** Global leaf index of the last message absorbed into this bucket. */ + lastMessageIndex: bigint; +}; + +export const InboxBucketSchema = z.object({ + seq: schemas.BigInt, + inboxRollingHash: Fr.schema, + totalMsgCount: schemas.BigInt, + timestamp: schemas.BigInt, + msgCount: schemas.Integer, + lastMessageIndex: schemas.BigInt, +}) satisfies z.ZodType; + +/** + * Reference to a settled Inbox rolling-hash bucket, carried alongside a block proposal so a + * validator can look the bucket up in its own Inbox view and derive the consumed-message bundle itself, rather than + * trusting a proposer-supplied message list. Pins the bucket by its dense sequence number and recency-key timestamp + * and asserts the expected consensus rolling hash. A wrong reference can only cause a lookup miss or hash mismatch; it + * can never change what a validator accepts, because the checkpoint header's `inboxRollingHash` remains the signed + * consensus commitment (mirrors the unsigned bucket hint on L1's `Rollup.propose`). + */ +export class InboxBucketRef { + constructor( + /** Dense, monotonically increasing sequence number of the referenced bucket in the Inbox ring. */ + public readonly bucketSeq: bigint, + /** L1 block timestamp (in seconds) at which the referenced bucket was opened; its recency key. */ + public readonly bucketTimestamp: bigint, + /** Consensus rolling hash (truncated sha256 chain) after the last message absorbed into the referenced bucket. */ + public readonly inboxRollingHash: Fr, + ) {} + + /** Serialized size in bytes: two uint64 fields plus one field element. */ + static readonly SIZE = 8 + 8 + Fr.SIZE_IN_BYTES; + + static get schema(): ZodFor { + return z + .object({ + bucketSeq: schemas.BigInt, + bucketTimestamp: schemas.BigInt, + inboxRollingHash: Fr.schema, + }) + .transform(InboxBucketRef.from); + } + + static from(fields: FieldsOf): InboxBucketRef { + return new InboxBucketRef(fields.bucketSeq, fields.bucketTimestamp, fields.inboxRollingHash); + } + + /** Derives a wire reference from a bucket snapshot as tracked by the archiver. */ + static fromBucket(bucket: InboxBucket): InboxBucketRef { + return new InboxBucketRef(bucket.seq, bucket.timestamp, bucket.inboxRollingHash); + } + + toBuffer(): Buffer { + return serializeToBuffer([ + bigintToUInt64BE(this.bucketSeq), + bigintToUInt64BE(this.bucketTimestamp), + this.inboxRollingHash, + ]); + } + + static fromBuffer(buffer: Buffer | BufferReader): InboxBucketRef { + const reader = BufferReader.asReader(buffer); + return new InboxBucketRef(reader.readUInt64(), reader.readUInt64(), reader.readObject(Fr)); + } + + getSize(): number { + return InboxBucketRef.SIZE; + } + + equals(other: InboxBucketRef): boolean { + return ( + this.bucketSeq === other.bucketSeq && + this.bucketTimestamp === other.bucketTimestamp && + this.inboxRollingHash.equals(other.inboxRollingHash) + ); + } + + static empty(): InboxBucketRef { + return new InboxBucketRef(0n, 0n, Fr.ZERO); + } + + static random(): InboxBucketRef { + return new InboxBucketRef( + BigInt(Math.floor(Math.random() * 1000)), + BigInt(Math.floor(Math.random() * 1_000_000)), + Fr.random(), + ); + } + + toInspect() { + return { + bucketSeq: this.bucketSeq.toString(), + bucketTimestamp: this.bucketTimestamp.toString(), + inboxRollingHash: this.inboxRollingHash.toString(), + }; + } +} diff --git a/yarn-project/stdlib/src/messaging/inbox_consumption.test.ts b/yarn-project/stdlib/src/messaging/inbox_consumption.test.ts new file mode 100644 index 000000000000..36d1f7653b0f --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_consumption.test.ts @@ -0,0 +1,95 @@ +import { SlotNumber } from '@aztec/foundation/branded-types'; + +import { describe, expect, it } from '@jest/globals'; + +import type { L1RollupConstants } from '../epoch-helpers/index.js'; +import { getInboxCutoffTimestamp, isInboxConsumptionSufficient } from './inbox_consumption.js'; + +// Cross-layer test vectors shared with the `ProposeInboxConsumptionTest` Foundry harness. +// The same vectors are asserted against `ProposeLib.validateInboxConsumption` on L1; keeping them identical here makes +// L1, TS, and the design doc agree on the cutoff formula and the mandatory-consumption boundary. +const GENESIS_TIME = 100_000n; +const SLOT_DURATION = 36; +const LAG_SECONDS = 12; + +const l1Constants = { l1GenesisTime: GENESIS_TIME, slotDuration: SLOT_DURATION } as Pick< + L1RollupConstants, + 'l1GenesisTime' | 'slotDuration' +>; + +describe('inbox_consumption', () => { + describe('getInboxCutoffTimestamp', () => { + // buildFrameStart(S) = 100000 + (S - 1) * 36; cutoff(S) = buildFrameStart(S) - 12. + it.each([ + [1, 99_988n], + [2, 100_024n], + [10, 100_312n], + [11, 100_348n], + ])('matches the A-1371 §13 cutoff table for slot %i', (slot, expectedCutoff) => { + expect(getInboxCutoffTimestamp(SlotNumber(slot), l1Constants, LAG_SECONDS)).toBe(expectedCutoff); + }); + }); + + describe('isInboxConsumptionSufficient', () => { + const base = { cutoffTimestamp: 100_312n, checkpointStartTotalMsgCount: 0n, perCheckpointCap: 1024 }; + + it('is sufficient when there is no next bucket (consumed everything)', () => { + expect(isInboxConsumptionSufficient({ ...base, nextBucket: undefined })).toBe(true); + }); + + // Boundary at S=10 (cutoff = 100312): a bucket opened exactly at the cutoff is mandatory (strict `>`). + it('is insufficient when the next bucket opened exactly at the cutoff is left unconsumed', () => { + expect(isInboxConsumptionSufficient({ ...base, nextBucket: { timestamp: 100_312n, totalMsgCount: 5n } })).toBe( + false, + ); + }); + + // Boundary at S=10: a bucket opened at cutoff + 1 is past the cutoff and need not be consumed. + it('is sufficient when the next bucket opened at cutoff + 1 is left unconsumed', () => { + expect(isInboxConsumptionSufficient({ ...base, nextBucket: { timestamp: 100_313n, totalMsgCount: 5n } })).toBe( + true, + ); + }); + + it('is sufficient via cap-escape when consuming through the next bucket would exceed the per-checkpoint cap', () => { + // Next bucket is at/before the cutoff (would otherwise be mandatory), but consuming through it consumes + // 1025 > 1024 messages, so leaving it unconsumed is allowed (the cap-escape branch). + expect( + isInboxConsumptionSufficient({ + ...base, + nextBucket: { timestamp: 100_000n, totalMsgCount: 1025n }, + }), + ).toBe(true); + }); + + it('is insufficient when consuming through the next bucket exactly reaches the per-checkpoint cap', () => { + // Delta of exactly 1024 does not escape (strict `>` on the cap), so a mandatory bucket must still be consumed. + expect( + isInboxConsumptionSufficient({ + ...base, + nextBucket: { timestamp: 100_000n, totalMsgCount: 1024n }, + }), + ).toBe(false); + }); + + it('measures the cap-escape delta from the checkpoint start, not from zero', () => { + // With a non-zero checkpoint start, only the delta consumed this checkpoint counts against the cap. + expect( + isInboxConsumptionSufficient({ + cutoffTimestamp: 100_312n, + checkpointStartTotalMsgCount: 500n, + perCheckpointCap: 1024, + nextBucket: { timestamp: 100_000n, totalMsgCount: 1524n }, + }), + ).toBe(false); // delta = 1024, not an escape + expect( + isInboxConsumptionSufficient({ + cutoffTimestamp: 100_312n, + checkpointStartTotalMsgCount: 500n, + perCheckpointCap: 1024, + nextBucket: { timestamp: 100_000n, totalMsgCount: 1525n }, + }), + ).toBe(true); // delta = 1025, escapes + }); + }); +}); diff --git a/yarn-project/stdlib/src/messaging/inbox_consumption.ts b/yarn-project/stdlib/src/messaging/inbox_consumption.ts new file mode 100644 index 000000000000..d2649dba8579 --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_consumption.ts @@ -0,0 +1,53 @@ +import { SlotNumber } from '@aztec/foundation/branded-types'; + +import { type L1RollupConstants, getTimestampForSlot } from '../epoch-helpers/index.js'; +import type { InboxBucket } from './inbox_bucket.js'; + +/** + * Censorship cutoff timestamp for a checkpoint proposed in `slot`, mirroring the cutoff in + * `ProposeLib.validateInboxConsumption`. A checkpoint proposed in slot `S` is built during slot `S - 1`, so + * `buildFrameStart(S) = toTimestamp(S - 1)` and `cutoff(S) = buildFrameStart(S) - lagSeconds`. Buckets opened at or + * before the cutoff are mandatory to consume by the checkpoint's last block; the strict `>` on the L1 "past cutoff" + * test (see {@link isInboxConsumptionSufficient}) makes a bucket opened exactly at the cutoff mandatory. + * + * This is the single source of truth for the cutoff formula shared by the sequencer's streaming bucket selection and + * the validator's last-block censorship check. + */ +export function getInboxCutoffTimestamp( + slot: SlotNumber, + l1Constants: Pick, + lagSeconds: number, +): bigint { + return getTimestampForSlot(SlotNumber(slot - 1), l1Constants) - BigInt(lagSeconds); +} + +/** + * Whether a checkpoint whose last-consumed bucket is immediately followed by `nextBucket` meets the censorship floor, + * mirroring the mandatory-consumption assert in `ProposeLib.validateInboxConsumption`. + * Consumption is sufficient when the first unconsumed bucket: + * - does not exist (the checkpoint consumed everything the Inbox has), or + * - was opened strictly after the cutoff (`timestamp > cutoffTimestamp`), or + * - consuming through it would exceed the per-checkpoint cap (the cap-escape). + * + * The strict `>` matches L1: a bucket opened exactly at the cutoff must be consumed. This is the single source of + * truth for the minimum-consumption / cap-escape rule shared by the sequencer's selection floor and the validator. + */ +export function isInboxConsumptionSufficient(input: { + /** The first unconsumed bucket (the one after the checkpoint's last-consumed bucket), or undefined if none exists. */ + nextBucket: Pick | undefined; + /** Censorship cutoff timestamp from {@link getInboxCutoffTimestamp}. */ + cutoffTimestamp: bigint; + /** Cumulative Inbox message count consumed as of the parent checkpoint; the per-checkpoint cap origin. */ + checkpointStartTotalMsgCount: bigint; + /** Maximum number of messages the checkpoint may consume in total (`MAX_L1_TO_L2_MSGS_PER_CHECKPOINT`). */ + perCheckpointCap: number; +}): boolean { + const { nextBucket, cutoffTimestamp, checkpointStartTotalMsgCount, perCheckpointCap } = input; + if (nextBucket === undefined) { + return true; + } + if (nextBucket.timestamp > cutoffTimestamp) { + return true; + } + return nextBucket.totalMsgCount - checkpointStartTotalMsgCount > BigInt(perCheckpointCap); +} diff --git a/yarn-project/stdlib/src/messaging/inbox_leaf.ts b/yarn-project/stdlib/src/messaging/inbox_leaf.ts deleted file mode 100644 index 21d703d06150..000000000000 --- a/yarn-project/stdlib/src/messaging/inbox_leaf.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { INITIAL_CHECKPOINT_NUMBER, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; -import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; -import { CheckpointNumber } from '@aztec/foundation/branded-types'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; - -export class InboxLeaf { - constructor( - /** Index of the leaf in the whole tree. */ - public readonly index: bigint, - /** Leaf in the subtree/message hash. */ - public readonly leaf: Fr, - ) {} - - toBuffer(): Buffer { - return serializeToBuffer([this.index, this.leaf]); - } - - fromBuffer(buffer: Buffer | BufferReader): InboxLeaf { - const reader = BufferReader.asReader(buffer); - const index = toBigIntBE(reader.readBytes(32)); - const leaf = reader.readObject(Fr); - return new InboxLeaf(index, leaf); - } - - static smallestIndexForCheckpoint(checkpointNumber: CheckpointNumber): bigint { - return BigInt(checkpointNumber - INITIAL_CHECKPOINT_NUMBER) * BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); - } - - /** - * Returns the range of valid indices for a given checkpoint. - * Start index is inclusive, end index is exclusive. - */ - static indexRangeForCheckpoint(checkpointNumber: CheckpointNumber): [bigint, bigint] { - const start = this.smallestIndexForCheckpoint(checkpointNumber); - const end = start + BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); - return [start, end]; - } - - /** Returns the checkpoint number for a given leaf index */ - static checkpointNumberFromIndex(index: bigint): CheckpointNumber { - return CheckpointNumber(Number(index / BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)) + INITIAL_CHECKPOINT_NUMBER); - } -} diff --git a/yarn-project/stdlib/src/messaging/inbox_rolling_hash.test.ts b/yarn-project/stdlib/src/messaging/inbox_rolling_hash.test.ts new file mode 100644 index 000000000000..aeba869aaaed --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_rolling_hash.test.ts @@ -0,0 +1,48 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; + +import { accumulateInboxRollingHash, updateInboxRollingHash } from './inbox_rolling_hash.js'; + +describe('inbox rolling hash', () => { + // Shared test vectors pinned against the noir `accumulate_inbox_rolling_hash` helper (FI-02). Any divergence here + // means the L1 / noir / TS rolling hashes would disagree. + const range = (from: number, to: number) => Array.from({ length: to - from + 1 }, (_, i) => new Fr(from + i)); + + it('chains a single leaf from zero', () => { + expect(accumulateInboxRollingHash(Fr.ZERO, [new Fr(11)])).toEqual( + Fr.fromHexString('0x00815fb1e9d2076ae5761439b6144ad11da69eb6c41ab2aca39e770407ad8d12'), + ); + }); + + it('chains three leaves from zero', () => { + expect(accumulateInboxRollingHash(Fr.ZERO, [new Fr(11), new Fr(22), new Fr(33)])).toEqual( + Fr.fromHexString('0x0014cae968461979aab6d33266a2310ed234d3f6cf4472737c57551db07bd0da'), + ); + }); + + it('chains 256 leaves from zero', () => { + expect(accumulateInboxRollingHash(Fr.ZERO, range(1, 256))).toEqual( + Fr.fromHexString('0x00ea95b96f17b75be03525b35a2a1918b42f03ad8c00a437cf641751825f3992'), + ); + }); + + it('chains from a non-zero start', () => { + expect(accumulateInboxRollingHash(new Fr(0x2a), [new Fr(7), new Fr(8)])).toEqual( + Fr.fromHexString('0x0054d96b8a074a5030a5838972d0a3c04ba47cf5956348c853e02e9566233f65'), + ); + }); + + it('is continuous across segments', () => { + const start = new Fr(0x2a); + const mid = updateInboxRollingHash(start, new Fr(7)); + expect(mid).toEqual(Fr.fromHexString('0x0032a934005556d1b9d22708666ee8b05f91fafad624dd64a6ea878e048e5438')); + // chain(chain(0x2a, [7]), [8]) == chain(0x2a, [7, 8]) + expect(accumulateInboxRollingHash(mid, [new Fr(8)])).toEqual( + accumulateInboxRollingHash(start, [new Fr(7), new Fr(8)]), + ); + }); + + it('returns the start unchanged for an empty list', () => { + const start = new Fr(0x2a); + expect(accumulateInboxRollingHash(start, [])).toEqual(start); + }); +}); diff --git a/yarn-project/stdlib/src/messaging/inbox_rolling_hash.ts b/yarn-project/stdlib/src/messaging/inbox_rolling_hash.ts new file mode 100644 index 000000000000..6a53831ee20d --- /dev/null +++ b/yarn-project/stdlib/src/messaging/inbox_rolling_hash.ts @@ -0,0 +1,20 @@ +import { sha256ToField } from '@aztec/foundation/crypto/sha256'; +import { Fr } from '@aztec/foundation/curves/bn254'; + +/** + * Extends the Inbox rolling-hash chain by a single message leaf, returning the new rolling hash. + * + * Each link is `sha256ToField(prev || leaf)` over the two 32-byte big-endian values, matching the truncated-to-field + * sha256 the L1 Inbox accumulates, today's `inHash` frontier tree, and the noir `accumulate_inbox_rolling_hash` helper. + */ +export function updateInboxRollingHash(prev: Fr, leaf: Fr): Fr { + return sha256ToField([prev.toBuffer(), leaf.toBuffer()]); +} + +/** + * Extends the Inbox rolling-hash chain by a list of message leaves, in order, returning the new rolling hash. + * The genesis rolling hash is `Fr.ZERO`, and an empty list returns `start` unchanged. + */ +export function accumulateInboxRollingHash(start: Fr, leaves: Fr[]): Fr { + return leaves.reduce(updateInboxRollingHash, start); +} diff --git a/yarn-project/stdlib/src/messaging/index.ts b/yarn-project/stdlib/src/messaging/index.ts index 2f9889a6e955..3f8fc52654d4 100644 --- a/yarn-project/stdlib/src/messaging/index.ts +++ b/yarn-project/stdlib/src/messaging/index.ts @@ -1,6 +1,9 @@ export * from './append_l1_to_l2_messages.js'; -export * from './in_hash.js'; -export * from './inbox_leaf.js'; +export * from './inbox_bucket.js'; +export * from './inbox_consumption.js'; +export * from './inbox_rolling_hash.js'; +export * from './l1_to_l2_message_bundle.js'; +export * from './l1_to_l2_message_sponge.js'; export * from './l1_to_l2_message.js'; export * from './l1_to_l2_message_source.js'; export * from './l1_actor.js'; diff --git a/yarn-project/stdlib/src/messaging/l1_to_l2_message_bundle.ts b/yarn-project/stdlib/src/messaging/l1_to_l2_message_bundle.ts new file mode 100644 index 000000000000..6704a5d70c0f --- /dev/null +++ b/yarn-project/stdlib/src/messaging/l1_to_l2_message_bundle.ts @@ -0,0 +1,65 @@ +import { MAX_L1_TO_L2_MSGS_PER_BLOCK } from '@aztec/constants'; +import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; + +/** + * A block's L1-to-L2 message bundle: the real message leaves it inserts into the L1-to-L2 message tree and the count + * that drives both the compact (unpadded) tree append and the message-sponge absorb. See the Noir + * `L1ToL2MessageBundle`. + */ +export class L1ToL2MessageBundle { + constructor( + /** The real message leaves in the leading lanes, padded with zeros to `MAX_L1_TO_L2_MSGS_PER_BLOCK`. Kept as a + * plain array (not a tuple) to avoid TS's deep-instantiation limit on the wide type. */ + public readonly messages: Fr[], + /** Number of real messages: drives both the compact tree append and the sponge absorb. */ + public readonly numMsgs: number, + ) {} + + /** An empty bundle: no leaves inserted, nothing absorbed. */ + static empty(): L1ToL2MessageBundle { + return new L1ToL2MessageBundle( + Array.from({ length: MAX_L1_TO_L2_MSGS_PER_BLOCK }, () => Fr.ZERO), + 0, + ); + } + + toBuffer() { + return serializeToBuffer(this.messages, this.numMsgs); + } + + toString() { + return bufferToHex(this.toBuffer()); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + // Array.from (not readArray with the literal cap) keeps the type `Fr[]` and avoids TS's deep-tuple instantiation. + const messages = Array.from({ length: MAX_L1_TO_L2_MSGS_PER_BLOCK }, () => Fr.fromBuffer(reader)); + return new L1ToL2MessageBundle(messages, reader.readNumber()); + } + + static fromString(str: string) { + return L1ToL2MessageBundle.fromBuffer(hexToBuffer(str)); + } + + toJSON() { + return this.toBuffer(); + } + + static get schema() { + return bufferSchemaFor(L1ToL2MessageBundle); + } +} + +/** Wraps `messages` (the real leaves) into a bundle: the leaves fill the leading lanes, the count is the real count. */ +export function makeL1ToL2MessageBundle(messages: Fr[]): L1ToL2MessageBundle { + // Explicit `` keeps the result `Fr[]`; padding to the literal cap would otherwise infer a deep tuple. + return new L1ToL2MessageBundle( + padArrayEnd(messages, Fr.ZERO, MAX_L1_TO_L2_MSGS_PER_BLOCK), + messages.length, + ); +} diff --git a/yarn-project/stdlib/src/messaging/l1_to_l2_message_source.ts b/yarn-project/stdlib/src/messaging/l1_to_l2_message_source.ts index 04572c4eb99c..4040483f144b 100644 --- a/yarn-project/stdlib/src/messaging/l1_to_l2_message_source.ts +++ b/yarn-project/stdlib/src/messaging/l1_to_l2_message_source.ts @@ -1,21 +1,12 @@ -import type { CheckpointNumber } from '@aztec/foundation/branded-types'; import type { Fr } from '@aztec/foundation/curves/bn254'; import type { L2Tips } from '../block/l2_block_source.js'; +import type { InboxBucket } from './inbox_bucket.js'; /** * Interface of classes allowing for the retrieval of L1 to L2 messages. */ export interface L1ToL2MessageSource { - /** - * Gets new L1 to L2 message (to be) included in a given checkpoint. - * @param checkpointNumber - Checkpoint number to get messages for. - * @returns The L1 to L2 messages/leaves of the messages subtree. - * @throws If the message tree for the given checkpoint has not yet been sealed on L1 - * (i.e., checkpointNumber >= inbox treeInProgress). - */ - getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise; - /** * Gets the L1 to L2 message index in the L1 to L2 message tree. * @param l1ToL2Message - The L1 to L2 message. @@ -23,6 +14,53 @@ export interface L1ToL2MessageSource { */ getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise; + /** + * Returns the latest Inbox bucket opened at or before the given L1 timestamp, or undefined if no such bucket + * exists (i.e., every synced bucket was opened strictly after the timestamp). Used by the sequencer/validator + * to resolve the censorship cutoff and message-lag boundaries. + * @param timestamp - The L1 timestamp (in seconds) to look up at-or-before. + */ + getLatestInboxBucketAtOrBefore(timestamp: bigint): Promise; + + /** + * Returns the Inbox bucket with the given sequence number, or undefined if it has not been synced. Validators use + * this to resolve the bucket a proposal references and check its rolling hash. + * @param seq - The bucket sequence number. + */ + getInboxBucket(seq: bigint): Promise; + + /** + * Returns the Inbox bucket whose cumulative message total equals `totalMsgCount`, or undefined if no synced bucket + * sits on that boundary. A block's or checkpoint's L1-to-L2 tree leaf count equals the cumulative total of the last + * bucket it consumed (messages are indexed compactly, with no padding), so validators use this to resolve the + * bucket a block consumed through from the block's leaf count, without trusting a wire hint. `totalMsgCount === 0` + * resolves the genesis sentinel bucket (sequence 0); a total that does not land on a bucket boundary returns + * undefined. + * @param totalMsgCount - The cumulative Inbox message count (leaf count) to resolve to a bucket boundary. + */ + getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise; + + /** + * Returns the message leaves absorbed into buckets in the range `(fromExclusive, toInclusive]`, in insertion + * order, for streaming message-bundle derivation. Both bounds must name buckets the source + * has synced; it throws otherwise, so that an empty result means the range holds no messages instead of hiding an + * unsynced bound. Callers that can tolerate an unsynced source resolve both bounds first, or map the failure to + * their own catch-up handling. + * @param fromExclusive - The lower bucket sequence bound, exclusive (0 means from the start of the Inbox). + * @param toInclusive - The upper bucket sequence bound, inclusive. + */ + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise; + + /** + * Returns the message leaves in the cumulative Inbox message-count range `[startLeafCount, endLeafCount)`, in + * insertion order. The bounds are compact L1-to-L2 tree leaf counts, which every block header + * carries, so a consumer can ask for the messages a block or checkpoint consumed without resolving Inbox buckets + * itself. Both bounds must land on a bucket boundary the source has synced; it throws otherwise. + * @param startLeafCount - The cumulative Inbox message count the range starts at, inclusive. + * @param endLeafCount - The cumulative Inbox message count the range ends at, exclusive. + */ + getL1ToL2MessagesBetweenLeafCounts(startLeafCount: bigint, endLeafCount: bigint): Promise; + /** * Returns the tips of the L2 chain. */ diff --git a/yarn-project/stdlib/src/messaging/l1_to_l2_message_sponge.ts b/yarn-project/stdlib/src/messaging/l1_to_l2_message_sponge.ts new file mode 100644 index 000000000000..50d4916aecbb --- /dev/null +++ b/yarn-project/stdlib/src/messaging/l1_to_l2_message_sponge.ts @@ -0,0 +1,69 @@ +import { Poseidon2Sponge } from '@aztec/blob-lib/types'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import type { FieldsOf } from '@aztec/foundation/types'; + +/** + * An absorb-only Poseidon2 sponge over L1-to-L2 message leaves. + * + * Mirrors `L1ToL2MessageSponge` in + * `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/l1_to_l2_message_sponge.nr`. Each block of a + * checkpoint absorbs its message bundle into the sponge it inherited from the previous block; the checkpoint root + * recomputes the sponge over the checkpoint's whole message list and asserts the accumulated states are equal. + */ +export class L1ToL2MessageSponge { + constructor( + /** Sponge accumulating the absorbed message leaves. */ + public readonly sponge: Poseidon2Sponge, + /** Number of message leaves absorbed so far. */ + public numAbsorbed: number, + ) {} + + /** A fresh, empty sponge (matching noir's `L1ToL2MessageSponge::new()` / `empty()`, i.e. `Poseidon2Sponge::new(0)`). */ + static empty(): L1ToL2MessageSponge { + return new L1ToL2MessageSponge(Poseidon2Sponge.empty(), 0); + } + + /** Absorb the given message leaves in order. */ + async absorb(leaves: Fr[]) { + await this.sponge.absorb(leaves); + this.numAbsorbed += leaves.length; + } + + clone() { + return L1ToL2MessageSponge.fromBuffer(this.toBuffer()); + } + + static getFields(fields: FieldsOf) { + return [fields.sponge, fields.numAbsorbed] as const; + } + + toBuffer() { + return serializeToBuffer(...L1ToL2MessageSponge.getFields(this)); + } + + static fromBuffer(buffer: Buffer | BufferReader): L1ToL2MessageSponge { + const reader = BufferReader.asReader(buffer); + return new L1ToL2MessageSponge(reader.readObject(Poseidon2Sponge), reader.readNumber()); + } + + toFields(): Fr[] { + return serializeToFields(...L1ToL2MessageSponge.getFields(this)); + } + + static fromFields(fields: Fr[] | FieldReader): L1ToL2MessageSponge { + const reader = FieldReader.asReader(fields); + return new L1ToL2MessageSponge(reader.readObject(Poseidon2Sponge), reader.readField().toNumber()); + } +} + +/** + * Accumulates a fresh message sponge over `leaves`, in order. This is the value the inbox parity proof commits to and + * the checkpoint's block roots reach, starting from the empty sponge. Every leaf passed in is absorbed, so any padding + * the caller includes is part of the accumulated state. + */ +export async function accumulateL1ToL2MessageSponge(leaves: Fr[]): Promise { + const sponge = L1ToL2MessageSponge.empty(); + await sponge.absorb(leaves); + return sponge; +} diff --git a/yarn-project/stdlib/src/p2p/block_proposal.test.ts b/yarn-project/stdlib/src/p2p/block_proposal.test.ts index 2f6601b74506..95ff697e5f64 100644 --- a/yarn-project/stdlib/src/p2p/block_proposal.test.ts +++ b/yarn-project/stdlib/src/p2p/block_proposal.test.ts @@ -1,11 +1,33 @@ // Serde test for the block proposal type +import { IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { Fr } from '@aztec/foundation/curves/bn254'; import { Signature } from '@aztec/foundation/eth-signature'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; +import { InboxBucketRef } from '../messaging/inbox_bucket.js'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, makeBlockProposal } from '../tests/mocks.js'; +import { BlockHeader } from '../tx/block_header.js'; import { Tx } from '../tx/tx.js'; +import { TxHash } from '../tx/tx_hash.js'; import { BlockProposal } from './block_proposal.js'; +import { EMPTY_COORDINATION_SIGNATURE_CONTEXT } from './signature_utils.js'; import { SignedTxs } from './signed_txs.js'; +import { LEGACY_BLOCK_PROPOSAL_HEX, LEGACY_BLOCK_PROPOSAL_PAYLOAD_HEX } from './wire_compat_fixtures.js'; + +/** + * Deterministic legacy-shaped proposal (no signedTxs, no bucketRef) matching the golden fixtures in + * wire_compat_fixtures.ts. Constructed identically to how those bytes were captured on the pre-change code. + */ +const makeLegacyFixtureProposal = () => + new BlockProposal( + BlockHeader.empty(), + IndexWithinCheckpoint(3), + new Fr(99n), + [TxHash.fromField(new Fr(7n)), TxHash.fromField(new Fr(8n))], + Signature.empty(), + EMPTY_COORDINATION_SIGNATURE_CONTEXT, + ); describe('Block Proposal serialization / deserialization', () => { const checkEquivalence = (serialized: BlockProposal, deserialized: BlockProposal) => { @@ -82,7 +104,6 @@ describe('Block Proposal serialization / deserialization', () => { const tampered = new BlockProposal( proposal.blockHeader, proposal.indexWithinCheckpoint, - proposal.inHash, proposal.archiveRoot, proposal.txHashes, proposal.signature, @@ -92,4 +113,112 @@ describe('Block Proposal serialization / deserialization', () => { expect(tampered.getSender()).toBeUndefined(); }); + + describe('bucket reference (AZIP-22 Fast Inbox)', () => { + it('round-trips with a bucket reference set', async () => { + const bucketRef = InboxBucketRef.random(); + const proposal = await makeBlockProposal({ bucketRef }); + + const deserialized = BlockProposal.fromBuffer(proposal.toBuffer()); + + expect(deserialized.bucketRef).toBeDefined(); + expect(deserialized.bucketRef!.equals(bucketRef)).toBe(true); + expect(deserialized.getSize()).toEqual(proposal.getSize()); + expect(deserialized).toEqual(proposal); + }); + + it('round-trips with a bucket reference set alongside signed txs', async () => { + const bucketRef = InboxBucketRef.random(); + const txs = await Promise.all([Tx.random(), Tx.random()]); + const proposal = await makeBlockProposal({ txs, bucketRef }); + + const deserialized = BlockProposal.fromBuffer(proposal.toBuffer()); + + expect(deserialized.bucketRef!.equals(bucketRef)).toBe(true); + expect(deserialized.txs?.length).toEqual(txs.length); + expect(deserialized).toEqual(proposal); + }); + + it('serializes byte-identically to the legacy format when unset', () => { + const proposal = makeLegacyFixtureProposal(); + expect(proposal.bucketRef).toBeUndefined(); + expect(bufferToHex(proposal.toBuffer())).toEqual(LEGACY_BLOCK_PROPOSAL_HEX); + expect(bufferToHex(proposal.getPayloadToSign())).toEqual(LEGACY_BLOCK_PROPOSAL_PAYLOAD_HEX); + }); + + it('decodes a legacy buffer (no tail) as having no bucket reference', () => { + const deserialized = BlockProposal.fromBuffer(hexToBuffer(LEGACY_BLOCK_PROPOSAL_HEX)); + expect(deserialized.bucketRef).toBeUndefined(); + // Re-encoding a legacy buffer yields the same legacy bytes: no phantom tail is introduced. + expect(bufferToHex(deserialized.toBuffer())).toEqual(LEGACY_BLOCK_PROPOSAL_HEX); + }); + + it('appends the bucket reference only when set, changing the signed payload', async () => { + const bucketRef = InboxBucketRef.random(); + const withRef = await makeBlockProposal({ bucketRef }); + const withoutRef = await makeBlockProposal({ + blockHeader: withRef.blockHeader, + indexWithinCheckpoint: withRef.indexWithinCheckpoint, + archiveRoot: withRef.archiveRoot, + txHashes: withRef.txHashes, + }); + + const withRefPayload = withRef.getPayloadToSign(); + const withoutRefPayload = withoutRef.getPayloadToSign(); + + // The set payload extends the unset payload by exactly the reference bytes (appended tail, no marker). + expect(withRefPayload.length).toEqual(withoutRefPayload.length + InboxBucketRef.SIZE); + expect(withRefPayload.subarray(0, withoutRefPayload.length)).toEqual(withoutRefPayload); + // The payload hashes differ, so the attestation pool treats set-vs-unset as distinct payloads. + expect(withRef.getPayloadHash().toString()).not.toEqual(withoutRef.getPayloadHash().toString()); + }); + + it('covers the bucket reference under the proposal signature', async () => { + const signer = Secp256k1Signer.random(); + const bucketRef = InboxBucketRef.random(); + const proposal = await makeBlockProposal({ signer, bucketRef }); + + const deserialized = BlockProposal.fromBuffer(proposal.toBuffer()); + expect(deserialized.getSender()).toEqual(signer.address); + }); + + it('breaks sender recovery when the bucket reference is tampered with', async () => { + const signer = Secp256k1Signer.random(); + const bucketRef = new InboxBucketRef(5n, 100n, new Fr(7n)); + const proposal = await makeBlockProposal({ signer, bucketRef }); + expect(proposal.getSender()).toEqual(signer.address); + + // A relay swapping the signed reference for a different one is not covered by the original signature. + const tampered = new BlockProposal( + proposal.blockHeader, + proposal.indexWithinCheckpoint, + proposal.archiveRoot, + proposal.txHashes, + proposal.signature, + proposal.signatureContext, + proposal.signedTxs, + new InboxBucketRef(6n, 100n, new Fr(7n)), + ); + expect(tampered.getSender()).not.toEqual(signer.address); + }); + + it('breaks sender recovery when a bucket reference is injected into an unsigned proposal', async () => { + const signer = Secp256k1Signer.random(); + const proposal = await makeBlockProposal({ signer }); + expect(proposal.getSender()).toEqual(signer.address); + + // A relay injecting a reference the proposer never signed over is rejected by signature recovery. + const injected = new BlockProposal( + proposal.blockHeader, + proposal.indexWithinCheckpoint, + proposal.archiveRoot, + proposal.txHashes, + proposal.signature, + proposal.signatureContext, + proposal.signedTxs, + InboxBucketRef.random(), + ); + expect(injected.getSender()).not.toEqual(signer.address); + }); + }); }); diff --git a/yarn-project/stdlib/src/p2p/block_proposal.ts b/yarn-project/stdlib/src/p2p/block_proposal.ts index 1d29fa05ff99..8bfe553c184f 100644 --- a/yarn-project/stdlib/src/p2p/block_proposal.ts +++ b/yarn-project/stdlib/src/p2p/block_proposal.ts @@ -18,6 +18,7 @@ import type { L2Block } from '../block/l2_block.js'; import type { L2BlockInfo } from '../block/l2_block_info.js'; import { MAX_TXS_PER_BLOCK } from '../deserialization/index.js'; import { DutyType, type SigningContext } from '../ha-signing/index.js'; +import { InboxBucketRef } from '../messaging/inbox_bucket.js'; import { BlockHeader } from '../tx/block_header.js'; import { TxHash } from '../tx/index.js'; import type { Tx } from '../tx/tx.js'; @@ -70,9 +71,6 @@ export class BlockProposal extends Gossipable implements Signable { /** Index of this block within the checkpoint (0-indexed) */ public readonly indexWithinCheckpoint: IndexWithinCheckpoint, - /** Hash of L1 to L2 messages for this checkpoint (constant across all blocks in checkpoint) */ - public readonly inHash: Fr, - /** Archive root after this block is applied */ public readonly archiveRoot: Fr, @@ -87,6 +85,13 @@ export class BlockProposal extends Gossipable implements Signable { /** The signed transactions in the block (optional, for DA guarantees) */ public readonly signedTxs?: SignedTxs, + + /** + * Reference to the Inbox bucket this block proposes to consume, when the proposer commits to one. Validators + * resolve it against their own Inbox view and derive the consumed message bundle from it rather than trusting a + * proposer-supplied message list. Covered by the proposal signature (part of `getPayloadToSign`). + */ + public readonly bucketRef?: InboxBucketRef, ) { super(); } @@ -124,16 +129,18 @@ export class BlockProposal extends Gossipable implements Signable { /** * Get the payload to sign for this block proposal. - * The signature is over: blockHeader + indexWithinCheckpoint + inHash + archiveRoot + txHashes + * The signature is over: blockHeader + indexWithinCheckpoint + archiveRoot + txHashes, plus the bucket reference + * when set. Appending only when set binds the reference to the signature so a relay cannot strip or inject it + * without breaking recovery. */ getPayloadToSign(): Buffer { return serializeToBuffer([ this.blockHeader, this.indexWithinCheckpoint, - this.inHash, this.archiveRoot, this.txHashes.length, this.txHashes, + ...(this.bucketRef ? [this.bucketRef] : []), ]); } @@ -156,23 +163,24 @@ export class BlockProposal extends Gossipable implements Signable { blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, indexWithinCheckpoint: IndexWithinCheckpoint, - inHash: Fr, archiveRoot: Fr, txHashes: TxHash[], txs: Tx[] | undefined, signatureContext: CoordinationSignatureContext, proposalSigner: (typedData: TypedDataDefinition, context: SigningContext) => Promise, txsSigner?: (typedData: TypedDataDefinition, context: SigningContext) => Promise, + bucketRef?: InboxBucketRef, ): Promise { // Create a temporary proposal to get the payload to sign const tempProposal = new BlockProposal( blockHeader, indexWithinCheckpoint, - inHash, archiveRoot, txHashes, Signature.empty(), signatureContext, + undefined, + bucketRef, ); // Create the block signing context @@ -202,12 +210,12 @@ export class BlockProposal extends Gossipable implements Signable { return new BlockProposal( blockHeader, indexWithinCheckpoint, - inHash, archiveRoot, txHashes, sig, signatureContext, signedTxs, + bucketRef, ); } @@ -248,7 +256,6 @@ export class BlockProposal extends Gossipable implements Signable { const buffer: any[] = [ this.blockHeader, this.indexWithinCheckpoint, - this.inHash, this.archiveRoot, this.signature, serializeCoordinationSignatureContext(this.signatureContext), @@ -261,6 +268,12 @@ export class BlockProposal extends Gossipable implements Signable { } else { buffer.push(0); // hasSignedTxs = false } + // Optional bucket-reference tail. Appended only when set, so a proposal without a reference + // serializes without the tail and a decoder that reaches EOF reads it as unset. + if (this.bucketRef) { + buffer.push(1); // hasBucketRef = true + buffer.push(this.bucketRef.toBuffer()); + } return serializeToBuffer(buffer); } @@ -269,7 +282,6 @@ export class BlockProposal extends Gossipable implements Signable { const blockHeader = reader.readObject(BlockHeader); const indexWithinCheckpoint = IndexWithinCheckpoint(reader.readNumber()); - const inHash = reader.readObject(Fr); const archiveRoot = reader.readObject(Fr); const signature = reader.readObject(Signature); const signatureContext = readCoordinationSignatureContext(reader); @@ -279,31 +291,33 @@ export class BlockProposal extends Gossipable implements Signable { } const txHashes = reader.readArray(txHashCount, TxHash); + let signedTxs: SignedTxs | undefined; if (!reader.isEmpty()) { const hasSignedTxs = reader.readNumber(); if (hasSignedTxs) { - const signedTxs = SignedTxs.fromBuffer(reader); - return new BlockProposal( - blockHeader, - indexWithinCheckpoint, - inHash, - archiveRoot, - txHashes, - signature, - signatureContext, - signedTxs, - ); + signedTxs = SignedTxs.fromBuffer(reader); + } + } + + // Optional bucket-reference tail. A buffer that ends after the signedTxs flag decodes as + // "no reference", so proposals written without the tail round-trip cleanly. + let bucketRef: InboxBucketRef | undefined; + if (!reader.isEmpty()) { + const hasBucketRef = reader.readNumber(); + if (hasBucketRef) { + bucketRef = InboxBucketRef.fromBuffer(reader); } } return new BlockProposal( blockHeader, indexWithinCheckpoint, - inHash, archiveRoot, txHashes, signature, signatureContext, + signedTxs, + bucketRef, ); } @@ -311,7 +325,6 @@ export class BlockProposal extends Gossipable implements Signable { return ( this.blockHeader.getSize() + 4 /* indexWithinCheckpoint */ + - this.inHash.size + this.archiveRoot.size + this.signature.getSize() + 4 /* chainId */ + @@ -319,7 +332,8 @@ export class BlockProposal extends Gossipable implements Signable { 4 /* txHashes.length */ + this.txHashes.length * TxHash.SIZE + 4 /* hasSignedTxs flag */ + - (this.signedTxs ? this.signedTxs.getSize() : 0) + (this.signedTxs ? this.signedTxs.getSize() : 0) + + (this.bucketRef ? 4 /* hasBucketRef flag */ + this.bucketRef.getSize() : 0) ); } @@ -328,7 +342,6 @@ export class BlockProposal extends Gossipable implements Signable { BlockHeader.empty(), IndexWithinCheckpoint(0), Fr.ZERO, - Fr.ZERO, [], Signature.empty(), EMPTY_COORDINATION_SIGNATURE_CONTEXT, @@ -340,7 +353,6 @@ export class BlockProposal extends Gossipable implements Signable { BlockHeader.random(), IndexWithinCheckpoint(Math.floor(Math.random() * 5)), Fr.random(), - Fr.random(), [TxHash.random(), TxHash.random()], Signature.random(), EMPTY_COORDINATION_SIGNATURE_CONTEXT, @@ -351,12 +363,12 @@ export class BlockProposal extends Gossipable implements Signable { return { blockHeader: this.blockHeader.toInspect(), indexWithinCheckpoint: this.indexWithinCheckpoint, - inHash: this.inHash.toString(), archiveRoot: this.archiveRoot.toString(), signature: this.signature.toString(), txHashes: this.txHashes.map(h => h.toString()), chainId: this.signatureContext.chainId, rollupAddress: this.signatureContext.rollupAddress.toString(), + bucketRef: this.bucketRef?.toInspect(), }; } @@ -378,11 +390,12 @@ export class BlockProposal extends Gossipable implements Signable { return new BlockProposal( this.blockHeader, this.indexWithinCheckpoint, - this.inHash, this.archiveRoot, this.txHashes, this.signature, this.signatureContext, + undefined, + this.bucketRef, ); } } diff --git a/yarn-project/stdlib/src/p2p/checkpoint_proposal.test.ts b/yarn-project/stdlib/src/p2p/checkpoint_proposal.test.ts new file mode 100644 index 000000000000..9f4698ec58a4 --- /dev/null +++ b/yarn-project/stdlib/src/p2p/checkpoint_proposal.test.ts @@ -0,0 +1,126 @@ +// Serde and consistency tests for the checkpoint proposal type +import { IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; +import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { Signature } from '@aztec/foundation/eth-signature'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; + +import { InboxBucketRef } from '../messaging/inbox_bucket.js'; +import { CheckpointHeader } from '../rollup/checkpoint_header.js'; +import { makeCheckpointProposal } from '../tests/mocks.js'; +import { BlockHeader } from '../tx/block_header.js'; +import { TxHash } from '../tx/tx_hash.js'; +import { CheckpointProposal } from './checkpoint_proposal.js'; +import { EMPTY_COORDINATION_SIGNATURE_CONTEXT } from './signature_utils.js'; +import { LEGACY_CHECKPOINT_PROPOSAL_HEX } from './wire_compat_fixtures.js'; + +/** + * Deterministic legacy-shaped checkpoint proposal (lastBlock without signedTxs or bucketRef) matching the golden + * fixture in wire_compat_fixtures.ts. Constructed identically to how those bytes were captured on the pre-change code. + */ +const makeLegacyFixtureCheckpointProposal = () => + new CheckpointProposal( + CheckpointHeader.empty(), + new Fr(123n), + 0n, + Signature.empty(), + EMPTY_COORDINATION_SIGNATURE_CONTEXT, + { + blockHeader: BlockHeader.empty(), + indexWithinCheckpoint: IndexWithinCheckpoint(4), + txHashes: [TxHash.fromField(new Fr(7n))], + signature: Signature.empty(), + }, + ); + +describe('CheckpointProposal serialization / deserialization', () => { + it('round-trips with a lastBlock', async () => { + const proposal = await makeCheckpointProposal({ lastBlock: {} }); + const deserialized = CheckpointProposal.fromBuffer(proposal.toBuffer()); + // The mock supplies a BlockProposal as lastBlock while decoding rebuilds a plain CheckpointLastBlock, so compare + // the re-serialized bytes rather than deep-equal. + expect(deserialized.getSize()).toEqual(proposal.getSize()); + expect(deserialized.toBuffer()).toEqual(proposal.toBuffer()); + }); + + describe('bucket reference (AZIP-22 Fast Inbox)', () => { + it('round-trips with a bucket reference on the last block', async () => { + const checkpointHeader = CheckpointHeader.random(); + const bucketRef = new InboxBucketRef(17n, 1_700_000_000n, checkpointHeader.inboxRollingHash); + const proposal = await makeCheckpointProposal({ checkpointHeader, lastBlock: { bucketRef } }); + + const deserialized = CheckpointProposal.fromBuffer(proposal.toBuffer()); + + expect(deserialized.lastBlock?.bucketRef?.equals(bucketRef)).toBe(true); + expect(deserialized.getSize()).toEqual(proposal.getSize()); + expect(deserialized.toBuffer()).toEqual(proposal.toBuffer()); + }); + + it('serializes byte-identically to the legacy format when unset', () => { + const proposal = makeLegacyFixtureCheckpointProposal(); + expect(proposal.lastBlock?.bucketRef).toBeUndefined(); + expect(bufferToHex(proposal.toBuffer())).toEqual(LEGACY_CHECKPOINT_PROPOSAL_HEX); + }); + + it('decodes a legacy buffer (no tail) as having no bucket reference', () => { + const deserialized = CheckpointProposal.fromBuffer(hexToBuffer(LEGACY_CHECKPOINT_PROPOSAL_HEX)); + expect(deserialized.lastBlock).toBeDefined(); + expect(deserialized.lastBlock?.bucketRef).toBeUndefined(); + expect(bufferToHex(deserialized.toBuffer())).toEqual(LEGACY_CHECKPOINT_PROPOSAL_HEX); + }); + + it('carries the bucket reference through getBlockProposal, covered by the block signature', async () => { + const signer = Secp256k1Signer.random(); + const checkpointHeader = CheckpointHeader.random(); + const bucketRef = new InboxBucketRef(3n, 42n, checkpointHeader.inboxRollingHash); + const proposal = await makeCheckpointProposal({ signer, checkpointHeader, lastBlock: { bucketRef } }); + + const blockProposal = proposal.getBlockProposal(); + expect(blockProposal?.bucketRef?.equals(bucketRef)).toBe(true); + expect(blockProposal?.getSender()).toEqual(signer.address); + expect(proposal.getSender()).toEqual(signer.address); + }); + + it('accepts a last-block reference whose rolling hash matches the checkpoint header', () => { + const checkpointHeader = CheckpointHeader.random({ inboxRollingHash: new Fr(0x1234n) }); + expect( + () => + new CheckpointProposal( + checkpointHeader, + Fr.random(), + 0n, + Signature.empty(), + EMPTY_COORDINATION_SIGNATURE_CONTEXT, + { + blockHeader: BlockHeader.empty(), + indexWithinCheckpoint: IndexWithinCheckpoint(4), + txHashes: [], + signature: Signature.empty(), + bucketRef: new InboxBucketRef(1n, 2n, new Fr(0x1234n)), + }, + ), + ).not.toThrow(); + }); + + it('throws when the last-block reference rolling hash does not match the checkpoint header', () => { + const checkpointHeader = CheckpointHeader.random({ inboxRollingHash: new Fr(0x1234n) }); + expect( + () => + new CheckpointProposal( + checkpointHeader, + Fr.random(), + 0n, + Signature.empty(), + EMPTY_COORDINATION_SIGNATURE_CONTEXT, + { + blockHeader: BlockHeader.empty(), + indexWithinCheckpoint: IndexWithinCheckpoint(4), + txHashes: [], + signature: Signature.empty(), + bucketRef: new InboxBucketRef(1n, 2n, new Fr(0x5678n)), + }, + ), + ).toThrow(/bucketRef rolling hash/); + }); + }); +}); diff --git a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts index 286be1c2b64f..a22dd24f21c2 100644 --- a/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts +++ b/yarn-project/stdlib/src/p2p/checkpoint_proposal.ts @@ -15,6 +15,7 @@ import type { TypedDataDefinition } from 'viem'; import type { L2BlockInfo } from '../block/l2_block_info.js'; import { MAX_TXS_PER_BLOCK } from '../deserialization/index.js'; import { DutyType, type SigningContext } from '../ha-signing/index.js'; +import { InboxBucketRef } from '../messaging/inbox_bucket.js'; import { CheckpointHeader } from '../rollup/checkpoint_header.js'; import { BlockHeader } from '../tx/block_header.js'; import { TxHash } from '../tx/index.js'; @@ -69,6 +70,11 @@ export type CheckpointLastBlock = Omit & { signature: Signature; /** The signed transactions in the last block (optional, for DA guarantees) */ signedTxs?: SignedTxs; + /** + * Reference to the Inbox bucket the last block proposes to consume. When set, its rolling hash must equal the + * checkpoint header's `inboxRollingHash` (enforced at construction). + */ + bucketRef?: InboxBucketRef; }; /** @@ -104,10 +110,11 @@ export class CheckpointProposal extends Gossipable implements Signable { ) { super(); - // Check that last block properties match those of the checkpoint. - if (lastBlock && 'inHash' in lastBlock && !lastBlock.inHash.equals(checkpointHeader.inHash)) { + // Check that last block properties match those of the checkpoint. The last block's bucket reference + // commits to the same rolling hash as the checkpoint header. Only enforced when the reference is set. + if (lastBlock?.bucketRef && !lastBlock.bucketRef.inboxRollingHash.equals(checkpointHeader.inboxRollingHash)) { throw new Error( - `CheckpointProposal lastBlock inHash ${lastBlock.inHash} does not match checkpoint inHash ${checkpointHeader.inHash}`, + `CheckpointProposal lastBlock bucketRef rolling hash ${lastBlock.bucketRef.inboxRollingHash} does not match checkpoint inboxRollingHash ${checkpointHeader.inboxRollingHash}`, ); } if (lastBlock && 'archiveRoot' in lastBlock && !lastBlock.archiveRoot.equals(archive)) { @@ -134,7 +141,6 @@ export class CheckpointProposal extends Gossipable implements Signable { /** * Extract a BlockProposal from the last block info. - * Uses inHash from checkpointHeader.contentCommitment.inHash */ getBlockProposal(): BlockProposal | undefined { if (!this.lastBlock) { @@ -144,12 +150,12 @@ export class CheckpointProposal extends Gossipable implements Signable { return new BlockProposal( this.lastBlock.blockHeader, this.lastBlock.indexWithinCheckpoint, - this.checkpointHeader.inHash, this.archive, this.lastBlock.txHashes, this.lastBlock.signature, this.signatureContext, this.lastBlock.signedTxs, + this.lastBlock.bucketRef, ); } @@ -288,6 +294,12 @@ export class CheckpointProposal extends Gossipable implements Signable { } else { buffer.push(0); // hasSignedTxs = false } + // Optional bucket-reference tail. Appended only when set, so a proposal without a reference + // serializes without the tail and a decoder that reaches EOF reads it as unset. + if (this.lastBlock.bucketRef) { + buffer.push(1); // hasBucketRef = true + buffer.push(this.lastBlock.bucketRef.toBuffer()); + } } else { buffer.push(0); // hasLastBlock = false } @@ -324,12 +336,23 @@ export class CheckpointProposal extends Gossipable implements Signable { } } + // Optional bucket-reference tail. A buffer that ends after the signedTxs flag decodes as + // "no reference", so proposals written without the tail round-trip cleanly. + let bucketRef: InboxBucketRef | undefined; + if (!reader.isEmpty()) { + const hasBucketRef = reader.readNumber(); + if (hasBucketRef) { + bucketRef = InboxBucketRef.fromBuffer(reader); + } + } + return new CheckpointProposal(checkpointHeader, archive, feeAssetPriceModifier, signature, signatureContext, { blockHeader, indexWithinCheckpoint, txHashes, signature: blockSignature, signedTxs, + bucketRef, }); } @@ -354,7 +377,8 @@ export class CheckpointProposal extends Gossipable implements Signable { 4 /* txHashes.length */ + this.lastBlock.txHashes.length * TxHash.SIZE + 4 /* hasSignedTxs flag */ + - (this.lastBlock.signedTxs ? this.lastBlock.signedTxs.getSize() : 0); + (this.lastBlock.signedTxs ? this.lastBlock.signedTxs.getSize() : 0) + + (this.lastBlock.bucketRef ? 4 /* hasBucketRef flag */ + this.lastBlock.bucketRef.getSize() : 0); } return size; @@ -400,6 +424,7 @@ export class CheckpointProposal extends Gossipable implements Signable { indexWithinCheckpoint: this.lastBlock.indexWithinCheckpoint, txHashes: this.lastBlock.txHashes.map(h => h.toString()), signature: this.lastBlock.signature.toString(), + bucketRef: this.lastBlock.bucketRef?.toInspect(), } : undefined, }; diff --git a/yarn-project/stdlib/src/p2p/wire_compat_fixtures.ts b/yarn-project/stdlib/src/p2p/wire_compat_fixtures.ts new file mode 100644 index 000000000000..59813e0aee65 --- /dev/null +++ b/yarn-project/stdlib/src/p2p/wire_compat_fixtures.ts @@ -0,0 +1,23 @@ +// Golden wire fixtures that pin the exact bytes a peer produces and consumes, so the optional bucket-reference tail +// added to proposals stays wire compatible: an unset proposal must serialize to these bytes, and decoding these bytes +// must yield no bucket reference. The block-proposal fixtures were refreshed for the removal of the legacy `inHash` +// field; the checkpoint-proposal fixture was refreshed for the checkpoint-header format change. +// +// Both fixtures come from a deterministic proposal built with: +// BlockHeader.empty(), IndexWithinCheckpoint(3), archiveRoot=Fr(99), +// txHashes=[TxHash.fromField(Fr(7)), TxHash.fromField(Fr(8))], Signature.empty(), EMPTY_COORDINATION_SIGNATURE_CONTEXT +// (checkpoint: CheckpointHeader.empty(), archive=Fr(123), feeAssetPriceModifier=0, empty signature/context, and a +// lastBlock with BlockHeader.empty(), IndexWithinCheckpoint(4), txHashes=[TxHash.fromField(Fr(7))], empty signature). +// Regenerate the checkpoint fixture only when the checkpoint serialization format changes on purpose. + +/** Legacy `BlockProposal.toBuffer()` bytes (no signedTxs, no bucket reference). */ +export const LEGACY_BLOCK_PROPOSAL_HEX = + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000800000000'; + +/** Legacy `CheckpointProposal.toBuffer()` bytes (lastBlock without signedTxs or bucket reference). */ +export const LEGACY_CHECKPOINT_PROPOSAL_HEX = + '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000700000000'; + +/** Legacy `BlockProposal.getPayloadToSign()` bytes (no bucket reference). */ +export const LEGACY_BLOCK_PROPOSAL_PAYLOAD_HEX = + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000630000000200000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000008'; diff --git a/yarn-project/stdlib/src/parity/inbox_parity_private_inputs.ts b/yarn-project/stdlib/src/parity/inbox_parity_private_inputs.ts new file mode 100644 index 000000000000..fb799887d425 --- /dev/null +++ b/yarn-project/stdlib/src/parity/inbox_parity_private_inputs.ts @@ -0,0 +1,134 @@ +import { INBOX_PARITY_SIZE_LARGE, INBOX_PARITY_SIZE_MEDIUM, INBOX_PARITY_SIZE_SMALL } from '@aztec/constants'; +import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; + +import { L1ToL2MessageSponge } from '../messaging/l1_to_l2_message_sponge.js'; + +/** The InboxParity size ladder, ascending. One VK per size; the prover proves the smallest that fits. */ +export const INBOX_PARITY_SIZES = [INBOX_PARITY_SIZE_SMALL, INBOX_PARITY_SIZE_MEDIUM, INBOX_PARITY_SIZE_LARGE] as const; + +/** A valid InboxParity ladder size. */ +export type InboxParitySize = (typeof INBOX_PARITY_SIZES)[number]; + +/** + * Picks the smallest ladder size that can hold `numMessages` messages. + * @throws if `numMessages` exceeds the largest rung. + */ +export function pickInboxParitySize(numMessages: number): InboxParitySize { + const size = INBOX_PARITY_SIZES.find(s => numMessages <= s); + if (size === undefined) { + throw new Error( + `Cannot fit ${numMessages} L1-to-L2 messages into any InboxParity size (max ${INBOX_PARITY_SIZE_LARGE})`, + ); + } + return size; +} + +/** + * Private inputs for one `InboxParity` proof (S = `size`). The prover produces exactly one per checkpoint, sized + * by the checkpoint's message count via {@link pickInboxParitySize}. + */ +export class InboxParityPrivateInputs { + constructor( + /** Ladder size S: the length of `messages` and the circuit variant to prove ({@link INBOX_PARITY_SIZES}). */ + public readonly size: InboxParitySize, + /** The checkpoint's L1-to-L2 messages, padded with zeros to `size`; the first `numMessages` are real. */ + public readonly messages: Fr[], + /** Number of real (non-padding) messages in `messages`. */ + public readonly numMessages: number, + /** Inbox rolling hash before this checkpoint's messages (the previous checkpoint's end; genesis is zero). */ + public readonly startRollingHash: Fr, + /** Message-bundle sponge before this checkpoint's messages (empty at checkpoint start). */ + public readonly startSponge: L1ToL2MessageSponge, + /** Root of the VK tree. */ + public readonly vkTreeRoot: Fr, + /** Prover identity committed to by the circuit, for sybil protection. */ + public readonly proverId: Fr, + ) { + if (messages.length !== size) { + throw new Error(`InboxParity messages length (${messages.length}) must equal size (${size})`); + } + } + + /** + * Builds the inputs from a checkpoint's real messages, sizing the circuit by the message count and padding the + * message array out to that size. + */ + static fromMessages( + messages: Fr[], + startRollingHash: Fr, + startSponge: L1ToL2MessageSponge, + vkTreeRoot: Fr, + proverId: Fr, + ): InboxParityPrivateInputs { + const size = pickInboxParitySize(messages.length); + // Explicit `` keeps the result `Fr[]`; padding to the union-literal `size` would infer a deep tuple. + return new InboxParityPrivateInputs( + size, + padArrayEnd(messages, Fr.ZERO, size), + messages.length, + startRollingHash, + startSponge, + vkTreeRoot, + proverId, + ); + } + + /** Serializes the inputs to a buffer. */ + toBuffer() { + return serializeToBuffer( + new Fr(this.size), + this.messages, + new Fr(this.numMessages), + this.startRollingHash, + this.startSponge, + this.vkTreeRoot, + this.proverId, + ); + } + + /** Serializes the inputs to a hex string. */ + toString() { + return bufferToHex(this.toBuffer()); + } + + /** + * Deserializes the inputs from a buffer. + * @param buffer - The buffer to deserialize from. + */ + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const size = Fr.fromBuffer(reader).toNumber() as InboxParitySize; + // Array.from keeps the type `Fr[]`; readArray with the union-literal `size` would infer a deep tuple. + const messages = Array.from({ length: size }, () => Fr.fromBuffer(reader)); + return new InboxParityPrivateInputs( + size, + messages, + Fr.fromBuffer(reader).toNumber(), + Fr.fromBuffer(reader), + reader.readObject(L1ToL2MessageSponge), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + ); + } + + /** + * Deserializes the inputs from a hex string. + * @param str - The hex string to deserialize from. + */ + static fromString(str: string) { + return InboxParityPrivateInputs.fromBuffer(hexToBuffer(str)); + } + + /** Returns a buffer representation for JSON serialization. */ + toJSON() { + return this.toBuffer(); + } + + static get schema() { + return bufferSchemaFor(InboxParityPrivateInputs); + } +} diff --git a/yarn-project/stdlib/src/parity/index.ts b/yarn-project/stdlib/src/parity/index.ts index c527165dbcb3..0a043655c73e 100644 --- a/yarn-project/stdlib/src/parity/index.ts +++ b/yarn-project/stdlib/src/parity/index.ts @@ -1,3 +1,2 @@ -export * from './parity_base_private_inputs.js'; +export * from './inbox_parity_private_inputs.js'; export * from './parity_public_inputs.js'; -export * from './parity_root_private_inputs.js'; diff --git a/yarn-project/stdlib/src/parity/parity_base_private_inputs.test.ts b/yarn-project/stdlib/src/parity/parity_base_private_inputs.test.ts deleted file mode 100644 index a0f6954e5967..000000000000 --- a/yarn-project/stdlib/src/parity/parity_base_private_inputs.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { makeParityBasePrivateInputs } from '../tests/factories.js'; -import { ParityBasePrivateInputs } from './parity_base_private_inputs.js'; - -describe('ParityBasePrivateInputs', () => { - it(`serializes a ParityBasePrivateInputs to buffer and deserializes it back`, () => { - const expected = makeParityBasePrivateInputs(); - const buffer = expected.toBuffer(); - const res = ParityBasePrivateInputs.fromBuffer(buffer); - expect(res).toEqual(expected); - }); - - it(`serializes a ParityBasePrivateInputs to hex string and deserializes it back`, () => { - const expected = makeParityBasePrivateInputs(); - const str = expected.toString(); - const res = ParityBasePrivateInputs.fromString(str); - expect(res).toEqual(expected); - }); -}); diff --git a/yarn-project/stdlib/src/parity/parity_base_private_inputs.ts b/yarn-project/stdlib/src/parity/parity_base_private_inputs.ts deleted file mode 100644 index 0c3bf62ac2f9..000000000000 --- a/yarn-project/stdlib/src/parity/parity_base_private_inputs.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_MSGS_PER_BASE_PARITY } from '@aztec/constants'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { bufferSchemaFor } from '@aztec/foundation/schemas'; -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; - -export class ParityBasePrivateInputs { - constructor( - /** Aggregated proof of all the parity circuit iterations. */ - public readonly msgs: Tuple, - /** Root of the VK tree */ - public readonly vkTreeRoot: Fr, - /** Prover identity committed to by the circuit, for sybil protection. */ - public readonly proverId: Fr, - ) {} - - public static fromSlice(array: Fr[], index: number, vkTreeRoot: Fr, proverId: Fr): ParityBasePrivateInputs { - // Can't use Tuple due to length - if (array.length !== NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) { - throw new Error( - `Msgs array length must be NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP=${NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP}`, - ); - } - const start = index * NUM_MSGS_PER_BASE_PARITY; - const end = start + NUM_MSGS_PER_BASE_PARITY; - const msgs = array.slice(start, end); - return new ParityBasePrivateInputs(msgs as Tuple, vkTreeRoot, proverId); - } - - /** Serializes the inputs to a buffer. */ - toBuffer() { - return serializeToBuffer(this.msgs, this.vkTreeRoot, this.proverId); - } - - /** Serializes the inputs to a hex string. */ - toString() { - return bufferToHex(this.toBuffer()); - } - - /** - * Deserializes the inputs from a buffer. - * @param buffer - The buffer to deserialize from. - */ - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new ParityBasePrivateInputs( - reader.readArray(NUM_MSGS_PER_BASE_PARITY, Fr), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - ); - } - - /** - * Deserializes the inputs from a hex string. - * @param str - The hex string to deserialize from. - * @returns - The deserialized inputs. - */ - static fromString(str: string) { - return ParityBasePrivateInputs.fromBuffer(hexToBuffer(str)); - } - - /** Returns a buffer representation for JSON serialization. */ - toJSON() { - return this.toBuffer(); - } - - /** Creates an instance from a hex string. */ - static get schema() { - return bufferSchemaFor(ParityBasePrivateInputs); - } -} diff --git a/yarn-project/stdlib/src/parity/parity_public_inputs.ts b/yarn-project/stdlib/src/parity/parity_public_inputs.ts index b8f0feaff2db..2c07ab721ad1 100644 --- a/yarn-project/stdlib/src/parity/parity_public_inputs.ts +++ b/yarn-project/stdlib/src/parity/parity_public_inputs.ts @@ -4,28 +4,40 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import type { FieldsOf } from '@aztec/foundation/types'; +import { L1ToL2MessageSponge } from '../messaging/l1_to_l2_message_sponge.js'; + export class ParityPublicInputs { constructor( - /** Root of the SHA256 tree. */ - public shaRoot: Fr, - /** Root of the converted tree. */ - public convertedRoot: Fr, + /** Inbox rolling hash before absorbing this checkpoint's messages. */ + public startRollingHash: Fr, + /** Inbox rolling hash after absorbing the `numMsgs` real messages. */ + public endRollingHash: Fr, + /** Message-bundle sponge before absorbing this checkpoint's messages (empty at checkpoint start). */ + public startSponge: L1ToL2MessageSponge, + /** Message-bundle sponge after absorbing the `numMsgs` real messages. */ + public endSponge: L1ToL2MessageSponge, + /** Number of real (non-padding) messages absorbed into the rolling hash and the sponge. */ + public numMsgs: number, /** Root of the VK tree */ public vkTreeRoot: Fr, /** Prover identity committed to by the circuit, for sybil protection. */ public proverId: Fr, - ) { - if (shaRoot.toBuffer()[0] != 0) { - throw new Error(`shaRoot buffer must be 31 bytes. Got 32 bytes`); - } - } + ) {} /** * Serializes the inputs to a buffer. * @returns The inputs serialized to a buffer. */ toBuffer() { - return serializeToBuffer(...ParityPublicInputs.getFields(this)); + return serializeToBuffer( + this.startRollingHash, + this.endRollingHash, + this.startSponge, + this.endSponge, + new Fr(this.numMsgs), + this.vkTreeRoot, + this.proverId, + ); } /** @@ -56,7 +68,15 @@ export class ParityPublicInputs { * @returns The instance fields. */ static getFields(fields: FieldsOf) { - return [fields.shaRoot, fields.convertedRoot, fields.vkTreeRoot, fields.proverId] as const; + return [ + fields.startRollingHash, + fields.endRollingHash, + fields.startSponge, + fields.endSponge, + fields.numMsgs, + fields.vkTreeRoot, + fields.proverId, + ] as const; } /** @@ -69,6 +89,9 @@ export class ParityPublicInputs { return new ParityPublicInputs( reader.readObject(Fr), reader.readObject(Fr), + reader.readObject(L1ToL2MessageSponge), + reader.readObject(L1ToL2MessageSponge), + Fr.fromBuffer(reader).toNumber(), Fr.fromBuffer(reader), Fr.fromBuffer(reader), ); diff --git a/yarn-project/stdlib/src/parity/parity_root_private_inputs.test.ts b/yarn-project/stdlib/src/parity/parity_root_private_inputs.test.ts deleted file mode 100644 index 649e816c950e..000000000000 --- a/yarn-project/stdlib/src/parity/parity_root_private_inputs.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { makeParityRootPrivateInputs } from '../tests/factories.js'; -import { ParityRootPrivateInputs } from './parity_root_private_inputs.js'; - -describe('ParityRootPrivateInputs', () => { - it(`serializes a ParityRootPrivateInputs to buffer and deserializes it back`, () => { - const expected = makeParityRootPrivateInputs(); - const buffer = expected.toBuffer(); - const res = ParityRootPrivateInputs.fromBuffer(buffer); - expect(res).toEqual(expected); - }); - - it(`serializes a ParityRootPrivateInputs to hex string and deserializes it back`, () => { - const expected = makeParityRootPrivateInputs(); - const str = expected.toString(); - const res = ParityRootPrivateInputs.fromString(str); - expect(res).toEqual(expected); - }); -}); diff --git a/yarn-project/stdlib/src/parity/parity_root_private_inputs.ts b/yarn-project/stdlib/src/parity/parity_root_private_inputs.ts deleted file mode 100644 index 157eb5204a10..000000000000 --- a/yarn-project/stdlib/src/parity/parity_root_private_inputs.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { NUM_BASE_PARITY_PER_ROOT_PARITY } from '@aztec/constants'; -import { makeTuple } from '@aztec/foundation/array'; -import { bufferSchemaFor } from '@aztec/foundation/schemas'; -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; - -import { ProofData, type UltraHonkProofData } from '../proofs/proof_data.js'; -import { ParityPublicInputs } from './parity_public_inputs.js'; - -export type ParityBaseProofData = UltraHonkProofData; - -export class ParityRootPrivateInputs { - constructor( - /** Public inputs of the parity base circuits and their proofs and vk data. */ - public readonly children: Tuple, - ) {} - - /** - * Serializes the inputs to a buffer. - * @returns The inputs serialized to a buffer. - */ - toBuffer() { - return serializeToBuffer(this.children); - } - - /** - * Serializes the inputs to a hex string. - * @returns The instance serialized to a hex string. - */ - toString() { - return bufferToHex(this.toBuffer()); - } - - /** - * Deserializes the inputs from a buffer. - * @param buffer - The buffer to deserialize from. - * @returns A new ParityRootPrivateInputs instance. - */ - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new ParityRootPrivateInputs( - makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, () => ProofData.fromBuffer(reader, ParityPublicInputs)), - ); - } - - /** - * Deserializes the inputs from a hex string. - * @param str - A hex string to deserialize from. - * @returns A new ParityRootPrivateInputs instance. - */ - static fromString(str: string) { - return ParityRootPrivateInputs.fromBuffer(hexToBuffer(str)); - } - - /** Returns a buffer representation for JSON serialization. */ - toJSON() { - return this.toBuffer(); - } - - /** Creates an instance from a hex string. */ - static get schema() { - return bufferSchemaFor(ParityRootPrivateInputs); - } -} diff --git a/yarn-project/stdlib/src/proofs/proving_request_type.ts b/yarn-project/stdlib/src/proofs/proving_request_type.ts index d7517c61cd56..8ea73232fa1b 100644 --- a/yarn-project/stdlib/src/proofs/proving_request_type.ts +++ b/yarn-project/stdlib/src/proofs/proving_request_type.ts @@ -10,6 +10,7 @@ export enum ProvingRequestType { BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP, BLOCK_ROOT_ROLLUP, BLOCK_ROOT_SINGLE_TX_ROLLUP, + BLOCK_ROOT_MSGS_ONLY_ROLLUP, BLOCK_MERGE_ROLLUP, CHECKPOINT_ROOT_ROLLUP, CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP, @@ -17,6 +18,5 @@ export enum ProvingRequestType { CHECKPOINT_MERGE_ROLLUP, ROOT_ROLLUP, - PARITY_BASE, - PARITY_ROOT, + INBOX_PARITY, } diff --git a/yarn-project/stdlib/src/rollup/block_constant_data.ts b/yarn-project/stdlib/src/rollup/block_constant_data.ts index 60979da2a73f..fd7e7f5c5f20 100644 --- a/yarn-project/stdlib/src/rollup/block_constant_data.ts +++ b/yarn-project/stdlib/src/rollup/block_constant_data.ts @@ -13,10 +13,10 @@ export class BlockConstantData { /** Archive tree snapshot at the very beginning of the entire rollup. */ public lastArchive: AppendOnlyTreeSnapshot, /** - * L1-to-L2 message tree snapshot after this block lands. - * For the first block in a checkpoint, this should be the snapshot after inserting the new l1-to-l2 message subtree - * into the last l1-to-l2 tree snapshot in `last_archive`. - * For subsequent blocks, this should match the snapshot of the previous block. + * L1-to-L2 message tree snapshot after this block's own message bundle has been inserted. The AVM validates this + * block's l1-to-l2 message read requests against it, so a tx in this block can read the messages this block + * inserts (same-block consumption). Every block-root variant that carries txs asserts this equals its computed + * post-bundle root, whether or not the block is the first in its checkpoint. */ public l1ToL2TreeSnapshot: AppendOnlyTreeSnapshot, /** Root of the verification key tree. */ diff --git a/yarn-project/stdlib/src/rollup/block_rollup_public_inputs.ts b/yarn-project/stdlib/src/rollup/block_rollup_public_inputs.ts index 12b6b1926e10..e597a2261ef2 100644 --- a/yarn-project/stdlib/src/rollup/block_rollup_public_inputs.ts +++ b/yarn-project/stdlib/src/rollup/block_rollup_public_inputs.ts @@ -4,6 +4,7 @@ import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize'; import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; +import { L1ToL2MessageSponge } from '../messaging/l1_to_l2_message_sponge.js'; import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js'; import { StateReference } from '../tx/state_reference.js'; import type { UInt64 } from '../types/shared.js'; @@ -53,9 +54,19 @@ export class BlockRollupPublicInputs { */ public blockHeadersHash: Fr, /** - * SHA256 hash of l1 to l2 messages. + * Whether this block range starts at the first block of its checkpoint. Only the first block root sets this true; + * merges propagate it from the left rollup. */ - public inHash: Fr, + public isFirstBlock: boolean, + /** + * Message-bundle sponge threaded across the checkpoint's blocks, before this block range absorbs its bundle. + */ + public startMsgSponge: L1ToL2MessageSponge, + /** + * Message-bundle sponge after this block range absorbs its bundle. The checkpoint root asserts the final value + * matches the parity root's sponge over the same (padded) message list. + */ + public endMsgSponge: L1ToL2MessageSponge, /** * SHA256 hash of L2 to L1 messages created in this block range. */ @@ -82,7 +93,9 @@ export class BlockRollupPublicInputs { reader.readObject(SpongeBlob), reader.readUInt64(), Fr.fromBuffer(reader), - Fr.fromBuffer(reader), + reader.readBoolean(), + reader.readObject(L1ToL2MessageSponge), + reader.readObject(L1ToL2MessageSponge), Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader), @@ -100,7 +113,9 @@ export class BlockRollupPublicInputs { this.endSpongeBlob, bigintToUInt64BE(this.timestamp), this.blockHeadersHash, - this.inHash, + this.isFirstBlock, + this.startMsgSponge, + this.endMsgSponge, this.outHash, this.accumulatedFees, this.accumulatedManaUsed, @@ -124,7 +139,9 @@ export class BlockRollupPublicInputs { previousArchiveRoot: this.previousArchive.root.toString(), newArchiveRoot: this.newArchive.root.toString(), blockHeadersHash: this.blockHeadersHash.toString(), - inHash: this.inHash.toString(), + isFirstBlock: this.isFirstBlock, + startMsgSpongeNumAbsorbed: this.startMsgSponge.numAbsorbed, + endMsgSpongeNumAbsorbed: this.endMsgSponge.numAbsorbed, outHash: this.outHash.toString(), timestamp: this.timestamp.toString(), accumulatedFees: this.accumulatedFees.toString(), diff --git a/yarn-project/stdlib/src/rollup/block_root_rollup_private_inputs.ts b/yarn-project/stdlib/src/rollup/block_root_rollup_private_inputs.ts index 19a99769dac9..206572d4a7c6 100644 --- a/yarn-project/stdlib/src/rollup/block_root_rollup_private_inputs.ts +++ b/yarn-project/stdlib/src/rollup/block_root_rollup_private_inputs.ts @@ -1,11 +1,13 @@ -import { ARCHIVE_HEIGHT, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH } from '@aztec/constants'; +import { SpongeBlob } from '@aztec/blob-lib/types'; +import { ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants'; import { Fr } from '@aztec/foundation/curves/bn254'; import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize'; import type { FieldsOf } from '@aztec/foundation/types'; -import { ParityPublicInputs } from '../parity/parity_public_inputs.js'; -import { ProofData, type RollupHonkProofData, type UltraHonkProofData } from '../proofs/proof_data.js'; +import { L1ToL2MessageBundle } from '../messaging/l1_to_l2_message_bundle.js'; +import { L1ToL2MessageSponge } from '../messaging/l1_to_l2_message_sponge.js'; +import { ProofData, type RollupHonkProofData } from '../proofs/proof_data.js'; import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js'; import { StateReference } from '../tx/state_reference.js'; import type { UInt64 } from '../types/shared.js'; @@ -14,22 +16,22 @@ import { TxRollupPublicInputs } from './tx_rollup_public_inputs.js'; export class BlockRootFirstRollupPrivateInputs { constructor( - /** - * The original and converted roots of the L1 to L2 messages subtrees. - */ - public l1ToL2Roots: UltraHonkProofData, /** * The previous rollup proof data from base or merge rollup circuits. */ public previousRollups: [RollupHonkProofData, RollupHonkProofData], + /** + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, /** * The l1 to l2 message tree snapshot immediately before this block. */ public previousL1ToL2: AppendOnlyTreeSnapshot, /** - * Hint for inserting the new l1 to l2 message subtree root into `previousL1ToL2`. + * Frontier hint for appending the message bundle to `previousL1ToL2`. */ - public newL1ToL2MessageSubtreeRootSiblingPath: Tuple, + public l1ToL2MessageFrontierHint: Tuple, /** * Hint for inserting the new block hash to the last archive. */ @@ -42,25 +44,31 @@ export class BlockRootFirstRollupPrivateInputs { static getFields(fields: FieldsOf) { return [ - fields.l1ToL2Roots, fields.previousRollups, + fields.messageBundle, fields.previousL1ToL2, - fields.newL1ToL2MessageSubtreeRootSiblingPath, + fields.l1ToL2MessageFrontierHint, fields.newArchiveSiblingPath, ] as const; } toBuffer() { - return serializeToBuffer(...BlockRootFirstRollupPrivateInputs.getFields(this)); + return serializeToBuffer( + this.previousRollups, + this.messageBundle, + this.previousL1ToL2, + this.l1ToL2MessageFrontierHint, + this.newArchiveSiblingPath, + ); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new BlockRootFirstRollupPrivateInputs( - ProofData.fromBuffer(reader, ParityPublicInputs), [ProofData.fromBuffer(reader, TxRollupPublicInputs), ProofData.fromBuffer(reader, TxRollupPublicInputs)], + reader.readObject(L1ToL2MessageBundle), AppendOnlyTreeSnapshot.fromBuffer(reader), - reader.readArray(L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, Fr), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), reader.readArray(ARCHIVE_HEIGHT, Fr), ); } @@ -76,22 +84,22 @@ export class BlockRootFirstRollupPrivateInputs { export class BlockRootSingleTxFirstRollupPrivateInputs { constructor( - /** - * The original and converted roots of the L1 to L2 messages subtrees. - */ - public l1ToL2Roots: UltraHonkProofData, /** * The previous rollup proof data from base or merge rollup circuits. */ public previousRollup: RollupHonkProofData, + /** + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, /** * The l1 to l2 message tree snapshot immediately before this block. */ public previousL1ToL2: AppendOnlyTreeSnapshot, /** - * Hint for inserting the new l1 to l2 message subtree root. + * Frontier hint for appending the message bundle to `previousL1ToL2`. */ - public newL1ToL2MessageSubtreeRootSiblingPath: Tuple, + public l1ToL2MessageFrontierHint: Tuple, /** * Hint for inserting the new block hash to the last archive. */ @@ -106,25 +114,31 @@ export class BlockRootSingleTxFirstRollupPrivateInputs { static getFields(fields: FieldsOf) { return [ - fields.l1ToL2Roots, fields.previousRollup, + fields.messageBundle, fields.previousL1ToL2, - fields.newL1ToL2MessageSubtreeRootSiblingPath, + fields.l1ToL2MessageFrontierHint, fields.newArchiveSiblingPath, ] as const; } toBuffer() { - return serializeToBuffer(...BlockRootSingleTxFirstRollupPrivateInputs.getFields(this)); + return serializeToBuffer( + this.previousRollup, + this.messageBundle, + this.previousL1ToL2, + this.l1ToL2MessageFrontierHint, + this.newArchiveSiblingPath, + ); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new BlockRootSingleTxFirstRollupPrivateInputs( - ProofData.fromBuffer(reader, ParityPublicInputs), ProofData.fromBuffer(reader, TxRollupPublicInputs), + reader.readObject(L1ToL2MessageBundle), AppendOnlyTreeSnapshot.fromBuffer(reader), - reader.readArray(L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, Fr), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), reader.readArray(ARCHIVE_HEIGHT, Fr), ); } @@ -140,10 +154,6 @@ export class BlockRootSingleTxFirstRollupPrivateInputs { export class BlockRootEmptyTxFirstRollupPrivateInputs { constructor( - /** - * The original and converted roots of the L1 to L2 messages subtrees. - */ - public l1ToL2Roots: UltraHonkProofData, /** * The archive after applying the previous block. */ @@ -161,9 +171,13 @@ export class BlockRootEmptyTxFirstRollupPrivateInputs { */ public timestamp: UInt64, /** - * Hint for inserting the new l1 to l2 message subtree root. + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, + /** + * Frontier hint for appending the message bundle to the previous state's l1 to l2 message tree. */ - public newL1ToL2MessageSubtreeRootSiblingPath: Tuple, + public l1ToL2MessageFrontierHint: Tuple, /** * Hint for inserting the new block hash to the last archive. */ @@ -176,37 +190,37 @@ export class BlockRootEmptyTxFirstRollupPrivateInputs { static getFields(fields: FieldsOf) { return [ - fields.l1ToL2Roots, fields.previousArchive, fields.previousState, fields.constants, fields.timestamp, - fields.newL1ToL2MessageSubtreeRootSiblingPath, + fields.messageBundle, + fields.l1ToL2MessageFrontierHint, fields.newArchiveSiblingPath, ] as const; } toBuffer() { - return serializeToBuffer([ - this.l1ToL2Roots, + return serializeToBuffer( this.previousArchive, this.previousState, this.constants, bigintToUInt64BE(this.timestamp), - this.newL1ToL2MessageSubtreeRootSiblingPath, + this.messageBundle, + this.l1ToL2MessageFrontierHint, this.newArchiveSiblingPath, - ]); + ); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new BlockRootEmptyTxFirstRollupPrivateInputs( - ProofData.fromBuffer(reader, ParityPublicInputs), AppendOnlyTreeSnapshot.fromBuffer(reader), StateReference.fromBuffer(reader), CheckpointConstantData.fromBuffer(reader), reader.readUInt64(), - reader.readArray(L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, Fr), + reader.readObject(L1ToL2MessageBundle), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), reader.readArray(ARCHIVE_HEIGHT, Fr), ); } @@ -220,12 +234,126 @@ export class BlockRootEmptyTxFirstRollupPrivateInputs { } } +export class BlockRootMsgsOnlyRollupPrivateInputs { + constructor( + /** + * The archive after applying the previous block. + */ + public previousArchive: AppendOnlyTreeSnapshot, + /** + * The state reference of the previous block. + */ + public previousState: StateReference, + /** + * The constants of the checkpoint. + */ + public constants: CheckpointConstantData, + /** + * The timestamp of this block. + */ + public timestamp: UInt64, + /** + * Sponge blob inherited from the previous block (checked against its `endSpongeBlob` in the merge/checkpoint root). + */ + public startSpongeBlob: SpongeBlob, + /** + * Message sponge inherited from the previous block (checked against its `endMsgSponge` in the merge/checkpoint root). + */ + public startMsgSponge: L1ToL2MessageSponge, + /** + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, + /** + * Frontier hint for appending the message bundle to the previous state's l1 to l2 message tree. + */ + public l1ToL2MessageFrontierHint: Tuple, + /** + * Hint for inserting the new block hash to the last archive. + */ + public newArchiveSiblingPath: Tuple, + ) {} + + static from(fields: FieldsOf) { + return new BlockRootMsgsOnlyRollupPrivateInputs(...BlockRootMsgsOnlyRollupPrivateInputs.getFields(fields)); + } + + static getFields(fields: FieldsOf) { + return [ + fields.previousArchive, + fields.previousState, + fields.constants, + fields.timestamp, + fields.startSpongeBlob, + fields.startMsgSponge, + fields.messageBundle, + fields.l1ToL2MessageFrontierHint, + fields.newArchiveSiblingPath, + ] as const; + } + + toBuffer() { + return serializeToBuffer( + this.previousArchive, + this.previousState, + this.constants, + bigintToUInt64BE(this.timestamp), + this.startSpongeBlob, + this.startMsgSponge, + this.messageBundle, + this.l1ToL2MessageFrontierHint, + this.newArchiveSiblingPath, + ); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new BlockRootMsgsOnlyRollupPrivateInputs( + AppendOnlyTreeSnapshot.fromBuffer(reader), + StateReference.fromBuffer(reader), + CheckpointConstantData.fromBuffer(reader), + reader.readUInt64(), + reader.readObject(SpongeBlob), + reader.readObject(L1ToL2MessageSponge), + reader.readObject(L1ToL2MessageBundle), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), + reader.readArray(ARCHIVE_HEIGHT, Fr), + ); + } + + toJSON() { + return this.toBuffer(); + } + + static get schema() { + return bufferSchemaFor(BlockRootMsgsOnlyRollupPrivateInputs); + } +} + export class BlockRootRollupPrivateInputs { constructor( /** * The previous rollup proof data from base or merge rollup circuits. */ public previousRollups: [RollupHonkProofData, RollupHonkProofData], + /** + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, + /** + * The l1 to l2 message tree snapshot this block builds on (the previous block's post-insertion snapshot). Pinned by + * block-merge continuity to the previous block's end state; the circuit appends this block's bundle on top and + * asserts the tx constants carry the resulting post-bundle snapshot. + */ + public previousL1ToL2: AppendOnlyTreeSnapshot, + /** + * Message sponge inherited from the previous block (checked against its `endMsgSponge` in the merge/checkpoint root). + */ + public startMsgSponge: L1ToL2MessageSponge, + /** + * Frontier hint for appending the message bundle to `previousL1ToL2`. + */ + public l1ToL2MessageFrontierHint: Tuple, /** * Hint for inserting the new block hash to the last archive. */ @@ -237,17 +365,35 @@ export class BlockRootRollupPrivateInputs { } static getFields(fields: FieldsOf) { - return [fields.previousRollups, fields.newArchiveSiblingPath] as const; + return [ + fields.previousRollups, + fields.messageBundle, + fields.previousL1ToL2, + fields.startMsgSponge, + fields.l1ToL2MessageFrontierHint, + fields.newArchiveSiblingPath, + ] as const; } toBuffer() { - return serializeToBuffer(...BlockRootRollupPrivateInputs.getFields(this)); + return serializeToBuffer( + this.previousRollups, + this.messageBundle, + this.previousL1ToL2, + this.startMsgSponge, + this.l1ToL2MessageFrontierHint, + this.newArchiveSiblingPath, + ); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new BlockRootRollupPrivateInputs( [ProofData.fromBuffer(reader, TxRollupPublicInputs), ProofData.fromBuffer(reader, TxRollupPublicInputs)], + reader.readObject(L1ToL2MessageBundle), + AppendOnlyTreeSnapshot.fromBuffer(reader), + reader.readObject(L1ToL2MessageSponge), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), reader.readArray(ARCHIVE_HEIGHT, Fr), ); } @@ -267,6 +413,24 @@ export class BlockRootSingleTxRollupPrivateInputs { * The previous rollup proof data from base or merge rollup circuits. */ public previousRollup: RollupHonkProofData, + /** + * L1-to-L2 message bundle inserted by this block. + */ + public messageBundle: L1ToL2MessageBundle, + /** + * The l1 to l2 message tree snapshot this block builds on (the previous block's post-insertion snapshot). Pinned by + * block-merge continuity to the previous block's end state; the circuit appends this block's bundle on top and + * asserts the tx constants carry the resulting post-bundle snapshot. + */ + public previousL1ToL2: AppendOnlyTreeSnapshot, + /** + * Message sponge inherited from the previous block (checked against its `endMsgSponge` in the merge/checkpoint root). + */ + public startMsgSponge: L1ToL2MessageSponge, + /** + * Frontier hint for appending the message bundle to `previousL1ToL2`. + */ + public l1ToL2MessageFrontierHint: Tuple, /** * Hint for inserting the new block hash to the last archive. */ @@ -278,17 +442,35 @@ export class BlockRootSingleTxRollupPrivateInputs { } static getFields(fields: FieldsOf) { - return [fields.previousRollup, fields.newArchiveSiblingPath] as const; + return [ + fields.previousRollup, + fields.messageBundle, + fields.previousL1ToL2, + fields.startMsgSponge, + fields.l1ToL2MessageFrontierHint, + fields.newArchiveSiblingPath, + ] as const; } toBuffer() { - return serializeToBuffer(...BlockRootSingleTxRollupPrivateInputs.getFields(this)); + return serializeToBuffer( + this.previousRollup, + this.messageBundle, + this.previousL1ToL2, + this.startMsgSponge, + this.l1ToL2MessageFrontierHint, + this.newArchiveSiblingPath, + ); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new BlockRootSingleTxRollupPrivateInputs( ProofData.fromBuffer(reader, TxRollupPublicInputs), + reader.readObject(L1ToL2MessageBundle), + AppendOnlyTreeSnapshot.fromBuffer(reader), + reader.readObject(L1ToL2MessageSponge), + reader.readArray(L1_TO_L2_MSG_TREE_HEIGHT, Fr), reader.readArray(ARCHIVE_HEIGHT, Fr), ); } diff --git a/yarn-project/stdlib/src/rollup/checkpoint_header.test.ts b/yarn-project/stdlib/src/rollup/checkpoint_header.test.ts index 2748572da831..764a57fdab9c 100644 --- a/yarn-project/stdlib/src/rollup/checkpoint_header.test.ts +++ b/yarn-project/stdlib/src/rollup/checkpoint_header.test.ts @@ -22,7 +22,7 @@ describe('CheckpointHeader', () => { const header = CheckpointHeader.empty(); const hash = header.hash().toString(); - expect(hash).toMatchInlineSnapshot('"0x002e384af86a480f952aa16443fd29646a9063865e62d7c403fc7ed697bb7712"'); + expect(hash).toMatchInlineSnapshot(`"0x002e384af86a480f952aa16443fd29646a9063865e62d7c403fc7ed697bb7712"`); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( @@ -37,7 +37,7 @@ describe('CheckpointHeader', () => { lastArchiveRoot: new Fr(123), blockHeadersHash: new Fr(456), blobsHash: new Fr(77), - inHash: new Fr(88), + inboxRollingHash: new Fr(89), epochOutHash: new Fr(99), slotNumber: SlotNumber(1234), timestamp: BigInt(5678), @@ -49,7 +49,7 @@ describe('CheckpointHeader', () => { }); const hash = header.hash().toString(); - expect(hash).toMatchInlineSnapshot('"0x00d0dc440023ae006b0880b29ebfd5fda599d1aa7707f925229a362c5f24f3fc"'); + expect(hash).toMatchInlineSnapshot(`"0x00751391e842cd7b2014478255dd3309df86327197a0feb03f0af1b758f62ba5"`); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( @@ -64,7 +64,7 @@ describe('CheckpointHeader', () => { lastArchiveRoot: new Fr(MAX_FIELD_VALUE - 123n), blockHeadersHash: new Fr(MAX_FIELD_VALUE - 456n), blobsHash: new Fr(MAX_FIELD_VALUE - 77n), - inHash: new Fr(MAX_FIELD_VALUE - 88n), + inboxRollingHash: new Fr(MAX_FIELD_VALUE - 89n), epochOutHash: new Fr(MAX_FIELD_VALUE - 99n), slotNumber: SlotNumber(1234), timestamp: 2n ** 64n - 1n - 5678n, @@ -79,7 +79,7 @@ describe('CheckpointHeader', () => { const hash = header.hash().toString(); - expect(hash).toMatchInlineSnapshot('"0x0077f763e5840cc3f24686ac79f58ef8a7f08c6418fd757e7e84566dc2eb032a"'); + expect(hash).toMatchInlineSnapshot(`"0x005bd09725c6e77a4a28a7ccdaf7875ba5882431ca3c82e62db96e8a12769ce5"`); // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( diff --git a/yarn-project/stdlib/src/rollup/checkpoint_header.ts b/yarn-project/stdlib/src/rollup/checkpoint_header.ts index 64b7d03e3062..85fece4ec6f2 100644 --- a/yarn-project/stdlib/src/rollup/checkpoint_header.ts +++ b/yarn-project/stdlib/src/rollup/checkpoint_header.ts @@ -30,8 +30,12 @@ export class CheckpointHeader { public blockHeadersHash: Fr, /** Hash of the blobs in the checkpoint. */ public blobsHash: Fr, - /** Root of the l1 to l2 messages subtree. */ - public inHash: Fr, + /** + * Inbox rolling-hash chain value after consuming all L1-to-L2 messages bundled into this checkpoint: + * the truncated-to-field sha256 chain the L1 Inbox accumulates. This is the checkpoint's only inbox + * commitment. + */ + public inboxRollingHash: Fr, /** * The root of the epoch out hash balanced tree. The out hash of the first checkpoint in the epoch is inserted at * index 0, the second at index 1, and so on. @@ -62,7 +66,7 @@ export class CheckpointHeader { lastArchiveRoot: schemas.Fr, blockHeadersHash: schemas.Fr, blobsHash: schemas.Fr, - inHash: schemas.Fr, + inboxRollingHash: schemas.Fr, epochOutHash: schemas.Fr, slotNumber: schemas.SlotNumber, timestamp: schemas.BigInt, @@ -80,7 +84,7 @@ export class CheckpointHeader { fields.lastArchiveRoot, fields.blockHeadersHash, fields.blobsHash, - fields.inHash, + fields.inboxRollingHash, fields.epochOutHash, fields.slotNumber, fields.timestamp, @@ -120,7 +124,7 @@ export class CheckpointHeader { this.lastArchiveRoot.equals(other.lastArchiveRoot) && this.blockHeadersHash.equals(other.blockHeadersHash) && this.blobsHash.equals(other.blobsHash) && - this.inHash.equals(other.inHash) && + this.inboxRollingHash.equals(other.inboxRollingHash) && this.epochOutHash.equals(other.epochOutHash) && this.slotNumber === other.slotNumber && this.timestamp === other.timestamp && @@ -149,7 +153,7 @@ export class CheckpointHeader { this.lastArchiveRoot, this.blockHeadersHash, this.blobsHash, - this.inHash, + this.inboxRollingHash, this.epochOutHash, new Fr(this.slotNumber), bigintToUInt64BE(this.timestamp), @@ -170,7 +174,7 @@ export class CheckpointHeader { lastArchiveRoot: Fr.ZERO, blockHeadersHash: Fr.ZERO, blobsHash: Fr.ZERO, - inHash: Fr.ZERO, + inboxRollingHash: Fr.ZERO, epochOutHash: Fr.ZERO, slotNumber: SlotNumber.ZERO, timestamp: 0n, @@ -188,7 +192,7 @@ export class CheckpointHeader { lastArchiveRoot: Fr.random(), blockHeadersHash: Fr.random(), blobsHash: Fr.random(), - inHash: Fr.random(), + inboxRollingHash: Fr.random(), epochOutHash: Fr.random(), slotNumber: SlotNumber(Math.floor(Math.random() * 1000) + 1), timestamp: BigInt(Math.floor(Date.now() / 1000)), @@ -206,7 +210,7 @@ export class CheckpointHeader { this.lastArchiveRoot.isZero() && this.blockHeadersHash.isZero() && this.blobsHash.isZero() && - this.inHash.isZero() && + this.inboxRollingHash.isZero() && this.epochOutHash.isZero() && this.slotNumber === 0 && this.timestamp === 0n && @@ -235,7 +239,7 @@ export class CheckpointHeader { Fr.fromString(header.lastArchiveRoot), Fr.fromString(header.blockHeadersHash), Fr.fromString(header.blobsHash), - Fr.fromString(header.inHash), + Fr.fromString(header.inboxRollingHash), Fr.fromString(header.outHash), SlotNumber.fromBigInt(header.slotNumber), header.timestamp, @@ -260,7 +264,7 @@ export class CheckpointHeader { lastArchiveRoot: this.lastArchiveRoot.toString(), blockHeadersHash: this.blockHeadersHash.toString(), blobsHash: this.blobsHash.toString(), - inHash: this.inHash.toString(), + inboxRollingHash: this.inboxRollingHash.toString(), outHash: this.epochOutHash.toString(), slotNumber: BigInt(this.slotNumber), timestamp: this.timestamp, @@ -280,7 +284,7 @@ export class CheckpointHeader { lastArchive: this.lastArchiveRoot.toString(), blockHeadersHash: this.blockHeadersHash.toString(), blobsHash: this.blobsHash.toString(), - inHash: this.inHash.toString(), + inboxRollingHash: this.inboxRollingHash.toString(), epochOutHash: this.epochOutHash.toString(), slotNumber: this.slotNumber, timestamp: this.timestamp, @@ -297,7 +301,7 @@ export class CheckpointHeader { lastArchiveRoot: ${this.lastArchiveRoot.toString()}, blockHeadersHash: ${this.blockHeadersHash.toString()}, blobsHash: ${inspect(this.blobsHash)}, - inHash: ${inspect(this.inHash)}, + inboxRollingHash: ${inspect(this.inboxRollingHash)}, epochOutHash: ${inspect(this.epochOutHash)}, slotNumber: ${this.slotNumber}, timestamp: ${this.timestamp}, diff --git a/yarn-project/stdlib/src/rollup/checkpoint_rollup_public_inputs.ts b/yarn-project/stdlib/src/rollup/checkpoint_rollup_public_inputs.ts index dc3049babbe8..3ec8bfdbc31c 100644 --- a/yarn-project/stdlib/src/rollup/checkpoint_rollup_public_inputs.ts +++ b/yarn-project/stdlib/src/rollup/checkpoint_rollup_public_inputs.ts @@ -35,6 +35,15 @@ export class CheckpointRollupPublicInputs { * The out hash tree snapshot after applying this checkpoint range. */ public newOutHash: AppendOnlyTreeSnapshot, + /** + * Inbox rolling hash before consuming this checkpoint range's messages. + */ + public startInboxRollingHash: Fr, + /** + * Inbox rolling hash after consuming this checkpoint range's messages (the end value lands in the checkpoint + * header). Checkpoint merges assert `right.start == left.end` for chain continuity. + */ + public endInboxRollingHash: Fr, /** * The hashes of the headers of the constituent checkpoints. */ @@ -65,6 +74,8 @@ export class CheckpointRollupPublicInputs { reader.readObject(AppendOnlyTreeSnapshot), reader.readObject(AppendOnlyTreeSnapshot), reader.readObject(AppendOnlyTreeSnapshot), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), reader.readArray(MAX_CHECKPOINTS_PER_EPOCH, Fr), reader.readArray(MAX_CHECKPOINTS_PER_EPOCH, FeeRecipient), reader.readObject(BlobAccumulator), @@ -80,6 +91,8 @@ export class CheckpointRollupPublicInputs { this.newArchive, this.previousOutHash, this.newOutHash, + this.startInboxRollingHash, + this.endInboxRollingHash, this.checkpointHeaderHashes, this.fees, this.startBlobAccumulator, @@ -108,6 +121,8 @@ export class CheckpointRollupPublicInputs { newArchiveRoot: this.newArchive.root.toString(), previousOutHashRoot: this.previousOutHash.root.toString(), newOutHashRoot: this.newOutHash.root.toString(), + startInboxRollingHash: this.startInboxRollingHash.toString(), + endInboxRollingHash: this.endInboxRollingHash.toString(), }; } diff --git a/yarn-project/stdlib/src/rollup/checkpoint_root_rollup_private_inputs.ts b/yarn-project/stdlib/src/rollup/checkpoint_root_rollup_private_inputs.ts index bb15e9110fb0..73230264205f 100644 --- a/yarn-project/stdlib/src/rollup/checkpoint_root_rollup_private_inputs.ts +++ b/yarn-project/stdlib/src/rollup/checkpoint_root_rollup_private_inputs.ts @@ -7,7 +7,8 @@ import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/s import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import type { FieldsOf } from '@aztec/foundation/types'; -import { ProofData, type RollupHonkProofData } from '../proofs/proof_data.js'; +import { ParityPublicInputs } from '../parity/parity_public_inputs.js'; +import { ProofData, type RollupHonkProofData, type UltraHonkProofData } from '../proofs/proof_data.js'; import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js'; import { BlockHeader } from '../tx/block_header.js'; import { BlockRollupPublicInputs } from './block_rollup_public_inputs.js'; @@ -117,6 +118,11 @@ export class CheckpointRootRollupPrivateInputs { RollupHonkProofData, RollupHonkProofData, ], + /** + * Inbox parity proof over the checkpoint's L1-to-L2 messages: it commits to the checkpoint's + * message list, and its message sponge is checked against the blocks' accumulated one. + */ + public inboxParity: UltraHonkProofData, public hints: CheckpointRootRollupHints, ) {} @@ -125,7 +131,7 @@ export class CheckpointRootRollupPrivateInputs { } static getFields(fields: FieldsOf) { - return [fields.previousRollups, fields.hints] as const; + return [fields.previousRollups, fields.inboxParity, fields.hints] as const; } toBuffer() { @@ -136,6 +142,7 @@ export class CheckpointRootRollupPrivateInputs { const reader = BufferReader.asReader(buffer); return new CheckpointRootRollupPrivateInputs( [ProofData.fromBuffer(reader, BlockRollupPublicInputs), ProofData.fromBuffer(reader, BlockRollupPublicInputs)], + ProofData.fromBuffer(reader, ParityPublicInputs), CheckpointRootRollupHints.fromBuffer(reader), ); } @@ -160,6 +167,11 @@ export class CheckpointRootRollupPrivateInputs { export class CheckpointRootSingleBlockRollupPrivateInputs { constructor( public previousRollup: RollupHonkProofData, + /** + * Inbox parity proof over the checkpoint's L1-to-L2 messages: it commits to the checkpoint's + * message list, and its message sponge is checked against the block's accumulated one. + */ + public inboxParity: UltraHonkProofData, public hints: CheckpointRootRollupHints, ) {} @@ -170,7 +182,7 @@ export class CheckpointRootSingleBlockRollupPrivateInputs { } static getFields(fields: FieldsOf) { - return [fields.previousRollup, fields.hints] as const; + return [fields.previousRollup, fields.inboxParity, fields.hints] as const; } toBuffer() { @@ -181,6 +193,7 @@ export class CheckpointRootSingleBlockRollupPrivateInputs { const reader = BufferReader.asReader(buffer); return new CheckpointRootSingleBlockRollupPrivateInputs( ProofData.fromBuffer(reader, BlockRollupPublicInputs), + ProofData.fromBuffer(reader, ParityPublicInputs), CheckpointRootRollupHints.fromBuffer(reader), ); } diff --git a/yarn-project/stdlib/src/rollup/root_rollup_public_inputs.ts b/yarn-project/stdlib/src/rollup/root_rollup_public_inputs.ts index 9c362ccd9e59..9851203e45d9 100644 --- a/yarn-project/stdlib/src/rollup/root_rollup_public_inputs.ts +++ b/yarn-project/stdlib/src/rollup/root_rollup_public_inputs.ts @@ -26,6 +26,10 @@ export class RootRollupPublicInputs { * The out hash of the first checkpoint in the epoch is inserted at index 0, the second at index 1, and so on. */ public outHash: Fr, + /** Inbox rolling hash before the epoch's first checkpoint's messages. */ + public previousInboxRollingHash: Fr, + /** Inbox rolling hash after the epoch's last checkpoint's messages. */ + public endInboxRollingHash: Fr, /** Hashes of checkpoint headers for this rollup. */ public checkpointHeaderHashes: Tuple, public fees: Tuple, @@ -38,6 +42,8 @@ export class RootRollupPublicInputs { fields.previousArchiveRoot, fields.endArchiveRoot, fields.outHash, + fields.previousInboxRollingHash, + fields.endInboxRollingHash, fields.checkpointHeaderHashes, fields.fees, fields.constants, @@ -65,6 +71,8 @@ export class RootRollupPublicInputs { public static fromBuffer(buffer: Buffer | BufferReader): RootRollupPublicInputs { const reader = BufferReader.asReader(buffer); return new RootRollupPublicInputs( + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader), @@ -96,6 +104,8 @@ export class RootRollupPublicInputs { /** Creates a random instance. Used for testing only - will not prove/verify. */ static random() { return new RootRollupPublicInputs( + Fr.random(), + Fr.random(), Fr.random(), Fr.random(), Fr.random(), diff --git a/yarn-project/stdlib/src/stats/stats.ts b/yarn-project/stdlib/src/stats/stats.ts index cc79352f8bd7..a1816ec6e966 100644 --- a/yarn-project/stdlib/src/stats/stats.ts +++ b/yarn-project/stdlib/src/stats/stats.ts @@ -101,8 +101,9 @@ export type ClientCircuitName = | 'app-circuit'; export type ServerCircuitName = - | 'parity-base' - | 'parity-root' + | 'inbox-parity-64' + | 'inbox-parity-256' + | 'inbox-parity-1024' | 'chonk-verifier-public' | 'rollup-tx-base-private' | 'rollup-tx-base-public' @@ -112,6 +113,7 @@ export type ServerCircuitName = | 'rollup-block-root-first-empty-tx' | 'rollup-block-root' | 'rollup-block-root-single-tx' + | 'rollup-block-root-msgs-only' | 'rollup-block-merge' | 'rollup-checkpoint-root' | 'rollup-checkpoint-root-single-block' diff --git a/yarn-project/stdlib/src/tests/factories.ts b/yarn-project/stdlib/src/tests/factories.ts index 5cff56878429..20b8ca8a0af0 100644 --- a/yarn-project/stdlib/src/tests/factories.ts +++ b/yarn-project/stdlib/src/tests/factories.ts @@ -9,12 +9,15 @@ import { AVM_V2_PROOF_LENGTH_IN_FIELDS, CHONK_PROOF_LENGTH, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, - L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, + INBOX_PARITY_SIZE_SMALL, + L1_TO_L2_MSG_TREE_HEIGHT, MAX_CHECKPOINTS_PER_EPOCH, MAX_CONTRACT_CLASS_LOGS_PER_TX, MAX_ENQUEUED_CALLS_PER_CALL, MAX_ENQUEUED_CALLS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_CALL, + MAX_L1_TO_L2_MSGS_PER_BLOCK, + MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_CALL, @@ -34,9 +37,6 @@ import { NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - NUM_BASE_PARITY_PER_ROOT_PARITY, - NUM_MSGS_PER_BASE_PARITY, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_DATA_TREE_HEIGHT, RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, @@ -129,10 +129,11 @@ import { ContractClassLog, ContractClassLogFields } from '../logs/index.js'; import type { LogResult } from '../logs/log_result.js'; import { PrivateLog } from '../logs/private_log.js'; import { FlatPublicLogs, PublicLog } from '../logs/public_log.js'; +import { L1ToL2MessageBundle } from '../messaging/l1_to_l2_message_bundle.js'; +import { L1ToL2MessageSponge } from '../messaging/l1_to_l2_message_sponge.js'; import { CountedL2ToL1Message, L2ToL1Message, ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js'; -import { ParityBasePrivateInputs } from '../parity/parity_base_private_inputs.js'; +import { InboxParityPrivateInputs } from '../parity/inbox_parity_private_inputs.js'; import { ParityPublicInputs } from '../parity/parity_public_inputs.js'; -import { ParityRootPrivateInputs } from '../parity/parity_root_private_inputs.js'; import { ProofData, ProofDataForFixedVk } from '../proofs/index.js'; import { Proof } from '../proofs/proof.js'; import { makeRecursiveProof } from '../proofs/recursive_proof.js'; @@ -788,13 +789,19 @@ export function makeBlockRollupPublicInputs(seed = 0): BlockRollupPublicInputs { makeSpongeBlob(seed + 0x700), BigInt(seed + 0x800), fr(seed + 0x820), - fr(seed + 0x830), + (seed & 1) === 0, + makeL1ToL2MessageSponge(seed + 0x835), + makeL1ToL2MessageSponge(seed + 0x838), fr(seed + 0x840), fr(seed + 0x850), fr(seed + 0x860), ); } +export function makeL1ToL2MessageSponge(seed = 0): L1ToL2MessageSponge { + return new L1ToL2MessageSponge(makeSpongeBlob(seed).sponge, seed % (INBOX_PARITY_SIZE_SMALL + 1)); +} + export function makeCheckpointRollupPublicInputs(seed = 0) { return new CheckpointRollupPublicInputs( makeEpochConstantData(seed), @@ -802,6 +809,8 @@ export function makeCheckpointRollupPublicInputs(seed = 0) { makeAppendOnlyTreeSnapshot(seed + 0x200), makeAppendOnlyTreeSnapshot(seed + 0x300), makeAppendOnlyTreeSnapshot(seed + 0x350), + fr(seed + 0x360), + fr(seed + 0x370), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => fr(seed), 0x400), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => makeFeeRecipient(seed), 0x500), makeBlobAccumulator(seed + 0x600), @@ -812,27 +821,31 @@ export function makeCheckpointRollupPublicInputs(seed = 0) { export function makeParityPublicInputs(seed = 0): ParityPublicInputs { return new ParityPublicInputs( - new Fr(BigInt(seed + 0x200)), - new Fr(BigInt(seed + 0x300)), new Fr(BigInt(seed + 0x400)), new Fr(BigInt(seed + 0x500)), + makeL1ToL2MessageSponge(seed + 0x550), + makeL1ToL2MessageSponge(seed + 0x580), + seed + 0x600, + new Fr(BigInt(seed + 0x700)), + new Fr(BigInt(seed + 0x800)), ); } -export function makeParityBasePrivateInputs(seed = 0): ParityBasePrivateInputs { - return new ParityBasePrivateInputs( - makeTuple(NUM_MSGS_PER_BASE_PARITY, fr, seed + 0x3000), +export function makeInboxParityPrivateInputs(seed = 0): InboxParityPrivateInputs { + const size = INBOX_PARITY_SIZE_SMALL; + const numMsgs = seed % (size + 1); + const messages = Array.from({ length: size }, (_, i) => (i < numMsgs ? fr(i + seed + 0x3000) : Fr.ZERO)); + return new InboxParityPrivateInputs( + size, + messages, + numMsgs, + new Fr(seed + 0x3500), + makeL1ToL2MessageSponge(seed + 0x3800), new Fr(seed + 0x4000), new Fr(seed + 0x5000), ); } -export function makeParityRootPrivateInputs(seed = 0) { - return new ParityRootPrivateInputs( - makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, () => makeProofData(seed, makeParityPublicInputs)), - ); -} - /** * Makes root rollup public inputs. * @param seed - The seed to use for generating the root rollup public inputs. @@ -844,6 +857,8 @@ export function makeRootRollupPublicInputs(seed = 0): RootRollupPublicInputs { fr(seed + 0x100), fr(seed + 0x200), fr(seed + 0x300), + fr(seed + 0x320), + fr(seed + 0x340), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => fr(seed), 0x400), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => makeFeeRecipient(seed), 0x500), makeEpochConstantData(seed + 0x600), @@ -871,7 +886,7 @@ export function makeCheckpointHeader(seed = 0, overrides: Partial => { const blockHeader = options?.blockHeader ?? makeBlockHeader(1); const indexWithinCheckpoint = options?.indexWithinCheckpoint ?? IndexWithinCheckpoint(0); - const inHash = options?.inHash ?? Fr.random(); const archiveRoot = options?.archiveRoot ?? Fr.random(); const txHashes = options?.txHashes ?? [0, 1, 2, 3, 4, 5].map(() => TxHash.random()); const txs = options?.txs; const signer = options?.signer ?? Secp256k1Signer.random(); const signatureContext = options?.signatureContext ?? TEST_COORDINATION_SIGNATURE_CONTEXT; + const bucketRef = options?.bucketRef; return BlockProposal.createProposalFromSigner( blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - inHash, archiveRoot, txHashes, txs, signatureContext, (typedData, _context) => Promise.resolve(signTypedData(signer, typedData)), (typedData, _context) => Promise.resolve(signTypedData(signer, typedData)), + bucketRef, ); }; @@ -628,12 +627,12 @@ export const makeCheckpointProposal = async (options?: MakeCheckpointProposalOpt ? await makeBlockProposal({ blockHeader: options.lastBlock.blockHeader, indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4), - inHash: checkpointHeader.inHash, archiveRoot, txHashes: options.lastBlock.txHashes, txs: options.lastBlock.txs, signer, signatureContext, + bucketRef: options.lastBlock.bucketRef, }) : undefined; diff --git a/yarn-project/stdlib/src/tx/state_reference.ts b/yarn-project/stdlib/src/tx/state_reference.ts index 79a59204c7ac..184b6a89c27f 100644 --- a/yarn-project/stdlib/src/tx/state_reference.ts +++ b/yarn-project/stdlib/src/tx/state_reference.ts @@ -1,9 +1,4 @@ -import { - MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - STATE_REFERENCE_LENGTH, -} from '@aztec/constants'; +import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, STATE_REFERENCE_LENGTH } from '@aztec/constants'; import type { Fr } from '@aztec/foundation/curves/bn254'; import { BufferReader, BufferSink, FieldReader, serializeToSink } from '@aztec/foundation/serialize'; import type { FieldsOf } from '@aztec/foundation/types'; @@ -106,14 +101,12 @@ export class StateReference { } /** - * Validates the trees in world state have the expected number of leaves (multiple of number of insertions per tx) + * Validates the partial-state trees have the expected number of leaves (multiple of number of insertions per tx). + * + * The L1-to-L2 message tree is not checked: it grows by real message counts at compact (unaligned) + * indices, so its next-available leaf index is no longer a multiple of any per-block subtree size. */ public validate() { - if (this.l1ToL2MessageTree.nextAvailableLeafIndex % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP !== 0) { - throw new Error( - `Invalid L1 to L2 message tree next available leaf index ${this.l1ToL2MessageTree.nextAvailableLeafIndex} (must be a multiple of ${NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP})`, - ); - } if (this.partial.noteHashTree.nextAvailableLeafIndex % MAX_NOTE_HASHES_PER_TX !== 0) { throw new Error( `Invalid note hash tree next available leaf index ${this.partial.noteHashTree.nextAvailableLeafIndex} (must be a multiple of ${MAX_NOTE_HASHES_PER_TX})`, diff --git a/yarn-project/txe/esbuild/stubs/archiver_stub.ts b/yarn-project/txe/esbuild/stubs/archiver_stub.ts index 163b03df5cac..b3471216c346 100644 --- a/yarn-project/txe/esbuild/stubs/archiver_stub.ts +++ b/yarn-project/txe/esbuild/stubs/archiver_stub.ts @@ -8,10 +8,3 @@ export { createArchiverDataStores } from '../../../archiver/dest/store/data_stor export function createArchiver(..._args: unknown[]): never { throwStub('createArchiver'); } - -export class L1ToL2MessagesNotReadyError extends Error { - constructor(message?: string) { - super(message); - this.name = 'L1ToL2MessagesNotReadyError'; - } -} diff --git a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts index 21af3d40f03c..327895abe241 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts @@ -1,8 +1,4 @@ -import { - CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, - MAX_PRIVATE_LOGS_PER_TX, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, -} from '@aztec/constants'; +import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { Schnorr } from '@aztec/foundation/crypto/schnorr'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -672,8 +668,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl txEffect.txHash = new TxHash(new Fr(blockNumber)); - const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero); - await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); + // TXE blocks carry no L1-to-L2 messages, so the message tree is left unadvanced. const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]); @@ -837,8 +832,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl txEffect.txHash = new TxHash(new Fr(blockNumber)); - const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero); - await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); + // TXE blocks carry no L1-to-L2 messages, so the message tree is left unadvanced. const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]); diff --git a/yarn-project/txe/src/state_machine/index.ts b/yarn-project/txe/src/state_machine/index.ts index 4f724f3f8130..94caba792da6 100644 --- a/yarn-project/txe/src/state_machine/index.ts +++ b/yarn-project/txe/src/state_machine/index.ts @@ -114,7 +114,7 @@ export class TXEStateMachine { block.archive, CheckpointHeader.from({ lastArchiveRoot: block.header.lastArchive.root, - inHash: Fr.ZERO, + inboxRollingHash: Fr.ZERO, blobsHash: Fr.ZERO, blockHeadersHash: Fr.ZERO, epochOutHash: Fr.ZERO, diff --git a/yarn-project/txe/src/state_machine/synchronizer.ts b/yarn-project/txe/src/state_machine/synchronizer.ts index b4d44ebc88bf..78dabcc2e81d 100644 --- a/yarn-project/txe/src/state_machine/synchronizer.ts +++ b/yarn-project/txe/src/state_machine/synchronizer.ts @@ -1,6 +1,4 @@ -import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; -import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import { AvmSimulatorPool } from '@aztec/simulator/server'; import type { BlockHash, L2Block } from '@aztec/stdlib/block'; @@ -35,10 +33,8 @@ export class TXESynchronizer implements WorldStateSynchronizer { } public async handleL2Block(block: L2Block, l1ToL2Messages: Fr[] = []) { - await this.nativeWorldStateService.handleL2BlockAndMessages( - block, - padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), - ); + // Append the block's real message leaves unpadded at compact indices. + await this.nativeWorldStateService.handleL2BlockAndMessages(block, l1ToL2Messages); this.blockNumber = block.header.globalVariables.blockNumber; } diff --git a/yarn-project/txe/src/utils/block_creation.ts b/yarn-project/txe/src/utils/block_creation.ts index dce7c90e1216..101139363fa6 100644 --- a/yarn-project/txe/src/utils/block_creation.ts +++ b/yarn-project/txe/src/utils/block_creation.ts @@ -1,9 +1,4 @@ -import { - MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX, - NULLIFIER_SUBTREE_HEIGHT, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, -} from '@aztec/constants'; +import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT } from '@aztec/constants'; import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -36,10 +31,8 @@ export async function insertTxEffectIntoWorldTrees( NULLIFIER_SUBTREE_HEIGHT, ); - await worldTrees.appendLeaves( - MerkleTreeId.L1_TO_L2_MESSAGE_TREE, - padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), - ); + // Append the block's real message leaves unpadded at compact indices. + await worldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); // We do not need to add public data writes because we apply them as we go. } diff --git a/yarn-project/validator-client/README.md b/yarn-project/validator-client/README.md index 06afb9a0328d..4d40defd785b 100644 --- a/yarn-project/validator-client/README.md +++ b/yarn-project/validator-client/README.md @@ -21,7 +21,7 @@ A `BlockProposal` is broadcast by the proposer for each block **except the last BlockProposal { blockHeader // Per-block header with global variables indexWithinCheckpoint // 0, 1, 2, ... position within checkpoint - inHash // L1-to-L2 messages hash (constant across checkpoint) + bucketRef? // Inbox bucket reference for the block's L1-to-L2 message bundle archive // Archive root after this block txHashes // Transaction hashes in order signature // Proposer's signature @@ -50,7 +50,7 @@ CheckpointProposal { } ``` -The `checkpointHeader` contains aggregated data: `blockHeadersHash` (hash of all block headers), `contentCommitment` (blobsHash, inHash, outHash), and shared global variables. +The `checkpointHeader` contains aggregated data: `blockHeadersHash` (hash of all block headers), `contentCommitment` (blobsHash, inboxRollingHash, outHash), and shared global variables. ### Checkpoint Attestations @@ -75,7 +75,7 @@ These rules must always hold: 1. **Attestations are checkpoint-only**: Validators never attest to individual `BlockProposal`s 2. **Global variables match within checkpoint**: All blocks within the same checkpoint must have identical global variables (except `blockNumber`), which includes the slot number -3. **inHash is constant**: All blocks in a checkpoint share the same L1-to-L2 messages hash +3. **Inbox consumption moves forward**: Each block's bucket reference consumes at or past its parent block's Inbox position (AZIP-22 Fast Inbox) 4. **Sequential indexWithinCheckpoint**: Block N must have `indexWithinCheckpoint = parent.indexWithinCheckpoint + 1` 5. **One proposer per slot**: Each slot has exactly one designated proposer. Sending multiple proposals for the same position (slot, indexWithinCheckpoint) with different content is equivocation and slashable 6. **One attestation per slot**: Validators should only attest to one checkpoint per slot. Attesting to different proposals (different archives) for the same slot is equivocation and slashable @@ -93,7 +93,7 @@ When a `BlockProposal` is received via P2P, the `BlockProposalHandler` performs: 4. Find parent block by archive root (wait/retry if not synced) 5. Compute checkpoint number from parent 6. If indexWithinCheckpoint > 0, then validate global variables match parent (chainId, version, slotNumber, timestamp, coinbase, feeRecipient, gasFees) -7. Verify inHash matches computed from L1-to-L2 messages +7. Run the streaming Inbox acceptance checks on the proposal's bucket reference and derive the block's L1-to-L2 message bundle (AZIP-22 Fast Inbox) 8. Collect transactions from pool/network/proposal 9. Re-execute transactions (if enabled) 10. Compare re-execution result with proposal diff --git a/yarn-project/validator-client/src/checkpoint_builder.test.ts b/yarn-project/validator-client/src/checkpoint_builder.test.ts index e0fe03bce5d1..1d140f683bc3 100644 --- a/yarn-project/validator-client/src/checkpoint_builder.test.ts +++ b/yarn-project/validator-client/src/checkpoint_builder.test.ts @@ -298,8 +298,8 @@ describe('CheckpointBuilder', () => { describe('capLimitsByCheckpointBudgets (validator mode)', () => { const totalBlobCapacity = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS; - const firstBlockEndOverhead = getNumBlockEndBlobFields(true); - const nonFirstBlockEndOverhead = getNumBlockEndBlobFields(false); + const firstBlockEndOverhead = getNumBlockEndBlobFields(); + const nonFirstBlockEndOverhead = getNumBlockEndBlobFields(); it('caps L2 gas by remaining checkpoint mana', () => { const rollupManaLimit = 1_000_000; diff --git a/yarn-project/validator-client/src/checkpoint_builder.ts b/yarn-project/validator-client/src/checkpoint_builder.ts index 14d1bb2130c7..7f7c10dddbaa 100644 --- a/yarn-project/validator-client/src/checkpoint_builder.ts +++ b/yarn-project/validator-client/src/checkpoint_builder.ts @@ -131,10 +131,15 @@ export class CheckpointBuilder implements ICheckpointBlockBuilder { // Commit the fork checkpoint await forkCheckpoint.commit(); - // Add block to checkpoint - const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, { - expectedEndState: opts.expectedEndState, - }); + // Add block to checkpoint, inserting this block's streaming L1-to-L2 message bundle (if any) into the fork. + const { block } = await this.checkpointBuilder.addBlock( + globalVariables, + processedTxs, + opts.l1ToL2Messages ?? [], + { + expectedEndState: opts.expectedEndState, + }, + ); this.contractsDB.commitCheckpoint(); @@ -203,8 +208,7 @@ export class CheckpointBuilder implements ICheckpointBlockBuilder { // Remaining blob fields (block blob fields include both tx data and block-end overhead) const usedBlobFields = sum(existingBlocks.map(b => b.toBlobFields().length)); const totalBlobCapacity = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS; - const isFirstBlock = existingBlocks.length === 0; - const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock); + const blockEndOverhead = getNumBlockEndBlobFields(); const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead; // Remaining txs @@ -317,8 +321,8 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, - l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, fork: MerkleTreeWriteOperations, bindings?: LoggerBindings, ): Promise { @@ -327,18 +331,17 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { this.log.verbose(`Building new checkpoint ${checkpointNumber}`, { checkpointNumber, - msgCount: l1ToL2Messages.length, initialStateReference: stateReference.toInspect(), initialArchiveRoot: bufferToHex(archiveTree.root), constants, feeAssetPriceModifier, }); - const lightweightBuilder = await LightweightCheckpointBuilder.startNewCheckpoint( + const lightweightBuilder = LightweightCheckpointBuilder.startNewCheckpoint( checkpointNumber, constants, - l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, bindings, feeAssetPriceModifier, @@ -359,6 +362,9 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { /** * Opens a checkpoint, either starting fresh or resuming from existing blocks. + * @param l1ToL2Messages - Messages the existing blocks already consumed, which seed the resumed checkpoint's + * rolling hash. Must be empty when starting fresh: a fresh checkpoint takes its messages per block, via + * `buildBlock`. */ async openCheckpoint( checkpointNumber: CheckpointNumber, @@ -366,6 +372,7 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, fork: MerkleTreeWriteOperations, existingBlocks: L2Block[] = [], bindings?: LoggerBindings, @@ -374,12 +381,18 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { const archiveTree = await fork.getTreeInfo(MerkleTreeId.ARCHIVE); if (existingBlocks.length === 0) { + if (l1ToL2Messages.length > 0) { + throw new Error( + `Cannot open checkpoint ${checkpointNumber} with ${l1ToL2Messages.length} messages and no existing blocks: ` + + `a fresh checkpoint consumes its messages per block`, + ); + } return this.startCheckpoint( checkpointNumber, constants, feeAssetPriceModifier, - l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, bindings, ); @@ -401,6 +414,7 @@ export class FullNodeCheckpointsBuilder implements ICheckpointsBuilder { feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, existingBlocks, bindings, diff --git a/yarn-project/validator-client/src/duties/validation_service.test.ts b/yarn-project/validator-client/src/duties/validation_service.test.ts index 1cecf73317ac..b631709247e5 100644 --- a/yarn-project/validator-client/src/duties/validation_service.test.ts +++ b/yarn-project/validator-client/src/duties/validation_service.test.ts @@ -34,14 +34,12 @@ describe('ValidationService', () => { const txs = await Promise.all([Tx.random(), Tx.random()]); const blockHeader = makeBlockHeader(1); const indexWithinCheckpoint = IndexWithinCheckpoint(0); - const inHash = Fr.random(); const archive = Fr.random(); const proposal = await service.createBlockProposal( blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - inHash, archive, txs, addresses[0], @@ -56,14 +54,12 @@ describe('ValidationService', () => { const txs = await Promise.all([Tx.random(), Tx.random()]); const blockHeader = makeBlockHeader(1); const indexWithinCheckpoint = IndexWithinCheckpoint(0); - const inHash = Fr.random(); const archive = Fr.random(); const proposal = await service.createBlockProposal( blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - inHash, archive, txs, addresses[0], @@ -89,13 +85,12 @@ describe('ValidationService', () => { const archive = Fr.random(); const checkpointHeader = makeCheckpointHeader(1); - // Create the block proposal first (as the sequencer would), using the checkpoint's inHash - // so that getSender() can verify the block proposal sender matches + // Create the block proposal first (as the sequencer would) so that getSender() can verify the block proposal + // sender matches. const blockProposal = await service.createBlockProposal( blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - checkpointHeader.inHash, archive, txs, addresses[0], diff --git a/yarn-project/validator-client/src/duties/validation_service.ts b/yarn-project/validator-client/src/duties/validation_service.ts index 5fd753a7bdce..c6c7d1143def 100644 --- a/yarn-project/validator-client/src/duties/validation_service.ts +++ b/yarn-project/validator-client/src/duties/validation_service.ts @@ -4,6 +4,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address'; import type { Signature } from '@aztec/foundation/eth-signature'; import { createLogger } from '@aztec/foundation/log'; import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block'; +import type { InboxBucketRef } from '@aztec/stdlib/messaging'; import { BlockProposal, type BlockProposalOptions, @@ -34,7 +35,6 @@ export class ValidationService { * * @param blockHeader - The block header * @param blockIndexWithinCheckpoint - The block index within checkpoint for HA signing context - * @param inHash - Hash of L1 to L2 messages for this checkpoint * @param archive - The archive of the current block * @param txs - Ordered list of transactions (Tx[]) * @param proposerAttesterAddress - The address of the proposer/attester, or undefined @@ -48,11 +48,11 @@ export class ValidationService { blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, blockIndexWithinCheckpoint: IndexWithinCheckpoint, - inHash: Fr, archive: Fr, txs: Tx[], proposerAttesterAddress: EthAddress | undefined, options: BlockProposalOptions, + bucketRef?: InboxBucketRef, ): Promise { // For testing: change the new archive to trigger state_mismatch validation failure if (options.broadcastInvalidBlockProposal) { @@ -75,13 +75,13 @@ export class ValidationService { blockHeader, checkpointNumber, blockIndexWithinCheckpoint, - inHash, archive, txs.map(tx => tx.getTxHash()), options.publishFullTxs ? txs : undefined, this.signatureContext, payloadSigner, txsSigner, + bucketRef, ); } diff --git a/yarn-project/validator-client/src/metrics.ts b/yarn-project/validator-client/src/metrics.ts index 8aad926ca859..401584c6a5f7 100644 --- a/yarn-project/validator-client/src/metrics.ts +++ b/yarn-project/validator-client/src/metrics.ts @@ -43,13 +43,7 @@ export class ValidatorMetrics { meter, Metrics.VALIDATOR_ATTESTATION_FAILED_BAD_PROPOSAL_COUNT, { - [Attributes.ERROR_TYPE]: [ - 'invalid_proposal', - 'state_mismatch', - 'failed_txs', - 'in_hash_mismatch', - 'parent_block_wrong_slot', - ], + [Attributes.ERROR_TYPE]: ['invalid_proposal', 'state_mismatch', 'failed_txs', 'parent_block_wrong_slot'], [Attributes.IS_COMMITTEE_MEMBER]: [true, false], }, ); diff --git a/yarn-project/validator-client/src/proposal_handler.test.ts b/yarn-project/validator-client/src/proposal_handler.test.ts index f3a414719329..fadffd8fb907 100644 --- a/yarn-project/validator-client/src/proposal_handler.test.ts +++ b/yarn-project/validator-client/src/proposal_handler.test.ts @@ -15,8 +15,8 @@ import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdl import { type Checkpoint, CheckpointReexecutionTracker, type ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers'; import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; -import { accumulateCheckpointOutHashes } from '@aztec/stdlib/messaging'; +import type { InboxBucket, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import { InboxBucketRef, accumulateCheckpointOutHashes } from '@aztec/stdlib/messaging'; import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, @@ -66,7 +66,6 @@ describe('ProposalHandler checkpoint validation', () => { blockSource.syncImmediate.mockResolvedValue(undefined); l1ToL2MessageSource = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); checkpointsBuilder = mock(); checkpointsBuilder.getConfig.mockReturnValue({ @@ -503,7 +502,10 @@ describe('ProposalHandler checkpoint validation', () => { archive: new AppendOnlyTreeSnapshot(archiveRoot, 1), number: 1, checkpointNumber: CheckpointNumber(1), - header: { globalVariables: GlobalVariables.empty({ slotNumber: SlotNumber(1) }) }, + header: { + globalVariables: GlobalVariables.empty({ slotNumber: SlotNumber(1) }), + state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } }, + }, } as unknown as L2Block; blockSource.getBlockData.mockResolvedValue({ header: makeBlockHeader() } as BlockData); @@ -798,4 +800,214 @@ describe('ProposalHandler checkpoint validation', () => { }); }); }); + + // Streaming Inbox: a block proposal's L1-to-L2 bundle is derived from its bucket reference and gated by the four + // acceptance checks, replacing the legacy per-checkpoint inHash comparison. + describe('handleBlockProposal streaming inbox checks', () => { + const bucket = (overrides: Partial = {}): InboxBucket => ({ + seq: 1n, + inboxRollingHash: new Fr(0xabc), + totalMsgCount: 2n, + timestamp: 100n, + msgCount: 2, + lastMessageIndex: 1n, + ...overrides, + }); + + /** Genesis-parent streaming block proposal at slot 1, with the handler wired to reach the streaming checks. */ + async function setupStreamingProposal(bucketRef: InboxBucketRef | undefined) { + const proposal = await makeBlockProposal({ + blockHeader: makeBlockHeader(1, { slotNumber: SlotNumber(1) }), + archiveRoot: Fr.random(), + txHashes: [], + bucketRef, + }); + blockSource.getGenesisValues.mockResolvedValue({ + genesisArchiveRoot: proposal.blockHeader.lastArchive.root, + } as any); + blockSource.getBlockData.mockResolvedValue(undefined); + + const blockProposalValidator = mock(); + blockProposalValidator.validate.mockResolvedValue({ result: 'accept' } as any); + const txProvider = mock(); + txProvider.getTxsForBlockProposal.mockResolvedValue({ txs: [], missingTxs: [] } as any); + + // Well past the 12s lag for a bucket opened at t=100. + dateProvider.setTime(1_000_000); + + const blockHandler = new ProposalHandler( + checkpointsBuilder, + mock(), + blockSource, + l1ToL2MessageSource, + txProvider, + blockProposalValidator, + epochCache, + consensusTimetable, + config, + mock(), + new CheckpointReexecutionTracker(), + metrics, + dateProvider, + ); + return { proposal, blockHandler }; + } + + it('rejects (without re-executing) when the referenced bucket is unknown', async () => { + const ref = new InboxBucketRef(1n, 100n, new Fr(0xabc)); + const { proposal, blockHandler } = await setupStreamingProposal(ref); + l1ToL2MessageSource.getInboxBucket.mockResolvedValue(undefined); + const reexecuteSpy = jest.spyOn(blockHandler, 'reexecuteTransactions'); + + const result = await blockHandler.handleBlockProposal(proposal, {} as any, true); + + expect(result).toEqual({ + isValid: false, + blockNumber: BlockNumber(INITIAL_L2_BLOCK_NUM), + reason: 'bucket_unknown', + }); + expect(reexecuteSpy).not.toHaveBeenCalled(); + }); + + it('rejects (without re-executing) when the resolved bucket hash disagrees with the reference', async () => { + const ref = new InboxBucketRef(1n, 100n, new Fr(0xdead)); + const { proposal, blockHandler } = await setupStreamingProposal(ref); + l1ToL2MessageSource.getInboxBucket.mockResolvedValue(bucket({ inboxRollingHash: new Fr(0xabc) })); + const reexecuteSpy = jest.spyOn(blockHandler, 'reexecuteTransactions'); + + const result = await blockHandler.handleBlockProposal(proposal, {} as any, true); + + expect(result).toEqual({ + isValid: false, + blockNumber: BlockNumber(INITIAL_L2_BLOCK_NUM), + reason: 'bucket_hash_mismatch', + }); + expect(reexecuteSpy).not.toHaveBeenCalled(); + }); + + it('re-executes with the bundle derived from the buckets when the checks pass', async () => { + const ref = new InboxBucketRef(1n, 100n, new Fr(0xabc)); + const { proposal, blockHandler } = await setupStreamingProposal(ref); + const derivedBundle = [new Fr(1000), new Fr(1001)]; + l1ToL2MessageSource.getInboxBucket.mockResolvedValue(bucket()); + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue( + bucket({ seq: 0n, totalMsgCount: 0n, msgCount: 0 }), + ); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue(derivedBundle); + const reexecuteSpy = jest + .spyOn(blockHandler, 'reexecuteTransactions') + .mockResolvedValue({ block: undefined } as any); + + const result = await blockHandler.handleBlockProposal(proposal, {} as any, true); + + expect(result.isValid).toBe(true); + // The block re-executes with the derived per-block bundle (streaming is the only path). + expect(reexecuteSpy).toHaveBeenCalledWith( + proposal, + BlockNumber(INITIAL_L2_BLOCK_NUM), + CheckpointNumber.INITIAL, + [], + derivedBundle, + expect.anything(), + expect.anything(), + ); + }); + }); + + // Streaming Inbox: the checkpoint handler enforces the last-block minimum-consumption (censorship) rule before + // attesting. + describe('checkpoint proposal last-block censorship', () => { + /** Two-block checkpoint at slot 10 whose last block consumed through leaf count `lastBlockTotal`. */ + function setupCensorshipMocks(lastBlockTotal: number) { + const archiveRoot = Fr.random(); + const blockWithLeafCount = (leafCount: number, archive: Fr, number: number) => + ({ + archive: new AppendOnlyTreeSnapshot(archive, number), + number, + checkpointNumber: CheckpointNumber(1), + header: { + globalVariables: GlobalVariables.empty({ slotNumber: SlotNumber(10) }), + state: { l1ToL2MessageTree: { nextAvailableLeafIndex: leafCount } }, + }, + }) as unknown as L2Block; + + blockSource.getBlockData.mockResolvedValue({ + header: makeBlockHeader(), + checkpointNumber: CheckpointNumber(1), + } as any); + blockSource.getBlocksForSlot.mockResolvedValue([ + blockWithLeafCount(0, Fr.random(), 1), + blockWithLeafCount(lastBlockTotal, archiveRoot, 2), + ]); + return { archiveRoot }; + } + + async function makeSlot10Proposal(archiveRoot: Fr) { + return ( + await makeCheckpointProposal({ + checkpointHeader: makeCheckpointHeader(0, { slotNumber: SlotNumber(10) }), + archiveRoot, + }) + ).toCore(); + } + + it('refuses to attest when a mandatory bucket (at or before the cutoff) is left unconsumed', async () => { + handler.updateConfig(config); + const { archiveRoot } = setupCensorshipMocks(2); + // cutoff(slot=10) with l1GenesisTime=0, slotDuration=24, lag=12 is (10-1)*24 - 12 = 204. + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue({ + seq: 1n, + totalMsgCount: 2n, + } as InboxBucket); + // The next (first unconsumed) bucket opened at t=100 <= cutoff 204 is mandatory and was left unconsumed. + l1ToL2MessageSource.getInboxBucket.mockResolvedValue({ + seq: 2n, + totalMsgCount: 5n, + timestamp: 100n, + } as InboxBucket); + + const result = await handler.handleCheckpointProposal(await makeSlot10Proposal(archiveRoot), proposalInfo); + + expect(result).toEqual({ + isValid: false, + reason: 'inbox_consumption_insufficient', + checkpointNumber: CheckpointNumber(1), + }); + }); + + it('does not reject on censorship when the first unconsumed bucket is past the cutoff', async () => { + handler.updateConfig(config); + const { archiveRoot } = setupCensorshipMocks(2); + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue({ + seq: 1n, + totalMsgCount: 2n, + } as InboxBucket); + // Next bucket opened at t=205 > cutoff 204: not mandatory, so the censorship check passes and validation + // proceeds past it to the checkpoint rebuild (which mismatches here, an unrelated reason). + l1ToL2MessageSource.getInboxBucket.mockResolvedValue({ + seq: 2n, + totalMsgCount: 5n, + timestamp: 205n, + } as InboxBucket); + checkpointsBuilder.getFork.mockResolvedValue({ [Symbol.asyncDispose]: jest.fn() } as any); + const mockBuilder = mock(); + mockBuilder.completeCheckpoint.mockResolvedValue({ + header: CheckpointHeader.empty(), + archive: new AppendOnlyTreeSnapshot(Fr.ZERO, 0), + getCheckpointOutHash: () => Fr.random(), + blocks: [], + number: CheckpointNumber(1), + } as unknown as Checkpoint); + checkpointsBuilder.openCheckpoint.mockResolvedValue(mockBuilder); + + const result = await handler.handleCheckpointProposal(await makeSlot10Proposal(archiveRoot), proposalInfo); + + // The censorship rule passed; the checkpoint is rejected later by the rebuild, not the consumption check. + expect(result).toEqual({ + isValid: false, + reason: 'checkpoint_header_mismatch', + checkpointNumber: CheckpointNumber(1), + }); + }); + }); }); diff --git a/yarn-project/validator-client/src/proposal_handler.ts b/yarn-project/validator-client/src/proposal_handler.ts index e1bec3a450f5..fe0037e5ba8f 100644 --- a/yarn-project/validator-client/src/proposal_handler.ts +++ b/yarn-project/validator-client/src/proposal_handler.ts @@ -1,7 +1,12 @@ import type { Archiver } from '@aztec/archiver'; import type { BlobClientInterface } from '@aztec/blob-client/client'; import { type Blob, encodeCheckpointBlobDataFromBlocks, getBlobsPerL1Block } from '@aztec/blob-lib'; -import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; +import { + INBOX_LAG_SECONDS, + INITIAL_L2_BLOCK_NUM, + MAX_L1_TO_L2_MSGS_PER_BLOCK, + MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, +} from '@aztec/constants'; import type { EpochCache } from '@aztec/epoch-cache'; import { validateFeeAssetPriceModifier } from '@aztec/ethereum/contracts'; import { @@ -22,7 +27,11 @@ import type { P2P, PeerId } from '@aztec/p2p'; import { BlockProposalValidator } from '@aztec/p2p/msg_validators'; import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; import type { CheckpointReexecutionTracker, ReexecutionOutcome } from '@aztec/stdlib/checkpoint'; -import { getPreviousCheckpointOutHashes, validateCheckpoint } from '@aztec/stdlib/checkpoint'; +import { + getPreviousCheckpointInboxRollingHash, + getPreviousCheckpointOutHashes, + validateCheckpoint, +} from '@aztec/stdlib/checkpoint'; import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas } from '@aztec/stdlib/gas'; import type { @@ -34,7 +43,8 @@ import type { import { type L1ToL2MessageSource, accumulateCheckpointOutHashes, - computeInHashFromL1ToL2Messages, + getInboxCutoffTimestamp, + isInboxConsumptionSufficient, } from '@aztec/stdlib/messaging'; import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p'; import type { ConsensusTimetable } from '@aztec/stdlib/timetable'; @@ -51,13 +61,19 @@ import { type TelemetryClient, type Tracer, getTelemetryClient } from '@aztec/te import type { FullNodeCheckpointsBuilder } from './checkpoint_builder.js'; import type { ValidatorMetrics } from './metrics.js'; +import { + type StreamingBlockCheckReason, + type StreamingBlockCheckResult, + checkStreamingBlockProposal, +} from './streaming_inbox_checks.js'; export type BlockProposalValidationFailureReason = | 'invalid_signature' | 'invalid_proposal' | 'parent_block_not_found' | 'parent_block_wrong_slot' - | 'in_hash_mismatch' + // Streaming Inbox per-block acceptance failures. + | StreamingBlockCheckReason | 'global_variables_mismatch' | 'block_number_already_exists' | 'txs_not_available' @@ -105,6 +121,8 @@ export type CheckpointProposalValidationFailureReason = | 'checkpoint_header_mismatch' | 'archive_mismatch' | 'out_hash_mismatch' + // Streaming Inbox last-block censorship failure. + | 'inbox_consumption_insufficient' | 'checkpoint_validation_failed'; /** @@ -130,6 +148,7 @@ const CHECKPOINT_VALIDATION_REASON_TO_OUTCOME: Record< checkpoint_header_mismatch: 'invalid', archive_mismatch: 'invalid', out_hash_mismatch: 'invalid', + inbox_consumption_insufficient: 'invalid', checkpoint_validation_failed: 'invalid', }; @@ -171,7 +190,6 @@ export const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT: BlockProposalValidation 'global_variables_mismatch', 'invalid_proposal', 'parent_block_wrong_slot', - 'in_hash_mismatch', ]; /** Checkpoint-proposal validation failures that constitute a slashable invalid-checkpoint offense. */ @@ -192,6 +210,9 @@ export const SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT: Record< ['last_block_archive_mismatch']: true, // disabled + // Streaming Inbox last-block censorship: kept out of slashing while the streaming path is new; L1 `propose` is the + // authoritative reject (Rollup__UnconsumedInboxMessages). + ['inbox_consumption_insufficient']: false, ['invalid_signature']: false, ['last_block_not_found']: false, ['block_fetch_error']: false, @@ -552,18 +573,18 @@ export class ProposalHandler { const checkpointNumber = checkpointResult.checkpointNumber; proposalInfo.checkpointNumber = checkpointNumber; - // Check that I have the same set of l1ToL2Messages as the proposal - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); - const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages); - const proposalInHash = proposal.inHash; - if (!computedInHash.equals(proposalInHash)) { - this.log.warn(`L1 to L2 messages in hash mismatch, skipping processing`, { - proposalInHash: proposalInHash.toString(), - computedInHash: computedInHash.toString(), + // Resolve this block's L1-to-L2 message bundle from its proposal bucket reference, gated by the four streaming + // acceptance checks. + const streamingResult = await this.runStreamingBlockChecks(proposal, blockNumber, parentBlock); + if (!streamingResult.accepted) { + this.log.warn(`Streaming Inbox block acceptance check failed, skipping processing`, { + reason: streamingResult.reason, + bucketRef: proposal.bucketRef?.toInspect(), ...proposalInfo, }); - return { isValid: false, blockNumber, reason: 'in_hash_mismatch' }; + return { isValid: false, blockNumber, reason: streamingResult.reason }; } + const l1ToL2Messages = streamingResult.bundle; // Check that all of the transactions in the proposal are available if (missingTxs.length > 0) { @@ -584,6 +605,12 @@ export class ProposalHandler { log: this.log, }); + const previousInboxRollingHash = await getPreviousCheckpointInboxRollingHash({ + blockSource: this.blockSource, + checkpointNumber, + log: this.log, + }); + // Try re-executing the transactions in the proposal if needed let reexecutionResult; try { @@ -595,6 +622,7 @@ export class ProposalHandler { txs, l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, ); } catch (error) { this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo); @@ -875,6 +903,121 @@ export class ProposalHandler { } } + /** + * Runs the streaming-Inbox per-block acceptance checks for a block proposal and returns the derived L1-to-L2 + * message bundle for re-execution, or a rejection reason. The parent block's consumed total and the checkpoint's + * starting total are derived from L1-to-L2 tree leaf counts; a parent whose count does not sit on a bucket boundary + * is rejected inside {@link checkStreamingBlockProposal}. + */ + private async runStreamingBlockChecks( + proposal: BlockProposal, + blockNumber: BlockNumber, + parentBlock: 'genesis' | BlockData, + ): Promise { + const parentTotalMsgCount = this.getConsumedMsgTotal(parentBlock); + const checkpointStartTotalMsgCount = await this.resolveCheckpointStartTotal( + blockNumber, + proposal.indexWithinCheckpoint, + parentTotalMsgCount, + ); + if (checkpointStartTotalMsgCount === undefined) { + // The block before the checkpoint's first block has not synced locally, so the per-checkpoint cap origin is + // unavailable: treat as an unknown local view. There is no bounded wait for the missing block yet. + return { accepted: false, reason: 'bucket_unknown' }; + } + const nowSeconds = BigInt(Math.floor(this.dateProvider.now() / 1000)); + return checkStreamingBlockProposal({ + messageSource: this.l1ToL2MessageSource, + bucketRef: proposal.bucketRef, + parentTotalMsgCount, + checkpointStartTotalMsgCount, + nowSeconds, + lagSeconds: INBOX_LAG_SECONDS, + perBlockCap: MAX_L1_TO_L2_MSGS_PER_BLOCK, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + }); + } + + /** A block's L1-to-L2 message tree leaf count: the cumulative Inbox message count it consumed through. */ + private blockLeafCount(block: BlockData | L2Block): bigint { + return BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); + } + + /** The cumulative Inbox message count consumed through a block: its L1-to-L2 tree leaf count (0 at genesis). */ + private getConsumedMsgTotal(block: 'genesis' | BlockData): bigint { + return block === 'genesis' ? 0n : this.blockLeafCount(block); + } + + /** + * The cumulative Inbox message count consumed as of the parent checkpoint (the per-checkpoint cap origin). For a + * checkpoint's first block this is the parent block's total; for a later block it is the leaf count of the block + * before the checkpoint's first block. Returns undefined when that block has not synced locally. + */ + private resolveCheckpointStartTotal( + blockNumber: BlockNumber, + indexWithinCheckpoint: number, + parentTotalMsgCount: bigint, + ): Promise { + return indexWithinCheckpoint === 0 + ? Promise.resolve(parentTotalMsgCount) + : this.getPreBlockConsumedTotal(blockNumber - indexWithinCheckpoint); + } + + /** + * The cumulative Inbox message count consumed as of the block immediately before `firstBlockNumber` (its L1-to-L2 + * tree leaf count): 0 when that block is genesis, undefined when it has not synced locally. + */ + private async getPreBlockConsumedTotal(firstBlockNumber: number): Promise { + const preBlockNumber = firstBlockNumber - 1; + if (preBlockNumber < INITIAL_L2_BLOCK_NUM) { + return 0n; + } + const preBlock = await this.blockSource.getBlockData({ number: BlockNumber(preBlockNumber) }); + return preBlock === undefined ? undefined : this.blockLeafCount(preBlock); + } + + /** + * Enforces the streaming-Inbox last-block minimum-consumption (censorship) rule for a checkpoint, mirroring + * `ProposeLib.validateInboxConsumption`: the first bucket the checkpoint left unconsumed must be absent, past the + * cutoff, or a cap-escape. Returns true (sufficient) when the checkpoint's consumption cannot be resolved against + * the local Inbox view, deferring to L1 `propose` as the authoritative reject. + */ + private async isLastBlockConsumptionSufficient(slot: SlotNumber, blocks: L2Block[]): Promise { + const lastBlockTotal = this.blockLeafCount(blocks[blocks.length - 1]); + const checkpointStartTotal = await this.getPreBlockConsumedTotal(blocks[0].number); + const lastConsumedBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(lastBlockTotal); + if (checkpointStartTotal === undefined || lastConsumedBucket === undefined) { + return true; + } + const nextBucket = await this.l1ToL2MessageSource.getInboxBucket(lastConsumedBucket.seq + 1n); + const cutoffTimestamp = getInboxCutoffTimestamp(slot, this.epochCache.getL1Constants(), INBOX_LAG_SECONDS); + return isInboxConsumptionSufficient({ + nextBucket, + cutoffTimestamp, + checkpointStartTotalMsgCount: checkpointStartTotal, + perCheckpointCap: MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + }); + } + + /** + * Derives the ordered list of L1-to-L2 messages a checkpoint consumed across its blocks, from the Inbox buckets + * between the parent checkpoint's consumed position and the checkpoint's last block. Empty when + * the checkpoint consumed nothing or its consumption cannot be resolved against the local Inbox view. + */ + private async deriveCheckpointConsumedMessages(blocks: L2Block[]): Promise { + const checkpointStartTotal = await this.getPreBlockConsumedTotal(blocks[0].number); + const lastBlockTotal = this.blockLeafCount(blocks[blocks.length - 1]); + if (checkpointStartTotal === undefined || lastBlockTotal <= checkpointStartTotal) { + return []; + } + const startBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(checkpointStartTotal); + const endBucket = await this.l1ToL2MessageSource.getInboxBucketByTotalMsgCount(lastBlockTotal); + if (startBucket === undefined || endBucket === undefined) { + return []; + } + return this.l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets(startBucket.seq, endBucket.seq); + } + async reexecuteTransactions( proposal: BlockProposal, blockNumber: BlockNumber, @@ -882,6 +1025,7 @@ export class ProposalHandler { txs: Tx[], l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], + previousInboxRollingHash: Fr, ): Promise { const { blockHeader, txHashes } = proposal; @@ -923,13 +1067,15 @@ export class ProposalHandler { gasFees: blockHeader.globalVariables.gasFees, }; - // Create checkpoint builder with prior blocks + // Create checkpoint builder with prior blocks. The messages the prior blocks consumed are not needed: this path + // only re-executes and compares the new block, never completing the checkpoint (whose rolling hash they seed). const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint( checkpointNumber, constants, 0n, // only takes effect in the following checkpoint. - l1ToL2Messages, + [], previousCheckpointOutHashes, + previousInboxRollingHash, fork, priorBlocks, this.log.getBindings(), @@ -948,6 +1094,7 @@ export class ProposalHandler { expectedEndState: blockHeader.state, maxTransactions: this.config.validateMaxTxsPerBlock, maxBlockGas, + l1ToL2Messages, }); const { block, failedTxs } = result; @@ -1158,8 +1305,20 @@ export class ProposalHandler { const constants = this.extractCheckpointConstants(firstBlock); const checkpointNumber = firstBlock.checkpointNumber; - // Get L1-to-L2 messages for this checkpoint - const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber); + // Streaming Inbox: on the last block of a checkpoint, enforce the minimum-consumption + // (censorship) rule before attesting. Reject (no attestation) if a mandatory bucket was left unconsumed. + if (!(await this.isLastBlockConsumptionSufficient(slot, blocks))) { + this.log.warn(`Streaming Inbox last-block censorship check failed, refusing to attest`, { + ...proposalInfo, + checkpointNumber, + }); + return { isValid: false, reason: 'inbox_consumption_insufficient', checkpointNumber }; + } + + // Derive the checkpoint's consumed L1-to-L2 message list from the Inbox buckets between the parent checkpoint's + // consumed position and the last block's (compact indexing). The messages are already in the db from per-block + // validation; this list only drives the checkpoint's rolling-hash recomputation in completeCheckpoint. + const l1ToL2Messages = await this.deriveCheckpointConsumedMessages(blocks); // Collect the out hashes of all the checkpoints before this one in the same epoch. // See note on the analogous block-proposal site: the helper handles pipelining lag. @@ -1173,6 +1332,12 @@ export class ProposalHandler { log: this.log, }); + const previousInboxRollingHash = await getPreviousCheckpointInboxRollingHash({ + blockSource: this.blockSource, + checkpointNumber, + log: this.log, + }); + // Fork world state at the block before the first block. getFork syncs world state to the parent block // first (see its doc): the block source (archiver) can already hold the block while world state still // trails it by one, and forking a not-yet-applied block throws a raw tree error that would otherwise @@ -1216,6 +1381,7 @@ export class ProposalHandler { proposal.feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, + previousInboxRollingHash, fork, blocks, this.log.getBindings(), diff --git a/yarn-project/validator-client/src/streaming_inbox_checks.test.ts b/yarn-project/validator-client/src/streaming_inbox_checks.test.ts new file mode 100644 index 000000000000..1608f2bcd2b7 --- /dev/null +++ b/yarn-project/validator-client/src/streaming_inbox_checks.test.ts @@ -0,0 +1,286 @@ +import { Fr } from '@aztec/foundation/curves/bn254'; +import type { InboxBucket } from '@aztec/stdlib/messaging'; +import { InboxBucketRef } from '@aztec/stdlib/messaging'; + +import { describe, expect, it } from '@jest/globals'; + +import { + type StreamingBlockCheckInput, + type StreamingInboxBucketSource, + checkStreamingBlockProposal, +} from './streaming_inbox_checks.js'; + +const LAG_SECONDS = 12; +const PER_BLOCK_CAP = 1024; +const PER_CHECKPOINT_CAP = 1024; +const NOW = 10_000n; + +/** + * In-memory Inbox-bucket view mirroring the archiver store's index semantics: buckets keyed by sequence number, a flat + * leaves array indexed by global message index, and `getL1ToL2MessagesBetweenBuckets` slicing that array by the + * `(from, to]` bucket range (start = fromBucket.lastMessageIndex + 1, genesis when from == 0). + */ +class FakeInboxView implements StreamingInboxBucketSource { + private readonly buckets = new Map(); + private readonly leaves: Fr[] = []; + + constructor() { + // Genesis sentinel bucket 0 {total 0}, as the archiver store holds it (the "consumed nothing" base case). + this.buckets.set(0n, { + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }); + } + + /** Appends a bucket of `msgCount` leaves opened at `timestamp`, with a rolling hash derived from `seq`. */ + addBucket(seq: number, msgCount: number, timestamp: number, rollingHash?: Fr): InboxBucket { + const priorTotal = this.leaves.length; + for (let i = 0; i < msgCount; i++) { + this.leaves.push(new Fr(1000 + priorTotal + i)); + } + const totalMsgCount = BigInt(this.leaves.length); + const bucket: InboxBucket = { + seq: BigInt(seq), + inboxRollingHash: rollingHash ?? new Fr(500 + seq), + totalMsgCount, + timestamp: BigInt(timestamp), + msgCount, + lastMessageIndex: totalMsgCount - 1n, + }; + this.buckets.set(BigInt(seq), bucket); + return bucket; + } + + getInboxBucket(seq: bigint): Promise { + return Promise.resolve(this.buckets.get(seq)); + } + + getInboxBucketByTotalMsgCount(totalMsgCount: bigint): Promise { + if (totalMsgCount === 0n) { + return Promise.resolve(this.buckets.get(0n)); + } + return Promise.resolve([...this.buckets.values()].find(b => b.totalMsgCount === totalMsgCount)); + } + + getL1ToL2MessagesBetweenBuckets(fromExclusive: bigint, toInclusive: bigint): Promise { + const toBucket = this.buckets.get(toInclusive); + if (toBucket === undefined) { + return Promise.resolve([]); + } + let startIndex = 0n; + if (fromExclusive > 0n) { + const fromBucket = this.buckets.get(fromExclusive); + if (fromBucket === undefined) { + return Promise.resolve([]); + } + startIndex = fromBucket.lastMessageIndex + 1n; + } + return Promise.resolve(this.leaves.slice(Number(startIndex), Number(toBucket.lastMessageIndex + 1n))); + } +} + +function refFor(bucket: InboxBucket, rollingHash = bucket.inboxRollingHash): InboxBucketRef { + return new InboxBucketRef(bucket.seq, bucket.timestamp, rollingHash); +} + +function baseInput(overrides: Partial): StreamingBlockCheckInput { + return { + messageSource: new FakeInboxView(), + bucketRef: undefined, + parentTotalMsgCount: 0n, + checkpointStartTotalMsgCount: 0n, + nowSeconds: NOW, + lagSeconds: LAG_SECONDS, + perBlockCap: PER_BLOCK_CAP, + perCheckpointCap: PER_CHECKPOINT_CAP, + ...overrides, + }; +} + +describe('checkStreamingBlockProposal', () => { + describe('check 1: bucket exists and hash matches', () => { + it('rejects a proposal with no bucket reference', async () => { + const result = await checkStreamingBlockProposal(baseInput({ bucketRef: undefined })); + expect(result).toEqual({ accepted: false, reason: 'bucket_unknown' }); + }); + + it('rejects promptly when the referenced bucket is unknown (no waiting)', async () => { + const view = new FakeInboxView(); + const start = Date.now(); + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: new InboxBucketRef(7n, 100n, new Fr(1)) }), + ); + expect(result).toEqual({ accepted: false, reason: 'bucket_unknown' }); + // The happy path rejects immediately; there is no bounded wait yet. Assert it did not sleep. + expect(Date.now() - start).toBeLessThan(500); + }); + + it('rejects when the resolved bucket hash differs from the reference', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 3, 100); + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket, new Fr(999)) }), + ); + expect(result).toEqual({ accepted: false, reason: 'bucket_hash_mismatch' }); + }); + }); + + describe('check 2: consumption moves forward', () => { + it('rejects when the bucket total is behind the parent block', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 3, 100); // total 3 + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket), parentTotalMsgCount: 5n }), + ); + expect(result).toEqual({ accepted: false, reason: 'bucket_moves_backwards' }); + }); + + it('accepts an empty-consumption block that reuses the parent bucket (empty bundle)', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 3, 100); // total 3 + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket), parentTotalMsgCount: 3n }), + ); + expect(result).toEqual({ accepted: true, bundle: [] }); + }); + }); + + describe('check 3: bucket is at least lagSeconds old', () => { + it('accepts a bucket exactly lagSeconds old (inclusive boundary)', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 2, Number(NOW) - LAG_SECONDS); // timestamp == now - lag + const result = await checkStreamingBlockProposal(baseInput({ messageSource: view, bucketRef: refFor(bucket) })); + expect(result.accepted).toBe(true); + }); + + it('rejects a bucket one second too new', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 2, Number(NOW) - LAG_SECONDS + 1); + const result = await checkStreamingBlockProposal(baseInput({ messageSource: view, bucketRef: refFor(bucket) })); + expect(result).toEqual({ accepted: false, reason: 'bucket_too_new' }); + }); + }); + + describe('check 4: caps', () => { + it('accepts a block consuming exactly the per-block cap', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, PER_BLOCK_CAP, 100); + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket), perBlockCap: PER_BLOCK_CAP }), + ); + expect(result.accepted).toBe(true); + }); + + it('rejects a block consuming one over the per-block cap', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 4, 100); + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket), perBlockCap: 3 }), + ); + expect(result).toEqual({ accepted: false, reason: 'bundle_over_block_cap' }); + }); + + it('rejects when the running checkpoint total exceeds the per-checkpoint cap', async () => { + const view = new FakeInboxView(); + view.addBucket(1, 3, 100); // total 3, the checkpoint's earlier consumption + const bucket = view.addBucket(2, 3, 100); // total 6 + const result = await checkStreamingBlockProposal( + baseInput({ + messageSource: view, + bucketRef: refFor(bucket), + parentTotalMsgCount: 3n, + checkpointStartTotalMsgCount: 0n, + perCheckpointCap: 5, // 6 - 0 = 6 > 5 + }), + ); + expect(result).toEqual({ accepted: false, reason: 'checkpoint_over_msg_cap' }); + }); + }); + + describe('bundle derivation', () => { + it('derives the bundle for a genesis-parent first block', async () => { + const view = new FakeInboxView(); + const bucket = view.addBucket(1, 3, 100); // leaves at global indices 0..2 + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(bucket), parentTotalMsgCount: 0n }), + ); + expect(result).toEqual({ accepted: true, bundle: [new Fr(1000), new Fr(1001), new Fr(1002)] }); + }); + + it('derives the bundle spanning multiple buckets since the parent', async () => { + const view = new FakeInboxView(); + view.addBucket(1, 2, 100); // parent consumed through here, total 2 + view.addBucket(2, 2, 100); // total 4 + const proposed = view.addBucket(3, 1, 100); // total 5 + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(proposed), parentTotalMsgCount: 2n }), + ); + // Bundle = leaves at global indices 2,3,4 (buckets 2 and 3), derived after resolving the parent bucket (seq 1). + expect(result).toEqual({ accepted: true, bundle: [new Fr(1002), new Fr(1003), new Fr(1004)] }); + }); + + it('rejects when the parent leaf count does not sit on a bucket boundary (padded legacy parent)', async () => { + const view = new FakeInboxView(); + view.addBucket(1, 2, 100); // total 2 + const proposed = view.addBucket(2, 2, 100); // total 4 + // Parent leaf count 3 is between bucket boundaries (2 and 4): unresolvable. + const result = await checkStreamingBlockProposal( + baseInput({ messageSource: view, bucketRef: refFor(proposed), parentTotalMsgCount: 3n }), + ); + expect(result).toEqual({ accepted: false, reason: 'parent_bucket_unresolved' }); + }); + }); + + describe('running-total accumulation across a checkpoint', () => { + it('accumulates the per-checkpoint total across three blocks against a fixed start', async () => { + // Checkpoint starts after bucket 1 (total 2). Three blocks each consume 2 messages: totals 4, 6, 8. + const view = new FakeInboxView(); + view.addBucket(1, 2, 100); // checkpoint start total 2 + const b2 = view.addBucket(2, 2, 100); // total 4 + const b3 = view.addBucket(3, 2, 100); // total 6 + const b4 = view.addBucket(4, 2, 100); // total 8 + const checkpointStart = 2n; + + // Block 1 (parent = bucket 1): checkpoint delta 4 - 2 = 2. + const r1 = await checkStreamingBlockProposal( + baseInput({ + messageSource: view, + bucketRef: refFor(b2), + parentTotalMsgCount: 2n, + checkpointStartTotalMsgCount: checkpointStart, + perCheckpointCap: 6, + }), + ); + expect(r1.accepted).toBe(true); + + // Block 3 (parent = bucket 3): checkpoint delta 8 - 2 = 6, exactly at the cap. + const r3 = await checkStreamingBlockProposal( + baseInput({ + messageSource: view, + bucketRef: refFor(b4), + parentTotalMsgCount: 6n, + checkpointStartTotalMsgCount: checkpointStart, + perCheckpointCap: 6, + }), + ); + expect(r3.accepted).toBe(true); + + // Same block against a tighter cap of 5: the accumulated delta 6 now exceeds it. + const r3Tight = await checkStreamingBlockProposal( + baseInput({ + messageSource: view, + bucketRef: refFor(b4), + parentTotalMsgCount: 6n, + checkpointStartTotalMsgCount: checkpointStart, + perCheckpointCap: 5, + }), + ); + expect(r3Tight).toEqual({ accepted: false, reason: 'checkpoint_over_msg_cap' }); + void b3; + }); + }); +}); diff --git a/yarn-project/validator-client/src/streaming_inbox_checks.ts b/yarn-project/validator-client/src/streaming_inbox_checks.ts new file mode 100644 index 000000000000..1859ead4d90d --- /dev/null +++ b/yarn-project/validator-client/src/streaming_inbox_checks.ts @@ -0,0 +1,132 @@ +import type { Fr } from '@aztec/foundation/curves/bn254'; +import type { InboxBucketRef, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; + +/** + * Reason a streaming-Inbox block proposal fails the per-block acceptance checks. Follows the + * handler's existing `{ isValid, reason }` string style. + */ +export type StreamingBlockCheckReason = + | 'bucket_unknown' + | 'bucket_hash_mismatch' + | 'parent_bucket_unresolved' + | 'bucket_moves_backwards' + | 'bucket_too_new' + | 'bundle_over_block_cap' + | 'checkpoint_over_msg_cap'; + +/** The subset of the archiver's Inbox-bucket queries the per-block streaming checks need. */ +export type StreamingInboxBucketSource = Pick< + L1ToL2MessageSource, + 'getInboxBucket' | 'getInboxBucketByTotalMsgCount' | 'getL1ToL2MessagesBetweenBuckets' +>; + +/** Inputs to the per-block streaming Inbox acceptance checks. */ +export type StreamingBlockCheckInput = { + /** Archiver Inbox-bucket queries (resolved against this node's own Inbox view). */ + messageSource: StreamingInboxBucketSource; + /** The proposal's bucket reference: `bucketSeq` is the lookup hint, `inboxRollingHash` the expected commitment. */ + bucketRef: InboxBucketRef | undefined; + /** Cumulative Inbox message count consumed through the parent block (its L1-to-L2 tree leaf count; 0 at genesis). */ + parentTotalMsgCount: bigint; + /** Cumulative Inbox message count consumed as of the parent checkpoint; the per-checkpoint cap origin. */ + checkpointStartTotalMsgCount: bigint; + /** Validation-time wall clock in seconds; the lag-eligibility anchor. */ + nowSeconds: bigint; + /** Minimum bucket age in seconds (`INBOX_LAG_SECONDS`) for a bucket to be lag-eligible. */ + lagSeconds: number; + /** Maximum number of messages this block may consume (`MAX_L1_TO_L2_MSGS_PER_BLOCK`). */ + perBlockCap: number; + /** Maximum number of messages the checkpoint may consume in total (`MAX_L1_TO_L2_MSGS_PER_CHECKPOINT`). */ + perCheckpointCap: number; +}; + +/** Result of the per-block streaming Inbox acceptance checks. */ +export type StreamingBlockCheckResult = + | { + /** All four checks passed; `bundle` is the message-leaf bundle this block consumes, for re-execution. */ + accepted: true; + bundle: Fr[]; + } + | { + /** A check failed; `reason` mirrors the L1 acceptance condition that would have rejected the proposal. */ + accepted: false; + reason: StreamingBlockCheckReason; + }; + +/** + * Runs the per-block acceptance checks a validator applies to a streaming block proposal, and + * derives the message-leaf bundle the block consumes (for re-execution). Mirrors the L1 acceptance conditions: + * + * 1. **Exists**: the referenced bucket resolves in this node's own Inbox view, and its consensus rolling hash matches + * the reference. An unknown bucket is an immediate reject here (there is no bounded wait yet); a hash + * mismatch means the wire reference disagrees with the local bucket. The reference is trusted only as a `bucketSeq` + * lookup hint — timestamp and message counts are read from the locally resolved bucket, never from the wire. + * 2. **Moves forward**: the bucket's cumulative total is at least the parent block's, so consumption never rewinds. + * Equal totals mean the block consumes nothing (empty bundle). + * 3. **Not too new**: the bucket is at least `lagSeconds` old at validation time (`timestamp <= now - lagSeconds`, + * inclusive — a bucket exactly `lagSeconds` old is eligible, matching L1's strict `>` "too new" test). + * 4. **Caps**: the per-block message count and the running per-checkpoint total fit their respective caps. + * + * The reject branch is a single function so a future bounded wait can wrap `bucket_unknown`. + */ +export async function checkStreamingBlockProposal(input: StreamingBlockCheckInput): Promise { + const { + messageSource, + bucketRef, + parentTotalMsgCount, + checkpointStartTotalMsgCount, + nowSeconds, + lagSeconds, + perBlockCap, + perCheckpointCap, + } = input; + + // A streaming proposal must carry a bucket reference to derive its bundle from. + if (bucketRef === undefined) { + return { accepted: false, reason: 'bucket_unknown' }; + } + + // Check 1: exists in our own Inbox view, and the resolved rolling hash matches the reference. + const bucket = await messageSource.getInboxBucket(bucketRef.bucketSeq); + if (bucket === undefined) { + return { accepted: false, reason: 'bucket_unknown' }; + } + if (!bucket.inboxRollingHash.equals(bucketRef.inboxRollingHash)) { + return { accepted: false, reason: 'bucket_hash_mismatch' }; + } + + // Check 2: consumption moves forward relative to the parent block. + if (bucket.totalMsgCount < parentTotalMsgCount) { + return { accepted: false, reason: 'bucket_moves_backwards' }; + } + + // Check 3: the bucket is at least `lagSeconds` old at validation time. + if (bucket.timestamp > nowSeconds - BigInt(lagSeconds)) { + return { accepted: false, reason: 'bucket_too_new' }; + } + + // Check 4a: the per-block message count fits the per-block cap. + const blockCount = bucket.totalMsgCount - parentTotalMsgCount; + if (blockCount > BigInt(perBlockCap)) { + return { accepted: false, reason: 'bundle_over_block_cap' }; + } + + // Check 4b: the running per-checkpoint total fits the per-checkpoint cap. + const checkpointCount = bucket.totalMsgCount - checkpointStartTotalMsgCount; + if (checkpointCount > BigInt(perCheckpointCap)) { + return { accepted: false, reason: 'checkpoint_over_msg_cap' }; + } + + // Derive the message bundle for re-execution: the leaves consumed between the parent bucket and the proposed one. + // The parent bucket is the one whose cumulative total equals the parent block's leaf count (messages are indexed + // compactly, with no padding); a parent whose count does not sit on a bucket boundary is unresolvable. + const parentBucket = await messageSource.getInboxBucketByTotalMsgCount(parentTotalMsgCount); + if (parentBucket === undefined) { + return { accepted: false, reason: 'parent_bucket_unresolved' }; + } + const bundle = + parentBucket.seq === bucket.seq + ? [] + : await messageSource.getL1ToL2MessagesBetweenBuckets(parentBucket.seq, bucket.seq); + return { accepted: true, bundle }; +} diff --git a/yarn-project/validator-client/src/validator.ha.integration.test.ts b/yarn-project/validator-client/src/validator.ha.integration.test.ts index b6bd10e4ad1d..e1f9e292ca7b 100644 --- a/yarn-project/validator-client/src/validator.ha.integration.test.ts +++ b/yarn-project/validator-client/src/validator.ha.integration.test.ts @@ -19,7 +19,6 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block'; import { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; import type { SlasherConfig, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, @@ -115,7 +114,6 @@ describe('ValidatorClient HA Integration', () => { blockSource = mock(); l1ToL2MessageSource = mock(); txProvider = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); dateProvider = new TestDateProvider(); blobClient = mock(); blobClient.canUpload.mockReturnValue(false); @@ -306,7 +304,6 @@ describe('ValidatorClient HA Integration', () => { // Use all 5 validators - all try to create the same block proposal const blockHeader = makeBlockHeader(1); const indexWithinCheckpoint = IndexWithinCheckpoint(0); - const inHash = computeInHashFromL1ToL2Messages([]); const archive = Fr.random(); const txs = await Promise.all([1, 2, 3].map(() => mockTx())); const proposerAddress = EthAddress.fromString(validatorAccounts[0].address); @@ -318,7 +315,6 @@ describe('ValidatorClient HA Integration', () => { blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - inHash, archive, txs, proposerAddress, @@ -348,7 +344,6 @@ describe('ValidatorClient HA Integration', () => { it('should allow different validators to create proposals for different slots', async () => { const proposerAddress = EthAddress.fromString(validatorAccounts[0].address); const txs = await Promise.all([1, 2, 3].map(() => mockTx())); - const inHash = computeInHashFromL1ToL2Messages([]); // Each of the 5 validators creates a proposal for a different slot const proposals = await Promise.all( @@ -359,7 +354,6 @@ describe('ValidatorClient HA Integration', () => { blockHeader, CheckpointNumber(1), IndexWithinCheckpoint(0), - inHash, archive, txs, proposerAddress, diff --git a/yarn-project/validator-client/src/validator.integration.test.ts b/yarn-project/validator-client/src/validator.integration.test.ts index aa89cae85e20..ee3c996e3b76 100644 --- a/yarn-project/validator-client/src/validator.integration.test.ts +++ b/yarn-project/validator-client/src/validator.integration.test.ts @@ -26,7 +26,7 @@ import { CheckpointReexecutionTracker, L1PublishedData, PublishedCheckpoint } fr import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { Gas, GasFees } from '@aztec/stdlib/gas'; import { tryStop } from '@aztec/stdlib/interfaces/server'; -import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; +import { InboxBucketRef } from '@aztec/stdlib/messaging'; import { type BlockProposal, CheckpointProposal } from '@aztec/stdlib/p2p'; import { mockTx } from '@aztec/stdlib/testing'; import { BlockHeader, type CheckpointGlobalVariables, Tx } from '@aztec/stdlib/tx'; @@ -48,7 +48,9 @@ jest.setTimeout(60_000); describe('ValidatorClient Integration', () => { // Constants for L1 const l1Constants: L1RollupConstants = { - l1GenesisTime: 0n, + // Non-zero genesis time so the slot-1 validation clock is well past INBOX_LAG_SECONDS; otherwise the streaming + // Inbox acceptance check rejects even a genesis-timestamp (0) bucket as `bucket_too_new`. + l1GenesisTime: 1_700_000_000n, slotDuration: 24, epochDuration: 16, ethereumSlotDuration: 12, @@ -238,7 +240,7 @@ describe('ValidatorClient Integration', () => { type BlockProposalResult = { block: L2Block; proposal: BlockProposal }; - /** Builds a new block proposal with the given txs and l1-to-l2 messages */ + /** Builds a new block proposal with the given txs and L1-to-L2 message bundle */ const buildBlockProposal = async ( checkpointBuilder: CheckpointBuilder, blockNumber: BlockNumber, @@ -246,24 +248,32 @@ describe('ValidatorClient Integration', () => { txs: Tx[] = [], l1ToL2Messages: Fr[] = [], ): Promise<{ block: L2Block; proposal: BlockProposal }> => { - const inHash = computeInHashFromL1ToL2Messages(l1ToL2Messages); const blockTimestamp = getTimestampForSlot(checkpointBuilder.getConstantData().slotNumber, l1Constants); const { block, usedTxs } = await checkpointBuilder.buildBlock(txs, blockNumber, blockTimestamp, { isBuildingProposal: true, maxBlocksPerCheckpoint: 1, perBlockAllocationMultiplier: 1.2, minValidTxs: 0, + l1ToL2Messages, }); + // Resolve the Inbox bucket this block consumed through (keyed by its cumulative L1-to-L2 leaf count) and attach + // the reference, mirroring the sequencer's block-building loop which carries a bucketRef on every proposal. + // Without it the validator's streaming acceptance check rejects the proposal as + // `bucket_unknown`. A block that consumed nothing resolves to the genesis (or reused parent) bucket. + const blockTotal = BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); + const bucket = await proposer.archiver.getInboxBucketByTotalMsgCount(blockTotal); + const bucketRef = bucket ? InboxBucketRef.fromBucket(bucket) : undefined; + const proposal = await proposer.validator.createBlockProposal( block.header, cpNumber, block.indexWithinCheckpoint, - inHash, block.archive.root, usedTxs, proposerSigner.address, {}, + bucketRef, ); logger.warn(`Built block proposal for block ${blockNumber}`, { ...block.toBlockInfo() }); @@ -332,8 +342,8 @@ describe('ValidatorClient Integration', () => { checkpointNumber, globalVariables, 0n, - l1ToL2Messages, previousCheckpointOutHashes, + Fr.ZERO, fork, ); @@ -341,7 +351,15 @@ describe('ValidatorClient Integration', () => { for (let i = 0; i < blockCount; i++) { const blockNumber = BlockNumber(startBlockNumber + i); const txs = await getTxsForBlock(blockNumber, blocks); - const block = await buildBlockProposal(builder, blockNumber, checkpointNumber, txs, l1ToL2Messages); + // The checkpoint's whole message bundle goes into its first block, matching how a validator derives each + // block's bundle from the block's own L1-to-L2 leaf-count delta. + const block = await buildBlockProposal( + builder, + blockNumber, + checkpointNumber, + txs, + i === 0 ? l1ToL2Messages : [], + ); blocks.push(block); } @@ -458,9 +476,9 @@ describe('ValidatorClient Integration', () => { it('validates and attests with txs anchored to proposed blocks and non-empty l1-to-l2 messages', async () => { // Create l1 to l2 messages and seed them into the archivers - const l1ToL2Messages = makeInboxMessages(4, { messagesPerCheckpoint: 4 }); - await proposer.archiver.dataStores.messages.addL1ToL2Messages(l1ToL2Messages); - await attestor.archiver.dataStores.messages.addL1ToL2Messages(l1ToL2Messages); + const l1ToL2Messages = makeInboxMessages(4); + await proposer.archiver.dataStores.messages.addL1ToL2MessageBuckets(l1ToL2Messages); + await attestor.archiver.dataStores.messages.addL1ToL2MessageBuckets(l1ToL2Messages); // Build txs anchored to the previously proposed block const { blocks, proposal } = await buildCheckpoint( @@ -658,11 +676,11 @@ describe('ValidatorClient Integration', () => { }); it('refuses block proposal with mismatching l1 to l2 messages', async () => { - const l1ToL2Messages = makeInboxMessages(4, { messagesPerCheckpoint: 4 }); - await proposer.archiver.dataStores.messages.addL1ToL2Messages(l1ToL2Messages); + const l1ToL2Messages = makeInboxMessages(4); + await proposer.archiver.dataStores.messages.addL1ToL2MessageBuckets(l1ToL2Messages); - const otherL1ToL2Messages = makeInboxMessages(4, { messagesPerCheckpoint: 4 }); - await attestor.archiver.dataStores.messages.addL1ToL2Messages(otherL1ToL2Messages); + const otherL1ToL2Messages = makeInboxMessages(4); + await attestor.archiver.dataStores.messages.addL1ToL2MessageBuckets(otherL1ToL2Messages); const { blocks } = await buildCheckpoint( CheckpointNumber(1), diff --git a/yarn-project/validator-client/src/validator.test.ts b/yarn-project/validator-client/src/validator.test.ts index 1ec793384eaa..47f4ef07cd46 100644 --- a/yarn-project/validator-client/src/validator.test.ts +++ b/yarn-project/validator-client/src/validator.test.ts @@ -30,10 +30,11 @@ import { import { OffenseType, WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT } from '@aztec/slasher'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type BlockData, BlockHash, L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block'; -import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint'; +import { type Checkpoint, CheckpointReexecutionTracker, type ProposedCheckpointData } from '@aztec/stdlib/checkpoint'; import type { SlasherConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server'; -import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging'; +import { type InboxBucket, InboxBucketRef, type L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import type { BlockProposal } from '@aztec/stdlib/p2p'; +import { CheckpointHeader } from '@aztec/stdlib/rollup'; import { TEST_COORDINATION_SIGNATURE_CONTEXT, makeBlockHeader, @@ -166,10 +167,18 @@ describe('ValidatorClient', () => { blockSource.getBlocksForSlot.mockResolvedValue([]); blockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(Number.MAX_SAFE_INTEGER)); blockSource.syncImmediate.mockResolvedValue(undefined); + // The proposal handler sources the parent checkpoint's inboxRollingHash from the block source; serve an + // empty (all-zero) parent header from the proposed-checkpoint fallback so proposals beyond the genesis + // checkpoint resolve their chain start. getCheckpointData stays undefined: the checkpoint-proposal path + // uses it as an already-published-on-L1 existence check. + blockSource.getProposedCheckpointData.mockImplementation(query => + Promise.resolve( + query && 'number' in query ? ({ header: CheckpointHeader.empty() } as ProposedCheckpointData) : undefined, + ), + ); epochCache.isEscapeHatchOpenAtSlot.mockResolvedValue(false); l1ToL2MessageSource = mock(); txProvider = mock(); - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([]); dateProvider = new TestDateProvider(); blobClient = mock(); blobClient.canUpload.mockReturnValue(false); @@ -228,7 +237,6 @@ describe('ValidatorClient', () => { it('should create a valid block proposal without txs', async () => { const blockHeader = makeBlockHeader(); const indexWithinCheckpoint = IndexWithinCheckpoint(0); - const inHash = Fr.random(); const archive = Fr.random(); const txs = await Promise.all([1, 2, 3, 4, 5].map(() => mockTx())); @@ -236,7 +244,6 @@ describe('ValidatorClient', () => { blockHeader, CheckpointNumber(1), indexWithinCheckpoint, - inHash, archive, txs, EthAddress.fromString(validatorAccounts[0].address), @@ -443,11 +450,22 @@ describe('ValidatorClient', () => { Array.isArray(args) && args[0]?.offenseType === OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, ); + // Streaming Inbox: an empty-consumption streaming setup. Proposals reference the genesis Inbox bucket, the + // parent block's L1-to-L2 leaf count equals its cumulative total (0), so the derived per-block bundle is empty. + const genesisInboxBucket: InboxBucket = { + seq: 0n, + inboxRollingHash: Fr.ZERO, + totalMsgCount: 0n, + timestamp: 0n, + msgCount: 0, + lastMessageIndex: 0n, + }; + const genesisBucketRef = InboxBucketRef.fromBucket(genesisInboxBucket); + beforeEach(async () => { - const emptyInHash = computeInHashFromL1ToL2Messages([]); const blockHeader = makeBlockHeader(1, { blockNumber: BlockNumber(100), slotNumber: SlotNumber(100) }); blockNumber = BlockNumber(blockHeader.globalVariables.blockNumber); - proposal = await makeBlockProposal({ blockHeader, inHash: emptyInHash }); + proposal = await makeBlockProposal({ blockHeader, bucketRef: genesisBucketRef }); // The proposal targets slot 100, which under pipelining is built during the previous slot. Set the // wall clock to the start of that build slot (target_slot_start - S), matching how a pipelined // proposer is positioned when validating an inbound block proposal. With S - 2E = 0 in this config @@ -507,6 +525,7 @@ describe('ValidatorClient', () => { getBlockNumber: () => blockNumber - 1, getSlot: () => parentSlot, globalVariables: blockHeader.globalVariables, + state: { l1ToL2MessageTree: { nextAvailableLeafIndex: 0 } }, }, archive: new AppendOnlyTreeSnapshot(Fr.random(), blockNumber - 1), blockHash: BlockHash.random(), @@ -520,6 +539,11 @@ describe('ValidatorClient', () => { blockSource.getGenesisValues.mockResolvedValue({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) }); blockSource.syncImmediate.mockImplementation(() => Promise.resolve()); + // Resolve every Inbox bucket query to the genesis bucket, so streaming checks accept with an empty bundle. + l1ToL2MessageSource.getInboxBucket.mockResolvedValue(genesisInboxBucket); + l1ToL2MessageSource.getInboxBucketByTotalMsgCount.mockResolvedValue(genesisInboxBucket); + l1ToL2MessageSource.getL1ToL2MessagesBetweenBuckets.mockResolvedValue([]); + const clonedBlockHeader = blockHeader.clone(); blockBuildResult = { publicProcessorDuration: 0, @@ -557,10 +581,9 @@ describe('ValidatorClient', () => { validatorClient.getProposalHandler().register(p2pClient, true); const signer = Secp256k1Signer.random(); - const emptyInHash = computeInHashFromL1ToL2Messages([]); const checkpointProposal = await makeCheckpointProposal({ signer, - checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber }), archiveRoot: Fr.random(), lastBlock: { blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), @@ -586,7 +609,6 @@ describe('ValidatorClient', () => { signer, blockHeader: laterBlockHeader, indexWithinCheckpoint: IndexWithinCheckpoint(1), - inHash: emptyInHash, archiveRoot: Fr.random(), }); @@ -636,9 +658,8 @@ describe('ValidatorClient', () => { validatorClient.updateConfig({ skipPushProposedBlocksToArchiver: false }); validatorClient.getProposalHandler().register(p2pClient, true); - const emptyInHash = computeInHashFromL1ToL2Messages([]); const checkpointProposal = await makeCheckpointProposal({ - checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber }), archiveRoot: Fr.random(), lastBlock: { blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), @@ -647,7 +668,7 @@ describe('ValidatorClient', () => { }, }); const equivocatedCheckpointProposal = await makeCheckpointProposal({ - checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber, inHash: emptyInHash }), + checkpointHeader: makeCheckpointHeader(1, { slotNumber: proposal.slotNumber }), archiveRoot: Fr.random(), lastBlock: { blockHeader: makeBlockHeader(1, { blockNumber, slotNumber: proposal.slotNumber }), @@ -676,7 +697,6 @@ describe('ValidatorClient', () => { blockNumber, slotNumber: futureSlot, }), - inHash: computeInHashFromL1ToL2Messages([]), }); // Under pipelining, the target slot is the future slot the proposer is building for, built during @@ -715,13 +735,12 @@ describe('ValidatorClient', () => { it('should process block proposal from own validator key (HA peer)', async () => { const selfSigner = new Secp256k1Signer(Buffer32.fromString(validatorPrivateKeys[0])); - const emptyInHash = computeInHashFromL1ToL2Messages([]); const selfProposal = await makeBlockProposal({ blockHeader: proposal.blockHeader, - inHash: emptyInHash, archiveRoot: proposal.archive, txHashes: proposal.txHashes, signer: selfSigner, + bucketRef: genesisBucketRef, }); epochCache.getProposerAttesterAddressInSlot.mockResolvedValue(selfSigner.address); @@ -1425,19 +1444,8 @@ describe('ValidatorClient', () => { expect(isValid).toBe(false); }); - it('should return false if messages do not match', async () => { - l1ToL2MessageSource.getL1ToL2Messages.mockResolvedValue([Fr.random()]); - - const isValid = await validatorClient.validateBlockProposal(proposal, sender); - expect(isValid).toBe(false); - }); - describe('non-first block in checkpoint validation', () => { // When indexWithinCheckpoint > 0, global variables must match parent block (except blockNumber). - // The inHash validation is implicitly handled: all blocks in a checkpoint share the same - // checkpointNumber, so they fetch the same L1-to-L2 messages and compute the same inHash. - // If a proposal has a different inHash, the existing validation (which computes inHash from - // L1 messages for the checkpoint) will catch it. it('should return false if global variables do not match parent for non-first block in checkpoint', async () => { // Create a proposal with indexWithinCheckpoint > 0 (non-first block in checkpoint) @@ -1459,8 +1467,6 @@ describe('ValidatorClient', () => { coinbase: EthAddress.random(), // Different from parent - should cause failure }); - // Use empty messages and compute the matching inHash - const emptyInHash = computeInHashFromL1ToL2Messages([]); const proposalBlockHeader = makeBlockHeader(1, { blockNumber: BlockNumber(parentBlockNumber + 1), slotNumber: SlotNumber(parentSlotNumber), @@ -1471,7 +1477,6 @@ describe('ValidatorClient', () => { const nonFirstBlockProposal = await makeBlockProposal({ blockHeader: proposalBlockHeader, indexWithinCheckpoint: IndexWithinCheckpoint(1), // Non-first block in checkpoint - inHash: emptyInHash, }); // Update epochCache mock for the new proposal @@ -1532,13 +1537,6 @@ describe('ValidatorClient', () => { const isValid = await validatorClient.validateBlockProposal(nonFirstBlockProposal, sender); expect(isValid).toBe(false); }); - - // Note: inHash validation for non-first blocks is implicitly handled by the existing - // validation that computes inHash from L1-to-L2 messages for the checkpoint. Since all - // blocks in the same checkpoint share the same checkpointNumber, they will always - // compute the same inHash from the same L1 messages. If a malicious proposal has a - // different inHash, it will fail the existing validation at lines 192-200 in - // proposal_handler.ts. }); it('should validate proposals in fisherman mode but not create or broadcast attestations', async () => { diff --git a/yarn-project/validator-client/src/validator.ts b/yarn-project/validator-client/src/validator.ts index d81bc2f2fb66..b3f93748de1f 100644 --- a/yarn-project/validator-client/src/validator.ts +++ b/yarn-project/validator-client/src/validator.ts @@ -31,7 +31,7 @@ import type { ValidatorClientFullConfig, WorldStateSynchronizer, } from '@aztec/stdlib/interfaces/server'; -import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging'; +import type { InboxBucketRef, L1ToL2MessageSource } from '@aztec/stdlib/messaging'; import { type BlockProposal, type BlockProposalOptions, @@ -478,7 +478,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) 'invalid_proposal', 'state_mismatch', 'failed_txs', - 'in_hash_mismatch', 'parent_block_wrong_slot', ]; @@ -917,11 +916,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) blockHeader: BlockHeader, checkpointNumber: CheckpointNumber, indexWithinCheckpoint: IndexWithinCheckpoint, - inHash: Fr, archive: Fr, txs: Tx[], proposerAddress: EthAddress | undefined, options: BlockProposalOptions = {}, + bucketRef?: InboxBucketRef, ): Promise { // Validate that we're not creating a proposal for an older or equal position if (this.lastProposedBlock) { @@ -944,7 +943,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) blockHeader, checkpointNumber, indexWithinCheckpoint, - inHash, archive, txs, proposerAddress, @@ -953,6 +951,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter) broadcastInvalidBlockProposal: options.broadcastInvalidBlockProposal || this.config.broadcastInvalidBlockProposal, }, + bucketRef, ); this.lastProposedBlock = newProposal; return newProposal; diff --git a/yarn-project/world-state/src/native/native_world_state.test.ts b/yarn-project/world-state/src/native/native_world_state.test.ts index 5d9e1b96c922..e205170c8676 100644 --- a/yarn-project/world-state/src/native/native_world_state.test.ts +++ b/yarn-project/world-state/src/native/native_world_state.test.ts @@ -1,12 +1,12 @@ import { ARCHIVE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, + MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PUBLIC_DATA_TREE_HEIGHT, } from '@aztec/constants'; import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types'; @@ -32,7 +32,14 @@ import { tmpdir } from 'os'; import { join } from 'path'; import type { WorldStateTreeMapSizes } from '../synchronizer/factory.js'; -import { assertSameState, compareChains, mockBlock, mockEmptyBlock, updateBlockState } from '../test/utils.js'; +import { + assertSameState, + compareChains, + mockBlock, + mockBlockWithIndex, + mockEmptyBlock, + updateBlockState, +} from '../test/utils.js'; import { INITIAL_NULLIFIER_TREE_SIZE, INITIAL_PUBLIC_DATA_TREE_SIZE } from '../world-state-db/merkle_tree_db.js'; import type { WorldStateStatusSummary } from './message.js'; import { NativeWorldStateService, WORLD_STATE_DB_VERSION, WORLD_STATE_DIR } from './native_world_state.js'; @@ -79,7 +86,7 @@ describe('NativeWorldState', () => { await ws.close(); }); - it('pads messages, note hashes, nullifiers correctly for first block', async () => { + it('appends messages unpadded and pads note hashes, nullifiers for first block', async () => { const isFirstBlock = true; const txsPerBlock = 2; const maxEffects = 1; @@ -95,7 +102,8 @@ describe('NativeWorldState', () => { const status = await ws.handleL2BlockAndMessages(block, messages); - expect(status.meta.messageTreeMeta.size).toBe(BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)); + // Messages are appended unpadded at compact indices. + expect(status.meta.messageTreeMeta.size).toBe(BigInt(numMessages)); const expectedNoteHashCount = txsPerBlock * MAX_NOTE_HASHES_PER_TX; expect(status.meta.noteHashTreeMeta.size).toBe(BigInt(expectedNoteHashCount)); @@ -140,23 +148,143 @@ describe('NativeWorldState', () => { expect(status.meta.publicDataTreeMeta.size).toBe(BigInt(INITIAL_PUBLIC_DATA_TREE_SIZE + expectedPublicDataCount)); }); - it('pads empty messages array for first block', async () => { + it('leaves the message tree empty for a first block with no messages', async () => { const isFirstBlock = true; const numMessages = 0; const { block, messages } = await mockBlock(BlockNumber(1), 1, fork, 1, numMessages, isFirstBlock); const status = await ws.handleL2BlockAndMessages(block, messages); - expect(status.meta.messageTreeMeta.size).toBe(BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)); + expect(status.meta.messageTreeMeta.size).toBe(0n); }); - it('throws error if messages are provided for non-first block', async () => { - const isFirstBlock = false; - const numMessages = 1; - const { block, messages } = await mockBlock(BlockNumber(1), 1, fork, 1, numMessages, isFirstBlock); - - await expect(ws.handleL2BlockAndMessages(block, messages)).rejects.toThrow( - 'L1 to L2 messages must be empty for non-first blocks', + it('appends a non-first block bundle without padding', async () => { + const numMessages = 3; + const { block, messages } = await mockBlockWithIndex( + BlockNumber(1), + /*indexWithinCheckpoint=*/ 1, + 1, + fork, + numMessages, + 1, ); + + const status = await ws.handleL2BlockAndMessages(block, messages); + + // Non-first blocks append their bundle exactly as given (no padding to MAX_L1_TO_L2_MSGS_PER_CHECKPOINT). + expect(status.meta.messageTreeMeta.size).toBe(BigInt(numMessages)); + }); + }); + + describe('Per-block message insertion', () => { + let ws: NativeWorldStateService; + + beforeEach(async () => { + ws = await NativeWorldStateService.tmp(); + }); + + afterEach(async () => { + await ws.close(); + }); + + it('advances the L1-to-L2 message tree per block, including on non-first blocks', async () => { + const fork = await ws.fork(); + + // Block 1 is first-in-checkpoint carrying 3 messages, appended unpadded at compact indices. + const { block: b1, messages: m1 } = await mockBlockWithIndex(BlockNumber(1), /*index=*/ 0, 1, fork, 3, 1); + const s1 = await ws.handleL2BlockAndMessages(b1, m1); + expect(s1.meta.messageTreeMeta.size).toBe(3n); + expect(s1.meta.messageTreeMeta.unfinalizedBlockHeight).toBe(1); + + // Block 2 is non-first and carries no messages: the message tree size and root are unchanged, but the tree is + // still committed as a new block (so its per-block history stays in lockstep with the other trees). + const { block: b2, messages: m2 } = await mockBlockWithIndex(BlockNumber(2), /*index=*/ 1, 1, fork, 0, 1); + const s2 = await ws.handleL2BlockAndMessages(b2, m2); + expect(s2.meta.messageTreeMeta.size).toBe(3n); + expect(s2.meta.messageTreeMeta.root).toEqual(s1.meta.messageTreeMeta.root); + expect(s2.meta.messageTreeMeta.unfinalizedBlockHeight).toBe(2); + + // Block 3 is non-first and carries messages: the bundle is appended unpadded, so the tree grows by exactly the + // bundle size and the root changes on a non-first block. + const { block: b3, messages: m3 } = await mockBlockWithIndex(BlockNumber(3), /*index=*/ 2, 1, fork, 5, 1); + const s3 = await ws.handleL2BlockAndMessages(b3, m3); + expect(s3.meta.messageTreeMeta.size).toBe(8n); + expect(s3.meta.messageTreeMeta.root).not.toEqual(s2.meta.messageTreeMeta.root); + expect(s3.meta.messageTreeMeta.unfinalizedBlockHeight).toBe(3); + + await fork.close(); + + // A fork opened at block 2 sees exactly the first two bundles (3 + 0); at block 3 it also sees the third. + const forkAt2 = await ws.fork(BlockNumber(2)); + expect((await forkAt2.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE)).size).toBe(3n); + await forkAt2.close(); + + const forkAt3 = await ws.fork(BlockNumber(3)); + expect((await forkAt3.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE)).size).toBe(8n); + await forkAt3.close(); + }); + + it('unwinds per block, reverting exactly the messages appended by a non-first block', async () => { + const fork = await ws.fork(); + + const { block: b1, messages: m1 } = await mockBlockWithIndex(BlockNumber(1), /*index=*/ 0, 1, fork, 2, 1); + const s1 = await ws.handleL2BlockAndMessages(b1, m1); + + // Non-first block carrying 4 messages. + const { block: b2, messages: m2 } = await mockBlockWithIndex(BlockNumber(2), /*index=*/ 1, 1, fork, 4, 1); + const s2 = await ws.handleL2BlockAndMessages(b2, m2); + expect(s2.meta.messageTreeMeta.size).toBe(6n); + + // Non-first block carrying 5 messages. + const { block: b3, messages: m3 } = await mockBlockWithIndex(BlockNumber(3), /*index=*/ 2, 1, fork, 5, 1); + const s3 = await ws.handleL2BlockAndMessages(b3, m3); + expect(s3.meta.messageTreeMeta.size).toBe(11n); + await fork.close(); + + // Unwind block 3: the message tree returns to the post-block-2 state. + const afterUnwind3 = await ws.unwindBlocks(BlockNumber(2)); + expect(afterUnwind3.meta.messageTreeMeta.size).toBe(s2.meta.messageTreeMeta.size); + expect(afterUnwind3.meta.messageTreeMeta.root).toEqual(s2.meta.messageTreeMeta.root); + + // Unwind block 2 (a message-carrying non-first block): its 4 messages are reverted, back to the post-block-1 + // state — the pending-chain rollback does not assume the message tree only changes at checkpoint starts. + const afterUnwind2 = await ws.unwindBlocks(BlockNumber(1)); + expect(afterUnwind2.meta.messageTreeMeta.size).toBe(s1.meta.messageTreeMeta.size); + expect(afterUnwind2.meta.messageTreeMeta.root).toEqual(s1.meta.messageTreeMeta.root); + + // Re-syncing after the unwind reconverges: fresh non-first blocks append cleanly on top of block 1. + const resyncFork = await ws.fork(); + const { block: b2b, messages: m2b } = await mockBlockWithIndex(BlockNumber(2), /*index=*/ 1, 1, resyncFork, 4, 1); + const s2b = await ws.handleL2BlockAndMessages(b2b, m2b); + expect(s2b.meta.messageTreeMeta.size).toBe(6n); + + const { block: b3b, messages: m3b } = await mockBlockWithIndex(BlockNumber(3), /*index=*/ 2, 1, resyncFork, 5, 1); + const s3b = await ws.handleL2BlockAndMessages(b3b, m3b); + expect(s3b.meta.messageTreeMeta.size).toBe(11n); + await resyncFork.close(); + }); + + it('leaves the message tree unchanged on every non-first block that carries no messages', async () => { + const fork = await ws.fork(); + + // A checkpoint whose messages are all consumed by its first block: non-first blocks carry an empty bundle, so the + // message tree must be unchanged (size and root) at every non-first block, not just at the checkpoint end. + const { block: b1, messages: m1 } = await mockBlockWithIndex(BlockNumber(1), /*index=*/ 0, 2, fork, 6, 2); + const s1 = await ws.handleL2BlockAndMessages(b1, m1); + expect(s1.meta.messageTreeMeta.size).toBe(6n); + + for (let index = 1; index <= 2; index++) { + const blockNumber = index + 1; + const { block, messages } = await mockBlockWithIndex(BlockNumber(blockNumber), index, 2, fork, 0, 2); + const status = await ws.handleL2BlockAndMessages(block, messages); + + // The message tree is untouched by non-first blocks in the legacy shape. + expect(status.meta.messageTreeMeta.size).toEqual(s1.meta.messageTreeMeta.size); + expect(status.meta.messageTreeMeta.root).toEqual(s1.meta.messageTreeMeta.root); + // But the chain as a whole still advances: the archive tree grows with each block. + expect(status.meta.archiveTreeMeta.unfinalizedBlockHeight).toBe(blockNumber); + } + + await fork.close(); }); }); @@ -1380,8 +1508,8 @@ describe('NativeWorldState', () => { expect(status.meta.messageTreeMeta).toMatchObject({ depth: L1_TO_L2_MSG_TREE_HEIGHT, - size: BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * (i + 1)), - committedSize: BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * (i + 1)), + size: BigInt(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT * (i + 1)), + committedSize: BigInt(MAX_L1_TO_L2_MSGS_PER_CHECKPOINT * (i + 1)), initialSize: BigInt(0), oldestHistoricBlock: 1, unfinalizedBlockHeight: i + 1, diff --git a/yarn-project/world-state/src/native/native_world_state.ts b/yarn-project/world-state/src/native/native_world_state.ts index dff25d024f5d..2adde41e0bce 100644 --- a/yarn-project/world-state/src/native/native_world_state.ts +++ b/yarn-project/world-state/src/native/native_world_state.ts @@ -1,4 +1,4 @@ -import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants'; +import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { fromEntries, padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; @@ -264,19 +264,11 @@ export class NativeWorldStateService implements MerkleTreeDatabase { } public async handleL2BlockAndMessages(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise { - const isFirstBlock = l2Block.indexWithinCheckpoint === 0; - if (!isFirstBlock && l1ToL2Messages.length > 0) { - throw new Error( - `L1 to L2 messages must be empty for non-first blocks, but got ${l1ToL2Messages.length} messages for block ${l2Block.number}.`, - ); - } - - // We have to pad the given l1 to l2 messages, and the note hashes and nullifiers within tx effects, because that's - // how the trees are built by circuits. - const paddedL1ToL2Messages = isFirstBlock - ? padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) - : []; + // Any block may carry an L1-to-L2 message bundle and transition the L1-to-L2 message tree by its real (unpadded, + // compact) leaves, matching how the circuits build the tree. + // We have to pad the note hashes and nullifiers within tx effects because that's how the trees are built by + // circuits. const paddedNoteHashes = l2Block.body.txEffects.flatMap(txEffect => padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX), ); @@ -301,7 +293,7 @@ export class NativeWorldStateService implements MerkleTreeDatabase { // Forwarded so the native sync verifies the archive root against canonical and rejects a divergent tree. expectedArchiveRoot: l2Block.archive.root.toBuffer(), expectedPreviousArchiveRoot: l2Block.header.lastArchive.root.toBuffer(), - paddedL1ToL2Messages: paddedL1ToL2Messages.map(serializeLeaf), + paddedL1ToL2Messages: l1ToL2Messages.map(serializeLeaf), paddedNoteHashes: paddedNoteHashes.map(serializeLeaf), paddedNullifiers: paddedNullifiers.map(serializeLeaf), publicDataWrites: publicDataWrites.map(serializeLeaf), diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts index f0de3e58977b..1edcaf2bdb64 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts @@ -51,9 +51,6 @@ describe('ServerWorldStateSynchronizer', () => { beforeEach(() => { blockAndMessagesSource = mock(); blockAndMessagesSource.getBlockNumber.mockResolvedValue(BlockNumber(LATEST_BLOCK_NUMBER)); - blockAndMessagesSource.getL1ToL2Messages.mockImplementation(checkNumber => { - return Promise.resolve(checkpoints.find(c => c.checkpoint.number === checkNumber)?.messages ?? []); - }); merkleTreeRead = mock(); merkleTreeRead.getInitialHeader.mockReturnValue({ @@ -251,34 +248,6 @@ describe('ServerWorldStateSynchronizer', () => { await expect(pushBlocks(1, 5)).rejects.toThrow(/Test error/i); }); - it('fetches L1->L2 messages only for the first block in a checkpoint', async () => { - // Generate 3 mock checkpoints, each with i + 1 block and i + 2 message. - checkpoints = await timesParallel(3, i => - mockCheckpointAndMessages(CheckpointNumber(i + 1), { - startBlockNumber: BlockNumber( - Array(i + 1) - .fill(0) - .reduce((acc, _, index) => acc + index, 1), - ), - numBlocks: i + 1, - numL1ToL2Messages: i + 2, - }), - ); - - void server.start(); - await pushBlocks(1, 6); - - await expectServerStatus(WorldStateRunningState.RUNNING, 6); - - expect(merkleTreeDb.handleL2BlockAndMessages).toHaveBeenCalledTimes(6); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[0][1]).toEqual(checkpoints[0].messages); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[1][1]).toEqual(checkpoints[1].messages); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[2][1]).toEqual([]); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[3][1]).toEqual(checkpoints[2].messages); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[4][1]).toEqual([]); - expect(merkleTreeDb.handleL2BlockAndMessages.mock.calls[5][1]).toEqual([]); - }); - describe('getVerifiedSnapshot', () => { let snapshot: MockProxy; diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index fb14ea56c8d2..eefe75f2a976 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -1,3 +1,4 @@ +import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants'; import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; import type { Fr } from '@aztec/foundation/curves/bn254'; import { type Logger, createLogger } from '@aztec/foundation/log'; @@ -368,16 +369,25 @@ export class ServerWorldStateSynchronizer private async handleL2Blocks(l2Blocks: L2Block[]) { this.log.debug(`Handling L2 blocks ${l2Blocks[0].number} to ${l2Blocks.at(-1)!.number}`); - // Fetch the L1->L2 messages for the first block in a checkpoint. + // Derive each block's real L1-to-L2 message bundle from the compact leaf-index range it inserted: + // the messages between the parent block's L1-to-L2 tree leaf count and this block's, resolved via the + // Inbox buckets. Blocks in a batch are consecutive, so we track the running leaf count. const messagesForBlocks = new Map(); - await Promise.all( - l2Blocks - .filter(b => b.indexWithinCheckpoint === 0) - .map(async block => { - const l1ToL2Messages = await this.l2BlockSource.getL1ToL2Messages(block.checkpointNumber); - messagesForBlocks.set(block.number, l1ToL2Messages); - }), - ); + let prevLeafCount = await this.getL1ToL2LeafCountBefore(l2Blocks[0].number); + for (const block of l2Blocks) { + const blockLeafCount = BigInt(block.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); + if (blockLeafCount > prevLeafCount) { + const startBucket = await this.l2BlockSource.getInboxBucketByTotalMsgCount(prevLeafCount); + const endBucket = await this.l2BlockSource.getInboxBucketByTotalMsgCount(blockLeafCount); + if (startBucket !== undefined && endBucket !== undefined) { + messagesForBlocks.set( + block.number, + await this.l2BlockSource.getL1ToL2MessagesBetweenBuckets(startBucket.seq, endBucket.seq), + ); + } + } + prevLeafCount = blockLeafCount; + } let updateStatus: WorldStateStatusFull | undefined = undefined; for (const block of l2Blocks) { @@ -400,13 +410,23 @@ export class ServerWorldStateSynchronizer this.instrumentation.updateWorldStateMetrics(updateStatus); } + /** The L1-to-L2 message tree leaf count as of the block before `blockNumber` (0 if that block is genesis). */ + private async getL1ToL2LeafCountBefore(blockNumber: BlockNumber): Promise { + const parentNumber = blockNumber - 1; + if (parentNumber < INITIAL_L2_BLOCK_NUM) { + return 0n; + } + const parentBlock = await this.l2BlockSource.getBlockData({ number: BlockNumber(parentNumber) }); + return parentBlock === undefined ? 0n : BigInt(parentBlock.header.state.l1ToL2MessageTree.nextAvailableLeafIndex); + } + /** * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param l2Block - The L2 block to handle. * @param l1ToL2Messages - The L1 to L2 messages for the block. * @returns Whether the block handled was produced by this same node. */ - private async handleL2Block(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise { + protected async handleL2Block(l2Block: L2Block, l1ToL2Messages: Fr[]): Promise { this.log.debug(`Pushing L2 block ${l2Block.number} to merkle tree db `, { blockNumber: l2Block.number, blockHash: await l2Block.hash().then(h => h.toString()), diff --git a/yarn-project/world-state/src/test/utils.ts b/yarn-project/world-state/src/test/utils.ts index 1364155ec208..4ce5c907bc44 100644 --- a/yarn-project/world-state/src/test/utils.ts +++ b/yarn-project/world-state/src/test/utils.ts @@ -1,8 +1,8 @@ import { + MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, - NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, } from '@aztec/constants'; import { asyncMap } from '@aztec/foundation/async-map'; import { BlockNumber, type CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types'; @@ -50,13 +50,9 @@ export async function updateBlockState(block: L2Block, l1ToL2Messages: Fr[], for padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX), ); - const l1ToL2MessagesPadded = - block.indexWithinCheckpoint === 0 - ? padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) - : l1ToL2Messages; - + // Every block appends its real message leaves unpadded at compact indices. const noteHashInsert = fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded); - const messageInsert = fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded); + const messageInsert = fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages); await Promise.all([publicDataInsert, nullifierInsert, noteHashInsert, messageInsert]); const state = await fork.getStateReference(); @@ -77,16 +73,32 @@ export async function updateBlockState(block: L2Block, l1ToL2Messages: Fr[], for block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size)); } -export async function mockBlock( +export function mockBlock( blockNum: BlockNumber, size: number, fork: MerkleTreeWriteOperations, maxEffects: number | undefined = 1000, // Defaults to the maximum tx effects. - numL1ToL2Messages: number = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + numL1ToL2Messages: number = MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, isFirstBlockInCheckpoint: boolean = true, +) { + return mockBlockWithIndex(blockNum, isFirstBlockInCheckpoint ? 0 : 1, size, fork, numL1ToL2Messages, maxEffects); +} + +/** + * Builds a mock L2 block at an explicit position within its checkpoint, applying its state (including its L1-to-L2 + * message bundle) to the given fork. Unlike {@link mockBlock}, the caller chooses the `indexWithinCheckpoint`, so + * non-first blocks can carry message bundles — exercising the per-block message insertion path. + */ +export async function mockBlockWithIndex( + blockNum: BlockNumber, + indexWithinCheckpoint: number, + size: number, + fork: MerkleTreeWriteOperations, + numL1ToL2Messages: number = MAX_L1_TO_L2_MSGS_PER_CHECKPOINT, + maxEffects: number | undefined = 1000, // Defaults to the maximum tx effects. ) { const block = await L2Block.random(blockNum, { - indexWithinCheckpoint: isFirstBlockInCheckpoint ? IndexWithinCheckpoint(0) : IndexWithinCheckpoint(1), + indexWithinCheckpoint: IndexWithinCheckpoint(indexWithinCheckpoint), txsPerBlock: size, txOptions: { maxEffects }, }); diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts index 86ff3ee57655..6dd5f77baa9c 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts @@ -31,7 +31,10 @@ export const INITIAL_PUBLIC_DATA_TREE_SIZE = 2 * MAX_TOTAL_PUBLIC_DATA_UPDATE_RE export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations, ReadonlyWorldStateAccess { /** - * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). + * Handles a single L2 block: inserts its note hashes, nullifiers, public data writes, and the block's L1-to-L2 + * message bundle into the merkle trees. Any block may carry a message bundle and transition the L1-to-L2 message + * tree, not just the first block of a checkpoint. The bundle's real (unpadded, compact) leaves are appended as + * given, matching how the circuits build the tree. * @param block - The L2 block to handle. * @param l1ToL2Messages - The L1 to L2 messages for the block. */