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

feat: Enable merge and root rollup circuits in noir #3248

Merged
merged 14 commits into from
Nov 9, 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
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/benchmarks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export async function sendTxs(
contract: BenchmarkingContract,
): Promise<SentTx[]> {
const calls = times(txCount, index => makeCall(index, context, contract));
calls.forEach(call => call.simulate({ skipPublicSimulation: true }));
await Promise.all(calls.map(call => call.simulate({ skipPublicSimulation: true })));
const sentTxs = calls.map(call => call.send());

// Awaiting txHash waits until the aztec node has received the tx into its p2p pool
Expand Down
1 change: 0 additions & 1 deletion yarn-project/noir-protocol-circuits/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
src/crates
src/target
src/types
2 changes: 1 addition & 1 deletion yarn-project/noir-protocol-circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
"formatting:fix": "run -T prettier -w ./src",
"noir:build": "cd src && nargo compile --no-backend && rm -rf ./target/debug_*",
"noir:types": "yarn ts-node --esm src/scripts/generate_ts_from_abi.ts",
"noir:types": "yarn ts-node --esm src/scripts/generate_ts_from_abi.ts && yarn formatting:fix",
"noir:test": "cd src && nargo test",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "rollup_merge"
name = "rollup_base"
type = "bin"
authors = [""]
compiler_version = ">=0.18.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod merge_rollup_inputs;
mod root_rollup_inputs;
mod previous_rollup_data;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::merge::merge_rollup_inputs::MergeRollupInputs;
use crate::abis::base_or_merge_rollup_public_inputs::BASE_ROLLUP_TYPE;
use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot;
use crate::fixtures::previous_rollup_data::default_previous_rollup_data;

pub fn default_merge_rollup_inputs() -> MergeRollupInputs {
let mut inputs: MergeRollupInputs = dep::std::unsafe::zeroed();

inputs.previous_rollup_data = default_previous_rollup_data();

inputs
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::abis::base_or_merge_rollup_public_inputs::BASE_ROLLUP_TYPE;
use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot;
use crate::abis::previous_rollup_data::PreviousRollupData;

pub fn default_previous_rollup_data() -> [PreviousRollupData; 2] {
let mut previous_rollup_data: [PreviousRollupData; 2] = dep::std::unsafe::zeroed();

previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot {
root: 0,
next_available_leaf_index: 0
};
previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot {
root: 2,
next_available_leaf_index: 2
};

previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_nullifier_tree_snapshot = AppendOnlyTreeSnapshot {
root: 0,
next_available_leaf_index: 0
};
previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_nullifier_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_nullifier_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_nullifier_tree_snapshot = AppendOnlyTreeSnapshot {
root: 2,
next_available_leaf_index: 2
};

previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_contract_tree_snapshot = AppendOnlyTreeSnapshot {
root: 0,
next_available_leaf_index: 0
};
previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_contract_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_contract_tree_snapshot = AppendOnlyTreeSnapshot {
root: 1,
next_available_leaf_index: 1
};
previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_contract_tree_snapshot = AppendOnlyTreeSnapshot {
root: 2,
next_available_leaf_index: 2
};

previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_public_data_tree_root = 3;
previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_public_data_tree_root = 3;

previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = BASE_ROLLUP_TYPE;
previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = BASE_ROLLUP_TYPE;

previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_subtree_height = 1;
previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_subtree_height = 1;

previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash = [0, 1];
previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash = [2, 3];

previous_rollup_data
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::{
root::{
root_rollup_inputs::RootRollupInputs,
},
};
use dep::aztec::constants_gen::{
L1_TO_L2_MSG_TREE_HEIGHT,
L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
L1_TO_L2_MSG_SUBTREE_HEIGHT,
HISTORIC_BLOCKS_TREE_HEIGHT,
};
use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot;
use crate::fixtures::previous_rollup_data::default_previous_rollup_data;

pub fn compute_zero_hashes<N>(mut hashes: [Field; N]) -> [Field; N] {
hashes[0] = dep::std::hash::pedersen_hash([0, 0]);

for i in 1..N {
hashes[i] = dep::std::hash::pedersen_hash([hashes[i-1], hashes[i-1]]);
}

hashes
}

pub fn compute_l1_l2_empty_snapshot() -> (AppendOnlyTreeSnapshot, [Field; L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH]) {
let zero_hashes = compute_zero_hashes([0; L1_TO_L2_MSG_TREE_HEIGHT]);
let mut new_l1_to_l2_messages_tree_root_sibling_path = [0; L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH];

for i in 0..L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH {
let index = L1_TO_L2_MSG_SUBTREE_HEIGHT + i - 1;
new_l1_to_l2_messages_tree_root_sibling_path[i] = zero_hashes[index];
}

(AppendOnlyTreeSnapshot{ root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, new_l1_to_l2_messages_tree_root_sibling_path)
}

pub fn compute_historic_blocks_tree_snapshot() -> (AppendOnlyTreeSnapshot, [Field; HISTORIC_BLOCKS_TREE_HEIGHT]) {
let zero_hashes = compute_zero_hashes([0; HISTORIC_BLOCKS_TREE_HEIGHT]);
let mut sibling_path = [0; HISTORIC_BLOCKS_TREE_HEIGHT];
for i in 1..HISTORIC_BLOCKS_TREE_HEIGHT {
sibling_path[i] = zero_hashes[i-1];
}
(AppendOnlyTreeSnapshot { root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, sibling_path)
}


pub fn default_root_rollup_inputs() -> RootRollupInputs {
let mut inputs: RootRollupInputs = dep::std::unsafe::zeroed();
let (l1_l2_empty_snapshot, l1_l2_empty_sibling_path) = compute_l1_l2_empty_snapshot();

inputs.new_l1_to_l2_messages_tree_root_sibling_path = l1_l2_empty_sibling_path;
inputs.start_l1_to_l2_messages_tree_snapshot = l1_l2_empty_snapshot;

let (historic_blocks_snapshot, historic_blocks_sibling_path) = compute_historic_blocks_tree_snapshot();

inputs.start_historic_blocks_tree_snapshot = historic_blocks_snapshot;
inputs.new_historic_blocks_tree_sibling_path = historic_blocks_sibling_path;

inputs.previous_rollup_data = default_previous_rollup_data();

inputs
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ mod components;

mod hash;

mod merkle_tree;
mod merkle_tree;

mod fixtures;
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,146 @@ impl MergeRollupInputs {

public_inputs
}
}

mod tests {
use crate::{
merge::merge_rollup_inputs::MergeRollupInputs,
fixtures::merge_rollup_inputs::default_merge_rollup_inputs,
};
use dep::types::hash::accumulate_sha256;
use dep::types::utils::uint128::U128;


#[test(should_fail_with="input proofs are of different rollup types")]
fn different_rollup_type_fails(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = 0;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = 1;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs are of different rollup heights")]
fn different_height_fails(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_subtree_height = 0;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_subtree_height = 1;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs have different constants")]
fn constants_different_fails(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.public_kernel_vk_tree_root = 1;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.public_kernel_vk_tree_root = 0;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs have different constants")]
fn constants_different_chain_id_fails(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 1;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 0;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs have different note hash tree snapshots")]
fn previous_rollups_dont_follow_note_hash(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_note_hash_tree_snapshot.root = 0;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_note_hash_tree_snapshot.root = 1;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs have different nullifier tree snapshots")]
fn previous_rollups_dont_follow_nullifier(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_nullifier_tree_snapshot.root = 0;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_nullifier_tree_snapshot.root = 1;
let _output = inputs.merge_rollup_circuit();
}

#[test(should_fail_with="input proofs have different contract tree snapshots")]
fn previous_rollups_dont_follow_contracts(){
let mut inputs = default_merge_rollup_inputs();
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end_contract_tree_snapshot.root = 0;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start_contract_tree_snapshot.root = 1;
let _output = inputs.merge_rollup_circuit();
}

#[test]
fn rollup_fields_are_set_correctly(){
let mut inputs = default_merge_rollup_inputs();
let mut outputs = inputs.merge_rollup_circuit();
assert_eq(outputs.rollup_type, 1);
assert_eq(outputs.rollup_subtree_height, inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_subtree_height + 1);

// set inputs to have a merge rollup type and set the rollup height and test again.
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = 1;
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_subtree_height = 1;

inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = 1;
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_subtree_height = 1;

outputs = inputs.merge_rollup_circuit();
assert_eq(outputs.rollup_type, 1);
assert_eq(outputs.rollup_subtree_height, 2);
}

#[test]
fn start_and_end_snapshots(){
let mut inputs = default_merge_rollup_inputs();
let outputs = inputs.merge_rollup_circuit();

assert(
outputs.start_note_hash_tree_snapshot.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_note_hash_tree_snapshot)
);
assert(
outputs.end_note_hash_tree_snapshot.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_note_hash_tree_snapshot)
);

assert(
outputs.start_nullifier_tree_snapshot.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_nullifier_tree_snapshot)
);
assert(
outputs.end_nullifier_tree_snapshot.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_nullifier_tree_snapshot)
);

assert(
outputs.start_contract_tree_snapshot.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_contract_tree_snapshot)
);
assert(
outputs.end_contract_tree_snapshot.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_contract_tree_snapshot)
);

assert_eq(
outputs.start_public_data_tree_root, inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start_public_data_tree_root
);
assert_eq(
outputs.end_public_data_tree_root, inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_public_data_tree_root
);
}

#[test]
fn calldata_hash(){
let mut inputs = default_merge_rollup_inputs();
let expected_calldata_hash = accumulate_sha256([
U128::from_field(0),
U128::from_field(1),
U128::from_field(2),
U128::from_field(3)
]);
let outputs = inputs.merge_rollup_circuit();

assert_eq(outputs.calldata_hash, expected_calldata_hash);
}

#[test]
fn constants_dont_change(){
let mut inputs = default_merge_rollup_inputs();
let outputs = inputs.merge_rollup_circuit();

assert(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants));
assert(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants));
}
}
Loading