diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp index 672c49fa708..e16d8b738e1 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp @@ -27,6 +27,14 @@ template struct RootRollupInputs { std::array new_historic_private_data_tree_root_sibling_path; std::array new_historic_contract_tree_root_sibling_path; + // inputs required to process l1 to l2 messages + std::array l1_to_l2_messages; + std::array new_l1_to_l2_message_tree_root_sibling_path; + std::array new_historic_l1_to_l2_message_roots_tree_sibling_path; + + AppendOnlyTreeSnapshot start_l1_to_l2_message_tree_snapshot; + AppendOnlyTreeSnapshot start_historic_tree_l1_to_l2_message_tree_roots_snapshot; + bool operator==(RootRollupInputs const&) const = default; }; @@ -37,6 +45,11 @@ template void read(uint8_t const*& it, RootRollupInputs& obj read(it, obj.previous_rollup_data); read(it, obj.new_historic_private_data_tree_root_sibling_path); read(it, obj.new_historic_contract_tree_root_sibling_path); + read(it, obj.l1_to_l2_messages); + read(it, obj.new_l1_to_l2_message_tree_root_sibling_path); + read(it, obj.new_historic_l1_to_l2_message_roots_tree_sibling_path); + read(it, obj.start_l1_to_l2_message_tree_snapshot); + read(it, obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot); }; template void write(std::vector& buf, RootRollupInputs const& obj) @@ -46,6 +59,11 @@ template void write(std::vector& buf, RootRollupInputs std::ostream& operator<<(std::ostream& os, RootRollupInputs const& obj) @@ -53,7 +71,15 @@ template std::ostream& operator<<(std::ostream& os, RootRollupInp return os << "previous_rollup_data: " << obj.previous_rollup_data << "\n" << "new_historic_private_data_tree_roots: " << obj.new_historic_private_data_tree_root_sibling_path << "\n" - << "new_historic_contract_tree_roots: " << obj.new_historic_contract_tree_root_sibling_path << "\n"; + << "new_historic_contract_tree_roots: " << obj.new_historic_contract_tree_root_sibling_path << "\n" + << "new_l1_to_l2_messages: " << obj.l1_to_l2_messages << "\n" + << "new_l1_to_l2_message_tree_root_sibling_path: " << obj.new_l1_to_l2_message_tree_root_sibling_path + << "\n" + << "new_historic_l1_to_l2_message_roots_tree_sibling_path: " + << obj.new_historic_l1_to_l2_message_roots_tree_sibling_path << "\n" + << "start_l1_to_l2_message_tree_snapshot: " << obj.start_l1_to_l2_message_tree_snapshot << "\n" + << "start_historic_tree_l1_to_l2_message_tree_roots_snapshot: " + << obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot << "\n"; } } // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp index a2d1b560b1f..5aca0ad21a1 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp @@ -15,6 +15,7 @@ namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; + template struct RootRollupPublicInputs { using fr = typename NCT::fr; using AggregationObject = typename NCT::AggregationObject; @@ -40,7 +41,14 @@ template struct RootRollupPublicInputs { AppendOnlyTreeSnapshot start_tree_of_historic_contract_tree_roots_snapshot; AppendOnlyTreeSnapshot end_tree_of_historic_contract_tree_roots_snapshot; + AppendOnlyTreeSnapshot start_l1_to_l2_messages_tree_snapshot; + AppendOnlyTreeSnapshot end_l1_to_l2_messages_tree_snapshot; + + AppendOnlyTreeSnapshot start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot; + AppendOnlyTreeSnapshot end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot; + std::array calldata_hash; + std::array l1_to_l2_messages_hash; bool operator==(RootRollupPublicInputs const&) const = default; @@ -53,11 +61,15 @@ template struct RootRollupPublicInputs { write(buf, start_contract_tree_snapshot); write(buf, start_tree_of_historic_private_data_tree_roots_snapshot); write(buf, start_tree_of_historic_contract_tree_roots_snapshot); + write(buf, start_l1_to_l2_messages_tree_snapshot); + write(buf, start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); write(buf, end_private_data_tree_snapshot); write(buf, end_nullifier_tree_snapshot); write(buf, end_contract_tree_snapshot); write(buf, end_tree_of_historic_private_data_tree_roots_snapshot); write(buf, end_tree_of_historic_contract_tree_roots_snapshot); + write(buf, end_l1_to_l2_messages_tree_snapshot); + write(buf, end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); // Stitching calldata hash together auto high_buffer = calldata_hash[0].to_buffer(); @@ -70,6 +82,17 @@ template struct RootRollupPublicInputs { buf.push_back(low_buffer[16 + i]); } + // Stitch l1_to_l2_messages_hash + auto high_buffer_m = l1_to_l2_messages_hash[0].to_buffer(); + auto low_buffer_m = l1_to_l2_messages_hash[1].to_buffer(); + + for (uint8_t i = 0; i < 16; i++) { + buf.push_back(high_buffer_m[16 + i]); + } + for (uint8_t i = 0; i < 16; i++) { + buf.push_back(low_buffer_m[16 + i]); + } + return sha256::sha256_to_field(buf); } }; @@ -91,7 +114,12 @@ template void read(uint8_t const*& it, RootRollupPublicInputs void write(std::vector& buf, RootRollupPublicInputs const& obj) @@ -111,7 +139,12 @@ template void write(std::vector& buf, RootRollupPublicIn write(buf, obj.end_tree_of_historic_private_data_tree_roots_snapshot); write(buf, obj.start_tree_of_historic_contract_tree_roots_snapshot); write(buf, obj.end_tree_of_historic_contract_tree_roots_snapshot); + write(buf, obj.start_l1_to_l2_messages_tree_snapshot); + write(buf, obj.end_l1_to_l2_messages_tree_snapshot); + write(buf, obj.start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); + write(buf, obj.end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); write(buf, obj.calldata_hash); + write(buf, obj.l1_to_l2_messages_hash); }; template std::ostream& operator<<(std::ostream& os, RootRollupPublicInputs const& obj) @@ -133,7 +166,15 @@ template std::ostream& operator<<(std::ostream& os, RootRollupPub << obj.start_tree_of_historic_contract_tree_roots_snapshot << "\n" << "end_tree_of_historic_contract_tree_roots_snapshot: " << obj.end_tree_of_historic_contract_tree_roots_snapshot << "\n" - << "calldata_hash: " << obj.calldata_hash << "\n"; + << "start_l1_to_l2_messages_tree_snapshot: " << obj.start_l1_to_l2_messages_tree_snapshot << "\n" + << "end_l1_tol2_messages_tree_snapshot: " << obj.end_l1_to_l2_messages_tree_snapshot << "\n" + << "start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot: " + << obj.start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot << "\n" + << "end_tree_of_historic_l1_tol2_messages_tree_roots_snapshot: " + << obj.end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot << "\n" + << "calldata_hash: " << obj.calldata_hash << "\n" + << "l1_to_l2_messages_hash: " << obj.l1_to_l2_messages_hash << "\n"; + ; }; } // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp index 6cf0e961217..926f16779b8 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp @@ -400,7 +400,7 @@ AppendOnlySnapshot check_nullifier_tree_non_membership_and_insert_to_tree(DummyC } // Check that the new subtree is to be inserted at the next location, and is empty currently - const auto empty_nullifier_subtree_root = calculate_empty_tree_root(NULLIFIER_SUBTREE_DEPTH); + const auto empty_nullifier_subtree_root = components::calculate_empty_tree_root(NULLIFIER_SUBTREE_DEPTH); auto leafIndexNullifierSubtreeDepth = baseRollupInputs.start_nullifier_tree_snapshot.next_available_leaf_index >> NULLIFIER_SUBTREE_DEPTH; check_membership(composer, @@ -541,7 +541,7 @@ BaseOrMergeRollupPublicInputs base_rollup_circuit(DummyComposer& composer, BaseR NT::fr const commitments_tree_subroot = calculate_commitments_subtree(composer, baseRollupInputs); // Insert commitment subtrees: - const auto empty_commitments_subtree_root = calculate_empty_tree_root(PRIVATE_DATA_SUBTREE_DEPTH); + const auto empty_commitments_subtree_root = components::calculate_empty_tree_root(PRIVATE_DATA_SUBTREE_DEPTH); auto end_private_data_tree_snapshot = components::insert_subtree_to_snapshot_tree(composer, baseRollupInputs.start_private_data_tree_snapshot, @@ -552,7 +552,7 @@ BaseOrMergeRollupPublicInputs base_rollup_circuit(DummyComposer& composer, BaseR "empty commitment subtree membership check"); // Insert contract subtrees: - const auto empty_contracts_subtree_root = calculate_empty_tree_root(CONTRACT_SUBTREE_DEPTH); + const auto empty_contracts_subtree_root = components::calculate_empty_tree_root(CONTRACT_SUBTREE_DEPTH); auto end_contract_tree_snapshot = components::insert_subtree_to_snapshot_tree(composer, baseRollupInputs.start_contract_tree_snapshot, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp b/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp index 8f776438660..48d2b3d84c4 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp @@ -8,6 +8,7 @@ #include "barretenberg/crypto/sha256/sha256.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/stdlib/hash/pedersen/pedersen.hpp" +#include "barretenberg/stdlib/merkle_tree/memory_tree.hpp" #include #include @@ -18,6 +19,18 @@ namespace aztec3::circuits::rollup::components { +/** + * @brief Get the root of an empty tree of a given depth + * + * @param depth + * @return NT::fr + */ +NT::fr calculate_empty_tree_root(const size_t depth) +{ + stdlib::merkle_tree::MemoryTree const empty_tree = stdlib::merkle_tree::MemoryTree(depth); + return empty_tree.root(); +} + /** * @brief Create an aggregation object for the proofs that are provided * - We add points P0 for each of our proofs diff --git a/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp b/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp index f6df9f8a8a7..42074456b1e 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/components/components.hpp @@ -8,6 +8,7 @@ using aztec3::circuits::check_membership; 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, 2> previous_rollup_data); void assert_prev_rollups_follow_on_from_each_other(DummyComposer& composer, BaseOrMergeRollupPublicInputs const& left, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp index ed2dfa6ce73..ecef5951bea 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp @@ -54,7 +54,9 @@ using aztec3::circuits::abis::PreviousKernelData; // using aztec3::circuits::mock::mock_circuit; +using aztec3::circuits::rollup::test_utils::utils::compare_field_hash_to_expected; 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; @@ -71,7 +73,7 @@ using aztec3::circuits::rollup::native_root_rollup::RootRollupPublicInputs; using aztec3::circuits::abis::NewContractData; -using MemoryTree = proof_system::plonk::stdlib::merkle_tree::MemoryTree; +using MemoryTree = stdlib::merkle_tree::MemoryTree; using KernelData = aztec3::circuits::abis::PreviousKernelData; } // namespace @@ -139,8 +141,11 @@ class root_rollup_tests : public ::testing::Test { } }; -TEST_F(root_rollup_tests, native_calldata_hash_empty_blocks) +TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks) { + MemoryTree const data_tree = MemoryTree(PRIVATE_DATA_TREE_HEIGHT); + + // calculate calldata hash std::vector const zero_bytes_vec(704, 0); auto call_data_hash_inner = sha256::sha256(zero_bytes_vec); @@ -152,31 +157,33 @@ TEST_F(root_rollup_tests, native_calldata_hash_empty_blocks) std::vector const calldata_hash_input_bytes_vec(hash_input.begin(), hash_input.end()); - auto hash = sha256::sha256(calldata_hash_input_bytes_vec); + auto calldata_hash = sha256::sha256(calldata_hash_input_bytes_vec); + + // get messages + std::array const l1_to_l2_messages = get_empty_l1_to_l2_messages(); + + // hash messages + std::vector const messages_hash_input_bytes_vec(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 32, 0); + auto messages_hash = sha256::sha256(messages_hash_input_bytes_vec); utils::DummyComposer composer = utils::DummyComposer(); std::array const kernels = { get_empty_kernel(), get_empty_kernel(), get_empty_kernel(), get_empty_kernel() }; - RootRollupInputs inputs = get_root_rollup_inputs(composer, kernels); + + RootRollupInputs inputs = get_root_rollup_inputs(composer, kernels, l1_to_l2_messages); RootRollupPublicInputs outputs = aztec3::circuits::rollup::native_root_rollup::root_rollup_circuit(composer, inputs); - std::array calldata_hash_fr = outputs.calldata_hash; - auto high_buffer = calldata_hash_fr[0].to_buffer(); - auto low_buffer = calldata_hash_fr[1].to_buffer(); + // check calldata hash + ASSERT_TRUE(compare_field_hash_to_expected(outputs.calldata_hash, calldata_hash)); + // Check messages hash + ASSERT_TRUE(compare_field_hash_to_expected(outputs.l1_to_l2_messages_hash, messages_hash)); - std::array calldata_hash; - for (uint8_t i = 0; i < 16; ++i) { - calldata_hash[i] = high_buffer[16 + i]; - calldata_hash[16 + i] = low_buffer[16 + i]; - } - - ASSERT_EQ(hash, calldata_hash); EXPECT_FALSE(composer.failed()); // Expected hash of public inputs for an empty L2 block. Also used in the contract tests. - fr const expected_hash = uint256_t("0013b2202a3e48b039cda7eef0976060d86e610d77fc9bb8cd5b0f1b561df48c"); + fr const expected_hash = uint256_t("11840efc30e9fcbdd0aae30da2a5b441132420b4f0cc4ffd6bdc41888845f775"); ASSERT_EQ(outputs.hash(), expected_hash); run_cbind(inputs, outputs, true); @@ -190,14 +197,18 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) MemoryTree contract_tree = MemoryTree(CONTRACT_TREE_HEIGHT); MemoryTree historic_data_tree = MemoryTree(PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT); MemoryTree historic_contract_tree = MemoryTree(CONTRACT_TREE_ROOTS_TREE_HEIGHT); + MemoryTree l1_to_l2_messages_tree = MemoryTree(L1_TO_L2_MSG_TREE_HEIGHT); + MemoryTree historic_l1_to_l2_tree = MemoryTree(L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT); // Historic trees are initialised with an empty root at position 0. historic_data_tree.update_element(0, data_tree.root()); historic_contract_tree.update_element(0, contract_tree.root()); + historic_l1_to_l2_tree.update_element(0, l1_to_l2_messages_tree.root()); std::array kernels = { get_empty_kernel(), get_empty_kernel(), get_empty_kernel(), get_empty_kernel() }; + std::array l1_to_l2_messages = get_empty_l1_to_l2_messages(); // Create commitments for (uint8_t kernel_j = 0; kernel_j < 4; kernel_j++) { @@ -230,24 +241,41 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) contract_tree.update_element(2, contract_leaf); kernels[2].public_inputs.end.new_contracts[0] = new_contract; - // The start historic data snapshot + // l1 to l2 messages snapshot + AppendOnlyTreeSnapshot const start_l1_to_l2_messages_tree_snapshot = { .root = l1_to_l2_messages_tree.root(), + .next_available_leaf_index = 0 }; + + // The start historic data snapshots AppendOnlyTreeSnapshot const start_historic_data_tree_snapshot = { .root = historic_data_tree.root(), .next_available_leaf_index = 1 }; AppendOnlyTreeSnapshot const start_historic_contract_tree_snapshot = { .root = historic_contract_tree.root(), .next_available_leaf_index = 1 }; + AppendOnlyTreeSnapshot const start_historic_l1_to_l2_tree_snapshot = { .root = historic_l1_to_l2_tree.root(), + .next_available_leaf_index = 1 }; + + // Create 16 empty l1 to l2 messages, and update the l1_to_l2 messages tree + for (size_t i = 0; i < l1_to_l2_messages.size(); i++) { + l1_to_l2_messages_tree.update_element(i, l1_to_l2_messages[i]); + } // Insert the newest data root into the historic tree historic_data_tree.update_element(1, data_tree.root()); historic_contract_tree.update_element(1, contract_tree.root()); + historic_l1_to_l2_tree.update_element(1, l1_to_l2_messages_tree.root()); // Compute the end snapshot AppendOnlyTreeSnapshot const end_historic_data_tree_snapshot = { .root = historic_data_tree.root(), .next_available_leaf_index = 2 }; AppendOnlyTreeSnapshot const end_historic_contract_tree_snapshot = { .root = historic_contract_tree.root(), .next_available_leaf_index = 2 }; + AppendOnlyTreeSnapshot const end_historic_l1_to_l2_tree_snapshot = { .root = historic_l1_to_l2_tree.root(), + .next_available_leaf_index = 2 }; + AppendOnlyTreeSnapshot const end_l1_to_l2_messages_tree_snapshot = { .root = l1_to_l2_messages_tree.root(), + .next_available_leaf_index = + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP }; - RootRollupInputs rootRollupInputs = get_root_rollup_inputs(composer, kernels); - RootRollupPublicInputs const outputs = + RootRollupInputs rootRollupInputs = get_root_rollup_inputs(composer, kernels, l1_to_l2_messages); + RootRollupPublicInputs outputs = aztec3::circuits::rollup::native_root_rollup::root_rollup_circuit(composer, rootRollupInputs); // Check private data trees @@ -286,7 +314,18 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) ASSERT_EQ(outputs.start_tree_of_historic_contract_tree_roots_snapshot, start_historic_contract_tree_snapshot); ASSERT_EQ(outputs.end_tree_of_historic_contract_tree_roots_snapshot, end_historic_contract_tree_snapshot); + // Check historic l1 to l2 messages trees + ASSERT_EQ(outputs.start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, + start_historic_l1_to_l2_tree_snapshot); + ASSERT_EQ(outputs.end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, end_historic_l1_to_l2_tree_snapshot); + + // Check l1 to l2 messages trees + 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); + EXPECT_FALSE(composer.failed()); + + run_cbind(rootRollupInputs, outputs, true); } } // namespace aztec3::circuits::rollup::root::native_root_rollup_circuit \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/init.hpp b/circuits/cpp/src/aztec3/circuits/rollup/root/init.hpp index 2a15f32de12..efb914db422 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/init.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/init.hpp @@ -6,12 +6,12 @@ #include "aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp" #include "aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp" #include "aztec3/utils/dummy_composer.hpp" -#include #include #include #include #include +#include "barretenberg/stdlib/merkle_tree/memory_tree.hpp" #include namespace aztec3::circuits::rollup::native_root_rollup { @@ -26,4 +26,6 @@ using RootRollupPublicInputs = abis::RootRollupPublicInputs; using Aggregator = aztec3::circuits::recursion::Aggregator; -} // namespace aztec3::circuits::rollup::native_root_rollup \ No newline at end of file +using MerkleTree = stdlib::merkle_tree::MemoryTree; + +} // namespace aztec3::circuits::rollup::native_root_rollup diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp index 64e0bd981f3..536f805f70a 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp @@ -28,6 +28,55 @@ namespace aztec3::circuits::rollup::native_root_rollup { // Access Native types through NT namespace +/** + * @brief Calculates the messages subtree from the leaves array + * @param leaves + * @return root + */ +NT::fr calculate_subtree(std::array leaves) +{ + MerkleTree merkle_tree = MerkleTree(L1_TO_L2_MSG_SUBTREE_DEPTH); + + for (size_t i = 0; i < NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP; i++) { + merkle_tree.update_element(i, leaves[i]); + } + return merkle_tree.root(); +} + +/** + * @brief Computes the messages hash from the leaves array + * @param leaves + * @param return - hash split into two field elements + */ +std::array compute_messages_hash(std::array leaves) +{ + // convert vector of field elements into uint_8 + std::array messages_hash_input_bytes; + for (size_t i = 0; i < NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP; i++) { + auto bytes = leaves[i].to_buffer(); + for (size_t j = 0; j < 32; j++) { + messages_hash_input_bytes[i * 32 + j] = bytes[j]; + } + } + + std::vector const messages_hash_input_bytes_vec(messages_hash_input_bytes.begin(), + messages_hash_input_bytes.end()); + auto h = sha256::sha256(messages_hash_input_bytes_vec); + + std::array buf_1; + std::array buf_2; + for (uint8_t i = 0; i < 16; i++) { + buf_1[i] = 0; + buf_1[16 + i] = h[i]; + buf_2[i] = 0; + buf_2[16 + i] = h[i + 16]; + } + auto high = fr::serialize_from_buffer(buf_1.data()); + auto low = fr::serialize_from_buffer(buf_2.data()); + + return { high, low }; +} + RootRollupPublicInputs root_rollup_circuit(DummyComposer& composer, RootRollupInputs const& rootRollupInputs) { // TODO: Verify the previous rollup proofs @@ -63,6 +112,31 @@ RootRollupPublicInputs root_rollup_circuit(DummyComposer& composer, RootRollupIn 0, "historic contract tree roots insertion"); + // Check correct l1 to l2 tree given + // Compute subtree inserting l1 to l2 messages + auto l1_to_l2_subtree_root = calculate_subtree(rootRollupInputs.l1_to_l2_messages); + + // // Insert subtree into the l1 to l2 data tree + const auto empty_l1_to_l2_subtree_root = components::calculate_empty_tree_root(L1_TO_L2_MSG_SUBTREE_DEPTH); + auto new_l1_to_l2_messages_tree_snapshot = + components::insert_subtree_to_snapshot_tree(composer, + rootRollupInputs.start_l1_to_l2_message_tree_snapshot, + rootRollupInputs.new_l1_to_l2_message_tree_root_sibling_path, + empty_l1_to_l2_subtree_root, + l1_to_l2_subtree_root, + L1_TO_L2_MSG_SUBTREE_INCLUSION_CHECK_DEPTH, + "l1 to l2 message tree insertion"); + + // Update the historic l1 to l2 data tree + auto end_l1_to_l2_data_roots_tree_snapshot = components::insert_subtree_to_snapshot_tree( + composer, + rootRollupInputs.start_historic_tree_l1_to_l2_message_tree_roots_snapshot, + rootRollupInputs.new_historic_l1_to_l2_message_roots_tree_sibling_path, + fr::zero(), + new_l1_to_l2_messages_tree_snapshot.root, + 0, + "historic l1 to l2 message tree roots insertion"); + RootRollupPublicInputs public_inputs = { .end_aggregation_object = aggregation_object, .start_private_data_tree_snapshot = left.start_private_data_tree_snapshot, @@ -79,7 +153,13 @@ RootRollupPublicInputs root_rollup_circuit(DummyComposer& composer, RootRollupIn .start_tree_of_historic_contract_tree_roots_snapshot = left.constants.start_tree_of_historic_contract_tree_roots_snapshot, .end_tree_of_historic_contract_tree_roots_snapshot = end_tree_of_historic_contract_tree_roots_snapshot, + .start_l1_to_l2_messages_tree_snapshot = rootRollupInputs.start_l1_to_l2_message_tree_snapshot, + .end_l1_to_l2_messages_tree_snapshot = new_l1_to_l2_messages_tree_snapshot, + .start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot = + rootRollupInputs.start_historic_tree_l1_to_l2_message_tree_roots_snapshot, + .end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot = end_l1_to_l2_data_roots_tree_snapshot, .calldata_hash = components::compute_calldata_hash(rootRollupInputs.previous_rollup_data), + .l1_to_l2_messages_hash = compute_messages_hash(rootRollupInputs.l1_to_l2_messages) }; return public_inputs; 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 ac3aa2ece62..714f8eca986 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp @@ -56,6 +56,12 @@ KernelData get_empty_kernel() return dummy_previous_kernel(); } +std::array get_empty_l1_to_l2_messages() +{ + std::array l1_to_l2_messages = { 0 }; + 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++) { @@ -298,7 +304,9 @@ MergeRollupInputs get_merge_rollup_inputs(utils::DummyComposer& composer, std::a return inputs; } -RootRollupInputs get_root_rollup_inputs(utils::DummyComposer& composer, std::array kernel_data) +RootRollupInputs get_root_rollup_inputs(utils::DummyComposer& composer, + std::array kernel_data, + std::array l1_to_l2_messages) { MerkleTree historic_private_data_tree = MerkleTree(PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT); MerkleTree historic_contract_tree = MerkleTree(CONTRACT_TREE_ROOTS_TREE_HEIGHT); @@ -306,21 +314,42 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyComposer& composer, std::arr MerkleTree const private_data_tree = MerkleTree(PRIVATE_DATA_TREE_HEIGHT); MerkleTree const contract_tree = MerkleTree(CONTRACT_TREE_HEIGHT); + MerkleTree l1_to_l2_msg_tree = MerkleTree(L1_TO_L2_MSG_TREE_HEIGHT); // Historic trees are initialised with an empty root at position 0. historic_private_data_tree.update_element(0, private_data_tree.root()); historic_contract_tree.update_element(0, contract_tree.root()); - historic_l1_to_l2_msg_tree.update_element(0, MerkleTree(L1_TO_L2_MSG_TREE_HEIGHT).root()); + historic_l1_to_l2_msg_tree.update_element(0, l1_to_l2_msg_tree.root()); auto historic_data_sibling_path = get_sibling_path(historic_private_data_tree, 1, 0); auto historic_contract_sibling_path = get_sibling_path(historic_contract_tree, 1, 0); + auto historic_l1_to_l2_msg_sibling_path = + get_sibling_path(historic_l1_to_l2_msg_tree, 1, 0); + auto l1_to_l2_tree_sibling_path = get_sibling_path( + l1_to_l2_msg_tree, 0, L1_TO_L2_MSG_SUBTREE_INCLUSION_CHECK_DEPTH); + + // l1_to_l2_message tree snapshots + AppendOnlyTreeSnapshot const start_l1_to_l2_msg_tree_snapshot = { + .root = l1_to_l2_msg_tree.root(), + .next_available_leaf_index = 0, + }; + AppendOnlyTreeSnapshot const start_historic_tree_l1_to_l2_message_tree_roots_snapshot = { + .root = historic_l1_to_l2_msg_tree.root(), + .next_available_leaf_index = 1, + }; RootRollupInputs rootRollupInputs = { .previous_rollup_data = get_previous_rollup_data(composer, std::move(kernel_data)), .new_historic_private_data_tree_root_sibling_path = historic_data_sibling_path, .new_historic_contract_tree_root_sibling_path = historic_contract_sibling_path, + .l1_to_l2_messages = l1_to_l2_messages, + .new_l1_to_l2_message_tree_root_sibling_path = l1_to_l2_tree_sibling_path, + .new_historic_l1_to_l2_message_roots_tree_sibling_path = historic_l1_to_l2_msg_sibling_path, + .start_l1_to_l2_message_tree_snapshot = start_l1_to_l2_msg_tree_snapshot, + .start_historic_tree_l1_to_l2_message_tree_roots_snapshot = + start_historic_tree_l1_to_l2_message_tree_roots_snapshot, }; return rootRollupInputs; } @@ -472,4 +501,27 @@ nullifier_tree_testing_values generate_nullifier_tree_testing_values_explicit( return std::make_tuple(rollupInputs, nullifier_tree_start_snapshot, nullifier_tree_end_snapshot); } -} // namespace aztec3::circuits::rollup::test_utils::utils \ No newline at end of file +/** + * @brief Compares a hash calculated within a circuit (made up of two field elements) against + * one generated natively, (32 bytes) and checks if they match + * + * @param field_hash + * @param expected_hash + * @return true + * @return false + */ +bool compare_field_hash_to_expected(std::array field_hash, std::array expected_hash) +{ + auto high_buffer = field_hash[0].to_buffer(); + auto low_buffer = field_hash[1].to_buffer(); + + std::array field_expanded_hash; + for (uint8_t i = 0; i < 16; ++i) { + field_expanded_hash[i] = high_buffer[16 + i]; + field_expanded_hash[16 + i] = low_buffer[16 + i]; + } + + return expected_hash == field_expanded_hash; +} + +} // namespace aztec3::circuits::rollup::test_utils::utils 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 525bf17192e..dd2a7b8c3f9 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp @@ -3,6 +3,7 @@ #include "nullifier_tree_testing_harness.hpp" #include "aztec3/circuits/abis/public_data_transition.hpp" +#include "aztec3/constants.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" @@ -88,6 +89,8 @@ nullifier_tree_testing_values generate_nullifier_tree_testing_values(BaseRollupI size_t starting_insertion_value, size_t spacing); +std::array get_empty_l1_to_l2_messages(); + nullifier_tree_testing_values generate_nullifier_tree_testing_values( BaseRollupInputs inputs, std::array new_nullifiers, size_t spacing); @@ -95,7 +98,9 @@ NullifierMemoryTreeTestingHarness get_initial_nullifier_tree(const std::vector kernel_data); +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); @@ -120,4 +125,6 @@ inline abis::PublicDataRead make_public_read(fr leaf_index, fr value) }; } -} // namespace aztec3::circuits::rollup::test_utils::utils \ No newline at end of file +bool compare_field_hash_to_expected(std::array field_hash, std::array expected_hash); + +} // namespace aztec3::circuits::rollup::test_utils::utils diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index edcc1460dc1..3bf6ed53269 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -43,6 +43,11 @@ constexpr size_t PRIVATE_DATA_SUBTREE_INCLUSION_CHECK_DEPTH = PRIVATE_DATA_TREE_ constexpr size_t NULLIFIER_SUBTREE_DEPTH = 3; constexpr size_t NULLIFIER_SUBTREE_INCLUSION_CHECK_DEPTH = NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_DEPTH; +// NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP must equal 2^L1_TO_L2_MSG_SUBTREE_DEPTH for subtree insertions. +constexpr size_t L1_TO_L2_MSG_SUBTREE_DEPTH = 4; +constexpr size_t NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; +constexpr size_t L1_TO_L2_MSG_SUBTREE_INCLUSION_CHECK_DEPTH = L1_TO_L2_MSG_TREE_HEIGHT - L1_TO_L2_MSG_SUBTREE_DEPTH; + constexpr size_t PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT = 8; constexpr size_t CONTRACT_TREE_ROOTS_TREE_HEIGHT = 8; constexpr size_t L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT = 8; @@ -50,6 +55,7 @@ constexpr size_t ROLLUP_VK_TREE_HEIGHT = 8; // TODO: update constexpr size_t FUNCTION_SELECTOR_NUM_BYTES = 4; // must be <= 31 + // Enumerate the hash_indices which are used for pedersen hashing // Start from 1 to avoid the default generators. enum GeneratorIndex { diff --git a/l1-contracts/src/core/Decoder.sol b/l1-contracts/src/core/Decoder.sol index 950cab912da..99947884153 100644 --- a/l1-contracts/src/core/Decoder.sol +++ b/l1-contracts/src/core/Decoder.sol @@ -27,34 +27,45 @@ pragma solidity >=0.8.18; * | 0x94 | 0x20 | startTreeOfHistoricContractTreeRootsSnapshot.root * | 0xb4 | 0x04 | startTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex * | 0xb8 | 0x20 | startPublicDataTreeRoot - * | 0xd8 | 0x20 | endPrivateDataTreeSnapshot.root - * | 0xf8 | 0x04 | endPrivateDataTreeSnapshot.nextAvailableLeafIndex - * | 0xfc | 0x20 | endNullifierTreeSnapshot.root - * | 0x11c | 0x04 | endNullifierTreeSnapshot.nextAvailableLeafIndex - * | 0x120 | 0x20 | endContractTreeSnapshot.root - * | 0x140 | 0x04 | endContractTreeSnapshot.nextAvailableLeafIndex - * | 0x144 | 0x20 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.root - * | 0x164 | 0x04 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x168 | 0x20 | endTreeOfHistoricContractTreeRootsSnapshot.root - * | 0x188 | 0x04 | endTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x18c | 0x20 | endPublicDataTreeRoot - * | 0x1ac | 0x04 | len(newCommitments) denoted a - * | 0x1b0 | a | newCommitments (each element 32 bytes) - * | 0x1b0 + a | 0x04 | len(newNullifiers) denoted b - * | 0x1b4 + a | b | newNullifiers (each element 32 bytes) - * | 0x1b4 + a + b | 0x04 | len(newPublicDataWrites) denoted c - * | 0x1b8 + a + b | c | newPublicDataWrites (each element 64 bytes) - * | 0x1b8 + a + b + c | 0x04 | len(newContracts) denoted d - * | 0x1bc + a + b + c | v | newContracts (each element 32 bytes) - * | 0x1bc + a + b + c + d | v | newContractData (each element 52 bytes) + * | 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 are number of elements and not bytes, need to be multiplied by the length of the elements. + * TODO: a,b,c,d,e are number of elements and not bytes, need to be multiplied by the length of the elements. */ 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 CONTRACTS_PER_KERNEL = 1; + uint256 internal constant L1_TO_L2_MESSAGES_PER_ROLLUP = 16; // Prime field order uint256 internal constant P = @@ -82,26 +93,31 @@ contract Decoder { // Note, for startStateHash to match the storage, the l2 block number must be new - 1. // Only jumping 1 block at a time. startStateHash = _computeStateHash(l2BlockNumber - 1, 0x4, _l2Block); - endStateHash = _computeStateHash(l2BlockNumber, 0xd8, _l2Block); + endStateHash = _computeStateHash(l2BlockNumber, 0x120, _l2Block); publicInputHash = _computePublicInputsHash(_l2Block); } /** * Computes a hash of the public inputs from the calldata * @param _l2Block - The L2 block calldata. - * @return sha256(header[0x4: 0x1ac], diffRoot) + * @return sha256(header[0x4: 0x23c], diffRoot, l1Tol2MessagesHash) */ function _computePublicInputsHash(bytes calldata _l2Block) internal pure returns (bytes32) { - // header size - block number size + one value for the diffRoot - uint256 size = 0x1ac - 0x04 + 0x20; + // header size - block number size + one value for the diffRoot + one value for l1ToL2MessagesHash + uint256 size = 0x23c - 0x04 + 0x20 + 0x20; + + // Compute the public inputs hash bytes memory temp = new bytes(size); assembly { calldatacopy(add(temp, 0x20), add(_l2Block.offset, 0x04), size) } - bytes32 diffRoot = _computeDiffRoot(_l2Block); + // Diff root + (bytes32 diffRoot, bytes32 l1ToL2messagesHash) = _computeDiffRootAndMessagesHash(_l2Block); assembly { - mstore(add(temp, add(0x20, sub(0x1ac, 0x04))), diffRoot) + let endOfTreesData := sub(0x23c, 0x04) + mstore(add(temp, add(0x20, endOfTreesData)), diffRoot) + mstore(add(temp, add(0x40, endOfTreesData)), l1ToL2messagesHash) } return bytes32(uint256(sha256(temp)) % P); @@ -130,7 +146,7 @@ contract Decoder { pure returns (bytes32) { - bytes memory temp = new bytes(0xd8); + bytes memory temp = new bytes(0x120); assembly { mstore8(add(temp, 0x20), shr(24, _l2BlockNumber)) @@ -140,30 +156,45 @@ contract Decoder { } assembly { // Copy header elements (not including block number) for start or end (size 0xd4) - calldatacopy(add(temp, 0x24), add(_l2Block.offset, _offset), 0xd4) + calldatacopy(add(temp, 0x24), add(_l2Block.offset, _offset), 0x11c) } return sha256(temp); } - struct Vars { + struct ArrayLengths { uint256 commitmentCount; uint256 nullifierCount; uint256 dataWritesCount; uint256 contractCount; + uint256 l1Tol2MessagesCount; + } + + struct ArrayOffsets { + uint256 commitmentOffset; + uint256 nullifierOffset; + uint256 publicDataOffset; + uint256 contractOffset; + uint256 contractDataOffset; + uint256 l1ToL2MessagesOffset; } /** * @notice Creates a "diff" tree and compute its root * @param _l2Block - The L2 block calldata. - * @return The root of the "diff" tree */ - function _computeDiffRoot(bytes calldata _l2Block) internal pure returns (bytes32) { + function _computeDiffRootAndMessagesHash(bytes calldata _l2Block) + internal + pure + returns (bytes32, bytes32) + { // Find the lengths of the different inputs - Vars memory vars; + // TOOD: Naming / getting the messages root within this function is a bit weird + ArrayLengths memory lengths; + ArrayOffsets memory offsets; { assembly { - let offset := add(_l2Block.offset, 0x1ac) + let offset := add(_l2Block.offset, 0x23c) let commitmentCount := and(shr(224, calldataload(offset)), 0xffffffff) offset := add(add(offset, 0x4), mul(commitmentCount, 0x20)) let nullifierCount := and(shr(224, calldataload(offset)), 0xffffffff) @@ -171,110 +202,140 @@ contract Decoder { let dataWritesCount := and(shr(224, calldataload(offset)), 0xffffffff) offset := add(add(offset, 0x4), mul(nullifierCount, 0x40)) let contractCount := and(shr(224, calldataload(offset)), 0xffffffff) + offset := add(add(offset, 0x4), mul(contractCount, 0x54)) + let l1Tol2MessagesCount := and(shr(224, calldataload(offset)), 0xffffffff) - // Store it in vars - mstore(vars, commitmentCount) - mstore(add(vars, 0x20), nullifierCount) - mstore(add(vars, 0x40), dataWritesCount) - mstore(add(vars, 0x60), contractCount) + // Store it in lengths + 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 } } bytes32[] memory baseLeafs = new bytes32[]( - vars.commitmentCount / (COMMITMENTS_PER_KERNEL * 2) + lengths.commitmentCount / (COMMITMENTS_PER_KERNEL * 2) ); // Data starts after header. Look at L2 Block Data specification at the top of this file. - uint256 srcCommitmentOffset = 0x1b0; - uint256 srcNullifierOffset = srcCommitmentOffset + 0x4 + vars.commitmentCount * 0x20; - uint256 srcDataOffset = srcNullifierOffset + 0x4 + vars.nullifierCount * 0x20; - uint256 srcContractOffset = srcDataOffset + 0x4 + vars.dataWritesCount * 0x40; - uint256 srcContractDataOffset = srcContractOffset + vars.contractCount * 0x20; - - for (uint256 i = 0; i < baseLeafs.length; i++) { - /** - * Compute the leaf to insert. - * Leaf_i = ( - * newCommitmentsKernel1, - * newCommitmentsKernel2, - * newNullifiersKernel1, - * newNullifiersKernel2, - * newPublicDataWritesKernel1, - * newPublicDataWritesKernel2, - * newContractLeafKernel1, - * newContractLeafKernel2, - * newContractDataKernel1.aztecAddress, - * newContractDataKernel1.ethAddress (padded to 32 bytes) - * newContractDataKernel2.aztecAddress, - * newContractDataKernel2.ethAddress (padded to 32 bytes) - * ); - * Note that we always read data, the l2Block (atm) must therefore include dummy or zero-notes for - * Zero values. - */ - // 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); + { + 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.contractDataOffset = offsets.contractOffset + lengths.contractCount * 0x20; + offsets.l1ToL2MessagesOffset = offsets.contractDataOffset + lengths.contractCount * 0x54; - assembly { - let dstOffset := 0x20 - // Adding new commitments - calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, srcCommitmentOffset), mul(0x08, 0x20) - ) - dstOffset := add(dstOffset, mul(0x08, 0x20)) + for (uint256 i = 0; i < baseLeafs.length; i++) { + /** + * Compute the leaf to insert. + * Leaf_i = ( + * newCommitmentsKernel1, + * newCommitmentsKernel2, + * newNullifiersKernel1, + * newNullifiersKernel2, + * newPublicDataWritesKernel1, + * newPublicDataWritesKernel2, + * newContractLeafKernel1, + * newContractLeafKernel2, + * newContractDataKernel1.aztecAddress, + * newContractDataKernel1.ethAddress (padded to 32 bytes) + * newContractDataKernel2.aztecAddress, + * newContractDataKernel2.ethAddress (padded to 32 bytes) + * ); + * Note that we always read data, the l2Block (atm) must therefore include dummy or zero-notes for + * Zero values. + */ + // 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); - // Adding new nullifiers - calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, srcNullifierOffset), mul(0x08, 0x20) - ) - dstOffset := add(dstOffset, mul(0x08, 0x20)) + assembly { + let dstOffset := 0x20 + // Adding new commitments + calldatacopy( + add(baseLeaf, dstOffset), add(_l2Block.offset, mload(offsets)), mul(0x08, 0x20) + ) + dstOffset := add(dstOffset, mul(0x08, 0x20)) - // Adding new public data writes - calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, srcDataOffset), mul(0x08, 0x40)) - dstOffset := add(dstOffset, mul(0x08, 0x40)) + // Adding new nullifiers + calldatacopy( + add(baseLeaf, dstOffset), + add(_l2Block.offset, mload(add(offsets, 0x20))), + mul(0x08, 0x20) + ) + dstOffset := add(dstOffset, mul(0x08, 0x20)) - // Adding Contract Leafs - calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, srcContractOffset), mul(2, 0x20) - ) - dstOffset := add(dstOffset, mul(2, 0x20)) + // Adding new public data writes + calldatacopy( + add(baseLeaf, dstOffset), + add(_l2Block.offset, mload(add(offsets, 0x40))), + mul(0x08, 0x40) + ) + dstOffset := add(dstOffset, mul(0x08, 0x40)) - // Kernel1.contract.aztecAddress - calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, srcContractDataOffset), 0x20) - dstOffset := add(dstOffset, 0x20) + // Adding Contract Leafs + calldatacopy( + add(baseLeaf, dstOffset), add(_l2Block.offset, mload(add(offsets, 0x60))), mul(2, 0x20) + ) + dstOffset := add(dstOffset, mul(2, 0x20)) - // Kernel1.contract.ethAddress padded to 32 bytes - // Add 12 (0xc) bytes of padding to the ethAddress - dstOffset := add(dstOffset, 0xc) - calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x20)), 0x14 - ) - dstOffset := add(dstOffset, 0x20) + // Kernel1.contract.aztecAddress + let contractDataOffset := mload(add(offsets, 0x80)) + calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, contractDataOffset), 0x20) + dstOffset := add(dstOffset, 0x20) - // Kernel2.contract.aztecAddress - calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x34)), 0x20 - ) - dstOffset := add(dstOffset, 0x20) + // Kernel1.contract.ethAddress padded to 32 bytes + // Add 12 (0xc) bytes of padding to the ethAddress + dstOffset := add(dstOffset, 0xc) + calldatacopy( + add(baseLeaf, dstOffset), add(_l2Block.offset, add(contractDataOffset, 0x20)), 0x14 + ) + dstOffset := add(dstOffset, 0x20) + + // Kernel2.contract.aztecAddress + calldatacopy( + add(baseLeaf, dstOffset), add(_l2Block.offset, add(contractDataOffset, 0x34)), 0x20 + ) + dstOffset := add(dstOffset, 0x20) + + // Kernel2.contract.ethAddress padded to 32 bytes + // Add 12 (0xc) bytes of padding to the ethAddress + dstOffset := add(dstOffset, 0xc) + calldatacopy( + add(baseLeaf, dstOffset), add(_l2Block.offset, add(contractDataOffset, 0x54)), 0x14 + ) + } + + offsets.commitmentOffset += 2 * COMMITMENTS_PER_KERNEL * 0x20; + offsets.nullifierOffset += 2 * NULLIFIERS_PER_KERNEL * 0x20; + offsets.publicDataOffset += 2 * PUBLIC_DATA_WRITES_PER_KERNEL * 0x40; + offsets.contractOffset += 2 * 0x20; + offsets.contractDataOffset += 2 * 0x34; - // Kernel2.contract.ethAddress padded to 32 bytes - // Add 12 (0xc) bytes of padding to the ethAddress - dstOffset := add(dstOffset, 0xc) + baseLeafs[i] = sha256(baseLeaf); + } + } + + bytes32 diffRoot = _computeRoot(baseLeafs); + + bytes32 messagesHash; + { + uint256 messagesHashPreimageSize = 0x20 * L1_TO_L2_MESSAGES_PER_ROLLUP; + bytes memory messagesHashPreimage = new bytes(messagesHashPreimageSize); + assembly { calldatacopy( - add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x54)), 0x14 + add(messagesHashPreimage, 0x20), + add(mload(add(offsets, 0xa0)), 20), + messagesHashPreimageSize ) } - srcCommitmentOffset += 2 * COMMITMENTS_PER_KERNEL * 0x20; - srcNullifierOffset += 2 * NULLIFIERS_PER_KERNEL * 0x20; - srcDataOffset += 2 * PUBLIC_DATA_WRITES_PER_KERNEL * 0x40; - srcContractOffset += 2 * 0x20; - srcContractDataOffset += 2 * 0x34; - - baseLeafs[i] = sha256(baseLeaf); + messagesHash = sha256(messagesHashPreimage); } - return _computeRoot(baseLeafs); + return (diffRoot, messagesHash); } /** diff --git a/l1-contracts/test/Decoder.t.sol b/l1-contracts/test/Decoder.t.sol index 19f3d8994dc..8e2c1f666d5 100644 --- a/l1-contracts/test/Decoder.t.sol +++ b/l1-contracts/test/Decoder.t.sol @@ -13,15 +13,15 @@ contract DecoderTest is Test { DecoderHelper internal helper; bytes block_1 = - hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00000001000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020300000000000000000000000000000000000000000000000000000000000002040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080200000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080500000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000806000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041b024f6e2e258ac4fa7b3a0d03f9fa242eee6d884ec85d0efd4beca26a88da2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006010202020202020202020202020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed000000020000001000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020300000000000000000000000000000000000000000000000000000000000002040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080200000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080500000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000806000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041b024f6e2e258ac4fa7b3a0d03f9fa242eee6d884ec85d0efd4beca26a88da2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006010202020202020202020202020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes block_2 = - hex"000000020283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba0013ffea42e60a3be0af304384d83ad4411df13f66213997a7f0b7551e242f19d0000002001872181b5fe2c7ea15e1e72f5672bc777d61c807771ff7ae40c9b2aa816323500000028063d7b42d552599d3f3ff8fbc93e55484d49fc20dcc41940e3ebeaac4483a8ba0000000803b6339133ac1ca21463e1e3370ca136862bac1be49bdc6e1e69f73068a22ebe0000000316204b8532027613f551ad0530dc70c1c3be36fb7828a3a6539a100c57d25034000000030aa1281a92ab93a92ea1e45d49ce373a45fdb0b7a988416e63cd0728252a112a0000001000000000000000000000000000000000000000000000000000000000000001020000000000000000000000000000000000000000000000000000000000000103000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000001050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080300000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080600000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000807000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042ddfdac63df2e340ea582ed2b6c9d23bf04f6e98c281c25c6dd7e87251185b3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006020303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000020283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed00000002013ffea42e60a3be0af304384d83ad4411df13f66213997a7f0b7551e242f19d0000002001872181b5fe2c7ea15e1e72f5672bc777d61c807771ff7ae40c9b2aa816323500000028063d7b42d552599d3f3ff8fbc93e55484d49fc20dcc41940e3ebeaac4483a8ba0000000803b6339133ac1ca21463e1e3370ca136862bac1be49bdc6e1e69f73068a22ebe0000000316204b8532027613f551ad0530dc70c1c3be36fb7828a3a6539a100c57d25034000000030aa1281a92ab93a92ea1e45d49ce373a45fdb0b7a988416e63cd0728252a112a0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000020236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030000001000000000000000000000000000000000000000000000000000000000000001020000000000000000000000000000000000000000000000000000000000000103000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000001050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080300000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080600000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000807000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042ddfdac63df2e340ea582ed2b6c9d23bf04f6e98c281c25c6dd7e87251185b3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006020303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes block_empty_1 = - hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e150000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed00000002000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes block_empty_2 = - hex"000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000202d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000282f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000008236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030aaa66ea64a4b9493d7237d092f8276e31eb3f8b14ae5c5e0a91fa5627745a83000000032b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000010238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000202d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000282f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000008236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030aaa66ea64a4b9493d7237d092f8276e31eb3f8b14ae5c5e0a91fa5627745a83000000032b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e1500000020236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c00000003000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; function setUp() public { rollup = new Rollup(); @@ -30,13 +30,20 @@ contract DecoderTest is Test { function testEmptyBlocks() public { { - bytes32 diffRoot = helper.computeDiffRoot(block_empty_1); + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_empty_2); assertEq( - 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, diffRoot, + 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, "Invalid diff root" ); + assertEq( + l1ToL2MessagesHash, + 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, + "Invalid messages hash" + ); + ( uint256 l2BlockNumber, bytes32 startStateHash, @@ -47,17 +54,17 @@ contract DecoderTest is Test { assertEq(l2BlockNumber, 1, "Invalid block number"); assertEq( startStateHash, - 0xc3c559a71e6e4e6120dc290ac2aefe6739be32216168d5c98899a86f1566d930, + 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, "Invalid start state hash" ); assertEq( endStateHash, - 0x448312391a3205ecaf22d804a780c19890d6425c621e9a731c342f9903a5e71f, + 0x3dff2c815f7e5f5b8b3a2397347cc928001c73e5442d6dad5af61c3329b4fc8c, "Invalid end state hash" ); assertEq( publicInputsHash, - 0x2e8af2457a0c7cef1b1d47efa0583f1e0840910ab1a802bff812bbc5e62b7321, + 0x23f698e487c4e1b7383889f8864bc19591773d136c364c01d980bd13d0786ba1, "Invalid public input hash" ); @@ -67,13 +74,20 @@ contract DecoderTest is Test { } { - bytes32 diffRoot = helper.computeDiffRoot(block_empty_2); + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_empty_2); assertEq( - 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, diffRoot, + 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, "Invalid diff root" ); + assertEq( + l1ToL2MessagesHash, + 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, + "Invalid messages hash" + ); + ( uint256 l2BlockNumber, bytes32 startStateHash, @@ -84,17 +98,17 @@ contract DecoderTest is Test { assertEq(l2BlockNumber, 2, "Invalid block number"); assertEq( startStateHash, - 0x448312391a3205ecaf22d804a780c19890d6425c621e9a731c342f9903a5e71f, + 0x3dff2c815f7e5f5b8b3a2397347cc928001c73e5442d6dad5af61c3329b4fc8c, "Invalid start state hash" ); assertEq( endStateHash, - 0x2fb8f70b8011dfa8111055c18a0068294d795c2c82701f18b5bf93b3156fe83f, + 0x906b283a0f25f74711aa8e1cdaea18a6e80bebe9ce9118315a0f31433feaffe3, "Invalid end state hash" ); assertEq( publicInputsHash, - 0x0b0c644c9a7106d293ca833a1cb332a576de6971951c2167408545dd7e31a7bb, + 0x0f6cd26577a7c4edf15eb3785315d9f8dbcbc8a3ffc0dba7e04be4e37b09228f, "Invalid public input hash" ); @@ -106,13 +120,20 @@ contract DecoderTest is Test { function testNonEmptyBlocks() public { { - bytes32 diffRoot = helper.computeDiffRoot(block_1); + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_1); assertEq( - 0x05ab40c0ddda5b1846c6283c0a99ea7da9ebb3ea46f33225e72e0d0333bf251f, diffRoot, + 0x05ab40c0ddda5b1846c6283c0a99ea7da9ebb3ea46f33225e72e0d0333bf251f, "Invalid diff root block 1" ); + assertEq( + l1ToL2MessagesHash, + 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, + "Invalid messages hash" + ); + ( uint256 l2BlockNumber, bytes32 startStateHash, @@ -123,17 +144,17 @@ contract DecoderTest is Test { assertEq(l2BlockNumber, 1, "Invalid block number"); assertEq( startStateHash, - 0xc3c559a71e6e4e6120dc290ac2aefe6739be32216168d5c98899a86f1566d930, + 0x2d5d49acd86a4ce5d71f632bd8c39d61d12c7be4ad4ab1f17e134e55aa4e29c2, "Invalid start state hash block 1" ); assertEq( endStateHash, - 0x45faded932e3a828a426370bd7275120c3f4ed27117a6c98c9c762e8b8cec9f6, + 0x8a6161ff9185b2354adadb2a6fbd0a8279d2b7558e617f46cfbd42af3073729c, "Invalid end state hash block 1" ); assertEq( publicInputsHash, - 0x28b90cb81b273c3ee583750e79bca15e9b01fe01a7eacacf462ee866cefb904a, + 0x04b30d90646ca894b0f04cafb6bd76cc7db900dc8cb0a8904b21ff2a6cd4f23e, "Invalid public input hash block 1" ); @@ -143,13 +164,20 @@ contract DecoderTest is Test { } { - bytes32 diffRoot = helper.computeDiffRoot(block_2); + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = + helper.computeDiffRootAndMessagesHash(block_2); assertEq( - 0x04a10b2ce6eb66a3ae547efacc53760ec64fb86c901f9cadb36c104cc532cb99, diffRoot, + 0x04a10b2ce6eb66a3ae547efacc53760ec64fb86c901f9cadb36c104cc532cb99, "Invalid diff root block 2" ); + assertEq( + l1ToL2MessagesHash, + 0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560, + "Invalid l1 to l2 messages hash block 2" + ); + ( uint256 l2BlockNumber, bytes32 startStateHash, @@ -160,17 +188,17 @@ contract DecoderTest is Test { assertEq(l2BlockNumber, 2, "Invalid block number"); assertEq( startStateHash, - 0x45faded932e3a828a426370bd7275120c3f4ed27117a6c98c9c762e8b8cec9f6, + 0x8a6161ff9185b2354adadb2a6fbd0a8279d2b7558e617f46cfbd42af3073729c, "Invalid start state hash block 2" ); assertEq( endStateHash, - 0x0b04cfd8792e17a123c3c5c82bd2593e8da745d05296d4e1058708e11489909a, + 0xd2055c0813616d7073f6bcc905a755ed525e5541b3e5e1b286fd583729c74ea7, "Invalid end state hash block 2" ); assertEq( publicInputsHash, - 0x04f8878ba2e56773029c2b246d41f04963cc8b2654bc35a66b72ff79a7a756ec, + 0x22d088d033eac3347d80581f49057fe24d366cdfdaa644ad4a286d4f8280842b, "Invalid public input hash block 2" ); diff --git a/l1-contracts/test/DecoderHelper.sol b/l1-contracts/test/DecoderHelper.sol index 90a32fd24bb..4bf7de3225c 100644 --- a/l1-contracts/test/DecoderHelper.sol +++ b/l1-contracts/test/DecoderHelper.sol @@ -13,7 +13,12 @@ contract DecoderHelper is Decoder { return _decode(_l2Block); } - function computeDiffRoot(bytes calldata _l2Block) external pure returns (bytes32) { - return _computeDiffRoot(_l2Block); + function computeDiffRootAndMessagesHash(bytes calldata _l2Block) + external + pure + returns (bytes32, bytes32) + { + (bytes32 diffRoot, bytes32 l1ToL2MessagesHash) = _computeDiffRootAndMessagesHash(_l2Block); + return (diffRoot, l1ToL2MessagesHash); } } diff --git a/yarn-project/circuits.js/src/structs/constants.ts b/yarn-project/circuits.js/src/structs/constants.ts index a4ba827ca06..8c06c37b2bb 100644 --- a/yarn-project/circuits.js/src/structs/constants.ts +++ b/yarn-project/circuits.js/src/structs/constants.ts @@ -29,9 +29,14 @@ export const CONTRACT_TREE_HEIGHT = 4; export const PRIVATE_DATA_TREE_HEIGHT = 8; export const PUBLIC_DATA_TREE_HEIGHT = 254; export const NULLIFIER_TREE_HEIGHT = 8; +export const L1_TO_L2_MESSAGES_TREE_HEIGHT = 8; +export const L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT = 8; +export const L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT = 4; export const PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT = 8; export const CONTRACT_TREE_ROOTS_TREE_HEIGHT = 8; export const ROLLUP_VK_TREE_HEIGHT = 8; export const FUNCTION_SELECTOR_NUM_BYTES = 4; + +export const NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; diff --git a/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap index 72ef4bfa0d7..5eeab7ec5d2 100644 --- a/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap @@ -160,6 +160,15 @@ sibling_path: [ 0x1120 0x1121 0x1122 0x1123 0x1124 0x1125 0x1126 0x1127 ] ] new_historic_private_data_tree_roots: [ 0x2000 0x2001 0x2002 0x2003 0x2004 0x2005 0x2006 0x2007 ] new_historic_contract_tree_roots: [ 0x2100 0x2101 0x2102 0x2103 0x2104 0x2105 0x2106 0x2107 ] +new_l1_to_l2_messages: [ 0x2100 0x2101 0x2102 0x2103 0x2104 0x2105 0x2106 0x2107 0x2108 0x2109 0x210a 0x210b 0x210c 0x210d 0x210e 0x210f ] +new_l1_to_l2_message_tree_root_sibling_path: [ 0x2100 0x2101 0x2102 0x2103 ] +new_historic_l1_to_l2_message_roots_tree_sibling_path: [ 0x2100 0x2101 0x2102 0x2103 0x2104 0x2105 0x2106 0x2107 ] +start_l1_to_l2_message_tree_snapshot: root: 0x2200 +next_available_leaf_index: 8704 + +start_historic_tree_l1_to_l2_message_tree_roots_snapshot: root: 0x2300 +next_available_leaf_index: 8960 + " `; @@ -207,6 +216,19 @@ next_available_leaf_index: 2816 end_tree_of_historic_contract_tree_roots_snapshot: root: 0xc00 next_available_leaf_index: 3072 +start_l1_to_l2_messages_tree_snapshot: root: 0xd00 +next_available_leaf_index: 3328 + +end_l1_tol2_messages_tree_snapshot: root: 0xe00 +next_available_leaf_index: 3584 + +start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot: root: 0xf00 +next_available_leaf_index: 3840 + +end_tree_of_historic_l1_tol2_messages_tree_roots_snapshot: root: 0x1000 +next_available_leaf_index: 4096 + calldata_hash: [ 0x1 0x2 ] +l1_to_l2_messages_hash: [ 0x3 0x4 ] " `; diff --git a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts index 055883a218c..0ae40fcb492 100644 --- a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts @@ -2,7 +2,13 @@ import { BufferReader, Fr } from '@aztec/foundation'; import { assertLength, FieldsOf } from '../../utils/jsUtils.js'; import { serializeToBuffer } from '../../utils/serialize.js'; import { AppendOnlyTreeSnapshot } from './append_only_tree_snapshot.js'; -import { CONTRACT_TREE_ROOTS_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT } from '../constants.js'; +import { + CONTRACT_TREE_ROOTS_TREE_HEIGHT, + L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT, + L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, + PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, +} from '../constants.js'; import { PreviousRollupData } from './previous_rollup_data.js'; import { AggregationObject } from '../aggregation_object.js'; @@ -12,17 +18,21 @@ export class RootRollupInputs { public newHistoricPrivateDataTreeRootSiblingPath: Fr[], public newHistoricContractDataTreeRootSiblingPath: Fr[], + public newL1ToL2Messages: Fr[], + public newL1ToL2MessageTreeRootSiblingPath: Fr[], + public newHistoricL1ToL2MessageTreeRootSiblingPath: Fr[], + public startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + public startHistoricTreeL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot, ) { assertLength(this, 'newHistoricPrivateDataTreeRootSiblingPath', PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT); assertLength(this, 'newHistoricContractDataTreeRootSiblingPath', CONTRACT_TREE_ROOTS_TREE_HEIGHT); + assertLength(this, 'newL1ToL2MessageTreeRootSiblingPath', L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT); + assertLength(this, 'newHistoricL1ToL2MessageTreeRootSiblingPath', L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT); + assertLength(this, 'newL1ToL2Messages', NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP); } toBuffer() { - return serializeToBuffer( - this.previousRollupData, - this.newHistoricPrivateDataTreeRootSiblingPath, - this.newHistoricContractDataTreeRootSiblingPath, - ); + return serializeToBuffer(...RootRollupInputs.getFields(this)); } static from(fields: FieldsOf): RootRollupInputs { @@ -34,6 +44,11 @@ export class RootRollupInputs { fields.previousRollupData, fields.newHistoricPrivateDataTreeRootSiblingPath, fields.newHistoricContractDataTreeRootSiblingPath, + fields.newL1ToL2Messages, + fields.newL1ToL2MessageTreeRootSiblingPath, + fields.newHistoricL1ToL2MessageTreeRootSiblingPath, + fields.startL1ToL2MessageTreeSnapshot, + fields.startHistoricTreeL1ToL2MessageTreeRootsSnapshot, ] as const; } } @@ -63,7 +78,14 @@ export class RootRollupPublicInputs { public startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, public endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + public endL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + + public startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public calldataHash: [Fr, Fr], + public l1ToL2MessagesHash: [Fr, Fr], ) {} static getFields(fields: FieldsOf) { @@ -81,7 +103,12 @@ export class RootRollupPublicInputs { fields.endTreeOfHistoricPrivateDataTreeRootsSnapshot, fields.startTreeOfHistoricContractTreeRootsSnapshot, fields.endTreeOfHistoricContractTreeRootsSnapshot, + fields.startL1ToL2MessageTreeSnapshot, + fields.endL1ToL2MessageTreeSnapshot, + fields.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, + fields.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, fields.calldataHash, + fields.l1ToL2MessagesHash, ] as const; } @@ -109,6 +136,11 @@ export class RootRollupPublicInputs { reader.readObject(AppendOnlyTreeSnapshot), reader.readObject(AppendOnlyTreeSnapshot), reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + [reader.readFr(), reader.readFr()], [reader.readFr(), reader.readFr()], ); } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 8052374eff6..3e40c575ed7 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -45,10 +45,13 @@ import { KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, KERNEL_PRIVATE_CALL_STACK_LENGTH, KERNEL_PUBLIC_CALL_STACK_LENGTH, + L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT, + L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT, NEW_L2_TO_L1_MSGS_LENGTH, NEW_COMMITMENTS_LENGTH, NEW_NULLIFIERS_LENGTH, NULLIFIER_TREE_HEIGHT, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_CALL_STACK_LENGTH, PRIVATE_DATA_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, @@ -430,6 +433,11 @@ export function makeRootRollupInputs(seed = 0) { [makePreviousBaseRollupData(seed), makePreviousBaseRollupData(seed + 0x1000)], range(PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, 0x2000).map(fr), range(CONTRACT_TREE_ROOTS_TREE_HEIGHT, 0x2100).map(fr), + range(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, 0x2100).map(fr), + range(L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT, 0x2100).map(fr), + range(L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT, 0x2100).map(fr), + makeAppendOnlyTreeSnapshot(seed + 0x2200), + makeAppendOnlyTreeSnapshot(seed + 0x2300), ); } @@ -448,7 +456,12 @@ export function makeRootRollupPublicInputs(seed = 0) { endTreeOfHistoricPrivateDataTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), startTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), endTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startL1ToL2MessageTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endL1ToL2MessageTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), calldataHash: [new Fr(1n), new Fr(2n)], + l1ToL2MessagesHash: [new Fr(3n), new Fr(4n)], }); } diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts index c942acf16ad..b9880043b92 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts @@ -10,7 +10,7 @@ interface DecoderHelperEventLogs {} interface DecoderHelperTxEventLogs {} export interface DecoderHelperTransactionReceipt extends ContractTxReceipt {} interface DecoderHelperMethods { - computeDiffRoot(_l2Block: Bytes.Bytes): TxCall; + computeDiffRootAndMessagesHash(_l2Block: Bytes.Bytes): TxCall<{ 0: Bytes.Bytes32; 1: Bytes.Bytes32 }>; decode(_l2Block: Bytes.Bytes): TxCall<{ 0: bigint; 1: Bytes.Bytes32; @@ -29,7 +29,7 @@ export class DecoderHelper extends Contract { } deploy(): TxSend { return super.deployBytecode( - '0x608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634f93f40e1461003b578063e5c5e9a314610061575b600080fd5b61004e610049366004610745565b610094565b6040519081526020015b60405180910390f35b61007461006f366004610745565b6100a9565b604080519485526020850193909352918301526060820152608001610058565b60006100a083836100c9565b90505b92915050565b6000806000806100b98686610414565b9299919850965090945092505050565b60006100f66040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061014c600460026107cd565b825161015891906107fa565b67ffffffffffffffff8111156101705761017061080e565b604051908082528060200260200182016040528015610199578160200160208202803683370190505b5082519091506101b0906000906101b19060206107cd565b6101bc836004610824565b6101c69190610824565b90506000846020015160206101db91906107cd565b6101e6836004610824565b6101f09190610824565b905060008560400151604061020591906107cd565b610210836004610824565b61021a9190610824565b905060008660600151602061022f91906107cd565b6102399083610824565b905060005b86518110156103fc57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f8701605401918501013750610305600460026107cd565b6103109060206107cd565b61031a9088610824565b9650610328600460026107cd565b6103339060206107cd565b61033d9087610824565b955061034b600460026107cd565b6103569060406107cd565b6103609086610824565b945061036d604085610824565b935061037a606884610824565b925060028160405161038c9190610837565b602060405180830381855afa1580156103a9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103cc9190610866565b8883815181106103de576103de61087f565b602090810291909101015250806103f481610895565b91505061023e565b506104068661045a565b9a9950505050505050505050565b813560e01c6000808061043461042b6001866108ae565b600488886105d2565b92506104438460d888886105d2565b915061044f868661067d565b905092959194509250565b6000805b825161046b8260026109a5565b1015610483578061047b81610895565b91505061045e565b60006104908260026109a5565b905080845260005b828110156105ad5760005b8281101561059a5760028682815181106104bf576104bf61087f565b6020026020010151878360016104d59190610824565b815181106104e5576104e561087f565b6020026020010151604051602001610507929190918252602082015260400190565b60408051601f198184030181529082905261052191610837565b602060405180830381855afa15801561053e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105619190610866565b8661056d6002846107fa565b8151811061057d5761057d61087f565b6020908102919091010152610593600282610824565b90506104a3565b50806105a581610895565b915050610498565b50836000815181106105c1576105c161087f565b602002602001015192505050919050565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516106339190610837565b602060405180830381855afa158015610650573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106739190610866565b9695505050505050565b604080516101c88082526102008201909252600091908290826020820181803683370190505090508160048601602083013760006106bb86866100c9565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516106fb9190610837565b602060405180830381855afa158015610718573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061073b9190610866565b61067391906109b1565b6000806020838503121561075857600080fd5b823567ffffffffffffffff8082111561077057600080fd5b818501915085601f83011261078457600080fd5b81358181111561079357600080fd5b8660208285010111156107a557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176100a3576100a36107b7565b634e487b7160e01b600052601260045260246000fd5b600082610809576108096107e4565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156100a3576100a36107b7565b6000825160005b81811015610858576020818601810151858301520161083e565b506000920191825250919050565b60006020828403121561087857600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000600182016108a7576108a76107b7565b5060010190565b818103818111156100a3576100a36107b7565b600181815b808511156108fc5781600019048211156108e2576108e26107b7565b808516156108ef57918102915b93841c93908002906108c6565b509250929050565b600082610913575060016100a3565b81610920575060006100a3565b816001811461093657600281146109405761095c565b60019150506100a3565b60ff841115610951576109516107b7565b50506001821b6100a3565b5060208310610133831016604e8410600b841016171561097f575081810a6100a3565b61098983836108c1565b806000190482111561099d5761099d6107b7565b029392505050565b60006100a08383610904565b6000826109c0576109c06107e4565b50069056fea26469706673582212202ef99c8a34102a8b892857ef4d2ff1773f31770e89ceca60a0bea54a127104f064736f6c63430008120033', + '0x608060405234801561001057600080fd5b50610bbd806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063bdfd97c01461003b578063e5c5e9a314610068575b600080fd5b61004e610049366004610900565b61009b565b604080519283526020830191909152015b60405180910390f35b61007b610076366004610900565b6100b8565b60408051948552602085019390935291830152606082015260800161005f565b6000806000806100ab86866100d8565b9097909650945050505050565b6000806000806100c886866105b6565b9299919850965090945092505050565b60008061010d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6101466040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61023c86013560e090811c80845260209081028801610240810135831c85830181905291820201610244810135831c60408681019190915290910201610248810135821c606085018190526054020161024c0135901c608083015260006101af60046002610988565b83516101bb91906109b5565b67ffffffffffffffff8111156101d3576101d36109c9565b6040519080825280602002602001820160405280156101fc578160200160208202803683370190505b5061024083528351909150610212906020610988565b825161021f9060046109df565b61022991906109df565b6020808401919091528381015161023f91610988565b602083015161024f9060046109df565b61025991906109df565b6040808401919091528381015161026f91610988565b604083015161027f9060046109df565b61028991906109df565b6060808401919091528301516102a0906020610988565b82606001516102af91906109df565b608083015260608301516102c4906054610988565b82608001516102d391906109df565b60a083015260005b81518110156104df57604080516104c08082526104e0820190925260009160208201818036833701905050905060208060080285518b018284013760208501516101008281019290918c01908401820137604085015161010082810192610200928d019190850101376060850151610200828101926040928d0191908501013760206002028101905060808501516020818c0183850137602c808301926014918d840160200191860101376020820191506020603482018c0183850137602c808301926014918d84016054019186010137506103bb905060046002610988565b6103c6906020610988565b845185906103d59083906109df565b9052506103e460046002610988565b6103ef906020610988565b8460200181815161040091906109df565b90525061040f60046002610988565b61041a906040610988565b8460400181815161042b91906109df565b905250606084018051604091906104439083906109df565b9052506080840180516068919061045b9083906109df565b90525060405160029061046f9083906109f2565b602060405180830381855afa15801561048c573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104af9190610a21565b8383815181106104c1576104c1610a3a565b602090810291909101015250806104d781610a50565b9150506102db565b5060006104eb826105fd565b90506000806104fc60106020610988565b905060008167ffffffffffffffff811115610519576105196109c9565b6040519080825280601f01601f191660200182016040528015610543576020820181803683370190505b50905081601460a088015101602083013760028160405161056491906109f2565b602060405180830381855afa158015610581573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105a49190610a21565b939b939a509298505050505050505050565b813560e01c600080806105d66105cd600186610a69565b60048888610775565b92506105e6846101208888610775565b91506105f28686610822565b905092959194509250565b6000805b825161060e826002610b60565b1015610626578061061e81610a50565b915050610601565b6000610633826002610b60565b905080845260005b828110156107505760005b8281101561073d57600286828151811061066257610662610a3a565b60200260200101518783600161067891906109df565b8151811061068857610688610a3a565b60200260200101516040516020016106aa929190918252602082015260400190565b60408051601f19818403018152908290526106c4916109f2565b602060405180830381855afa1580156106e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107049190610a21565b866107106002846109b5565b8151811061072057610720610a3a565b60209081029190910101526107366002826109df565b9050610646565b508061074881610a50565b91505061063b565b508360008151811061076457610764610a3a565b602002602001015192505050919050565b6040805161012080825261014082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015361011c85850160248301376002816040516107d891906109f2565b602060405180830381855afa1580156107f5573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108189190610a21565b9695505050505050565b604080516102788082526102a08201909252600091908290826020820181803683370190505090508160048601602083013760008061086187876100d8565b6102588501829052610278850181905260405191935091507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001906002906108a99086906109f2565b602060405180830381855afa1580156108c6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108e99190610a21565b6108f39190610b73565b9450505050505b92915050565b6000806020838503121561091357600080fd5b823567ffffffffffffffff8082111561092b57600080fd5b818501915085601f83011261093f57600080fd5b81358181111561094e57600080fd5b86602082850101111561096057600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108fa576108fa610972565b634e487b7160e01b600052601260045260246000fd5b6000826109c4576109c461099f565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156108fa576108fa610972565b6000825160005b81811015610a1357602081860181015185830152016109f9565b506000920191825250919050565b600060208284031215610a3357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b600060018201610a6257610a62610972565b5060010190565b818103818111156108fa576108fa610972565b600181815b80851115610ab7578160001904821115610a9d57610a9d610972565b80851615610aaa57918102915b93841c9390800290610a81565b509250929050565b600082610ace575060016108fa565b81610adb575060006108fa565b8160018114610af15760028114610afb57610b17565b60019150506108fa565b60ff841115610b0c57610b0c610972565b50506001821b6108fa565b5060208310610133831016604e8410600b8410161715610b3a575081810a6108fa565b610b448383610a7c565b8060001904821115610b5857610b58610972565b029392505050565b6000610b6c8383610abf565b9392505050565b600082610b8257610b8261099f565b50069056fea26469706673582212206f67550bf823fc5222b9bd273c244e63478d38338fa160a09802c12fd933f68964736f6c63430008120033', ) as any; } } diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts index bc6ba0393e6..fb2cbe3e729 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts @@ -8,15 +8,20 @@ export default new ContractAbi([ type: 'bytes', }, ], - name: 'computeDiffRoot', + name: 'computeDiffRootAndMessagesHash', outputs: [ { internalType: 'bytes32', name: '', type: 'bytes32', }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, ], - stateMutability: 'pure', + stateMutability: 'view', type: 'function', }, { @@ -50,7 +55,7 @@ export default new ContractAbi([ type: 'bytes32', }, ], - stateMutability: 'pure', + stateMutability: 'view', type: 'function', }, ]); diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts index 5277921c129..6a6fa590afb 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts @@ -35,7 +35,7 @@ export class Rollup extends Contract { } deploy(): TxSend { return super.deployBytecode( - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610d5483390190565b608051610cdb61007960003960008181604b015261016b0152610cdb6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461091e565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508181600081518110610149576101496109f9565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610a33565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610aad565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610aec565b6004888861027d565b92506102668460d8888861027d565b91506102728686610328565b905092959194509250565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516102de9190610aff565b602060405180830381855afa1580156102fb573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031e9190610b1b565b9695505050505050565b604080516101c880825261020082019092526000919082908260208201818036833701905050905081600486016020830137600061036686866103fc565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516103a69190610aff565b602060405180830381855afa1580156103c3573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103e69190610b1b565b6103f09190610b4a565b93505050505b92915050565b60006104296040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061047f60046002610b5e565b825161048b9190610b75565b67ffffffffffffffff8111156104a3576104a36108bf565b6040519080825280602002602001820160405280156104cc578160200160208202803683370190505b5082519091506101b0906000906104e4906020610b5e565b6104ef836004610b89565b6104f99190610b89565b905060008460200151602061050e9190610b5e565b610519836004610b89565b6105239190610b89565b90506000856040015160406105389190610b5e565b610543836004610b89565b61054d9190610b89565b90506000866060015160206105629190610b5e565b61056c9083610b89565b905060005b865181101561072f57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f870160540191850101375061063860046002610b5e565b610643906020610b5e565b61064d9088610b89565b965061065b60046002610b5e565b610666906020610b5e565b6106709087610b89565b955061067e60046002610b5e565b610689906040610b5e565b6106939086610b89565b94506106a0604085610b89565b93506106ad606884610b89565b92506002816040516106bf9190610aff565b602060405180830381855afa1580156106dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106ff9190610b1b565b888381518110610711576107116109f9565b6020908102919091010152508061072781610b9c565b915050610571565b5061073986610747565b9a9950505050505050505050565b6000805b8251610758826002610c99565b1015610770578061076881610b9c565b91505061074b565b600061077d826002610c99565b905080845260005b8281101561089a5760005b828110156108875760028682815181106107ac576107ac6109f9565b6020026020010151878360016107c29190610b89565b815181106107d2576107d26109f9565b60200260200101516040516020016107f4929190918252602082015260400190565b60408051601f198184030181529082905261080e91610aff565b602060405180830381855afa15801561082b573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061084e9190610b1b565b8661085a600284610b75565b8151811061086a5761086a6109f9565b6020908102919091010152610880600282610b89565b9050610790565b508061089281610b9c565b915050610785565b50836000815181106108ae576108ae6109f9565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126108e757600080fd5b50813567ffffffffffffffff8111156108ff57600080fd5b60208301915083602082850101111561091757600080fd5b9250929050565b60008060006040848603121561093357600080fd5b833567ffffffffffffffff8082111561094b57600080fd5b818601915086601f83011261095f57600080fd5b813581811115610971576109716108bf565b604051601f8201601f19908116603f01168101908382118183101715610999576109996108bf565b816040528281528960208487010111156109b257600080fd5b8260208601602083013760006020848301015280975050505060208601359150808211156109df57600080fd5b506109ec868287016108d5565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610a2a578181015183820152602001610a12565b50506000910152565b60408152600083518060408401526020610a538260608601838901610a0f565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610aa15784518252938301936001929092019190830190610a81565b50979650505050505050565b600060208284031215610abf57600080fd5b81518015158114610acf57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103f6576103f6610ad6565b60008251610b11818460208701610a0f565b9190910192915050565b600060208284031215610b2d57600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610b5957610b59610b34565b500690565b80820281158282048414176103f6576103f6610ad6565b600082610b8457610b84610b34565b500490565b808201808211156103f6576103f6610ad6565b600060018201610bae57610bae610ad6565b5060010190565b600181815b80851115610bf0578160001904821115610bd657610bd6610ad6565b80851615610be357918102915b93841c9390800290610bba565b509250929050565b600082610c07575060016103f6565b81610c14575060006103f6565b8160018114610c2a5760028114610c3457610c50565b60019150506103f6565b60ff841115610c4557610c45610ad6565b50506001821b6103f6565b5060208310610133831016604e8410600b8410161715610c73575081810a6103f6565b610c7d8383610bb5565b8060001904821115610c9157610c91610ad6565b029392505050565b6000610acf8383610bf856fea2646970667358221220ddf248ba6894d5466329c62aa3e8d071d039ec5f5594b21af88ea780d45fefb364736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033', + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610eef83390190565b608051610e7661007960003960008181604b015261016b0152610e766000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af366004610ab9565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061014957610149610b94565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610bce565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610c48565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610c87565b6004888861027e565b925061026784610120888861027e565b9150610273868661032b565b905092959194509250565b6040805161012080825261014082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015361011c85850160248301376002816040516102e19190610c9a565b602060405180830381855afa1580156102fe573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103219190610cb6565b9695505050505050565b604080516102788082526102a08201909252600091908290826020820181803683370190505090508160048601602083013760008061036a8787610409565b6102588501829052610278850181905260405191935091507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001906002906103b2908690610c9a565b602060405180830381855afa1580156103cf573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103f29190610cb6565b6103fc9190610ce5565b9450505050505b92915050565b60008061043e6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6104776040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61023c86013560e090811c80845260209081028801610240810135831c85830181905291820201610244810135831c60408681019190915290910201610248810135821c606085018190526054020161024c0135901c608083015260006104e060046002610cf9565b83516104ec9190610d10565b67ffffffffffffffff81111561050457610504610a61565b60405190808252806020026020018201604052801561052d578160200160208202803683370190505b5061024083528351909150610543906020610cf9565b8251610550906004610d24565b61055a9190610d24565b6020808401919091528381015161057091610cf9565b6020830151610580906004610d24565b61058a9190610d24565b604080840191909152838101516105a091610cf9565b60408301516105b0906004610d24565b6105ba9190610d24565b6060808401919091528301516105d1906020610cf9565b82606001516105e09190610d24565b608083015260608301516105f5906054610cf9565b82608001516106049190610d24565b60a083015260005b815181101561081057604080516104c08082526104e0820190925260009160208201818036833701905050905060208060080285518b018284013760208501516101008281019290918c01908401820137604085015161010082810192610200928d019190850101376060850151610200828101926040928d0191908501013760206002028101905060808501516020818c0183850137602c808301926014918d840160200191860101376020820191506020603482018c0183850137602c808301926014918d84016054019186010137506106ec905060046002610cf9565b6106f7906020610cf9565b84518590610706908390610d24565b90525061071560046002610cf9565b610720906020610cf9565b846020018181516107319190610d24565b90525061074060046002610cf9565b61074b906040610cf9565b8460400181815161075c9190610d24565b90525060608401805160409190610774908390610d24565b9052506080840180516068919061078c908390610d24565b9052506040516002906107a0908390610c9a565b602060405180830381855afa1580156107bd573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107e09190610cb6565b8383815181106107f2576107f2610b94565b6020908102919091010152508061080881610d37565b91505061060c565b50600061081c826108e9565b905060008061082d60106020610cf9565b905060008167ffffffffffffffff81111561084a5761084a610a61565b6040519080825280601f01601f191660200182016040528015610874576020820181803683370190505b50905081601460a08801510160208301376002816040516108959190610c9a565b602060405180830381855afa1580156108b2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108d59190610cb6565b9398509296505050505050505b9250929050565b6000805b82516108fa826002610e34565b1015610912578061090a81610d37565b9150506108ed565b600061091f826002610e34565b905080845260005b82811015610a3c5760005b82811015610a2957600286828151811061094e5761094e610b94565b6020026020010151878360016109649190610d24565b8151811061097457610974610b94565b6020026020010151604051602001610996929190918252602082015260400190565b60408051601f19818403018152908290526109b091610c9a565b602060405180830381855afa1580156109cd573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109f09190610cb6565b866109fc600284610d10565b81518110610a0c57610a0c610b94565b6020908102919091010152610a22600282610d24565b9050610932565b5080610a3481610d37565b915050610927565b5083600081518110610a5057610a50610b94565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f840112610a8957600080fd5b50813567ffffffffffffffff811115610aa157600080fd5b6020830191508360208285010111156108e257600080fd5b600080600060408486031215610ace57600080fd5b833567ffffffffffffffff80821115610ae657600080fd5b818601915086601f830112610afa57600080fd5b813581811115610b0c57610b0c610a61565b604051601f8201601f19908116603f01168101908382118183101715610b3457610b34610a61565b81604052828152896020848701011115610b4d57600080fd5b826020860160208301376000602084830101528097505050506020860135915080821115610b7a57600080fd5b50610b8786828701610a77565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610bc5578181015183820152602001610bad565b50506000910152565b60408152600083518060408401526020610bee8260608601838901610baa565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610c3c5784518252938301936001929092019190830190610c1c565b50979650505050505050565b600060208284031215610c5a57600080fd5b81518015158114610c6a57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561040357610403610c71565b60008251610cac818460208701610baa565b9190910192915050565b600060208284031215610cc857600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610cf457610cf4610ccf565b500690565b808202811582820484141761040357610403610c71565b600082610d1f57610d1f610ccf565b500490565b8082018082111561040357610403610c71565b600060018201610d4957610d49610c71565b5060010190565b600181815b80851115610d8b578160001904821115610d7157610d71610c71565b80851615610d7e57918102915b93841c9390800290610d55565b509250929050565b600082610da257506001610403565b81610daf57506000610403565b8160018114610dc55760028114610dcf57610deb565b6001915050610403565b60ff841115610de057610de0610c71565b50506001821b610403565b5060208310610133831016604e8410600b8410161715610e0e575081810a610403565b610e188383610d50565b8060001904821115610e2c57610e2c610c71565b029392505050565b6000610c6a8383610d9356fea26469706673582212201c00b2c5d56e1c81c09d1676bc7d8d03a02f0908b4d016f19893cdd27242d27e64736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033', ) as any; } } diff --git a/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts b/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts index fddfb2ee271..7bd614dc0d6 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts @@ -10,15 +10,20 @@ export const DecoderHelperAbi = [ type: 'bytes', }, ], - name: 'computeDiffRoot', + name: 'computeDiffRootAndMessagesHash', outputs: [ { internalType: 'bytes32', name: '', type: 'bytes32', }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, ], - stateMutability: 'pure', + stateMutability: 'view', type: 'function', }, { @@ -52,7 +57,7 @@ export const DecoderHelperAbi = [ type: 'bytes32', }, ], - stateMutability: 'pure', + stateMutability: 'view', type: 'function', }, ] as const; @@ -60,4 +65,4 @@ export const DecoderHelperAbi = [ * DecoderHelper Bytecode for viem. */ export const DecoderHelperBytecode = - '0x608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634f93f40e1461003b578063e5c5e9a314610061575b600080fd5b61004e610049366004610745565b610094565b6040519081526020015b60405180910390f35b61007461006f366004610745565b6100a9565b604080519485526020850193909352918301526060820152608001610058565b60006100a083836100c9565b90505b92915050565b6000806000806100b98686610414565b9299919850965090945092505050565b60006100f66040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061014c600460026107cd565b825161015891906107fa565b67ffffffffffffffff8111156101705761017061080e565b604051908082528060200260200182016040528015610199578160200160208202803683370190505b5082519091506101b0906000906101b19060206107cd565b6101bc836004610824565b6101c69190610824565b90506000846020015160206101db91906107cd565b6101e6836004610824565b6101f09190610824565b905060008560400151604061020591906107cd565b610210836004610824565b61021a9190610824565b905060008660600151602061022f91906107cd565b6102399083610824565b905060005b86518110156103fc57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f8701605401918501013750610305600460026107cd565b6103109060206107cd565b61031a9088610824565b9650610328600460026107cd565b6103339060206107cd565b61033d9087610824565b955061034b600460026107cd565b6103569060406107cd565b6103609086610824565b945061036d604085610824565b935061037a606884610824565b925060028160405161038c9190610837565b602060405180830381855afa1580156103a9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103cc9190610866565b8883815181106103de576103de61087f565b602090810291909101015250806103f481610895565b91505061023e565b506104068661045a565b9a9950505050505050505050565b813560e01c6000808061043461042b6001866108ae565b600488886105d2565b92506104438460d888886105d2565b915061044f868661067d565b905092959194509250565b6000805b825161046b8260026109a5565b1015610483578061047b81610895565b91505061045e565b60006104908260026109a5565b905080845260005b828110156105ad5760005b8281101561059a5760028682815181106104bf576104bf61087f565b6020026020010151878360016104d59190610824565b815181106104e5576104e561087f565b6020026020010151604051602001610507929190918252602082015260400190565b60408051601f198184030181529082905261052191610837565b602060405180830381855afa15801561053e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105619190610866565b8661056d6002846107fa565b8151811061057d5761057d61087f565b6020908102919091010152610593600282610824565b90506104a3565b50806105a581610895565b915050610498565b50836000815181106105c1576105c161087f565b602002602001015192505050919050565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516106339190610837565b602060405180830381855afa158015610650573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106739190610866565b9695505050505050565b604080516101c88082526102008201909252600091908290826020820181803683370190505090508160048601602083013760006106bb86866100c9565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516106fb9190610837565b602060405180830381855afa158015610718573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061073b9190610866565b61067391906109b1565b6000806020838503121561075857600080fd5b823567ffffffffffffffff8082111561077057600080fd5b818501915085601f83011261078457600080fd5b81358181111561079357600080fd5b8660208285010111156107a557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176100a3576100a36107b7565b634e487b7160e01b600052601260045260246000fd5b600082610809576108096107e4565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156100a3576100a36107b7565b6000825160005b81811015610858576020818601810151858301520161083e565b506000920191825250919050565b60006020828403121561087857600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000600182016108a7576108a76107b7565b5060010190565b818103818111156100a3576100a36107b7565b600181815b808511156108fc5781600019048211156108e2576108e26107b7565b808516156108ef57918102915b93841c93908002906108c6565b509250929050565b600082610913575060016100a3565b81610920575060006100a3565b816001811461093657600281146109405761095c565b60019150506100a3565b60ff841115610951576109516107b7565b50506001821b6100a3565b5060208310610133831016604e8410600b841016171561097f575081810a6100a3565b61098983836108c1565b806000190482111561099d5761099d6107b7565b029392505050565b60006100a08383610904565b6000826109c0576109c06107e4565b50069056fea26469706673582212202ef99c8a34102a8b892857ef4d2ff1773f31770e89ceca60a0bea54a127104f064736f6c63430008120033'; + '0x608060405234801561001057600080fd5b50610bbd806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063bdfd97c01461003b578063e5c5e9a314610068575b600080fd5b61004e610049366004610900565b61009b565b604080519283526020830191909152015b60405180910390f35b61007b610076366004610900565b6100b8565b60408051948552602085019390935291830152606082015260800161005f565b6000806000806100ab86866100d8565b9097909650945050505050565b6000806000806100c886866105b6565b9299919850965090945092505050565b60008061010d6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6101466040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61023c86013560e090811c80845260209081028801610240810135831c85830181905291820201610244810135831c60408681019190915290910201610248810135821c606085018190526054020161024c0135901c608083015260006101af60046002610988565b83516101bb91906109b5565b67ffffffffffffffff8111156101d3576101d36109c9565b6040519080825280602002602001820160405280156101fc578160200160208202803683370190505b5061024083528351909150610212906020610988565b825161021f9060046109df565b61022991906109df565b6020808401919091528381015161023f91610988565b602083015161024f9060046109df565b61025991906109df565b6040808401919091528381015161026f91610988565b604083015161027f9060046109df565b61028991906109df565b6060808401919091528301516102a0906020610988565b82606001516102af91906109df565b608083015260608301516102c4906054610988565b82608001516102d391906109df565b60a083015260005b81518110156104df57604080516104c08082526104e0820190925260009160208201818036833701905050905060208060080285518b018284013760208501516101008281019290918c01908401820137604085015161010082810192610200928d019190850101376060850151610200828101926040928d0191908501013760206002028101905060808501516020818c0183850137602c808301926014918d840160200191860101376020820191506020603482018c0183850137602c808301926014918d84016054019186010137506103bb905060046002610988565b6103c6906020610988565b845185906103d59083906109df565b9052506103e460046002610988565b6103ef906020610988565b8460200181815161040091906109df565b90525061040f60046002610988565b61041a906040610988565b8460400181815161042b91906109df565b905250606084018051604091906104439083906109df565b9052506080840180516068919061045b9083906109df565b90525060405160029061046f9083906109f2565b602060405180830381855afa15801561048c573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104af9190610a21565b8383815181106104c1576104c1610a3a565b602090810291909101015250806104d781610a50565b9150506102db565b5060006104eb826105fd565b90506000806104fc60106020610988565b905060008167ffffffffffffffff811115610519576105196109c9565b6040519080825280601f01601f191660200182016040528015610543576020820181803683370190505b50905081601460a088015101602083013760028160405161056491906109f2565b602060405180830381855afa158015610581573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105a49190610a21565b939b939a509298505050505050505050565b813560e01c600080806105d66105cd600186610a69565b60048888610775565b92506105e6846101208888610775565b91506105f28686610822565b905092959194509250565b6000805b825161060e826002610b60565b1015610626578061061e81610a50565b915050610601565b6000610633826002610b60565b905080845260005b828110156107505760005b8281101561073d57600286828151811061066257610662610a3a565b60200260200101518783600161067891906109df565b8151811061068857610688610a3a565b60200260200101516040516020016106aa929190918252602082015260400190565b60408051601f19818403018152908290526106c4916109f2565b602060405180830381855afa1580156106e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107049190610a21565b866107106002846109b5565b8151811061072057610720610a3a565b60209081029190910101526107366002826109df565b9050610646565b508061074881610a50565b91505061063b565b508360008151811061076457610764610a3a565b602002602001015192505050919050565b6040805161012080825261014082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015361011c85850160248301376002816040516107d891906109f2565b602060405180830381855afa1580156107f5573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108189190610a21565b9695505050505050565b604080516102788082526102a08201909252600091908290826020820181803683370190505090508160048601602083013760008061086187876100d8565b6102588501829052610278850181905260405191935091507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001906002906108a99086906109f2565b602060405180830381855afa1580156108c6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108e99190610a21565b6108f39190610b73565b9450505050505b92915050565b6000806020838503121561091357600080fd5b823567ffffffffffffffff8082111561092b57600080fd5b818501915085601f83011261093f57600080fd5b81358181111561094e57600080fd5b86602082850101111561096057600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108fa576108fa610972565b634e487b7160e01b600052601260045260246000fd5b6000826109c4576109c461099f565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156108fa576108fa610972565b6000825160005b81811015610a1357602081860181015185830152016109f9565b506000920191825250919050565b600060208284031215610a3357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b600060018201610a6257610a62610972565b5060010190565b818103818111156108fa576108fa610972565b600181815b80851115610ab7578160001904821115610a9d57610a9d610972565b80851615610aaa57918102915b93841c9390800290610a81565b509250929050565b600082610ace575060016108fa565b81610adb575060006108fa565b8160018114610af15760028114610afb57610b17565b60019150506108fa565b60ff841115610b0c57610b0c610972565b50506001821b6108fa565b5060208310610133831016604e8410600b8410161715610b3a575081810a6108fa565b610b448383610a7c565b8060001904821115610b5857610b58610972565b029392505050565b6000610b6c8383610abf565b9392505050565b600082610b8257610b8261099f565b50069056fea26469706673582212206f67550bf823fc5222b9bd273c244e63478d38338fa160a09802c12fd933f68964736f6c63430008120033'; diff --git a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts index 843bfd9b2a7..04e882b4f8c 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts @@ -90,4 +90,4 @@ export const RollupAbi = [ * Rollup Bytecode for viem. */ export const RollupBytecode = - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610d5483390190565b608051610cdb61007960003960008181604b015261016b0152610cdb6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461091e565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508181600081518110610149576101496109f9565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610a33565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610aad565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610aec565b6004888861027d565b92506102668460d8888861027d565b91506102728686610328565b905092959194509250565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516102de9190610aff565b602060405180830381855afa1580156102fb573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031e9190610b1b565b9695505050505050565b604080516101c880825261020082019092526000919082908260208201818036833701905050905081600486016020830137600061036686866103fc565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516103a69190610aff565b602060405180830381855afa1580156103c3573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103e69190610b1b565b6103f09190610b4a565b93505050505b92915050565b60006104296040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061047f60046002610b5e565b825161048b9190610b75565b67ffffffffffffffff8111156104a3576104a36108bf565b6040519080825280602002602001820160405280156104cc578160200160208202803683370190505b5082519091506101b0906000906104e4906020610b5e565b6104ef836004610b89565b6104f99190610b89565b905060008460200151602061050e9190610b5e565b610519836004610b89565b6105239190610b89565b90506000856040015160406105389190610b5e565b610543836004610b89565b61054d9190610b89565b90506000866060015160206105629190610b5e565b61056c9083610b89565b905060005b865181101561072f57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f870160540191850101375061063860046002610b5e565b610643906020610b5e565b61064d9088610b89565b965061065b60046002610b5e565b610666906020610b5e565b6106709087610b89565b955061067e60046002610b5e565b610689906040610b5e565b6106939086610b89565b94506106a0604085610b89565b93506106ad606884610b89565b92506002816040516106bf9190610aff565b602060405180830381855afa1580156106dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106ff9190610b1b565b888381518110610711576107116109f9565b6020908102919091010152508061072781610b9c565b915050610571565b5061073986610747565b9a9950505050505050505050565b6000805b8251610758826002610c99565b1015610770578061076881610b9c565b91505061074b565b600061077d826002610c99565b905080845260005b8281101561089a5760005b828110156108875760028682815181106107ac576107ac6109f9565b6020026020010151878360016107c29190610b89565b815181106107d2576107d26109f9565b60200260200101516040516020016107f4929190918252602082015260400190565b60408051601f198184030181529082905261080e91610aff565b602060405180830381855afa15801561082b573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061084e9190610b1b565b8661085a600284610b75565b8151811061086a5761086a6109f9565b6020908102919091010152610880600282610b89565b9050610790565b508061089281610b9c565b915050610785565b50836000815181106108ae576108ae6109f9565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126108e757600080fd5b50813567ffffffffffffffff8111156108ff57600080fd5b60208301915083602082850101111561091757600080fd5b9250929050565b60008060006040848603121561093357600080fd5b833567ffffffffffffffff8082111561094b57600080fd5b818601915086601f83011261095f57600080fd5b813581811115610971576109716108bf565b604051601f8201601f19908116603f01168101908382118183101715610999576109996108bf565b816040528281528960208487010111156109b257600080fd5b8260208601602083013760006020848301015280975050505060208601359150808211156109df57600080fd5b506109ec868287016108d5565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610a2a578181015183820152602001610a12565b50506000910152565b60408152600083518060408401526020610a538260608601838901610a0f565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610aa15784518252938301936001929092019190830190610a81565b50979650505050505050565b600060208284031215610abf57600080fd5b81518015158114610acf57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103f6576103f6610ad6565b60008251610b11818460208701610a0f565b9190910192915050565b600060208284031215610b2d57600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610b5957610b59610b34565b500690565b80820281158282048414176103f6576103f6610ad6565b600082610b8457610b84610b34565b500490565b808201808211156103f6576103f6610ad6565b600060018201610bae57610bae610ad6565b5060010190565b600181815b80851115610bf0578160001904821115610bd657610bd6610ad6565b80851615610be357918102915b93841c9390800290610bba565b509250929050565b600082610c07575060016103f6565b81610c14575060006103f6565b8160018114610c2a5760028114610c3457610c50565b60019150506103f6565b60ff841115610c4557610c45610ad6565b50506001821b6103f6565b5060208310610133831016604e8410600b8410161715610c73575081810a6103f6565b610c7d8383610bb5565b8060001904821115610c9157610c91610ad6565b029392505050565b6000610acf8383610bf856fea2646970667358221220ddf248ba6894d5466329c62aa3e8d071d039ec5f5594b21af88ea780d45fefb364736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033'; + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610eef83390190565b608051610e7661007960003960008181604b015261016b0152610e766000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af366004610ab9565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061014957610149610b94565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610bce565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610c48565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610c87565b6004888861027e565b925061026784610120888861027e565b9150610273868661032b565b905092959194509250565b6040805161012080825261014082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015361011c85850160248301376002816040516102e19190610c9a565b602060405180830381855afa1580156102fe573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103219190610cb6565b9695505050505050565b604080516102788082526102a08201909252600091908290826020820181803683370190505090508160048601602083013760008061036a8787610409565b6102588501829052610278850181905260405191935091507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001906002906103b2908690610c9a565b602060405180830381855afa1580156103cf573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103f29190610cb6565b6103fc9190610ce5565b9450505050505b92915050565b60008061043e6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6104776040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61023c86013560e090811c80845260209081028801610240810135831c85830181905291820201610244810135831c60408681019190915290910201610248810135821c606085018190526054020161024c0135901c608083015260006104e060046002610cf9565b83516104ec9190610d10565b67ffffffffffffffff81111561050457610504610a61565b60405190808252806020026020018201604052801561052d578160200160208202803683370190505b5061024083528351909150610543906020610cf9565b8251610550906004610d24565b61055a9190610d24565b6020808401919091528381015161057091610cf9565b6020830151610580906004610d24565b61058a9190610d24565b604080840191909152838101516105a091610cf9565b60408301516105b0906004610d24565b6105ba9190610d24565b6060808401919091528301516105d1906020610cf9565b82606001516105e09190610d24565b608083015260608301516105f5906054610cf9565b82608001516106049190610d24565b60a083015260005b815181101561081057604080516104c08082526104e0820190925260009160208201818036833701905050905060208060080285518b018284013760208501516101008281019290918c01908401820137604085015161010082810192610200928d019190850101376060850151610200828101926040928d0191908501013760206002028101905060808501516020818c0183850137602c808301926014918d840160200191860101376020820191506020603482018c0183850137602c808301926014918d84016054019186010137506106ec905060046002610cf9565b6106f7906020610cf9565b84518590610706908390610d24565b90525061071560046002610cf9565b610720906020610cf9565b846020018181516107319190610d24565b90525061074060046002610cf9565b61074b906040610cf9565b8460400181815161075c9190610d24565b90525060608401805160409190610774908390610d24565b9052506080840180516068919061078c908390610d24565b9052506040516002906107a0908390610c9a565b602060405180830381855afa1580156107bd573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107e09190610cb6565b8383815181106107f2576107f2610b94565b6020908102919091010152508061080881610d37565b91505061060c565b50600061081c826108e9565b905060008061082d60106020610cf9565b905060008167ffffffffffffffff81111561084a5761084a610a61565b6040519080825280601f01601f191660200182016040528015610874576020820181803683370190505b50905081601460a08801510160208301376002816040516108959190610c9a565b602060405180830381855afa1580156108b2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108d59190610cb6565b9398509296505050505050505b9250929050565b6000805b82516108fa826002610e34565b1015610912578061090a81610d37565b9150506108ed565b600061091f826002610e34565b905080845260005b82811015610a3c5760005b82811015610a2957600286828151811061094e5761094e610b94565b6020026020010151878360016109649190610d24565b8151811061097457610974610b94565b6020026020010151604051602001610996929190918252602082015260400190565b60408051601f19818403018152908290526109b091610c9a565b602060405180830381855afa1580156109cd573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109f09190610cb6565b866109fc600284610d10565b81518110610a0c57610a0c610b94565b6020908102919091010152610a22600282610d24565b9050610932565b5080610a3481610d37565b915050610927565b5083600081518110610a5057610a50610b94565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f840112610a8957600080fd5b50813567ffffffffffffffff811115610aa157600080fd5b6020830191508360208285010111156108e257600080fd5b600080600060408486031215610ace57600080fd5b833567ffffffffffffffff80821115610ae657600080fd5b818601915086601f830112610afa57600080fd5b813581811115610b0c57610b0c610a61565b604051601f8201601f19908116603f01168101908382118183101715610b3457610b34610a61565b81604052828152896020848701011115610b4d57600080fd5b826020860160208301376000602084830101528097505050506020860135915080821115610b7a57600080fd5b50610b8786828701610a77565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610bc5578181015183820152602001610bad565b50506000910152565b60408152600083518060408401526020610bee8260608601838901610baa565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610c3c5784518252938301936001929092019190830190610c1c565b50979650505050505050565b600060208284031215610c5a57600080fd5b81518015158114610c6a57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561040357610403610c71565b60008251610cac818460208701610baa565b9190910192915050565b600060208284031215610cc857600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610cf457610cf4610ccf565b500690565b808202811582820484141761040357610403610c71565b600082610d1f57610d1f610ccf565b500490565b8082018082111561040357610403610c71565b600060018201610d4957610d49610c71565b5060010190565b600181815b80851115610d8b578160001904821115610d7157610d71610c71565b80851615610d7e57918102915b93841c9390800290610d55565b509250929050565b600082610da257506001610403565b81610daf57506000610403565b8160018114610dc55760028114610dcf57610deb565b6001915050610403565b60ff841115610de057610de0610c71565b50506001821b610403565b5060208310610133831016604e8410600b8410161715610e0e575081810a610403565b610e188383610d50565b8060001904821115610e2c57610e2c610c71565b029392505050565b6000610c6a8383610d9356fea26469706673582212201c00b2c5d56e1c81c09d1676bc7d8d03a02f0908b4d016f19893cdd27242d27e64736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033'; diff --git a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts index b310b04bc90..a490101e430 100644 --- a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts @@ -6,6 +6,7 @@ import { KernelCircuitPublicInputs, PublicDataRead, PublicDataTransition, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, RootRollupPublicInputs, UInt8Vector, } from '@aztec/circuits.js'; @@ -55,6 +56,7 @@ describe('sequencer/circuit_block_builder', () => { let baseRollupOutputLeft: BaseOrMergeRollupPublicInputs; let baseRollupOutputRight: BaseOrMergeRollupPublicInputs; let rootRollupOutput: RootRollupPublicInputs; + let mockL1ToL2Messages: Fr[]; let wasm: CircuitsWasm; @@ -73,6 +75,9 @@ describe('sequencer/circuit_block_builder', () => { prover = mock(); builder = new CircuitBlockBuilder(builderDb, vks, simulator, prover); + // Create mock l1 to L2 messages + mockL1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); + // Create mock outputs for simualator baseRollupOutputLeft = makeBaseRollupPublicInputs(); baseRollupOutputRight = makeBaseRollupPublicInputs(); @@ -107,54 +112,71 @@ describe('sequencer/circuit_block_builder', () => { } }; + const updateL1ToL2MessagesTree = async (l1ToL2Messages: Fr[]) => { + const asBuffer = l1ToL2Messages.map(m => m.toBuffer()); + await expectsDb.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, asBuffer); + }; + const getTreeSnapshot = async (tree: MerkleTreeId) => { const treeInfo = await expectsDb.getTreeInfo(tree); return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size)); }; + const buildMockSimulatorInputs = async () => { + const kernelOutput = makeKernelPublicInputs(); + kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(expectsDb); + const tx = await makeProcessedTx(Tx.createPrivate(kernelOutput, emptyProof, makeEmptyUnverifiedData())); + + const txsLeft = [tx, await makeEmptyProcessedTx()]; + const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; + + // Calculate what would be the tree roots after the txs from the first base rollup land and update mock circuit output + await updateExpectedTreesFromTxs(txsLeft); + baseRollupOutputLeft.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + baseRollupOutputLeft.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + baseRollupOutputLeft.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + baseRollupOutputLeft.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; + + // Same for the two txs on the right + await updateExpectedTreesFromTxs(txsRight); + baseRollupOutputRight.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + baseRollupOutputRight.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + baseRollupOutputRight.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + baseRollupOutputRight.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; + + // Update l1 to l2 data tree + // And update the root trees now to create proper output to the root rollup circuit + await updateL1ToL2MessagesTree(mockL1ToL2Messages); + await expectsDb.updateHistoricRootsTrees(); + rootRollupOutput.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + rootRollupOutput.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + rootRollupOutput.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; + rootRollupOutput.endTreeOfHistoricContractTreeRootsSnapshot = await getTreeSnapshot( + MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, + ); + rootRollupOutput.endTreeOfHistoricPrivateDataTreeRootsSnapshot = await getTreeSnapshot( + MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, + ); + rootRollupOutput.endL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); + rootRollupOutput.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = await getTreeSnapshot( + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, + ); + + return [...txsLeft, ...txsRight]; + }; + describe('mock simulator', () => { - it('builds an L2 block using mock simulator', async () => { + beforeEach(() => { // Create instance to test builder = new CircuitBlockBuilder(builderDb, vks, simulator, prover); - + }); + it('builds an L2 block using mock simulator', async () => { // Assemble a fake transaction - const kernelOutput = makeKernelPublicInputs(); - kernelOutput.constants.historicTreeRoots = await getCombinedHistoricTreeRoots(expectsDb); - const tx = await makeProcessedTx(Tx.createPrivate(kernelOutput, emptyProof, makeEmptyUnverifiedData())); - - const txsLeft = [tx, await makeEmptyProcessedTx()]; - const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; - - // Calculate what would be the tree roots after the txs from the first base rollup land and update mock circuit output - await updateExpectedTreesFromTxs(txsLeft); - baseRollupOutputLeft.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); - baseRollupOutputLeft.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); - baseRollupOutputLeft.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); - baseRollupOutputLeft.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; - - // Same for the two txs on the right - await updateExpectedTreesFromTxs(txsRight); - baseRollupOutputRight.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); - baseRollupOutputRight.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); - baseRollupOutputRight.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); - baseRollupOutputRight.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; - - // And update the root trees now to create proper output to the root rollup circuit - await expectsDb.updateRootsTrees(); - rootRollupOutput.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); - rootRollupOutput.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); - rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); - rootRollupOutput.endPublicDataTreeRoot = (await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE)).root; - rootRollupOutput.endTreeOfHistoricContractTreeRootsSnapshot = await getTreeSnapshot( - MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, - ); - rootRollupOutput.endTreeOfHistoricPrivateDataTreeRootsSnapshot = await getTreeSnapshot( - MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, - ); + const txs = await buildMockSimulatorInputs(); // Actually build a block! - const txs = [tx, await makeEmptyProcessedTx(), await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; - const [l2Block, proof] = await builder.buildL2Block(blockNumber, txs); + const [l2Block, proof] = await builder.buildL2Block(blockNumber, txs, mockL1ToL2Messages); expect(l2Block.number).toEqual(blockNumber); expect(proof).toEqual(emptyProof); @@ -170,14 +192,20 @@ describe('sequencer/circuit_block_builder', () => { const leaves = nullifiers.map(i => toBufferBE(BigInt(i), 32)); await expectsDb.appendLeaves(MerkleTreeId.NULLIFIER_TREE, leaves); - builder = new CircuitBlockBuilder(builderDb, vks, simulator, prover); - await builder.performBaseRollupBatchInsertionProofs(leaves); const expected = await expectsDb.getTreeInfo(MerkleTreeId.NULLIFIER_TREE); const actual = await builderDb.getTreeInfo(MerkleTreeId.NULLIFIER_TREE); expect(actual).toEqual(expected); }); + + it('Rejects if too many l1 to l2 messages are provided', async () => { + // Assemble a fake transaction + const txs = await buildMockSimulatorInputs(); + const l1ToL2Messages = new Array(100).fill(new Fr(0n)); + + await expect(builder.buildL2Block(blockNumber, txs, l1ToL2Messages)).rejects.toThrow(); + }); }); describe('circuits simulator', () => { @@ -218,7 +246,7 @@ describe('sequencer/circuit_block_builder', () => { ...(await Promise.all(times(totalCount - deployCount, makeEmptyProcessedTx))), ]; - const [l2Block] = await builder.buildL2Block(blockNumber, txs); + const [l2Block] = await builder.buildL2Block(blockNumber, txs, mockL1ToL2Messages); expect(l2Block.number).toEqual(blockNumber); await updateExpectedTreesFromTxs(txs); @@ -243,7 +271,7 @@ describe('sequencer/circuit_block_builder', () => { makeEmptyProcessedTx(), ]); - const [l2Block] = await builder.buildL2Block(blockNumber, txs); + const [l2Block] = await builder.buildL2Block(blockNumber, txs, mockL1ToL2Messages); expect(l2Block.number).toEqual(blockNumber); expect(l2Block.newPublicDataWrites[0]).toEqual(new PublicDataWrite(fr(2), fr(12))); await updateExpectedTreesFromTxs(txs); @@ -274,8 +302,11 @@ describe('sequencer/circuit_block_builder', () => { ); const txs = [tx, await makeEmptyProcessedTx(), await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; - const [l2Block] = await builder.buildL2Block(blockNumber, txs); + const [l2Block] = await builder.buildL2Block(blockNumber, txs, mockL1ToL2Messages); expect(l2Block.number).toEqual(blockNumber); }, 10000); }); + + // describe("Input guard tests", () => { + // }) }); diff --git a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts index c9e946b223c..0ea40b71d95 100644 --- a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts @@ -5,9 +5,11 @@ import { CONTRACT_TREE_ROOTS_TREE_HEIGHT, CircuitsWasm, ConstantBaseRollupData, + L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT, MembershipWitness, MergeRollupInputs, NULLIFIER_TREE_HEIGHT, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NullifierLeafPreimage, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, @@ -36,6 +38,7 @@ import { RollupSimulator } from '../simulator/index.js'; import { ProcessedTx } from '../sequencer/processed_tx.js'; import { BlockBuilder } from './index.js'; import { toFriendlyJSON } from '@aztec/circuits.js/utils'; +import { AllowedTreeNames, OutputWithTreeSnapshot } from './types.js'; const frToBigInt = (fr: Fr) => toBigIntBE(fr.toBuffer()); const bigintToFr = (num: bigint) => new Fr(num); @@ -83,7 +86,11 @@ export class CircuitBlockBuilder implements BlockBuilder { protected debug = createDebugLogger('aztec:sequencer'), ) {} - public async buildL2Block(blockNumber: number, txs: ProcessedTx[]): Promise<[L2Block, UInt8Vector]> { + public async buildL2Block( + blockNumber: number, + txs: ProcessedTx[], + newL1ToL2Messages: Fr[], + ): Promise<[L2Block, UInt8Vector]> { const [ startPrivateDataTreeSnapshot, startNullifierTreeSnapshot, @@ -91,6 +98,8 @@ export class CircuitBlockBuilder implements BlockBuilder { startPublicDataTreeSnapshot, startTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, + startL1ToL2MessageTreeSnapshot, + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, ] = await Promise.all( [ MerkleTreeId.PRIVATE_DATA_TREE, @@ -99,6 +108,8 @@ export class CircuitBlockBuilder implements BlockBuilder { MerkleTreeId.PUBLIC_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, + MerkleTreeId.L1_TO_L2_MESSAGES_TREE, + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, ].map(tree => this.getTreeSnapshot(tree)), ); @@ -106,7 +117,7 @@ export class CircuitBlockBuilder implements BlockBuilder { this.validateTxs(txs); // We fill the tx batch with empty txs, we process only one tx at a time for now - const [circuitsOutput, proof] = await this.runCircuits(txs); + const [circuitsOutput, proof] = await this.runCircuits(txs, newL1ToL2Messages); const { endPrivateDataTreeSnapshot, @@ -115,6 +126,8 @@ export class CircuitBlockBuilder implements BlockBuilder { endPublicDataTreeRoot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, + endL1ToL2MessageTreeSnapshot, + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, } = circuitsOutput; // Collect all new nullifiers, commitments, and contracts from all txs in this block @@ -143,11 +156,16 @@ export class CircuitBlockBuilder implements BlockBuilder { endTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, + startL1ToL2MessageTreeSnapshot, + endL1ToL2MessageTreeSnapshot, + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, newCommitments, newNullifiers, newContracts, newContractData, newPublicDataWrites, + newL1ToL2Messages, }); return [l2Block, proof]; @@ -168,13 +186,20 @@ export class CircuitBlockBuilder implements BlockBuilder { return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size)); } - protected async runCircuits(txs: ProcessedTx[]): Promise<[RootRollupPublicInputs, Proof]> { + protected async runCircuits(txs: ProcessedTx[], newL1ToL2Messages: Fr[]): Promise<[RootRollupPublicInputs, Proof]> { // Check that the length of the array of txs is a power of two // See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 if (txs.length < 4 || (txs.length & (txs.length - 1)) !== 0) { throw new Error(`Length of txs for the block should be a power of two and at least four (got ${txs.length})`); } + // Check that the number of new L1 to L2 messages is the same as the max + if (newL1ToL2Messages.length !== NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) { + throw new Error( + `Length of the l1 to l2 messages per block should be a constant ${NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP} (got ${newL1ToL2Messages.length})`, + ); + } + // Run the base rollup circuits for the txs const baseRollupOutputs: [BaseOrMergeRollupPublicInputs, Proof][] = []; for (const pair of chunk(txs, 2)) { @@ -196,7 +221,7 @@ export class CircuitBlockBuilder implements BlockBuilder { // Run the root rollup with the last two merge rollups (or base, if no merge layers) const [mergeOutputLeft, mergeOutputRight] = mergeRollupInputs; - return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight); + return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, newL1ToL2Messages); } protected async baseRollupCircuit( @@ -241,18 +266,26 @@ export class CircuitBlockBuilder implements BlockBuilder { protected async rootRollupCircuit( left: [BaseOrMergeRollupPublicInputs, Proof], right: [BaseOrMergeRollupPublicInputs, Proof], + newL1ToL2Messages: Fr[], ): Promise<[RootRollupPublicInputs, Proof]> { this.debug(`Running root rollup circuit`); - const rootInput = await this.getRootRollupInput(...left, ...right); + const rootInput = await this.getRootRollupInput(...left, ...right, newL1ToL2Messages); + + // Update the local trees to include the new l1 to l2 messages + await this.db.appendLeaves( + MerkleTreeId.L1_TO_L2_MESSAGES_TREE, + newL1ToL2Messages.map(m => m.toBuffer()), + ); // Simulate and get proof for the root circuit const rootOutput = await this.simulator.rootRollupCircuit(rootInput); + const rootProof = await this.prover.getRootRollupProof(rootInput, rootOutput); // Update the root trees with the latest data and contract tree roots, // and validate them against the output of the root circuit simulation this.debug(`Updating and validating root trees`); - await this.db.updateRootsTrees(); + await this.db.updateHistoricRootsTrees(); await this.validateRootOutput(rootOutput); return [rootOutput, rootProof]; @@ -261,9 +294,9 @@ export class CircuitBlockBuilder implements BlockBuilder { // Validate that the new roots we calculated from manual insertions match the outputs of the simulation protected async validateTrees(rollupOutput: BaseOrMergeRollupPublicInputs | RootRollupPublicInputs) { await Promise.all([ - this.validateTreeSnapshot(rollupOutput, MerkleTreeId.CONTRACT_TREE, 'Contract'), - this.validateTreeSnapshot(rollupOutput, MerkleTreeId.PRIVATE_DATA_TREE, 'PrivateData'), - this.validateTreeSnapshot(rollupOutput, MerkleTreeId.NULLIFIER_TREE, 'Nullifier'), + this.validateTree(rollupOutput, MerkleTreeId.CONTRACT_TREE, 'Contract'), + this.validateTree(rollupOutput, MerkleTreeId.PRIVATE_DATA_TREE, 'PrivateData'), + this.validateTree(rollupOutput, MerkleTreeId.NULLIFIER_TREE, 'Nullifier'), this.validatePublicDataTreeRoot(rollupOutput), ]); } @@ -274,6 +307,8 @@ export class CircuitBlockBuilder implements BlockBuilder { this.validateTrees(rootOutput), this.validateRootTree(rootOutput, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, 'Contract'), this.validateRootTree(rootOutput, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, 'PrivateData'), + this.validateRootTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, 'L1ToL2Message'), + this.validateTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_TREE, 'L1ToL2Message'), ]); } @@ -281,7 +316,7 @@ export class CircuitBlockBuilder implements BlockBuilder { protected async validateRootTree( rootOutput: RootRollupPublicInputs, treeId: MerkleTreeId, - name: 'Contract' | 'PrivateData', + name: 'Contract' | 'PrivateData' | 'L1ToL2Message', ) { const localTree = await this.getTreeSnapshot(treeId); const simulatedTree = rootOutput[`endTreeOfHistoric${name}TreeRootsSnapshot`]; @@ -304,13 +339,17 @@ export class CircuitBlockBuilder implements BlockBuilder { } // Helper for validating a non-roots tree against a circuit simulation output - protected async validateTreeSnapshot( - output: BaseOrMergeRollupPublicInputs | RootRollupPublicInputs, + protected async validateTree( + output: T, treeId: MerkleTreeId, - name: 'PrivateData' | 'Contract' | 'Nullifier', + name: AllowedTreeNames, ) { + if ('endL1ToL2MessageTreeSnapshot' in output && !(output instanceof RootRollupPublicInputs)) { + throw new Error(`The name 'L1ToL2Message' can only be used when output is of type RootRollupPublicInputs`); + } + const localTree = await this.getTreeSnapshot(treeId); - const simulatedTree = output[`end${name}TreeSnapshot`]; + const simulatedTree = (output as OutputWithTreeSnapshot)[`end${name}TreeSnapshot`]; this.validateSimulatedTree(localTree, simulatedTree, name); } @@ -318,7 +357,7 @@ export class CircuitBlockBuilder implements BlockBuilder { protected validateSimulatedTree( localTree: AppendOnlyTreeSnapshot, simulatedTree: AppendOnlyTreeSnapshot, - name: 'PrivateData' | 'Contract' | 'Nullifier', + name: 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Message', label?: string, ) { if (!simulatedTree.root.toBuffer().equals(localTree.root.toBuffer())) { @@ -339,6 +378,7 @@ export class CircuitBlockBuilder implements BlockBuilder { rollupProofLeft: Proof, rollupOutputRight: BaseOrMergeRollupPublicInputs, rollupProofRight: Proof, + newL1ToL2Messages: Fr[], ) { const vk = this.getVerificationKey(rollupOutputLeft.rollupType); const previousRollupData: RootRollupInputs['previousRollupData'] = [ @@ -360,11 +400,29 @@ export class CircuitBlockBuilder implements BlockBuilder { const newHistoricPrivateDataTreeRootSiblingPath = await getRootTreeSiblingPath( MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, ); + const newHistoricL1ToL2MessageTreeRootSiblingPath = await getRootTreeSiblingPath( + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, + ); + const newL1ToL2MessageTreeRootSiblingPath = await this.getSubtreeSiblingPath( + MerkleTreeId.L1_TO_L2_MESSAGES_TREE, + L1_TO_L2_MESSAGES_SUBTREE_INSERTION_HEIGHT, + ); + + // Get tree snapshots + const startL1ToL2MessageTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); + const startHistoricTreeL1ToL2MessageTreeRootsSnapshot = await this.getTreeSnapshot( + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, + ); return RootRollupInputs.from({ previousRollupData, newHistoricContractDataTreeRootSiblingPath, newHistoricPrivateDataTreeRootSiblingPath, + newL1ToL2Messages, + newHistoricL1ToL2MessageTreeRootSiblingPath, + newL1ToL2MessageTreeRootSiblingPath, + startL1ToL2MessageTreeSnapshot, + startHistoricTreeL1ToL2MessageTreeRootsSnapshot, }); } diff --git a/yarn-project/sequencer-client/src/block_builder/index.ts b/yarn-project/sequencer-client/src/block_builder/index.ts index 8859a405a7a..72a930476e6 100644 --- a/yarn-project/sequencer-client/src/block_builder/index.ts +++ b/yarn-project/sequencer-client/src/block_builder/index.ts @@ -1,7 +1,8 @@ import { L2Block } from '@aztec/types'; import { Proof } from '../prover/index.js'; import { ProcessedTx } from '../sequencer/processed_tx.js'; +import { Fr } from '@aztec/foundation'; export interface BlockBuilder { - buildL2Block(blockNumber: number, txs: ProcessedTx[]): Promise<[L2Block, Proof]>; + buildL2Block(blockNumber: number, txs: ProcessedTx[], newL1ToL2Messages: Fr[]): Promise<[L2Block, Proof]>; } diff --git a/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts index f103d029a3e..b60455977d9 100644 --- a/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts @@ -31,7 +31,7 @@ export class StandaloneBlockBuilder implements BlockBuilder { constructor(private db: MerkleTreeOperations, private log = createDebugLogger('aztec:block_builder')) {} - async buildL2Block(blockNumber: number, txs: ProcessedTx[]): Promise<[L2Block, Proof]> { + async buildL2Block(blockNumber: number, txs: ProcessedTx[], newL1ToL2Messages: Fr[]): Promise<[L2Block, Proof]> { const startPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); const startNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); @@ -42,10 +42,15 @@ export class StandaloneBlockBuilder implements BlockBuilder { const startTreeOfHistoricContractTreeRootsSnapshot = await this.getTreeSnapshot( MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, ); + const startL1ToL2MessageTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); + const startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = await this.getTreeSnapshot( + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, + ); for (const tx of txs) { await this.updateTrees(tx); } + await this.updateL1ToL2MessagesTree(newL1ToL2Messages); await this.updateRootTrees(); @@ -59,6 +64,10 @@ export class StandaloneBlockBuilder implements BlockBuilder { const endTreeOfHistoricContractTreeRootsSnapshot = await this.getTreeSnapshot( MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, ); + const endL1ToL2MessageTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); + const endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = await this.getTreeSnapshot( + MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, + ); const l2Block = L2Block.fromFields({ number: blockNumber, @@ -74,6 +83,10 @@ export class StandaloneBlockBuilder implements BlockBuilder { endTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, + startL1ToL2MessageTreeSnapshot, + endL1ToL2MessageTreeSnapshot, + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, newCommitments: this.dataTreeLeaves.map(b => Fr.fromBuffer(b)), newNullifiers: this.nullifierTreeLeaves.map(b => Fr.fromBuffer(b)), newContracts: this.contractTreeLeaves.map(b => Fr.fromBuffer(b)), @@ -81,6 +94,7 @@ export class StandaloneBlockBuilder implements BlockBuilder { newPublicDataWrites: txs.flatMap(tx => tx.data.end.stateTransitions.map(t => new PublicDataWrite(t.leafIndex, t.newValue)), ), + newL1ToL2Messages, }); return [l2Block, makeEmptyProof()]; } @@ -98,21 +112,22 @@ export class StandaloneBlockBuilder implements BlockBuilder { computeContractLeaf(wasm, x).toBuffer(), ); - for (let i = 0; i < KERNEL_NEW_COMMITMENTS_LENGTH; i++) { - await this.db.appendLeaves(MerkleTreeId.PRIVATE_DATA_TREE, [dataTreeLeaves[i]]); - } - for (let i = 0; i < KERNEL_NEW_NULLIFIERS_LENGTH; i++) { - await this.db.appendLeaves(MerkleTreeId.NULLIFIER_TREE, [nullifierTreeLeaves[i]]); - } - for (let i = 0; i < KERNEL_NEW_CONTRACTS_LENGTH; i++) { - await this.db.appendLeaves(MerkleTreeId.CONTRACT_TREE, [contractTreeLeaves[i]]); - } + await this.db.appendLeaves(MerkleTreeId.PRIVATE_DATA_TREE, dataTreeLeaves); + await this.db.appendLeaves(MerkleTreeId.NULLIFIER_TREE, nullifierTreeLeaves); + await this.db.appendLeaves(MerkleTreeId.CONTRACT_TREE, contractTreeLeaves); + } + + private async updateL1ToL2MessagesTree(l1ToL2Messages: Fr[]) { + const leaves = l1ToL2Messages.map((x: Fr) => x.toBuffer()); + await this.db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, leaves); } private async updateRootTrees() { const newDataTreeInfo = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); const newContractsTreeInfo = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + const newL1ToL2MessagesTreeInfo = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); await this.db.appendLeaves(MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, [newContractsTreeInfo.root.toBuffer()]); await this.db.appendLeaves(MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, [newDataTreeInfo.root.toBuffer()]); + await this.db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE, [newL1ToL2MessagesTreeInfo.root.toBuffer()]); } } diff --git a/yarn-project/sequencer-client/src/block_builder/types.ts b/yarn-project/sequencer-client/src/block_builder/types.ts new file mode 100644 index 00000000000..d3fc4845051 --- /dev/null +++ b/yarn-project/sequencer-client/src/block_builder/types.ts @@ -0,0 +1,16 @@ +import { AppendOnlyTreeSnapshot, BaseOrMergeRollupPublicInputs, RootRollupPublicInputs } from '@aztec/circuits.js'; + +/** + * Type to assert that only the correct trees are checked when validating rollup tree outputs + */ +export type AllowedTreeNames = + T extends RootRollupPublicInputs + ? 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Message' + : 'PrivateData' | 'Contract' | 'Nullifier'; + +/** + * Type to assert the correct object field is indexed when validating rollup tree outputs + */ +export type OutputWithTreeSnapshot = { + [K in `end${AllowedTreeNames}TreeSnapshot`]: AppendOnlyTreeSnapshot; +}; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index f55205937c9..e39d672b744 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -1,4 +1,4 @@ -import { CombinedHistoricTreeRoots, makeEmptyProof } from '@aztec/circuits.js'; +import { CombinedHistoricTreeRoots, Fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, makeEmptyProof } from '@aztec/circuits.js'; import { P2P, P2PClientState } from '@aztec/p2p'; import { L2Block, PrivateTx, Tx, UnverifiedData } from '@aztec/types'; import { MerkleTreeId, MerkleTreeOperations, WorldStateRunningState, WorldStateSynchroniser } from '@aztec/world-state'; @@ -65,6 +65,7 @@ describe('sequencer', () => { expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( lastBlockNumber + 1, expectedTxHashes.map(hash => expect.objectContaining({ hash })), + Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)), ); expect(publisher.processL2Block).toHaveBeenCalledWith(block); expect(publisher.processUnverifiedData).toHaveBeenCalledWith(lastBlockNumber + 1, expectedUnverifiedData); @@ -101,6 +102,7 @@ describe('sequencer', () => { expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( lastBlockNumber + 1, expectedTxHashes.map(hash => expect.objectContaining({ hash })), + Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)), ); expect(publisher.processL2Block).toHaveBeenCalledWith(block); expect(publisher.processUnverifiedData).toHaveBeenCalledWith(lastBlockNumber + 1, expectedUnverifiedData); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index e7cd3442422..04d17edd3c9 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -1,4 +1,4 @@ -import { RunningPromise, createDebugLogger } from '@aztec/foundation'; +import { Fr, RunningPromise, createDebugLogger } from '@aztec/foundation'; import { P2P } from '@aztec/p2p'; import { ContractData, ContractPublicData, PrivateTx, PublicTx, Tx, UnverifiedData, isPrivateTx } from '@aztec/types'; import { MerkleTreeId, WorldStateStatus, WorldStateSynchroniser } from '@aztec/world-state'; @@ -9,6 +9,7 @@ import { ceilPowerOfTwo } from '../utils.js'; import { SequencerConfig } from './config.js'; import { ProcessedTx } from './processed_tx.js'; import { PublicProcessor } from './public_processor.js'; +import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js'; /** * Sequencer client @@ -111,9 +112,14 @@ export class Sequencer { await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxs)); } + // Get l1 to l2 messages from the contract + this.log('Requesting L1 to L2 messages from contract'); + const l1ToL2Messages = this.takeL1ToL2MessagesFromContract(); + this.log('Successfully retrieved L1 to L2 messages from contract'); + // Build the new block by running the rollup circuits this.log(`Assembling block with txs ${processedTxs.map(tx => tx.hash).join(', ')}`); - const block = await this.buildBlock(processedTxs); + const block = await this.buildBlock(processedTxs, l1ToL2Messages); this.log(`Assembled block ${block.number}`); // Publishes new block to the network and awaits the tx to be mined @@ -209,7 +215,7 @@ export class Sequencer { ); } - protected async buildBlock(txs: ProcessedTx[]) { + protected async buildBlock(txs: ProcessedTx[], newL1ToL2Messages: Fr[]) { // Pad the txs array with empty txs to be a power of two, at least 4 const txsTargetSize = Math.max(ceilPowerOfTwo(txs.length), 4); const emptyTxCount = txsTargetSize - txs.length; @@ -218,10 +224,19 @@ export class Sequencer { ...txs, ...(await Promise.all(times(emptyTxCount, () => this.publicProcessor.makeEmptyProcessedTx()))), ]; - const [block] = await this.blockBuilder.buildL2Block(this.lastBlockNumber + 1, allTxs); + const [block] = await this.blockBuilder.buildL2Block(this.lastBlockNumber + 1, allTxs, newL1ToL2Messages); return block; } + // TODO: this is a stubbed method + /** + * Checks on chain messages inbox and selects messages to inlcude within the + * next rollup block + */ + protected takeL1ToL2MessagesFromContract(): Fr[] { + return new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); + } + /** * Returns true if one of the transaction nullifiers exist. * Nullifiers prevent double spends in a private context. diff --git a/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts b/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts index d5d56d81816..774b2650ce6 100644 --- a/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts +++ b/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts @@ -3,6 +3,7 @@ import { BaseOrMergeRollupPublicInputs, CircuitsWasm, Fr, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, RootRollupPublicInputs, UInt8Vector, } from '@aztec/circuits.js'; @@ -68,8 +69,8 @@ describe.skip('L1Publisher integration', () => { const simulator = await WasmRollupCircuitSimulator.new(); const prover = new EmptyRollupProver(); builder = new CircuitBlockBuilder(builderDb, vks, simulator, prover); - await expectsDb.updateRootsTrees(); - await builderDb.updateRootsTrees(); + await expectsDb.updateHistoricRootsTrees(); + await builderDb.updateHistoricRootsTrees(); baseRollupOutputLeft = makeBaseRollupPublicInputs(); baseRollupOutputRight = makeBaseRollupPublicInputs(); @@ -97,6 +98,8 @@ describe.skip('L1Publisher integration', () => { }; it('Build 2 blocks of 4 txs building on each other', async () => { + const newL1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); + const stateInRollup_ = await rollup.methods.rollupStateHash().call(); expect(hexStringToBuffer(stateInRollup_.toString())).toEqual(Buffer.alloc(32, 0)); @@ -105,7 +108,7 @@ describe.skip('L1Publisher integration', () => { Tx.createPrivate(makeKernelPublicInputs(1 + i), emptyProof, makeEmptyUnverifiedData()), ); - const txsLeft = [tx, await makeEmptyProcessedTx()]; + const txsLeft = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; // Set tree roots to proper values in the tx @@ -124,7 +127,7 @@ describe.skip('L1Publisher integration', () => { baseRollupOutputRight.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); // And update the root trees now to create proper output to the root rollup circuit - await expectsDb.updateRootsTrees(); + await expectsDb.updateHistoricRootsTrees(); rootRollupOutput.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); rootRollupOutput.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); @@ -137,8 +140,7 @@ describe.skip('L1Publisher integration', () => { // Actually build a block! const txs = [tx, await makeEmptyProcessedTx(), await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; - // Here we die. - const [block] = await builder.buildL2Block(1 + i, txs); + const [block] = await builder.buildL2Block(1 + i, txs, newL1ToL2Messages); // Now we can use the block we built! const blockNumber = await ethRpc.blockNumber(); @@ -151,7 +153,7 @@ describe.skip('L1Publisher integration', () => { const expectedData = rollup.methods.process(l2Proof, block.encode()).encodeABI(); expect(ethTx.input).toEqual(expectedData); - const decodedCalldataHash = await decoderHelper.methods.computeDiffRoot(block.encode()).call(); + const decodedHashes = await decoderHelper.methods.computeDiffRootAndMessagesHash(block.encode()).call(); const decodedRes = await decoderHelper.methods.decode(block.encode()).call(); const stateInRollup = await rollup.methods.rollupStateHash().call(); @@ -161,7 +163,8 @@ describe.skip('L1Publisher integration', () => { 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(decodedCalldataHash.toString())); + expect(block.getCalldataHash()).toEqual(hexStringToBuffer(decodedHashes[0].toString())); + expect(block.getL1ToL2MessagesHash()).toEqual(hexStringToBuffer(decodedHashes[1].toString())); } }, 60_000); diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index 17e97e6e572..9cb32f3936e 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -4,6 +4,7 @@ import { KERNEL_NEW_CONTRACTS_LENGTH, KERNEL_NEW_NULLIFIERS_LENGTH, STATE_TRANSITIONS_LENGTH, + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot } from '@aztec/circuits.js/factories'; import { BufferReader, serializeToBuffer } from '@aztec/circuits.js/utils'; @@ -28,17 +29,22 @@ export class L2Block { * @param startTreeOfHistoricPrivateDataTreeRootsSnapshot - The tree snapshot of the historic private data tree roots at the start of the rollup. * @param startTreeOfHistoricContractTreeRootsSnapshot - The tree snapshot of the historic contract tree roots at the start of the rollup. * @param startPublicDataTreeRoot - The tree root of the public data tree at the start of the rollup. + * @param startL1ToL2MessageTreeSnapshot - The tree snapshot of the L2 message tree at the start of the rollup. + * @param startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot - The tree snapshot of the historic L2 message tree roots at the start of the rollup. * @param endPrivateDataTreeSnapshot - The tree snapshot of the private data tree at the end of the rollup. * @param endNullifierTreeSnapshot - The tree snapshot of the nullifier tree at the end of the rollup. * @param endContractTreeSnapshot - The tree snapshot of the contract tree at the end of the rollup. * @param endTreeOfHistoricPrivateDataTreeRootsSnapshot - The tree snapshot of the historic private data tree roots at the end of the rollup. * @param endTreeOfHistoricContractTreeRootsSnapshot - The tree snapshot of the historic contract tree roots at the end of the rollup. * @param endPublicDataTreeRoot - The tree root of the public data tree at the end of the rollup. + * @param endL1ToL2MessageTreeSnapshot - The tree snapshot of the L2 message tree at the end of the rollup. + * @param endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot - The tree snapshot of the historic L2 message tree roots at the end of the rollup. * @param newCommitments - The commitments to be inserted into the private data tree. * @param newNullifiers - The nullifiers to be inserted into the nullifier tree. * @param newPublicDataWrites - The public data writes to be inserted into the public data tree. * @param newContracts - The contracts leafs to be inserted into the contract tree. * @param newContractData - The aztec_address and eth_address for the deployed contract and its portal contract. + * @param newL1ToL2Messages - The L1 to L2 messages to be inserted into the L2 toL2 message tree. */ constructor( public number: number, @@ -48,17 +54,22 @@ export class L2Block { public startTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot, public startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, public startPublicDataTreeRoot: Fr, + public startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + public startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot, public endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, public endNullifierTreeSnapshot: AppendOnlyTreeSnapshot, public endContractTreeSnapshot: AppendOnlyTreeSnapshot, public endTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot, public endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, public endPublicDataTreeRoot: Fr, + public endL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot, + public endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot, public newCommitments: Fr[], public newNullifiers: Fr[], public newPublicDataWrites: PublicDataWrite[], public newContracts: Fr[], public newContractData: ContractData[], + public newL1ToL2Messages: Fr[] = [], ) {} static random(l2BlockNum: number, txsPerBlock = 4) { @@ -67,6 +78,7 @@ export class L2Block { const newContracts = times(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock, Fr.random); 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); return L2Block.fromFields({ number: l2BlockNum, @@ -74,12 +86,16 @@ export class L2Block { startNullifierTreeSnapshot: makeAppendOnlyTreeSnapshot(0), startContractTreeSnapshot: makeAppendOnlyTreeSnapshot(0), startPublicDataTreeRoot: Fr.random(), + startL1ToL2MessageTreeSnapshot: makeAppendOnlyTreeSnapshot(0), + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(0), startTreeOfHistoricPrivateDataTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(0), startTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(0), endPrivateDataTreeSnapshot: makeAppendOnlyTreeSnapshot(newCommitments.length), endNullifierTreeSnapshot: makeAppendOnlyTreeSnapshot(newNullifiers.length), endContractTreeSnapshot: makeAppendOnlyTreeSnapshot(newContracts.length), endPublicDataTreeRoot: Fr.random(), + endL1ToL2MessageTreeSnapshot: makeAppendOnlyTreeSnapshot(1), + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(1), endTreeOfHistoricPrivateDataTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(1), endTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(1), newCommitments, @@ -87,6 +103,7 @@ export class L2Block { newContracts, newContractData, newPublicDataWrites, + newL1ToL2Messages, }); } @@ -103,17 +120,22 @@ export class L2Block { startTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot; startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot; startPublicDataTreeRoot: Fr; + startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot; + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot; endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot; endNullifierTreeSnapshot: AppendOnlyTreeSnapshot; endContractTreeSnapshot: AppendOnlyTreeSnapshot; endTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot; endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot; endPublicDataTreeRoot: Fr; + endL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot; + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: AppendOnlyTreeSnapshot; newCommitments: Fr[]; newNullifiers: Fr[]; newPublicDataWrites: PublicDataWrite[]; newContracts: Fr[]; newContractData: ContractData[]; + newL1ToL2Messages: Fr[]; }) { return new this( fields.number, @@ -123,17 +145,22 @@ export class L2Block { fields.startTreeOfHistoricPrivateDataTreeRootsSnapshot, fields.startTreeOfHistoricContractTreeRootsSnapshot, fields.startPublicDataTreeRoot, + fields.startL1ToL2MessageTreeSnapshot, + fields.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, fields.endPrivateDataTreeSnapshot, fields.endNullifierTreeSnapshot, fields.endContractTreeSnapshot, fields.endTreeOfHistoricPrivateDataTreeRootsSnapshot, fields.endTreeOfHistoricContractTreeRootsSnapshot, fields.endPublicDataTreeRoot, + fields.endL1ToL2MessageTreeSnapshot, + fields.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, fields.newCommitments, fields.newNullifiers, fields.newPublicDataWrites, fields.newContracts, fields.newContractData, + fields.newL1ToL2Messages, ); } @@ -150,12 +177,16 @@ export class L2Block { this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, this.startTreeOfHistoricContractTreeRootsSnapshot, this.startPublicDataTreeRoot, + this.startL1ToL2MessageTreeSnapshot, + this.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, this.endPrivateDataTreeSnapshot, this.endNullifierTreeSnapshot, this.endContractTreeSnapshot, this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, this.endTreeOfHistoricContractTreeRootsSnapshot, this.endPublicDataTreeRoot, + this.endL1ToL2MessageTreeSnapshot, + this.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, this.newCommitments.length, this.newCommitments, this.newNullifiers.length, @@ -165,6 +196,8 @@ export class L2Block { this.newContracts.length, this.newContracts, this.newContractData, + this.newL1ToL2Messages.length, + this.newL1ToL2Messages, ); } @@ -190,17 +223,23 @@ export class L2Block { const startTreeOfHistoricPrivateDataTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const startTreeOfHistoricContractTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const startPublicDataTreeRoot = reader.readObject(Fr); + const startL1ToL2MessageTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endPrivateDataTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endNullifierTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endContractTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endTreeOfHistoricPrivateDataTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endTreeOfHistoricContractTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endPublicDataTreeRoot = reader.readObject(Fr); + const endL1ToL2MessageTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const newCommitments = reader.readVector(Fr); const newNullifiers = reader.readVector(Fr); const newPublicDataWrites = reader.readVector(PublicDataWrite); 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 + const newL1ToL2Messages = reader.readVector(Fr); return L2Block.fromFields({ number, @@ -210,17 +249,22 @@ export class L2Block { startTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, startPublicDataTreeRoot, + startL1ToL2MessageTreeSnapshot, + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, endPrivateDataTreeSnapshot, endNullifierTreeSnapshot, endContractTreeSnapshot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, endPublicDataTreeRoot, + endL1ToL2MessageTreeSnapshot, + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, newCommitments, newNullifiers, newPublicDataWrites, newContracts, newContractData, + newL1ToL2Messages, }); } @@ -237,14 +281,20 @@ export class L2Block { this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, this.startTreeOfHistoricContractTreeRootsSnapshot, this.startPublicDataTreeRoot, + this.startL1ToL2MessageTreeSnapshot, + this.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, this.endPrivateDataTreeSnapshot, this.endNullifierTreeSnapshot, this.endContractTreeSnapshot, this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, this.endTreeOfHistoricContractTreeRootsSnapshot, this.endPublicDataTreeRoot, + this.endL1ToL2MessageTreeSnapshot, + this.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, this.getCalldataHash(), + this.getL1ToL2MessagesHash(), ); + const temp = toBigIntBE(sha256(buf)); // Prime order of BN254 curve const p = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617'); @@ -264,6 +314,8 @@ export class L2Block { this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, this.startTreeOfHistoricContractTreeRootsSnapshot, this.startPublicDataTreeRoot, + this.startL1ToL2MessageTreeSnapshot, + this.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, ); return sha256(inputValue); } @@ -281,6 +333,8 @@ export class L2Block { this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, this.endTreeOfHistoricContractTreeRootsSnapshot, this.endPublicDataTreeRoot, + this.endL1ToL2MessageTreeSnapshot, + this.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, ); return sha256(inputValue); } @@ -349,6 +403,17 @@ export class L2Block { return computeRoot(leafs); } + /** + * Compute the hash of all of this blocks l1 to l2 messages, + * The hash is also calculated within the contract when the block is submitted + * @returns + */ + getL1ToL2MessagesHash() { + // Create a long buffer of all of the l1 to l2 messages + const l1ToL2Messages = Buffer.concat(this.newL1ToL2Messages.map(message => message.toBuffer())); + return sha256(l1ToL2Messages); + } + /** * Get the ith transaction in an L2 block. * @param txIndex - The index of the tx in the block. @@ -415,6 +480,10 @@ export class L2Block { this.startTreeOfHistoricContractTreeRootsSnapshot, )}`, `startPublicDataTreeRoot: ${this.startPublicDataTreeRoot.toString()}`, + `startL1ToL2MessageTreeSnapshot: ${inspectTreeSnapshot(this.startL1ToL2MessageTreeSnapshot)}`, + `startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: ${inspectTreeSnapshot( + this.startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, + )}`, `endPrivateDataTreeSnapshot: ${inspectTreeSnapshot(this.endPrivateDataTreeSnapshot)}`, `endNullifierTreeSnapshot: ${inspectTreeSnapshot(this.endNullifierTreeSnapshot)}`, `endContractTreeSnapshot: ${inspectTreeSnapshot(this.endContractTreeSnapshot)}`, @@ -426,12 +495,17 @@ export class L2Block { this.endTreeOfHistoricContractTreeRootsSnapshot, )}`, `endPublicDataTreeRoot: ${this.endPublicDataTreeRoot.toString()}`, + `endL1ToL2MessageTreeSnapshot: ${inspectTreeSnapshot(this.endL1ToL2MessageTreeSnapshot)}`, + `endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: ${inspectTreeSnapshot( + this.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot, + )}`, `newCommitments: ${inspectFrArray(this.newCommitments)}`, `newNullifiers: ${inspectFrArray(this.newNullifiers)}`, `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, `newContracts: ${inspectFrArray(this.newContracts)}`, `newContractData: ${inspectContractDataArray(this.newContractData)}`, `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, + `newL1ToL2Messages: ${inspectFrArray(this.newL1ToL2Messages)}`, ].join('\n'); } } diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts index 918caefae71..047743daa50 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts @@ -107,7 +107,7 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations { * the current roots of the corresponding trees (CONTRACT_TREE, PRIVATE_DATA_TREE). * @returns Empty promise. */ - public updateRootsTrees(): Promise { - return this.trees.updateRootsTrees(this.includeUncommitted); + public updateHistoricRootsTrees(): Promise { + return this.trees.updateHistoricRootsTrees(this.includeUncommitted); } } 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 bf67b8c8677..19fa68cf645 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 @@ -1,5 +1,5 @@ import { BarretenbergWasm } from '@aztec/barretenberg.js/wasm'; -import { AppendOnlyTreeSnapshot } from '@aztec/circuits.js'; +import { AppendOnlyTreeSnapshot, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js'; import { fr } from '@aztec/circuits.js/factories'; import { Fr, sleep } from '@aztec/foundation'; import { INITIAL_LEAF, Pedersen, SiblingPath } from '@aztec/merkle-tree'; @@ -33,6 +33,10 @@ const getMockContractData = () => { return ContractData.random(); }; +const getMockL1ToL2MessagesData = () => { + return new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).map(() => Fr.random()); +}; + const getMockBlock = (blockNumber: number, newContractsCommitments?: Buffer[]) => { const block = L2Block.fromFields({ number: blockNumber, @@ -42,17 +46,22 @@ const getMockBlock = (blockNumber: number, newContractsCommitments?: Buffer[]) = startTreeOfHistoricPrivateDataTreeRootsSnapshot: getMockTreeSnapshot(), startTreeOfHistoricContractTreeRootsSnapshot: getMockTreeSnapshot(), startPublicDataTreeRoot: Fr.random(), + startL1ToL2MessageTreeSnapshot: getMockTreeSnapshot(), + startTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: getMockTreeSnapshot(), endPrivateDataTreeSnapshot: getMockTreeSnapshot(), endNullifierTreeSnapshot: getMockTreeSnapshot(), endContractTreeSnapshot: getMockTreeSnapshot(), endTreeOfHistoricPrivateDataTreeRootsSnapshot: getMockTreeSnapshot(), endTreeOfHistoricContractTreeRootsSnapshot: getMockTreeSnapshot(), endPublicDataTreeRoot: Fr.random(), + endL1ToL2MessageTreeSnapshot: getMockTreeSnapshot(), + endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot: getMockTreeSnapshot(), newCommitments: [Fr.random()], newNullifiers: [Fr.random()], newContracts: newContractsCommitments?.map(x => Fr.fromBuffer(x)) ?? [Fr.random()], newContractData: [getMockContractData()], newPublicDataWrites: [PublicDataWrite.random()], + newL1ToL2Messages: getMockL1ToL2MessagesData(), }); return block; }; @@ -81,7 +90,7 @@ describe('server_world_state_synchroniser', () => { SiblingPath.ZERO(32, INITIAL_LEAF, pedersen); }; //Promise.resolve(); }), - updateRootsTrees: jest.fn().mockImplementation(() => Promise.resolve()), + updateHistoricRootsTrees: jest.fn().mockImplementation(() => Promise.resolve()), commit: jest.fn().mockImplementation(() => Promise.resolve()), rollback: jest.fn().mockImplementation(() => Promise.resolve()), } as any; @@ -231,7 +240,7 @@ describe('server_world_state_synchroniser', () => { it('updates the contract tree', async () => { merkleTreeDb.appendLeaves.mockReset(); - merkleTreeDb.updateRootsTrees.mockReset(); + merkleTreeDb.updateHistoricRootsTrees.mockReset(); const server = createSynchroniser(merkleTreeDb, rollupSource); const totalBlocks = LATEST_BLOCK_NUMBER + 1; nextBlocks = Array(totalBlocks) @@ -242,7 +251,7 @@ describe('server_world_state_synchroniser', () => { // there are 3 data trees updated expect(merkleTreeDb.appendLeaves).toHaveBeenCalledTimes(totalBlocks * 3); // and 2 root trees - expect(merkleTreeDb.updateRootsTrees).toHaveBeenCalledTimes(totalBlocks); + expect(merkleTreeDb.updateHistoricRootsTrees).toHaveBeenCalledTimes(totalBlocks); // there should be a call to append to the contract tree for each block for (let i = 0; i < totalBlocks; i++) { expect( diff --git a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts index 570f1c08459..05018273f43 100644 --- a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts +++ b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.ts @@ -167,7 +167,7 @@ export class ServerWorldStateSynchroniser implements WorldStateSynchroniser { await this.merkleTreeDb.updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, newValue.toBuffer(), leafIndex.value); } - await this.merkleTreeDb.updateRootsTrees(true); + await this.merkleTreeDb.updateHistoricRootsTrees(true); await this.merkleTreeDb.commit(); } this.currentL2BlockNum = l2Block.number; diff --git a/yarn-project/world-state/src/world-state-db/index.ts b/yarn-project/world-state/src/world-state-db/index.ts index 469b6a219a3..36944827a88 100644 --- a/yarn-project/world-state/src/world-state-db/index.ts +++ b/yarn-project/world-state/src/world-state-db/index.ts @@ -13,6 +13,8 @@ export enum MerkleTreeId { PRIVATE_DATA_TREE = 3, PRIVATE_DATA_TREE_ROOTS_TREE = 4, PUBLIC_DATA_TREE = 5, + L1_TO_L2_MESSAGES_TREE = 6, + L1_TO_L2_MESSAGES_ROOTS_TREE = 7, } /** @@ -152,7 +154,7 @@ export interface MerkleTreeOperations { * Inserts into the roots trees (CONTRACT_TREE_ROOTS_TREE, PRIVATE_DATA_TREE_ROOTS_TREE) * the current roots of the corresponding trees (CONTRACT_TREE, PRIVATE_DATA_TREE). */ - updateRootsTrees(): Promise; + updateHistoricRootsTrees(): Promise; } /** diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index d79f60da7b5..036ed0c5df9 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -2,6 +2,8 @@ import { PrimitivesWasm } from '@aztec/barretenberg.js/wasm'; import { CONTRACT_TREE_HEIGHT, CONTRACT_TREE_ROOTS_TREE_HEIGHT, + L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT, + L1_TO_L2_MESSAGES_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PRIVATE_DATA_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, @@ -92,7 +94,20 @@ export class MerkleTrees implements MerkleTreeDb { `${MerkleTreeId[MerkleTreeId.PUBLIC_DATA_TREE]}`, PUBLIC_DATA_TREE_HEIGHT, ); - + const l1Tol2MessagesTree: AppendOnlyTree = await newTree( + StandardTree, + this.db, + hasher, + `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGES_TREE]}`, + L1_TO_L2_MESSAGES_TREE_HEIGHT, + ); + const l1Tol2MessagesRootsTree: AppendOnlyTree = await newTree( + StandardTree, + this.db, + hasher, + `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE]}`, + L1_TO_L2_MESSAGES_ROOTS_TREE_HEIGHT, + ); this.trees = [ contractTree, contractTreeRootsTree, @@ -100,11 +115,13 @@ export class MerkleTrees implements MerkleTreeDb { privateDataTree, privateDataTreeRootsTree, publicDataTree, + l1Tol2MessagesTree, + l1Tol2MessagesRootsTree, ]; this.jobQueue.start(); - await this.updateRootsTrees(true); + await this.updateHistoricRootsTrees(true); } /** @@ -147,10 +164,11 @@ export class MerkleTrees implements MerkleTreeDb { * the current roots of the corresponding trees (CONTRACT_TREE, PRIVATE_DATA_TREE). * @param includeUncommitted - Indicates whether to include uncommitted data. */ - public async updateRootsTrees(includeUncommitted: boolean) { + public async updateHistoricRootsTrees(includeUncommitted: boolean) { for (const [newTree, rootTree] of [ [MerkleTreeId.PRIVATE_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE], [MerkleTreeId.CONTRACT_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE], + [MerkleTreeId.L1_TO_L2_MESSAGES_TREE, MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE], ] as const) { const newTreeInfo = await this.getTreeInfo(newTree, includeUncommitted); await this.appendLeaves(rootTree, [newTreeInfo.root]);