Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L2 -> L1 msgs, sol/cpp/ts #469

Merged
merged 10 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ using aztec3::circuits::abis::PreviousKernelData;
using aztec3::circuits::rollup::test_utils::utils::base_rollup_inputs_from_kernels;
using aztec3::circuits::rollup::test_utils::utils::get_empty_kernel;
using aztec3::circuits::rollup::test_utils::utils::get_initial_nullifier_tree;
using aztec3::circuits::rollup::test_utils::utils::set_kernel_commitments;
using aztec3::circuits::rollup::test_utils::utils::set_kernel_nullifiers;
// using aztec3::circuits::mock::mock_kernel_inputs;

using aztec3::circuits::abis::AppendOnlyTreeSnapshot;
Expand Down Expand Up @@ -287,7 +285,7 @@ TEST_F(base_rollup_tests, native_new_commitments_tree)
for (uint8_t j = 0; j < KERNEL_NEW_COMMITMENTS_LENGTH; j++) {
kernel_commitments[j] = new_commitments[i * KERNEL_NEW_COMMITMENTS_LENGTH + j];
}
set_kernel_commitments(kernel_data[i], kernel_commitments);
kernel_data[i].public_inputs.end.new_commitments = kernel_commitments;
}

// get sibling path
Expand Down Expand Up @@ -389,7 +387,7 @@ void nullifier_insertion_test(std::array<fr, KERNEL_NEW_NULLIFIERS_LENGTH * 2> n
for (uint8_t j = 0; j < KERNEL_NEW_NULLIFIERS_LENGTH; j++) {
kernel_nullifiers[j] = new_nullifiers[i * KERNEL_NEW_NULLIFIERS_LENGTH + j];
}
set_kernel_nullifiers(kernel_data[i], kernel_nullifiers);
kernel_data[i].public_inputs.end.new_nullifiers = kernel_nullifiers;
}
BaseRollupInputs const inputs = base_rollup_inputs_from_kernels(kernel_data);

Expand Down
51 changes: 36 additions & 15 deletions circuits/cpp/src/aztec3/circuits/rollup/components/components.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,19 @@ std::array<fr, 2> compute_kernels_calldata_hash(std::array<abis::PreviousKernelD
// 8 commitments (4 per kernel) -> 8 fields
// 8 nullifiers (4 per kernel) -> 8 fields
// 8 public state transitions (4 per kernel) -> 16 fields
// 4 l2 -> l1 messages (2 per kernel) -> 4 fields
// 2 contract deployments (1 per kernel) -> 6 fields
auto const number_of_inputs = (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH +
STATE_TRANSITIONS_LENGTH * 2 + KERNEL_NEW_CONTRACTS_LENGTH * 3) *
2;
auto const number_of_inputs =
(KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + STATE_TRANSITIONS_LENGTH * 2 +
KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + KERNEL_NEW_CONTRACTS_LENGTH * 3) *
2;
std::array<NT::fr, number_of_inputs> calldata_hash_inputs;

for (size_t i = 0; i < 2; i++) {
auto new_commitments = kernel_data[i].public_inputs.end.new_commitments;
auto new_nullifiers = kernel_data[i].public_inputs.end.new_nullifiers;
auto state_transitions = kernel_data[i].public_inputs.end.state_transitions;
auto newL2ToL1msgs = kernel_data[i].public_inputs.end.new_l2_to_l1_msgs;

size_t offset = 0;

Expand All @@ -138,6 +141,11 @@ std::array<fr, 2> compute_kernels_calldata_hash(std::array<abis::PreviousKernelD
}
offset += STATE_TRANSITIONS_LENGTH * 2 * 2;

for (size_t j = 0; j < KERNEL_NEW_L2_TO_L1_MSGS_LENGTH; j++) {
calldata_hash_inputs[offset + i * KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + j] = newL2ToL1msgs[j];
}
offset += KERNEL_NEW_L2_TO_L1_MSGS_LENGTH * 2;

auto const contract_leaf = kernel_data[i].public_inputs.end.new_contracts[0];
calldata_hash_inputs[offset + i] = contract_leaf.is_empty() ? NT::fr::zero() : contract_leaf.hash();

Expand Down Expand Up @@ -178,22 +186,21 @@ std::array<fr, 2> compute_kernels_calldata_hash(std::array<abis::PreviousKernelD
return std::array<NT::fr, 2>{ high, low };
}

// Generates a 512 bit input from right and left 256 bit hashes. Then computes the sha256, and splits the hash into two
// field elements, a high and a low that is returned.
std::array<fr, 2> compute_calldata_hash(std::array<abis::PreviousRollupData<NT>, 2> previous_rollup_data)
/**
* @brief From two calldata hashes, compute a single calldata hash
*
* @param calldata_hashes takes the 4 elements of 2 calldata hashes [high, low, high, low]
* @return std::array<fr, 2>
*/
std::array<fr, 2> compute_calldata_hash(std::array<fr, 4> calldata_hashes)
{
// Generate a 512 bit input from right and left 256 bit hashes
constexpr auto num_bytes = 2 * 32;
std::array<uint8_t, num_bytes> calldata_hash_input_bytes;
for (uint8_t i = 0; i < 2; i++) {
std::array<fr, 2> calldata_hash_fr = previous_rollup_data[i].base_or_merge_rollup_public_inputs.calldata_hash;

auto high_buffer = calldata_hash_fr[0].to_buffer();
auto low_buffer = calldata_hash_fr[1].to_buffer();

for (uint8_t j = 0; j < 16; ++j) {
calldata_hash_input_bytes[i * 32 + j] = high_buffer[16 + j];
calldata_hash_input_bytes[i * 32 + 16 + j] = low_buffer[16 + j];
for (uint8_t i = 0; i < 4; i++) {
auto half = calldata_hashes[i].to_buffer();
for (uint8_t j = 0; j < 16; j++) {
calldata_hash_input_bytes[i * 16 + j] = half[16 + j];
}
}

Expand All @@ -217,6 +224,20 @@ std::array<fr, 2> compute_calldata_hash(std::array<abis::PreviousRollupData<NT>,
return { high, low };
}

/**
* @brief From two previous rollup data, compute a single calldata hash
*
* @param previous_rollup_data
* @return std::array<fr, 2>
*/
std::array<fr, 2> compute_calldata_hash(std::array<abis::PreviousRollupData<NT>, 2> previous_rollup_data)
{
return compute_calldata_hash({ previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[0],
previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[1],
previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[0],
previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[1] });
}

// asserts that the end snapshot of previous_rollup 0 equals the start snapshot of previous_rollup 1 (i.e. ensure they
// follow on from one-another). Ensures that right uses the tres that was updated by left.
void assert_prev_rollups_follow_on_from_each_other(DummyComposer& composer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using aztec3::circuits::root_from_sibling_path;

namespace aztec3::circuits::rollup::components {
NT::fr calculate_empty_tree_root(size_t depth);
std::array<fr, 2> compute_calldata_hash(std::array<fr, 4> calldata_hashes);
std::array<fr, 2> compute_kernels_calldata_hash(std::array<abis::PreviousKernelData<NT>, 2> kernel_data);
std::array<fr, 2> compute_calldata_hash(std::array<abis::PreviousRollupData<NT>, 2> previous_rollup_data);
void assert_prev_rollups_follow_on_from_each_other(DummyComposer& composer,
Expand Down
30 changes: 19 additions & 11 deletions circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "aztec3/circuits/kernel/private/utils.hpp"
#include "aztec3/circuits/rollup/base/init.hpp"
#include "aztec3/circuits/rollup/base/native_base_rollup_circuit.hpp"
#include "aztec3/circuits/rollup/components/components.hpp"
#include "aztec3/circuits/rollup/test_utils/utils.hpp"
#include "aztec3/constants.hpp"
#include "aztec3/utils/dummy_composer.hpp"
Expand Down Expand Up @@ -58,7 +59,6 @@ using aztec3::circuits::rollup::test_utils::utils::compare_field_hash_to_expecte
using aztec3::circuits::rollup::test_utils::utils::get_empty_kernel;
using aztec3::circuits::rollup::test_utils::utils::get_empty_l1_to_l2_messages;
using aztec3::circuits::rollup::test_utils::utils::get_root_rollup_inputs;
using aztec3::circuits::rollup::test_utils::utils::set_kernel_commitments;
// using aztec3::circuits::mock::mock_kernel_inputs;

using aztec3::circuits::abis::AppendOnlyTreeSnapshot;
Expand Down Expand Up @@ -146,14 +146,13 @@ TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks)
std::vector<uint8_t> const zero_bytes_vec = test_utils::utils::get_empty_calldata_leaf();
auto call_data_hash_inner = sha256::sha256(zero_bytes_vec);

// Compute a new calldata hash based on TWO of the above rollups
std::array<uint8_t, 64> hash_input;
for (uint8_t i = 0; i < 32; ++i) {
hash_input[i] = call_data_hash_inner[i];
hash_input[32 + i] = call_data_hash_inner[i];
}

std::vector<uint8_t> const calldata_hash_input_bytes_vec(hash_input.begin(), hash_input.end());

auto calldata_hash = sha256::sha256(calldata_hash_input_bytes_vec);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: i know you didn't do this, but can you rename this to expected_calldata_hash


// get messages
Expand All @@ -179,11 +178,6 @@ TEST_F(root_rollup_tests, native_check_block_hashes_empty_blocks)

EXPECT_FALSE(composer.failed());

// Expected hash of public inputs for an empty L2 block. Also used in the contract tests.
// Computed using l2-block-publisher.test.ts
fr const expected_hash = uint256_t("23f698e487c4e1b7383889f8864bc19591773d136c364c01d980bd13d0786ba1");
ASSERT_EQ(outputs.hash(), expected_hash);

run_cbind(inputs, outputs, true);
}

Expand Down Expand Up @@ -216,10 +210,18 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic)
new_commitments[commitment_k] = val;
data_tree.update_element(kernel_j * KERNEL_NEW_COMMITMENTS_LENGTH + commitment_k, val);
}
set_kernel_commitments(kernels[kernel_j], new_commitments);
kernels[kernel_j].public_inputs.end.new_commitments = new_commitments;

std::array<fr, KERNEL_NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_messages;
for (uint8_t i = 0; i < KERNEL_NEW_L2_TO_L1_MSGS_LENGTH; i++) {
auto val = fr(kernel_j * KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + i + 1);
new_l2_to_l1_messages[i] = val;
}
kernels[kernel_j].public_inputs.end.new_l2_to_l1_msgs = new_l2_to_l1_messages;
}

// TODO: Add nullifiers
// @todo @LHerskind: Add nullifiers
// @todo @LHerskind: Add public data writes

// Contract tree
NewContractData<NT> new_contract = {
Expand Down Expand Up @@ -302,7 +304,7 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic)
.next_available_leaf_index = 4 };
ASSERT_EQ(outputs.end_contract_tree_snapshot, expected_contract_tree_snapshot);

// TODO: Check nullifier trees
// @todo @LHerskind: Check nullifier trees

// Check historic data trees
ASSERT_EQ(outputs.start_tree_of_historic_private_data_tree_roots_snapshot, start_historic_data_tree_snapshot);
Expand All @@ -321,6 +323,12 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic)
ASSERT_EQ(outputs.start_l1_to_l2_messages_tree_snapshot, start_l1_to_l2_messages_tree_snapshot);
ASSERT_EQ(outputs.end_l1_to_l2_messages_tree_snapshot, end_l1_to_l2_messages_tree_snapshot);

// Compute the expected calldata hash for the root rollup (including the l2 -> l1 messages)
auto left = components::compute_kernels_calldata_hash({ kernels[0], kernels[1] });
auto right = components::compute_kernels_calldata_hash({ kernels[2], kernels[3] });
auto root = components::compute_calldata_hash({ left[0], left[1], right[0], right[1] });
ASSERT_EQ(outputs.calldata_hash, root);

EXPECT_FALSE(composer.failed());

run_cbind(rootRollupInputs, outputs, true);
Expand Down
21 changes: 4 additions & 17 deletions circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ namespace aztec3::circuits::rollup::test_utils::utils {

std::vector<uint8_t> get_empty_calldata_leaf()
{
auto const number_of_inputs = (KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH +
STATE_TRANSITIONS_LENGTH * 2 + KERNEL_NEW_CONTRACTS_LENGTH * 3) *
2;
auto const number_of_inputs =
(KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH + STATE_TRANSITIONS_LENGTH * 2 +
KERNEL_NEW_L2_TO_L1_MSGS_LENGTH + KERNEL_NEW_CONTRACTS_LENGTH * 3) *
2;
auto const size = number_of_inputs * 32;
std::vector<uint8_t> input_data(size, 0);
return input_data;
Expand All @@ -72,20 +73,6 @@ std::array<fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP> get_empty_l1_to_l2_messages(
return l1_to_l2_messages;
}

void set_kernel_nullifiers(KernelData& kernel_data, std::array<fr, KERNEL_NEW_NULLIFIERS_LENGTH> new_nullifiers)
{
for (size_t i = 0; i < KERNEL_NEW_NULLIFIERS_LENGTH; i++) {
kernel_data.public_inputs.end.new_nullifiers[i] = new_nullifiers[i];
}
}

void set_kernel_commitments(KernelData& kernel_data, std::array<fr, KERNEL_NEW_COMMITMENTS_LENGTH> new_commitments)
{
for (size_t i = 0; i < KERNEL_NEW_COMMITMENTS_LENGTH; i++) {
kernel_data.public_inputs.end.new_commitments[i] = new_commitments[i];
}
}

BaseRollupInputs base_rollup_inputs_from_kernels(std::array<KernelData, 2> kernel_data,
MerkleTree& private_data_tree,
MerkleTree& contract_tree,
Expand Down
4 changes: 0 additions & 4 deletions circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyComposer& composer,
std::array<KernelData, 4> kernel_data,
std::array<fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP> l1_to_l2_messages);

void set_kernel_commitments(KernelData& kernel_data, std::array<fr, KERNEL_NEW_COMMITMENTS_LENGTH> new_commitments);

void set_kernel_nullifiers(KernelData& kernel_data, std::array<fr, KERNEL_NEW_NULLIFIERS_LENGTH> new_nullifiers);

MergeRollupInputs get_merge_rollup_inputs(utils::DummyComposer& composer, std::array<KernelData, 4> kernel_data);

inline abis::PublicDataTransition<NT> make_public_write(fr leaf_index, fr old_value, fr new_value)
Expand Down
2 changes: 1 addition & 1 deletion circuits/cpp/src/aztec3/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ constexpr size_t KERNEL_NEW_NULLIFIERS_LENGTH = 4;
constexpr size_t KERNEL_NEW_CONTRACTS_LENGTH = 1;
constexpr size_t KERNEL_PRIVATE_CALL_STACK_LENGTH = 8;
constexpr size_t KERNEL_PUBLIC_CALL_STACK_LENGTH = 8;
constexpr size_t KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 4;
constexpr size_t KERNEL_NEW_L2_TO_L1_MSGS_LENGTH = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

How is this different to NEW_L2_TO_L1_MSGS_LENGTH?
Also each tx can now have 2 L2<>L1 messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the same manner as KERNEL_NEW_COMMITMENTS_LENGTH etc. One kernel might have multiple inner function calls and such so it can be useful to allow kernels with more than individual calls. However, for now thought that it made sense that the values were the same similar to what it is for the commitments and nullifiers.

constexpr size_t KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH = 4;

constexpr size_t VK_TREE_HEIGHT = 3;
Expand Down
Loading