diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index b4e01d50183..b92d0fddd8c 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -63,8 +63,6 @@ using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::rollup::test_utils::utils::base_rollup_inputs_from_kernels; using aztec3::circuits::rollup::test_utils::utils::get_empty_kernel; using aztec3::circuits::rollup::test_utils::utils::get_initial_nullifier_tree; -using aztec3::circuits::rollup::test_utils::utils::set_kernel_commitments; -using aztec3::circuits::rollup::test_utils::utils::set_kernel_nullifiers; // using aztec3::circuits::mock::mock_kernel_inputs; using aztec3::circuits::abis::AppendOnlyTreeSnapshot; @@ -287,7 +285,7 @@ TEST_F(base_rollup_tests, native_new_commitments_tree) for (uint8_t j = 0; j < KERNEL_NEW_COMMITMENTS_LENGTH; j++) { kernel_commitments[j] = new_commitments[i * KERNEL_NEW_COMMITMENTS_LENGTH + j]; } - set_kernel_commitments(kernel_data[i], kernel_commitments); + kernel_data[i].public_inputs.end.new_commitments = kernel_commitments; } // get sibling path @@ -389,7 +387,7 @@ void nullifier_insertion_test(std::array n for (uint8_t j = 0; j < KERNEL_NEW_NULLIFIERS_LENGTH; j++) { kernel_nullifiers[j] = new_nullifiers[i * KERNEL_NEW_NULLIFIERS_LENGTH + j]; } - set_kernel_nullifiers(kernel_data[i], kernel_nullifiers); + kernel_data[i].public_inputs.end.new_nullifiers = kernel_nullifiers; } BaseRollupInputs const inputs = base_rollup_inputs_from_kernels(kernel_data); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp b/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp index d18767dd490..044a5ed63ad 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp @@ -108,16 +108,19 @@ std::array compute_kernels_calldata_hash(std::array 8 fields // 8 nullifiers (4 per kernel) -> 8 fields // 8 public state transitions (4 per kernel) -> 16 fields + // 4 l2 -> l1 messages (2 per kernel) -> 4 fields // 2 contract deployments (1 per kernel) -> 6 fields - auto const number_of_inputs = (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + - STATE_TRANSITIONS_LENGTH * 2 + KERNEL_NEW_CONTRACTS_LENGTH * 3) * - 2; + auto const number_of_inputs = + (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + STATE_TRANSITIONS_LENGTH * 2 + + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + KERNEL_NEW_CONTRACTS_LENGTH * 3) * + 2; std::array calldata_hash_inputs; for (size_t i = 0; i < 2; i++) { auto new_commitments = kernel_data[i].public_inputs.end.new_commitments; auto new_nullifiers = kernel_data[i].public_inputs.end.new_nullifiers; auto state_transitions = kernel_data[i].public_inputs.end.state_transitions; + auto newL2ToL1msgs = kernel_data[i].public_inputs.end.new_l2_to_l1_msgs; size_t offset = 0; @@ -138,6 +141,11 @@ std::array compute_kernels_calldata_hash(std::array compute_kernels_calldata_hash(std::array{ high, low }; } -// Generates a 512 bit input from right and left 256 bit hashes. Then computes the sha256, and splits the hash into two -// field elements, a high and a low that is returned. -std::array compute_calldata_hash(std::array, 2> previous_rollup_data) +/** + * @brief From two calldata hashes, compute a single calldata hash + * + * @param calldata_hashes takes the 4 elements of 2 calldata hashes [high, low, high, low] + * @return std::array + */ +std::array compute_calldata_hash(std::array calldata_hashes) { // Generate a 512 bit input from right and left 256 bit hashes constexpr auto num_bytes = 2 * 32; std::array calldata_hash_input_bytes; - for (uint8_t i = 0; i < 2; i++) { - std::array calldata_hash_fr = previous_rollup_data[i].base_or_merge_rollup_public_inputs.calldata_hash; - - auto high_buffer = calldata_hash_fr[0].to_buffer(); - auto low_buffer = calldata_hash_fr[1].to_buffer(); - - for (uint8_t j = 0; j < 16; ++j) { - calldata_hash_input_bytes[i * 32 + j] = high_buffer[16 + j]; - calldata_hash_input_bytes[i * 32 + 16 + j] = low_buffer[16 + j]; + for (uint8_t i = 0; i < 4; i++) { + auto half = calldata_hashes[i].to_buffer(); + for (uint8_t j = 0; j < 16; j++) { + calldata_hash_input_bytes[i * 16 + j] = half[16 + j]; } } @@ -217,6 +224,20 @@ std::array compute_calldata_hash(std::array, return { high, low }; } +/** + * @brief From two previous rollup data, compute a single calldata hash + * + * @param previous_rollup_data + * @return std::array + */ +std::array compute_calldata_hash(std::array, 2> previous_rollup_data) +{ + return compute_calldata_hash({ previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[0], + previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[1], + previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[0], + previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[1] }); +} + // asserts that the end snapshot of previous_rollup 0 equals the start snapshot of previous_rollup 1 (i.e. ensure they // follow on from one-another). Ensures that right uses the tres that was updated by left. void assert_prev_rollups_follow_on_from_each_other(DummyComposer& composer, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp b/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp index 31f1015c048..fff00131db1 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp @@ -9,6 +9,7 @@ using aztec3::circuits::root_from_sibling_path; namespace aztec3::circuits::rollup::components { NT::fr calculate_empty_tree_root(size_t depth); +std::array compute_calldata_hash(std::array calldata_hashes); std::array compute_kernels_calldata_hash(std::array, 2> kernel_data); std::array compute_calldata_hash(std::array, 2> previous_rollup_data); void assert_prev_rollups_follow_on_from_each_other(DummyComposer& composer, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp index ff87a503838..588e365251d 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp @@ -11,6 +11,7 @@ #include "aztec3/circuits/kernel/private/utils.hpp" #include "aztec3/circuits/rollup/base/init.hpp" #include "aztec3/circuits/rollup/base/native_base_rollup_circuit.hpp" +#include "aztec3/circuits/rollup/components/components.hpp" #include "aztec3/circuits/rollup/test_utils/utils.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/dummy_composer.hpp" @@ -58,7 +59,6 @@ using aztec3::circuits::rollup::test_utils::utils::compare_field_hash_to_expecte using aztec3::circuits::rollup::test_utils::utils::get_empty_kernel; using aztec3::circuits::rollup::test_utils::utils::get_empty_l1_to_l2_messages; using aztec3::circuits::rollup::test_utils::utils::get_root_rollup_inputs; -using aztec3::circuits::rollup::test_utils::utils::set_kernel_commitments; // using aztec3::circuits::mock::mock_kernel_inputs; using aztec3::circuits::abis::AppendOnlyTreeSnapshot; @@ -146,14 +146,13 @@ TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks) std::vector const zero_bytes_vec = test_utils::utils::get_empty_calldata_leaf(); auto call_data_hash_inner = sha256::sha256(zero_bytes_vec); + // Compute a new calldata hash based on TWO of the above rollups std::array hash_input; for (uint8_t i = 0; i < 32; ++i) { hash_input[i] = call_data_hash_inner[i]; hash_input[32 + i] = call_data_hash_inner[i]; } - std::vector const calldata_hash_input_bytes_vec(hash_input.begin(), hash_input.end()); - auto calldata_hash = sha256::sha256(calldata_hash_input_bytes_vec); // get messages @@ -179,11 +178,6 @@ TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks) EXPECT_FALSE(composer.failed()); - // Expected hash of public inputs for an empty L2 block. Also used in the contract tests. - // Computed using l2-block-publisher.test.ts - fr const expected_hash = uint256_t("23f698e487c4e1b7383889f8864bc19591773d136c364c01d980bd13d0786ba1"); - ASSERT_EQ(outputs.hash(), expected_hash); - run_cbind(inputs, outputs, true); } @@ -216,10 +210,18 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) new_commitments[commitment_k] = val; data_tree.update_element(kernel_j * KERNEL_NEW_COMMITMENTS_LENGTH + commitment_k, val); } - set_kernel_commitments(kernels[kernel_j], new_commitments); + kernels[kernel_j].public_inputs.end.new_commitments = new_commitments; + + std::array new_l2_to_l1_messages; + for (uint8_t i = 0; i < KERNEL_NEW_L2_TO_L1_MSGS_LENGTH; i++) { + auto val = fr(kernel_j * KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + i + 1); + new_l2_to_l1_messages[i] = val; + } + kernels[kernel_j].public_inputs.end.new_l2_to_l1_msgs = new_l2_to_l1_messages; } - // TODO: Add nullifiers + // @todo @LHerskind: Add nullifiers + // @todo @LHerskind: Add public data writes // Contract tree NewContractData new_contract = { @@ -302,7 +304,7 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) .next_available_leaf_index = 4 }; ASSERT_EQ(outputs.end_contract_tree_snapshot, expected_contract_tree_snapshot); - // TODO: Check nullifier trees + // @todo @LHerskind: Check nullifier trees // Check historic data trees ASSERT_EQ(outputs.start_tree_of_historic_private_data_tree_roots_snapshot, start_historic_data_tree_snapshot); @@ -321,6 +323,12 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) ASSERT_EQ(outputs.start_l1_to_l2_messages_tree_snapshot, start_l1_to_l2_messages_tree_snapshot); ASSERT_EQ(outputs.end_l1_to_l2_messages_tree_snapshot, end_l1_to_l2_messages_tree_snapshot); + // Compute the expected calldata hash for the root rollup (including the l2 -> l1 messages) + auto left = components::compute_kernels_calldata_hash({ kernels[0], kernels[1] }); + auto right = components::compute_kernels_calldata_hash({ kernels[2], kernels[3] }); + auto root = components::compute_calldata_hash({ left[0], left[1], right[0], right[1] }); + ASSERT_EQ(outputs.calldata_hash, root); + EXPECT_FALSE(composer.failed()); run_cbind(rootRollupInputs, outputs, true); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp index 51308bfcf18..ff6ec136aeb 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp @@ -53,9 +53,10 @@ namespace aztec3::circuits::rollup::test_utils::utils { std::vector get_empty_calldata_leaf() { - auto const number_of_inputs = (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + - STATE_TRANSITIONS_LENGTH * 2 + KERNEL_NEW_CONTRACTS_LENGTH * 3) * - 2; + auto const number_of_inputs = + (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + STATE_TRANSITIONS_LENGTH * 2 + + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + KERNEL_NEW_CONTRACTS_LENGTH * 3) * + 2; auto const size = number_of_inputs * 32; std::vector input_data(size, 0); return input_data; @@ -72,20 +73,6 @@ std::array get_empty_l1_to_l2_messages( return l1_to_l2_messages; } -void set_kernel_nullifiers(KernelData& kernel_data, std::array new_nullifiers) -{ - for (size_t i = 0; i < KERNEL_NEW_NULLIFIERS_LENGTH; i++) { - kernel_data.public_inputs.end.new_nullifiers[i] = new_nullifiers[i]; - } -} - -void set_kernel_commitments(KernelData& kernel_data, std::array new_commitments) -{ - for (size_t i = 0; i < KERNEL_NEW_COMMITMENTS_LENGTH; i++) { - kernel_data.public_inputs.end.new_commitments[i] = new_commitments[i]; - } -} - BaseRollupInputs base_rollup_inputs_from_kernels(std::array kernel_data, MerkleTree& private_data_tree, MerkleTree& contract_tree, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp index b9c74e12f18..988966d53ed 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp @@ -102,10 +102,6 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyComposer& composer, std::array kernel_data, std::array l1_to_l2_messages); -void set_kernel_commitments(KernelData& kernel_data, std::array new_commitments); - -void set_kernel_nullifiers(KernelData& kernel_data, std::array new_nullifiers); - MergeRollupInputs get_merge_rollup_inputs(utils::DummyComposer& composer, std::array kernel_data); inline abis::PublicDataTransition make_public_write(fr leaf_index, fr old_value, fr new_value) diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index 3bf6ed53269..cd23cbdc541 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -23,7 +23,7 @@ constexpr size_t KERNEL_NEW_NULLIFIERS_LENGTH = 4; constexpr size_t KERNEL_NEW_CONTRACTS_LENGTH = 1; constexpr size_t KERNEL_PRIVATE_CALL_STACK_LENGTH = 8; constexpr size_t KERNEL_PUBLIC_CALL_STACK_LENGTH = 8; -constexpr size_t KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 4; +constexpr size_t KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 2; constexpr size_t KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH = 4; constexpr size_t VK_TREE_HEIGHT = 3; diff --git a/l1-contracts/src/core/Decoder.sol b/l1-contracts/src/core/Decoder.sol index 99947884153..2c5480613e1 100644 --- a/l1-contracts/src/core/Decoder.sol +++ b/l1-contracts/src/core/Decoder.sol @@ -13,57 +13,59 @@ pragma solidity >=0.8.18; * L2 Block Data specification * ------------------- * - * | byte start | num bytes | name - * | --- | --- | --- - * | 0x00 | 0x04 | L2 block number - * | 0x04 | 0x20 | startPrivateDataTreeSnapshot.root - * | 0x24 | 0x04 | startPrivateDataTreeSnapshot.nextAvailableLeafIndex - * | 0x28 | 0x20 | startNullifierTreeSnapshot.root - * | 0x48 | 0x04 | startNullifierTreeSnapshot.nextAvailableLeafIndex - * | 0x4c | 0x20 | startContractTreeSnapshot.root - * | 0x6c | 0x04 | startContractTreeSnapshot.nextAvailableLeafIndex - * | 0x70 | 0x20 | startTreeOfHistoricPrivateDataTreeRootsSnapshot.root - * | 0x90 | 0x04 | startTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x94 | 0x20 | startTreeOfHistoricContractTreeRootsSnapshot.root - * | 0xb4 | 0x04 | startTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex - * | 0xb8 | 0x20 | startPublicDataTreeRoot - * | 0xd8 | 0x20 | startL1ToL2MessagesTreeSnapshot.root - * | 0xf8 | 0x04 | startL1ToL2MessagesTreeSnapshot.nextAvailableLeafIndex - * | 0xfc | 0x20 | startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.root - * | 0x11c | 0x04 | startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x120 | 0x20 | endPrivateDataTreeSnapshot.root - * | 0x140 | 0x04 | endPrivateDataTreeSnapshot.nextAvailableLeafIndex - * | 0x144 | 0x20 | endNullifierTreeSnapshot.root - * | 0x164 | 0x04 | endNullifierTreeSnapshot.nextAvailableLeafIndex - * | 0x168 | 0x20 | endContractTreeSnapshot.root - * | 0x188 | 0x04 | endContractTreeSnapshot.nextAvailableLeafIndex - * | 0x18c | 0x20 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.root - * | 0x1ac | 0x04 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x1b0 | 0x20 | endTreeOfHistoricContractTreeRootsSnapshot.root - * | 0x1d0 | 0x04 | endTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x1d4 | 0x20 | endPublicDataTreeRoot - * | 0x1f4 | 0x20 | endL1ToL2MessagesTreeSnapshot.root - * | 0x214 | 0x04 | endL1ToL2MessagesTreeSnapshot.nextAvailableLeafIndex - * | 0x218 | 0x20 | endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.root - * | 0x238 | 0x04 | endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x23c | 0x04 | len(newCommitments) denoted x - * | 0x240 | x | newCommits - * | 0x240 + x | 0x04 | len(newNullifiers) denoted y - * | 0x244 + x | y | newNullifiers - * | 0x244 + a + b | 0x04 | len(newPublicDataWrites) denoted c - * | 0x248 + a + b | c | newPublicDataWrites (each element 64 bytes) - * | 0x248 + a + b + c | 0x04 | len(newContracts) denoted d - * | 0x24c + a + b + c | d | newContracts (each element 32 bytes) - * | 0x24c + a + b + c + d | d | newContractData (each element 52 bytes) - * | 0x24c + a + b + c + d | 0x04 | len(l1ToL2Messages) denoted e - * | 0x250 + a + b + c + d + e| e | l1ToL2Messages - * |--- |--- | --- - * TODO: a,b,c,d,e are number of elements and not bytes, need to be multiplied by the length of the elements. + * | byte start | num bytes | name + * | --- | --- | --- + * | 0x00 | 0x04 | L2 block number + * | 0x04 | 0x20 | startPrivateDataTreeSnapshot.root + * | 0x24 | 0x04 | startPrivateDataTreeSnapshot.nextAvailableLeafIndex + * | 0x28 | 0x20 | startNullifierTreeSnapshot.root + * | 0x48 | 0x04 | startNullifierTreeSnapshot.nextAvailableLeafIndex + * | 0x4c | 0x20 | startContractTreeSnapshot.root + * | 0x6c | 0x04 | startContractTreeSnapshot.nextAvailableLeafIndex + * | 0x70 | 0x20 | startTreeOfHistoricPrivateDataTreeRootsSnapshot.root + * | 0x90 | 0x04 | startTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x94 | 0x20 | startTreeOfHistoricContractTreeRootsSnapshot.root + * | 0xb4 | 0x04 | startTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex + * | 0xb8 | 0x20 | startPublicDataTreeRoot + * | 0xd8 | 0x20 | startL1ToL2MessagesTreeSnapshot.root + * | 0xf8 | 0x04 | startL1ToL2MessagesTreeSnapshot.nextAvailableLeafIndex + * | 0xfc | 0x20 | startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.root + * | 0x11c | 0x04 | startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x120 | 0x20 | endPrivateDataTreeSnapshot.root + * | 0x140 | 0x04 | endPrivateDataTreeSnapshot.nextAvailableLeafIndex + * | 0x144 | 0x20 | endNullifierTreeSnapshot.root + * | 0x164 | 0x04 | endNullifierTreeSnapshot.nextAvailableLeafIndex + * | 0x168 | 0x20 | endContractTreeSnapshot.root + * | 0x188 | 0x04 | endContractTreeSnapshot.nextAvailableLeafIndex + * | 0x18c | 0x20 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.root + * | 0x1ac | 0x04 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x1b0 | 0x20 | endTreeOfHistoricContractTreeRootsSnapshot.root + * | 0x1d0 | 0x04 | endTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x1d4 | 0x20 | endPublicDataTreeRoot + * | 0x1f4 | 0x20 | endL1ToL2MessagesTreeSnapshot.root + * | 0x214 | 0x04 | endL1ToL2MessagesTreeSnapshot.nextAvailableLeafIndex + * | 0x218 | 0x20 | endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.root + * | 0x238 | 0x04 | endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x23c | 0x04 | len(newCommitments) denoted a + * | 0x240 | a * 0x20 | newCommits (each element 32 bytes) + * | 0x240 + a * 0x20 | 0x04 | len(newNullifiers) denoted b + * | 0x244 + a * 0x20 | b * 0x20 | newNullifiers (each element 32 bytes) + * | 0x244 + (a + b) * 0x20 | 0x04 | len(newPublicDataWrites) denoted c + * | 0x248 + (a + b) * 0x20 | c * 0x40 | newPublicDataWrites (each element 64 bytes) + * | 0x248 + (a + b) * 0x20 + c * 0x40 | 0x04 | len(newL2ToL1msgs) denoted d + * | 0x24c + (a + b) * 0x20 + c * 0x40 | d * 0x20 | newL2ToL1msgs (each element 32 bytes) + * | 0x24c + (a + b + d) * 0x20 + c * 0x40 | 0x04 | len(newContracts) denoted e + * | 0x250 + (a + b + d) * 0x20 + c * 0x40 | e * 0x20 | newContracts (each element 32 bytes) + * | 0x250 + (a + b + d) * 0x20 + c * 0x40 + e * 0x20 | e * 0x34 | newContractData (each element 52 bytes) + * | 0x250 + (a + b + d) * 0x20 + c * 0x40 + e * 0x54 | 0x04 | len(l1ToL2Messages) denoted f + * | 0x254 + (a + b + d) * 0x20 + c * 0x40 + e * 0x54 | f * 0x20 | l1ToL2Messages (each element 32 bytes) + * |--- |--- | --- */ contract Decoder { uint256 internal constant COMMITMENTS_PER_KERNEL = 4; uint256 internal constant NULLIFIERS_PER_KERNEL = 4; uint256 internal constant PUBLIC_DATA_WRITES_PER_KERNEL = 4; + uint256 internal constant L2_TO_L1_MSGS_PER_KERNEL = 2; uint256 internal constant CONTRACTS_PER_KERNEL = 1; uint256 internal constant L1_TO_L2_MESSAGES_PER_ROLLUP = 16; @@ -166,6 +168,7 @@ contract Decoder { uint256 commitmentCount; uint256 nullifierCount; uint256 dataWritesCount; + uint256 l2ToL1MessagesCount; uint256 contractCount; uint256 l1Tol2MessagesCount; } @@ -174,6 +177,7 @@ contract Decoder { uint256 commitmentOffset; uint256 nullifierOffset; uint256 publicDataOffset; + uint256 l2ToL1MsgsOffset; uint256 contractOffset; uint256 contractDataOffset; uint256 l1ToL2MessagesOffset; @@ -201,6 +205,8 @@ contract Decoder { offset := add(add(offset, 0x4), mul(nullifierCount, 0x20)) let dataWritesCount := and(shr(224, calldataload(offset)), 0xffffffff) offset := add(add(offset, 0x4), mul(nullifierCount, 0x40)) + let l2ToL1Count := and(shr(224, calldataload(offset)), 0xffffffff) + offset := add(add(offset, 0x4), mul(l2ToL1Count, 0x20)) let contractCount := and(shr(224, calldataload(offset)), 0xffffffff) offset := add(add(offset, 0x4), mul(contractCount, 0x54)) let l1Tol2MessagesCount := and(shr(224, calldataload(offset)), 0xffffffff) @@ -209,8 +215,9 @@ contract Decoder { mstore(lengths, commitmentCount) mstore(add(lengths, 0x20), nullifierCount) mstore(add(lengths, 0x40), dataWritesCount) - mstore(add(lengths, 0x60), contractCount) - mstore(add(lengths, 0x80), l1Tol2MessagesCount) // currently included to allow optimisation where empty messages are not included in calldata + mstore(add(lengths, 0x60), l2ToL1Count) + mstore(add(lengths, 0x80), contractCount) + mstore(add(lengths, 0xa0), l1Tol2MessagesCount) // currently included to allow optimisation where empty messages are not included in calldata } } @@ -223,9 +230,10 @@ contract Decoder { offsets.commitmentOffset = 0x240; offsets.nullifierOffset = offsets.commitmentOffset + 0x4 + lengths.commitmentCount * 0x20; offsets.publicDataOffset = offsets.nullifierOffset + 0x4 + lengths.nullifierCount * 0x20; - offsets.contractOffset = offsets.publicDataOffset + 0x4 + lengths.dataWritesCount * 0x40; + offsets.l2ToL1MsgsOffset = offsets.publicDataOffset + 0x4 + lengths.dataWritesCount * 0x40; + offsets.contractOffset = offsets.l2ToL1MsgsOffset + 0x4 + lengths.l2ToL1MessagesCount * 0x20; offsets.contractDataOffset = offsets.contractOffset + lengths.contractCount * 0x20; - offsets.l1ToL2MessagesOffset = offsets.contractDataOffset + lengths.contractCount * 0x54; + offsets.l1ToL2MessagesOffset = offsets.contractDataOffset + 0x4 + lengths.contractCount * 0x34; for (uint256 i = 0; i < baseLeafs.length; i++) { /** @@ -237,6 +245,8 @@ contract Decoder { * newNullifiersKernel2, * newPublicDataWritesKernel1, * newPublicDataWritesKernel2, + * newL2ToL1MsgsKernel1, + * newL2ToL1MsgsKernel2, * newContractLeafKernel1, * newContractLeafKernel2, * newContractDataKernel1.aztecAddress, @@ -249,7 +259,7 @@ contract Decoder { */ // Create the leaf to contain commitments (8 * 0x20) + nullifiers (8 * 0x20) // + new public data writes (8 * 0x40) + contract deployments (2 * 0x60) - bytes memory baseLeaf = new bytes(0x4c0); + bytes memory baseLeaf = new bytes(0x540); assembly { let dstOffset := 0x20 @@ -275,14 +285,24 @@ contract Decoder { ) dstOffset := add(dstOffset, mul(0x08, 0x40)) + // Adding new l2 to l1 msgs + calldatacopy( + add(baseLeaf, dstOffset), + add(_l2Block.offset, mload(add(offsets, 0x60))), + mul(0x04, 0x20) + ) + dstOffset := add(dstOffset, mul(0x04, 0x20)) + // Adding Contract Leafs calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, mload(add(offsets, 0x60))), mul(2, 0x20) + add(baseLeaf, dstOffset), + add(_l2Block.offset, mload(add(offsets, 0x80))), + mul(0x2, 0x20) ) dstOffset := add(dstOffset, mul(2, 0x20)) // Kernel1.contract.aztecAddress - let contractDataOffset := mload(add(offsets, 0x80)) + let contractDataOffset := mload(add(offsets, 0xa0)) calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, contractDataOffset), 0x20) dstOffset := add(dstOffset, 0x20) @@ -292,7 +312,7 @@ contract Decoder { calldatacopy( add(baseLeaf, dstOffset), add(_l2Block.offset, add(contractDataOffset, 0x20)), 0x14 ) - dstOffset := add(dstOffset, 0x20) + dstOffset := add(dstOffset, 0x14) // Kernel2.contract.aztecAddress calldatacopy( @@ -311,6 +331,7 @@ contract Decoder { offsets.commitmentOffset += 2 * COMMITMENTS_PER_KERNEL * 0x20; offsets.nullifierOffset += 2 * NULLIFIERS_PER_KERNEL * 0x20; offsets.publicDataOffset += 2 * PUBLIC_DATA_WRITES_PER_KERNEL * 0x40; + offsets.l2ToL1MsgsOffset += 2 * L2_TO_L1_MSGS_PER_KERNEL * 0x20; offsets.contractOffset += 2 * 0x20; offsets.contractDataOffset += 2 * 0x34; @@ -323,11 +344,13 @@ contract Decoder { bytes32 messagesHash; { uint256 messagesHashPreimageSize = 0x20 * L1_TO_L2_MESSAGES_PER_ROLLUP; - bytes memory messagesHashPreimage = new bytes(messagesHashPreimageSize); + bytes memory messagesHashPreimage = new bytes( + messagesHashPreimageSize + ); assembly { calldatacopy( add(messagesHashPreimage, 0x20), - add(mload(add(offsets, 0xa0)), 20), + add(_l2Block.offset, mload(add(offsets, 0xc0))), messagesHashPreimageSize ) } diff --git a/l1-contracts/test/Decoder.t.sol b/l1-contracts/test/Decoder.t.sol index 8e2c1f666d5..3f1cf9bdc1f 100644 --- a/l1-contracts/test/Decoder.t.sol +++ b/l1-contracts/test/Decoder.t.sol @@ -7,204 +7,102 @@ import {Decoder} from "@aztec3/core/Decoder.sol"; import {Rollup} from "@aztec3/core/Rollup.sol"; import {DecoderHelper} from "./DecoderHelper.sol"; -// Blocks generated using `l2-block-publisher.test.ts` +/** + * Blocks are generated using the `integration_l1_publisher.test.ts` tests. + * Main use of these test is shorter cycles when updating the decoder contract. + */ contract DecoderTest is Test { Rollup internal rollup; DecoderHelper internal helper; - bytes block_1 = - hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed000000020000001000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020300000000000000000000000000000000000000000000000000000000000002040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080200000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080500000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000806000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041b024f6e2e258ac4fa7b3a0d03f9fa242eee6d884ec85d0efd4beca26a88da2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006010202020202020202020202020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - bytes block_2 = - hex"000000020283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed00000002013ffea42e60a3be0af304384d83ad4411df13f66213997a7f0b7551e242f19d0000002001872181b5fe2c7ea15e1e72f5672bc777d61c807771ff7ae40c9b2aa816323500000028063d7b42d552599d3f3ff8fbc93e55484d49fc20dcc41940e3ebeaac4483a8ba0000000803b6339133ac1ca21463e1e3370ca136862bac1be49bdc6e1e69f73068a22ebe0000000316204b8532027613f551ad0530dc70c1c3be36fb7828a3a6539a100c57d25034000000030aa1281a92ab93a92ea1e45d49ce373a45fdb0b7a988416e63cd0728252a112a0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000020236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030000001000000000000000000000000000000000000000000000000000000000000001020000000000000000000000000000000000000000000000000000000000000103000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000001050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080300000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080600000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000807000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042ddfdac63df2e340ea582ed2b6c9d23bf04f6e98c281c25c6dd7e87251185b3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006020303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - bytes block_empty_1 = - hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed00000002000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - bytes block_empty_2 = - hex"000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000202d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000282f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000008236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030aaa66ea64a4b9493d7237d092f8276e31eb3f8b14ae5c5e0a91fa5627745a83000000032b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000020236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c00000003000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes block_mixed_1 = + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010813349a787d3f13ec3492de8b6a5c06ba871cb7d2533b8859f3c4069338450100000010069dae963409c321ded6da153196448d64875d356f0ed54bfcf4ba554d6519ba00000018279f38b90665ef7dae8a59f015029274d7837545f62f1f00ab64ffb714d043e90000000412e58befb4676abe3a279ec129e4d48b53eb1b1724a6c01274b39f6122dfc0bf00000002128683784c66165b4b7acf1502ee0f2ed6e5e614f9992375e5f98b1566f2d20a000000022d9b8d2353587ca56bdf967b4bb8847af3671bd6901e9e28f82c240c6e33129a2be9dc687a1bbe5b10ecac6869ca85a46d9c9afe064f55d2e8e237ba01f4faa3000000101a3cc59d6b87c8046f558f7c16e2880c120ad353f83c20c604fdb34458b15a5100000002000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000012100000000000000000000000000000000000000000000000000000000000001220000000000000000000000000000000000000000000000000000000000000123000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001410000000000000000000000000000000000000000000000000000000000000142000000000000000000000000000000000000000000000000000000000000014300000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000161000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000018100000000000000000000000000000000000000000000000000000000000001820000000000000000000000000000000000000000000000000000000000000183000000100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000022100000000000000000000000000000000000000000000000000000000000002220000000000000000000000000000000000000000000000000000000000000223000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002410000000000000000000000000000000000000000000000000000000000000242000000000000000000000000000000000000000000000000000000000000024300000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000261000000000000000000000000000000000000000000000000000000000000026200000000000000000000000000000000000000000000000000000000000002630000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000028100000000000000000000000000000000000000000000000000000000000002820000000000000000000000000000000000000000000000000000000000000283000000100000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000052a0000000000000000000000000000000000000000000000000000000000000521000000000000000000000000000000000000000000000000000000000000052b0000000000000000000000000000000000000000000000000000000000000522000000000000000000000000000000000000000000000000000000000000052c0000000000000000000000000000000000000000000000000000000000000523000000000000000000000000000000000000000000000000000000000000052d0000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000054a0000000000000000000000000000000000000000000000000000000000000541000000000000000000000000000000000000000000000000000000000000054b0000000000000000000000000000000000000000000000000000000000000542000000000000000000000000000000000000000000000000000000000000054c0000000000000000000000000000000000000000000000000000000000000543000000000000000000000000000000000000000000000000000000000000054d0000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000056a0000000000000000000000000000000000000000000000000000000000000561000000000000000000000000000000000000000000000000000000000000056b0000000000000000000000000000000000000000000000000000000000000562000000000000000000000000000000000000000000000000000000000000056c0000000000000000000000000000000000000000000000000000000000000563000000000000000000000000000000000000000000000000000000000000056d0000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000058a0000000000000000000000000000000000000000000000000000000000000581000000000000000000000000000000000000000000000000000000000000058b0000000000000000000000000000000000000000000000000000000000000582000000000000000000000000000000000000000000000000000000000000058c0000000000000000000000000000000000000000000000000000000000000583000000000000000000000000000000000000000000000000000000000000058d00000008000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003210000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000361000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003810000000426fcb9639d15aabe6d792e23ab12fb9633046d4be6911a60d64471d7560d3f6809143b7d4943a3485115d37e7596938a16c91b6055f3837640d8c36b8303bb3c06fb5fb553496e5e0b48834087e036acf99d6d935dc2ebf43c82788cb5ed1c6a2f4bd77ac2bb5474d48c2856135d18168cd6f69f77143c60b3cc370319419dac0000000000000000000000000000000000000000000000000000000000001020212121212121212121212121212121212121212100000000000000000000000000000000000000000000000000000000000010404141414141414141414141414141414141414141000000000000000000000000000000000000000000000000000000000000106061616161616161616161616161616161616161610000000000000000000000000000000000000000000000000000000000001080818181818181818181818181818181818181818100000010000000000000000000000000000000000000000000000000000000000000040100000000000000000000000000000000000000000000000000000000000004020000000000000000000000000000000000000000000000000000000000000403000000000000000000000000000000000000000000000000000000000000040400000000000000000000000000000000000000000000000000000000000004050000000000000000000000000000000000000000000000000000000000000406000000000000000000000000000000000000000000000000000000000000040700000000000000000000000000000000000000000000000000000000000004080000000000000000000000000000000000000000000000000000000000000409000000000000000000000000000000000000000000000000000000000000040a000000000000000000000000000000000000000000000000000000000000040b000000000000000000000000000000000000000000000000000000000000040c000000000000000000000000000000000000000000000000000000000000040d000000000000000000000000000000000000000000000000000000000000040e000000000000000000000000000000000000000000000000000000000000040f0000000000000000000000000000000000000000000000000000000000000410"; function setUp() public { rollup = new Rollup(); helper = new DecoderHelper(); } - function testEmptyBlocks() public { - { - (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = - helper.computeDiffRootAndMessagesHash(block_empty_2); - assertEq( - diffRoot, - 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, - "Invalid diff root" - ); - - assertEq( - l1ToL2MessagesHash, - 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, - "Invalid messages hash" - ); - - ( - uint256 l2BlockNumber, - bytes32 startStateHash, - bytes32 endStateHash, - bytes32 publicInputsHash - ) = helper.decode(block_empty_1); - - assertEq(l2BlockNumber, 1, "Invalid block number"); - assertEq( - startStateHash, - 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, - "Invalid start state hash" - ); - assertEq( - endStateHash, - 0x3dff2c815f7e5f5b8b3a2397347cc928001c73e5442d6dad5af61c3329b4fc8c, - "Invalid end state hash" - ); - assertEq( - publicInputsHash, - 0x23f698e487c4e1b7383889f8864bc19591773d136c364c01d980bd13d0786ba1, - "Invalid public input hash" - ); - - rollup.process(bytes(""), block_empty_1); - - assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); - } - - { - (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = - helper.computeDiffRootAndMessagesHash(block_empty_2); - assertEq( - diffRoot, - 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, - "Invalid diff root" - ); - - assertEq( - l1ToL2MessagesHash, - 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, - "Invalid messages hash" - ); - - ( - uint256 l2BlockNumber, - bytes32 startStateHash, - bytes32 endStateHash, - bytes32 publicInputsHash - ) = helper.decode(block_empty_2); - - assertEq(l2BlockNumber, 2, "Invalid block number"); - assertEq( - startStateHash, - 0x3dff2c815f7e5f5b8b3a2397347cc928001c73e5442d6dad5af61c3329b4fc8c, - "Invalid start state hash" - ); - assertEq( - endStateHash, - 0x906b283a0f25f74711aa8e1cdaea18a6e80bebe9ce9118315a0f31433feaffe3, - "Invalid end state hash" - ); - assertEq( - publicInputsHash, - 0x0f6cd26577a7c4edf15eb3785315d9f8dbcbc8a3ffc0dba7e04be4e37b09228f, - "Invalid public input hash" - ); - - rollup.process(bytes(""), block_empty_2); - - assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); - } + function testEmptyBlock() public { + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_empty_1); + assertEq( + diffRoot, + 0xe861f905de96ae1d3fcec548d838e11aac2a74fccd23a7950689a46200f875ed, + "Invalid diff root" + ); + + assertEq( + l1ToL2MessagesHash, + 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, + "Invalid messages hash" + ); + + (uint256 l2BlockNumber, bytes32 startStateHash, bytes32 endStateHash, bytes32 publicInputsHash) + = helper.decode(block_empty_1); + + assertEq(l2BlockNumber, 1, "Invalid block number"); + assertEq( + startStateHash, + 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, + "Invalid start state hash" + ); + assertEq( + endStateHash, + 0x3dff2c815f7e5f5b8b3a2397347cc928001c73e5442d6dad5af61c3329b4fc8c, + "Invalid end state hash" + ); + assertEq( + publicInputsHash, + 0x2c6390588e4d61282f591e92758e46770196d0fe7fe873285a52a540455eb001, + "Invalid public input hash" + ); + + rollup.process(bytes(""), block_empty_1); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); } - function testNonEmptyBlocks() public { - { - (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = - helper.computeDiffRootAndMessagesHash(block_1); - assertEq( - diffRoot, - 0x05ab40c0ddda5b1846c6283c0a99ea7da9ebb3ea46f33225e72e0d0333bf251f, - "Invalid diff root block 1" - ); - - assertEq( - l1ToL2MessagesHash, - 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, - "Invalid messages hash" - ); - - ( - uint256 l2BlockNumber, - bytes32 startStateHash, - bytes32 endStateHash, - bytes32 publicInputsHash - ) = helper.decode(block_1); - - assertEq(l2BlockNumber, 1, "Invalid block number"); - assertEq( - startStateHash, - 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, - "Invalid start state hash block 1" - ); - assertEq( - endStateHash, - 0x8a6161ff9185b2354adadb2a6fbd0a8279d2b7558e617f46cfbd42af3073729c, - "Invalid end state hash block 1" - ); - assertEq( - publicInputsHash, - 0x04b30d90646ca894b0f04cafb6bd76cc7db900dc8cb0a8904b21ff2a6cd4f23e, - "Invalid public input hash block 1" - ); - - rollup.process(bytes(""), block_1); - - assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash block 1"); - } - - { - (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = - helper.computeDiffRootAndMessagesHash(block_2); - assertEq( - diffRoot, - 0x04a10b2ce6eb66a3ae547efacc53760ec64fb86c901f9cadb36c104cc532cb99, - "Invalid diff root block 2" - ); - - assertEq( - l1ToL2MessagesHash, - 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, - "Invalid l1 to l2 messages hash block 2" - ); - - ( - uint256 l2BlockNumber, - bytes32 startStateHash, - bytes32 endStateHash, - bytes32 publicInputsHash - ) = helper.decode(block_2); - - assertEq(l2BlockNumber, 2, "Invalid block number"); - assertEq( - startStateHash, - 0x8a6161ff9185b2354adadb2a6fbd0a8279d2b7558e617f46cfbd42af3073729c, - "Invalid start state hash block 2" - ); - assertEq( - endStateHash, - 0xd2055c0813616d7073f6bcc905a755ed525e5541b3e5e1b286fd583729c74ea7, - "Invalid end state hash block 2" - ); - assertEq( - publicInputsHash, - 0x22d088d033eac3347d80581f49057fe24d366cdfdaa644ad4a286d4f8280842b, - "Invalid public input hash block 2" - ); - - rollup.process(bytes(""), block_2); - - assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); - } + function testMixBlock() public { + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_mixed_1); + assertEq( + diffRoot, + 0xc2ff90c3a27cbc7a6708919ca24ac2c073af629439ac8a356722f6f93c210fcc, + "Invalid diff root" + ); + + assertEq( + l1ToL2MessagesHash, + 0x8aa5c6281fed753c0154da77a3a71f875962b64c12b1d1e28e22b23a32069178, + "Invalid messages hash" + ); + + (uint256 l2BlockNumber, bytes32 startStateHash, bytes32 endStateHash, bytes32 publicInputsHash) + = helper.decode(block_mixed_1); + + assertEq(l2BlockNumber, 1, "Invalid block number"); + assertEq( + startStateHash, + 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, + "Invalid start state hash" + ); + assertEq( + endStateHash, + 0x1feaf0c58ed1deb655c6e6762d329f381277e66bd703652b648963ffc8beea8f, + "Invalid end state hash" + ); + assertEq( + publicInputsHash, + 0x2bc18700305b59209fa7180fdb2aea9e1ad19f98e08acb45b8a6318ddf3d3282, + "Invalid public input hash" + ); + + rollup.process(bytes(""), block_mixed_1); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); } } diff --git a/yarn-project/circuits.js/src/structs/constants.ts b/yarn-project/circuits.js/src/structs/constants.ts index d825f7d2138..f25b38b5ca0 100644 --- a/yarn-project/circuits.js/src/structs/constants.ts +++ b/yarn-project/circuits.js/src/structs/constants.ts @@ -20,7 +20,7 @@ export const KERNEL_NEW_NULLIFIERS_LENGTH = 4; export const KERNEL_NEW_CONTRACTS_LENGTH = 1; export const KERNEL_PRIVATE_CALL_STACK_LENGTH = 8; export const KERNEL_PUBLIC_CALL_STACK_LENGTH = 8; -export const KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 4; +export const KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 2; export const KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH = 4; export const VK_TREE_HEIGHT = 3; diff --git a/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap index df5bb8aa164..0816233fc6c 100644 --- a/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap @@ -24,7 +24,7 @@ private_call_stack: public_call_stack: [ 0x401 0x402 0x403 0x404 0x405 0x406 0x407 0x408 ] new_l2_to_l1_msgs: -[ 0x501 0x502 0x503 0x504 ] +[ 0x501 0x502 ] new_contracts: [ contract_address: 0x601 portal_contract_address: 0x202020202020202020202020202020202020202 @@ -167,7 +167,7 @@ private_call_stack: public_call_stack: [ 0x401 0x402 0x403 0x404 0x405 0x406 0x407 0x408 ] new_l2_to_l1_msgs: -[ 0x501 0x502 0x503 0x504 ] +[ 0x501 0x502 ] new_contracts: [ contract_address: 0x601 portal_contract_address: 0x202020202020202020202020202020202020202 @@ -340,7 +340,7 @@ private_call_stack: public_call_stack: [ 0x1401 0x1402 0x1403 0x1404 0x1405 0x1406 0x1407 0x1408 ] new_l2_to_l1_msgs: -[ 0x1501 0x1502 0x1503 0x1504 ] +[ 0x1501 0x1502 ] new_contracts: [ contract_address: 0x1601 portal_contract_address: 0x202020202020202020202020202020202020202 @@ -683,7 +683,7 @@ private_call_stack: public_call_stack: [ 0x401 0x402 0x403 0x404 0x405 0x406 0x407 0x408 ] new_l2_to_l1_msgs: -[ 0x501 0x502 0x503 0x504 ] +[ 0x501 0x502 ] new_contracts: [ contract_address: 0x601 portal_contract_address: 0x202020202020202020202020202020202020202 @@ -819,7 +819,7 @@ private_call_stack: public_call_stack: [ 0x401 0x402 0x403 0x404 0x405 0x406 0x407 0x408 ] new_l2_to_l1_msgs: -[ 0x501 0x502 0x503 0x504 ] +[ 0x501 0x502 ] new_contracts: [ contract_address: 0x601 portal_contract_address: 0x202020202020202020202020202020202020202 diff --git a/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap index 389baab97a5..2a5da1f562e 100644 --- a/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap @@ -26,7 +26,7 @@ private_call_stack: public_call_stack: [ 0x500 0x501 0x502 0x503 0x504 0x505 0x506 0x507 ] new_l2_to_l1_msgs: -[ 0x600 0x601 0x602 0x603 ] +[ 0x600 0x601 ] new_contracts: [ contract_address: 0x700 portal_contract_address: 0x101010101010101010101010101010101010101 @@ -171,7 +171,7 @@ private_call_stack: public_call_stack: [ 0x600 0x601 0x602 0x603 0x604 0x605 0x606 0x607 ] new_l2_to_l1_msgs: -[ 0x700 0x701 0x702 0x703 ] +[ 0x700 0x701 ] new_contracts: [ contract_address: 0x800 portal_contract_address: 0x101010101010101010101010101010101010101 diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 0a4bf5747be..3cc1e48d5c8 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -3,11 +3,12 @@ import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { KERNEL_NEW_COMMITMENTS_LENGTH, + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, KERNEL_NEW_NULLIFIERS_LENGTH, KernelCircuitPublicInputs, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - PublicDataRead, PublicDataTransition, + STATE_TRANSITIONS_LENGTH, range, } from '@aztec/circuits.js'; import { fr, makeNewContractData, makeProof } from '@aztec/circuits.js/factories'; @@ -26,7 +27,7 @@ import { makePublicTx, } from '@aztec/sequencer-client'; import { MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; -import { beforeAll, describe, expect, it } from '@jest/globals'; +import { beforeEach, describe, expect, it } from '@jest/globals'; import { default as levelup } from 'levelup'; import { Address, @@ -53,6 +54,9 @@ const logger = createDebugLogger('aztec:integration_l1_publisher'); const config = getConfigEnvVars(); +// @todo (Issue https://github.com/AztecProtocol/aztec-packages/issues/472) Figure out why l1 -> l2 messages are breaking >1 consecutive blocks for mixed blocks. +const numberOfConsecutiveBlocks = 1; + describe('L1Publisher integration', () => { let publicClient: PublicClient; @@ -69,7 +73,7 @@ describe('L1Publisher integration', () => { let builder: SoloBlockBuilder; let builderDb: MerkleTreeOperations; - beforeAll(async () => { + beforeEach(async () => { const deployerAccount = privateKeyToAccount(deployerPK); const { rollupAddress: rollupAddress_, @@ -122,46 +126,104 @@ describe('L1Publisher integration', () => { return makeEmptyProcessedTxFromHistoricTreeRoots(historicTreeRoots); }; - const makeContractDeployProcessedTx = async (seed = 0x1) => { - const tx = await makeEmptyProcessedTx(); - tx.data.end.newContracts = [makeNewContractData(seed + 0x1000)]; - return tx; - }; + const makeBloatedProcessedTx = async (seed = 0x1) => { + const publicTx = makePublicTx(seed); + const kernelOutput = KernelCircuitPublicInputs.empty(); + kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(builderDb); + kernelOutput.end.stateTransitions = range(STATE_TRANSITIONS_LENGTH, seed + 0x500).map( + i => new PublicDataTransition(fr(i), fr(0), fr(i + 10)), + ); + + const tx = await makeProcessedTx(publicTx, kernelOutput, makeProof()); - const makePrivateProcessedTx = async (seed = 0x1) => { - const tx = await makeEmptyProcessedTx(); tx.data.end.newCommitments = range(KERNEL_NEW_COMMITMENTS_LENGTH, seed + 0x100).map(fr); tx.data.end.newNullifiers = range(KERNEL_NEW_NULLIFIERS_LENGTH, seed + 0x200).map(fr); + tx.data.end.newL2ToL1Msgs = range(KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, seed + 0x300).map(fr); + tx.data.end.newContracts = [makeNewContractData(seed + 0x1000)]; + return tx; }; - const makePublicCallProcessedTx = async (seed = 0x1) => { - const publicTx = makePublicTx(seed); - const kernelOutput = KernelCircuitPublicInputs.empty(); - kernelOutput.end.stateReads[0] = new PublicDataRead(fr(1), fr(0)); - kernelOutput.end.stateTransitions[0] = new PublicDataTransition(fr(2), fr(0), fr(12)); - kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(builderDb); - return await makeProcessedTx(publicTx, kernelOutput, makeProof()); - }; + it(`Build ${numberOfConsecutiveBlocks} blocks of 4 bloated txs building on each other`, async () => { + const stateInRollup_ = await rollup.read.rollupStateHash(); + expect(hexStringToBuffer(stateInRollup_.toString())).toEqual(Buffer.alloc(32, 0)); + + const blockNumber = await publicClient.getBlockNumber(); + + for (let i = 0; i < numberOfConsecutiveBlocks; i++) { + const l1ToL2Messages = range(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, 128 * i + 1 + 0x400).map(fr); + const txs = [ + await makeBloatedProcessedTx(128 * i + 32), + await makeBloatedProcessedTx(128 * i + 64), + await makeBloatedProcessedTx(128 * i + 96), + await makeBloatedProcessedTx(128 * i + 128), + ]; + const [block] = await builder.buildL2Block(1 + i, txs, l1ToL2Messages); + + /*// Useful for sol tests block generation + const encoded = block.encode(); + console.log(`Size (${encoded.length}): ${encoded.toString('hex')}`); + console.log(`calldata hash: 0x${block.getCalldataHash().toString('hex')}`); + console.log(`l1 to l2 message hash: 0x${block.getL1ToL2MessagesHash().toString('hex')}`); + console.log(`start state hash: 0x${block.getStartStateHash().toString('hex')}`); + console.log(`end state hash: 0x${block.getEndStateHash().toString('hex')}`); + console.log(`public data hash: 0x${block.getPublicInputsHash().toBuffer().toString('hex')}`);*/ + + await publisher.processL2Block(block); + + const logs = await publicClient.getLogs({ + address: rollupAddress, + event: getAbiItem({ + abi: RollupAbi, + name: 'L2BlockProcessed', + }), + fromBlock: blockNumber + 1n, + }); + expect(logs).toHaveLength(i + 1); + expect(logs[i].args.blockNum).toEqual(BigInt(i + 1)); + + const ethTx = await publicClient.getTransaction({ + hash: logs[i].transactionHash!, + }); - it('Build 2 blocks of 4 txs building on each other', async () => { + const expectedData = encodeFunctionData({ + abi: RollupAbi, + functionName: 'process', + args: [`0x${l2Proof.toString('hex')}`, `0x${block.encode().toString('hex')}`], + }); + expect(ethTx.input).toEqual(expectedData); + + const decoderArgs = [`0x${block.encode().toString('hex')}`] as const; + const decodedHashes = await decoderHelper.read.computeDiffRootAndMessagesHash(decoderArgs); + const decodedRes = await decoderHelper.read.decode(decoderArgs); + const stateInRollup = await rollup.read.rollupStateHash(); + + expect(block.number).toEqual(Number(decodedRes[0])); + expect(block.getStartStateHash()).toEqual(hexStringToBuffer(decodedRes[1].toString())); + expect(block.getEndStateHash()).toEqual(hexStringToBuffer(decodedRes[2].toString())); + expect(block.getEndStateHash()).toEqual(hexStringToBuffer(stateInRollup.toString())); + expect(block.getPublicInputsHash().toBuffer()).toEqual(hexStringToBuffer(decodedRes[3].toString())); + expect(block.getCalldataHash()).toEqual(hexStringToBuffer(decodedHashes[0].toString())); + expect(block.getL1ToL2MessagesHash()).toEqual(hexStringToBuffer(decodedHashes[1].toString())); + } + }, 60_000); + + it(`Build ${numberOfConsecutiveBlocks} blocks of 4 empty txs building on each other`, async () => { const stateInRollup_ = await rollup.read.rollupStateHash(); expect(hexStringToBuffer(stateInRollup_.toString())).toEqual(Buffer.alloc(32, 0)); - for (let i = 0; i < 2; i++) { - // @todo Should have advanced txs as well instead of these simple transactions. - // @todo Should have messages l1 -> l2 + const blockNumber = await publicClient.getBlockNumber(); - const txsLeft = [await makePrivateProcessedTx(i + 1), await makePublicCallProcessedTx(i + 1)]; - const txsRight = [await makeContractDeployProcessedTx(i + 1), await makeEmptyProcessedTx()]; + for (let i = 0; i < numberOfConsecutiveBlocks; i++) { const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); - - // Actually build a block! - const txs = [...txsLeft, ...txsRight]; + const txs = [ + await makeEmptyProcessedTx(), + await makeEmptyProcessedTx(), + await makeEmptyProcessedTx(), + await makeEmptyProcessedTx(), + ]; const [block] = await builder.buildL2Block(1 + i, txs, l1ToL2Messages); - // Now we can use the block we built! - const blockNumber = await publicClient.getBlockNumber(); await publisher.processL2Block(block); const logs = await publicClient.getLogs({ @@ -172,11 +234,11 @@ describe('L1Publisher integration', () => { }), fromBlock: blockNumber + 1n, }); - expect(logs).toHaveLength(1); - expect(logs[0].args.blockNum).toEqual(BigInt(i + 1)); + expect(logs).toHaveLength(i + 1); + expect(logs[i].args.blockNum).toEqual(BigInt(i + 1)); const ethTx = await publicClient.getTransaction({ - hash: logs[0].transactionHash!, + hash: logs[i].transactionHash!, }); const expectedData = encodeFunctionData({ @@ -191,7 +253,6 @@ describe('L1Publisher integration', () => { const decodedRes = await decoderHelper.read.decode(decoderArgs); const stateInRollup = await rollup.read.rollupStateHash(); - // @note There seems to be something wrong here. The Bytes32 returned are actually strings :( expect(block.number).toEqual(Number(decodedRes[0])); expect(block.getStartStateHash()).toEqual(hexStringToBuffer(decodedRes[1].toString())); expect(block.getEndStateHash()).toEqual(hexStringToBuffer(decodedRes[2].toString())); @@ -199,9 +260,6 @@ describe('L1Publisher integration', () => { expect(block.getPublicInputsHash().toBuffer()).toEqual(hexStringToBuffer(decodedRes[3].toString())); expect(block.getCalldataHash()).toEqual(hexStringToBuffer(decodedHashes[0].toString())); expect(block.getL1ToL2MessagesHash()).toEqual(hexStringToBuffer(decodedHashes[1].toString())); - - // @todo Broken if making two blocks in a row... - return; } }, 60_000); }); diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index bf00f7f5d86..7ddf6c8c839 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -9,6 +9,11 @@ import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, RootRollupPublicInputs, UInt8Vector, + KERNEL_NEW_COMMITMENTS_LENGTH, + range, + KERNEL_NEW_NULLIFIERS_LENGTH, + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, + STATE_TRANSITIONS_LENGTH, } from '@aztec/circuits.js'; import { computeContractLeaf } from '@aztec/circuits.js/abis'; import { @@ -174,6 +179,7 @@ describe('sequencer/solo_block_builder', () => { const newPublicDataWrites = flatMap(txs, tx => tx.data.end.stateTransitions.map(t => new PublicDataWrite(t.leafIndex, t.newValue)), ); + const newL2ToL1Msgs = flatMap(txs, tx => tx.data.end.newL2ToL1Msgs); const l2Block = L2Block.fromFields({ number: blockNumber, @@ -200,6 +206,7 @@ describe('sequencer/solo_block_builder', () => { newContractData, newPublicDataWrites, newL1ToL2Messages: mockL1ToL2Messages, + newL2ToL1Msgs, }); const callDataHash = l2Block.getCalldataHash(); @@ -276,6 +283,24 @@ describe('sequencer/solo_block_builder', () => { return await makeProcessedTx(publicTx, kernelOutput, makeProof()); }; + const makeBloatedProcessedTx = async (seed = 0x1) => { + const publicTx = makePublicTx(seed); + const kernelOutput = KernelCircuitPublicInputs.empty(); + kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(builderDb); + kernelOutput.end.stateTransitions = range(STATE_TRANSITIONS_LENGTH, seed + 0x500).map( + i => new PublicDataTransition(fr(i), fr(0), fr(i + 10)), + ); + + const tx = await makeProcessedTx(publicTx, kernelOutput, makeProof()); + + tx.data.end.newCommitments = range(KERNEL_NEW_COMMITMENTS_LENGTH, seed + 0x100).map(fr); + tx.data.end.newNullifiers = range(KERNEL_NEW_NULLIFIERS_LENGTH, seed + 0x200).map(fr); + tx.data.end.newL2ToL1Msgs = range(KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, seed + 0x300).map(fr); + tx.data.end.newContracts = [makeNewContractData(seed + 0x1000)]; + + return tx; + }; + it.each([ [0, 4], [1, 4], @@ -309,6 +334,32 @@ describe('sequencer/solo_block_builder', () => { 10000, ); + it('builds an empty L2 block', async () => { + const txs = await Promise.all([ + makeEmptyProcessedTx(), + makeEmptyProcessedTx(), + makeEmptyProcessedTx(), + makeEmptyProcessedTx(), + ]); + + const [l2Block] = await builder.buildL2Block(1, txs, mockL1ToL2Messages); + expect(l2Block.number).toEqual(1); + }, 10_000); + + it('builds a mixed L2 block', async () => { + const txs = await Promise.all([ + makeBloatedProcessedTx(32), + makeBloatedProcessedTx(64), + makeBloatedProcessedTx(96), + makeBloatedProcessedTx(128), + ]); + + const l1ToL2Messages = range(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, 1 + 0x400).map(fr); + + const [l2Block] = await builder.buildL2Block(1, txs, l1ToL2Messages); + expect(l2Block.number).toEqual(1); + }, 20_000); + it('builds an L2 block with private and public txs', async () => { const txs = await Promise.all([ makePublicCallProcessedTx(), diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index 6ae9b1d7159..28758b74487 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -153,6 +153,7 @@ export class SoloBlockBuilder implements BlockBuilder { const newPublicDataWrites = flatMap(txs, tx => tx.data.end.stateTransitions.map(t => new PublicDataWrite(t.leafIndex, t.newValue)), ); + const newL2ToL1Msgs = flatMap(txs, tx => tx.data.end.newL2ToL1Msgs); const l2Block = L2Block.fromFields({ number: blockNumber, @@ -174,6 +175,7 @@ export class SoloBlockBuilder implements BlockBuilder { endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, newCommitments, newNullifiers, + newL2ToL1Msgs, newContracts, newContractData, newPublicDataWrites, @@ -524,7 +526,7 @@ export class SoloBlockBuilder implements BlockBuilder { startTreeOfHistoricPrivateDataTreeRootsSnapshot: await this.getTreeSnapshot( MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, ), - treeOfHistoricL1ToL2MsgTreeRootsSnapshot: new AppendOnlyTreeSnapshot(DELETE_FR, DELETE_NUM), + treeOfHistoricL1ToL2MsgTreeRootsSnapshot: await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE), }); } diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index 3a91e34c6a9..cda5e148952 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -5,6 +5,7 @@ import { KERNEL_NEW_NULLIFIERS_LENGTH, STATE_TRANSITIONS_LENGTH, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot } from '@aztec/circuits.js/factories'; import { BufferReader, serializeToBuffer } from '@aztec/circuits.js/utils'; @@ -101,6 +102,10 @@ export class L2Block { * The public data writes to be inserted into the public data tree. */ public newPublicDataWrites: PublicDataWrite[], + /** + * The L2 to L1 messages to be inserted into the messagebox on L1. + */ + public newL2ToL1Msgs: Fr[], /** * The contracts leafs to be inserted into the contract tree. */ @@ -128,6 +133,7 @@ export class L2Block { const newContractData = times(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock, ContractData.random); const newPublicDataWrites = times(STATE_TRANSITIONS_LENGTH * txsPerBlock, PublicDataWrite.random); const newL1ToL2Messages = times(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, Fr.random); + const newL2ToL1Msgs = times(KERNEL_NEW_L2_TO_L1_MSGS_LENGTH, Fr.random); return L2Block.fromFields({ number: l2BlockNum, @@ -153,6 +159,7 @@ export class L2Block { newContractData, newPublicDataWrites, newL1ToL2Messages, + newL2ToL1Msgs, }); } @@ -242,6 +249,10 @@ export class L2Block { * The public data writes to be inserted into the public data tree. */ newPublicDataWrites: PublicDataWrite[]; + /** + * The L2 to L1 messages to be inserted into the messagebox on L1. + */ + newL2ToL1Msgs: Fr[]; /** * The contracts leafs to be inserted into the contract tree. */ @@ -276,6 +287,7 @@ export class L2Block { fields.newCommitments, fields.newNullifiers, fields.newPublicDataWrites, + fields.newL2ToL1Msgs, fields.newContracts, fields.newContractData, fields.newL1ToL2Messages, @@ -311,6 +323,8 @@ export class L2Block { this.newNullifiers, this.newPublicDataWrites.length, this.newPublicDataWrites, + this.newL2ToL1Msgs.length, + this.newL2ToL1Msgs, this.newContracts.length, this.newContracts, this.newContractData, @@ -354,6 +368,7 @@ export class L2Block { const newCommitments = reader.readVector(Fr); const newNullifiers = reader.readVector(Fr); const newPublicDataWrites = reader.readVector(PublicDataWrite); + const newL2ToL1Msgs = reader.readVector(Fr); const newContracts = reader.readVector(Fr); const newContractData = reader.readArray(newContracts.length, ContractData); // TODO(sean): could an optimisation of this be that it is encoded such that zeros are assumed @@ -380,6 +395,7 @@ export class L2Block { newCommitments, newNullifiers, newPublicDataWrites, + newL2ToL1Msgs, newContracts, newContractData, newL1ToL2Messages, @@ -493,6 +509,7 @@ export class L2Block { const commitmentPerBase = KERNEL_NEW_COMMITMENTS_LENGTH * 2; const nullifierPerBase = KERNEL_NEW_NULLIFIERS_LENGTH * 2; const publicDataWritesPerBase = STATE_TRANSITIONS_LENGTH * 2; // @note why is this constant named differently? + const l2ToL1MsgsPerBase = KERNEL_NEW_L2_TO_L1_MSGS_LENGTH * 2; const commitmentBuffer = Buffer.concat( this.newCommitments.slice(i * commitmentPerBase, (i + 1) * commitmentPerBase).map(x => x.toBuffer()), ); @@ -504,11 +521,15 @@ export class L2Block { .slice(i * publicDataWritesPerBase, (i + 1) * publicDataWritesPerBase) .map(x => x.toBuffer()), ); + const newL2ToL1MsgsBuffer = Buffer.concat( + this.newL2ToL1Msgs.slice(i * l2ToL1MsgsPerBase, (i + 1) * l2ToL1MsgsPerBase).map(x => x.toBuffer()), + ); const inputValue = Buffer.concat([ commitmentBuffer, nullifierBuffer, dataWritesBuffer, + newL2ToL1MsgsBuffer, this.newContracts[i * 2].toBuffer(), this.newContracts[i * 2 + 1].toBuffer(), this.newContractData[i * 2].contractAddress.toBuffer(), @@ -555,6 +576,10 @@ export class L2Block { STATE_TRANSITIONS_LENGTH * txIndex, STATE_TRANSITIONS_LENGTH * (txIndex + 1), ); + const newL2ToL1Msgs = this.newL2ToL1Msgs.slice( + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH * txIndex, + KERNEL_NEW_L2_TO_L1_MSGS_LENGTH * (txIndex + 1), + ); const newContracts = this.newContracts.slice( KERNEL_NEW_CONTRACTS_LENGTH * txIndex, KERNEL_NEW_CONTRACTS_LENGTH * (txIndex + 1), @@ -564,7 +589,7 @@ export class L2Block { KERNEL_NEW_CONTRACTS_LENGTH * (txIndex + 1), ); - return new L2Tx(newCommitments, newNullifiers, newPublicDataWrites, newContracts, newContractData); + return new L2Tx(newCommitments, newNullifiers, newPublicDataWrites, newL2ToL1Msgs, newContracts, newContractData); } /** @@ -624,6 +649,7 @@ export class L2Block { `newCommitments: ${inspectFrArray(this.newCommitments)}`, `newNullifiers: ${inspectFrArray(this.newNullifiers)}`, `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, + `newL2ToL1Msgs: ${inspectFrArray(this.newL2ToL1Msgs)}`, `newContracts: ${inspectFrArray(this.newContracts)}`, `newContractData: ${inspectContractDataArray(this.newContractData)}`, `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, diff --git a/yarn-project/types/src/l2_tx.ts b/yarn-project/types/src/l2_tx.ts index 0389a0356d0..9a2ff95c4b6 100644 --- a/yarn-project/types/src/l2_tx.ts +++ b/yarn-project/types/src/l2_tx.ts @@ -21,6 +21,10 @@ export class L2Tx { * New public data writes created by the transaction. */ public newPublicDataWrites: PublicDataWrite[], + /** + * New L2 to L1 messages created by the transaction. + */ + public newL2ToL1Msgs: Fr[], /** * New contracts leafs created by the transaction to be inserted into the contract tree. */ diff --git a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts index eaa5fabc371..4fd843bf6cc 100644 --- a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts +++ b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts @@ -64,6 +64,7 @@ const getMockBlock = (blockNumber: number, newContractsCommitments?: Buffer[]) = newContractData: [getMockContractData()], newPublicDataWrites: [PublicDataWrite.random()], newL1ToL2Messages: getMockL1ToL2MessagesData(), + newL2ToL1Msgs: [Fr.random()], }); return block; };