From 2a277f77ddb52214b517e00e9297e39e9971d7a0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 12:39:24 +0000 Subject: [PATCH 01/11] feat: updating txs hash --- .../src/core/libraries/ConstantsGen.sol | 2 +- .../src/core/libraries/decoders/Decoder.sol | 2 +- .../core/libraries/decoders/TxsDecoder.sol | 2 +- .../src/private_kernel_inner.nr | 6 +- .../src/private_kernel_tail.nr | 22 ++--- .../rollup-lib/src/base/base_rollup_inputs.nr | 24 +++--- .../combined_accumulated_data.nr | 4 +- .../combined_accumulated_data_builder.nr | 6 +- .../src/crates/types/src/constants.nr | 6 +- .../types/src/tests/kernel_data_builder.nr | 4 +- .../brillig_cow_regression/src/main.nr | 82 +++++++++---------- .../src/archiver/archiver_store_test_suite.ts | 2 - yarn-project/circuit-types/src/body.ts | 21 ++--- yarn-project/circuit-types/src/l2_block.ts | 15 ++-- yarn-project/circuit-types/src/l2_tx.ts | 4 +- yarn-project/circuit-types/src/tx_effect.ts | 39 ++++----- yarn-project/circuits.js/src/constants.gen.ts | 2 +- .../kernel/combined_accumulated_data.ts | 10 +-- ...vate_kernel_tail_circuit_private_inputs.ts | 10 +-- .../circuits.js/src/tests/factories.ts | 4 +- .../src/type_conversion.ts | 4 +- .../src/kernel_prover/kernel_prover.test.ts | 4 +- .../pxe/src/kernel_prover/kernel_prover.ts | 8 +- .../src/note_processor/note_processor.test.ts | 19 +++-- .../pxe/src/note_processor/note_processor.ts | 4 +- .../block_builder/solo_block_builder.test.ts | 19 +++-- .../src/block_builder/solo_block_builder.ts | 13 +-- yellow-paper/docs/constants.md | 2 +- 28 files changed, 174 insertions(+), 166 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index f8a7ae2576e..eed1cc5937a 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -25,7 +25,7 @@ library Constants { uint256 internal constant MAX_PUBLIC_DATA_READS_PER_CALL = 16; uint256 internal constant MAX_READ_REQUESTS_PER_CALL = 32; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; - uint256 internal constant MAX_NEW_COMMITMENTS_PER_TX = 64; + uint256 internal constant MAX_NEW_NOTE_HASHES_PER_TX = 64; uint256 internal constant MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; uint256 internal constant MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX = 64; diff --git a/l1-contracts/src/core/libraries/decoders/Decoder.sol b/l1-contracts/src/core/libraries/decoders/Decoder.sol index 39efa07f04d..81d41999b84 100644 --- a/l1-contracts/src/core/libraries/decoders/Decoder.sol +++ b/l1-contracts/src/core/libraries/decoders/Decoder.sol @@ -174,7 +174,7 @@ library Decoder { // Commitments uint256 count = read4(_body, offset); - vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_COMMITMENTS_PER_TX); + vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_NOTE_HASHES_PER_TX); offset += 0x4; offsets.commitment = offset; offset += count * 0x20; diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index 93bb8d922d4..79c6595fd28 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -77,7 +77,7 @@ library TxsDecoder { // Commitments uint256 count = read4(_body, offset); - vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_COMMITMENTS_PER_TX); + vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_NOTE_HASHES_PER_TX); offsets.commitment = 0x4; offset += 0x4 + count * 0x20; offsets.nullifier = offset + 0x4; // + 0x4 to offset by next read4 diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index d91407955f9..870eeac8bb2 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -85,7 +85,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { mod tests { use crate::private_kernel_inner::PrivateKernelInnerCircuitPrivateInputs; - use dep::types::constants::{MAX_READ_REQUESTS_PER_CALL, MAX_NEW_COMMITMENTS_PER_TX}; + use dep::types::constants::{MAX_READ_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX}; use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, @@ -519,8 +519,8 @@ mod tests { builder.private_call.public_inputs.new_commitments.push(SideEffect { value: 4321, counter: 0 }); // Mock the previous new commitments to be full, therefore no more commitments can be added. - let mut full_new_commitments = [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_TX]; - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { + let mut full_new_commitments = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { full_new_commitments[i] = SideEffect { value: i + 1, counter: i as u32, diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 1569820df9a..8bb8196ca01 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -8,7 +8,7 @@ use dep::types::{ side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, constants::{ - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_READ_REQUESTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX }, @@ -19,8 +19,8 @@ use dep::types::{ struct PrivateKernelTailCircuitPrivateInputs { previous_kernel: PrivateKernelInnerData, - sorted_new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], - sorted_new_commitments_indexes: [u32; MAX_NEW_COMMITMENTS_PER_TX], + sorted_new_commitments: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_new_commitments_indexes: [u32; MAX_NEW_NOTE_HASHES_PER_TX], read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], sorted_new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_TX], @@ -136,7 +136,7 @@ impl PrivateKernelTailCircuitPrivateInputs { // 0-valued nullified_commitment is empty and will be ignored if nullified_commitment != 0 { assert( - hint_pos < MAX_NEW_COMMITMENTS_PER_TX as u64, "New nullifier is transient but hint is invalid" + hint_pos < MAX_NEW_NOTE_HASHES_PER_TX as u64, "New nullifier is transient but hint is invalid" ); let commitment = new_commitments[hint_pos]; assert_eq(nullified_commitment, commitment.value, "Hinted commitment does not match"); @@ -157,7 +157,7 @@ impl PrivateKernelTailCircuitPrivateInputs { let mut new_commitments_vec = BoundedVec::new(SideEffect::empty()); - for c_idx in 0..MAX_NEW_COMMITMENTS_PER_TX { + for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { if new_commitments[c_idx].value != 0 { new_commitments_vec.push(new_commitments[c_idx]); } @@ -182,7 +182,7 @@ impl PrivateKernelTailCircuitPrivateInputs { let first_nullifier = public_inputs.end.new_nullifiers.get(0); let mut unique_commitments = public_inputs.end.new_commitments.storage; - for c_idx in 0..MAX_NEW_COMMITMENTS_PER_TX { + for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { // Apply nonce to all non-zero/non-empty commitments // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_commitments array let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); @@ -228,7 +228,7 @@ mod tests { use dep::std::cmp::Eq; use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; use dep::types::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX }; use dep::types::{ @@ -255,7 +255,7 @@ mod tests { } } - pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { + pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { self.previous_kernel.end.new_commitments.storage } @@ -263,7 +263,7 @@ mod tests { self.previous_kernel.end.new_nullifiers.storage } - pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { + pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) } @@ -375,7 +375,7 @@ mod tests { #[test] unconstrained fn native_matching_some_read_requests_to_commitments_works() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); + builder.append_transient_commitments(MAX_NEW_NOTE_HASHES_PER_TX); // prepare for the split: first MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX are added to end_non_revertible_accumulted_data // neeed to take the counter of the side effect at the given index because builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_commitments.get(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX).counter; @@ -543,7 +543,7 @@ mod tests { // The nullifier at index 1 is nullifying the commitment at index 0; builder.nullify_transient_commitment(1, 0); // Change the hint to be out of bounds. - builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; + builder.nullifier_commitment_hints[1] = MAX_NEW_NOTE_HASHES_PER_TX; builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index d6f86134c40..7c9840c0190 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -21,7 +21,7 @@ use dep::types::{ NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, NUM_FIELDS_PER_SHA256, - MAX_NEW_COMMITMENTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, NUM_ENCRYPTED_LOGS_HASHES_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_HEIGHT, @@ -256,7 +256,7 @@ impl BaseRollupInputs { fn components_compute_kernel_calldata_hash(combined: CombinedAccumulatedData) -> [Field; NUM_FIELDS_PER_SHA256] { // Compute calldata hashes // Consist of - // MAX_NEW_COMMITMENTS_PER_TX fields for commitments + // MAX_NEW_NOTE_HASHES_PER_TX fields for commitments // MAX_NEW_NULLIFIERS_PER_TX fields for nullifiers // 32 public data update requests -> 64 fields // 2 l2 -> l1 messages -> 2 fields @@ -274,10 +274,10 @@ impl BaseRollupInputs { let mut offset = 0; - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { + for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { calldata_hash_inputs[offset + j] = new_commitments[j].value; } - offset += MAX_NEW_COMMITMENTS_PER_TX ; + offset += MAX_NEW_NOTE_HASHES_PER_TX ; for j in 0..MAX_NEW_NULLIFIERS_PER_TX { calldata_hash_inputs[offset + j] = new_nullifiers[j].value; @@ -493,7 +493,7 @@ fn validate_public_data_reads( #[test] fn consistent_not_hash_subtree_width() { assert_eq( - MAX_NEW_COMMITMENTS_PER_TX, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT), "note hash subtree width is incorrect" + MAX_NEW_NOTE_HASHES_PER_TX, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT), "note hash subtree width is incorrect" ); } @@ -501,7 +501,7 @@ global CALLDATA_HASH_INPUT_SIZE = 201; #[test] fn consistent_calldata_hash_input_size() { - let expected_size = MAX_NEW_COMMITMENTS_PER_TX + let expected_size = MAX_NEW_NOTE_HASHES_PER_TX + MAX_NEW_NULLIFIERS_PER_TX + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + MAX_NEW_L2_TO_L1_MSGS_PER_TX @@ -574,7 +574,7 @@ mod tests { constants::{ CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_TREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, ARCHIVE_HEIGHT, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NOTE_HASH_TREE_HEIGHT, NOTE_HASH_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, @@ -697,7 +697,7 @@ mod tests { struct BaseRollupInputsBuilder { kernel_data: PreviousKernelDataBuilder, - pre_existing_notes: [Field; MAX_NEW_COMMITMENTS_PER_TX], + pre_existing_notes: [Field; MAX_NEW_NOTE_HASHES_PER_TX], pre_existing_nullifiers: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], pre_existing_contracts: [Field; 2], pre_existing_public_data: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], @@ -1028,7 +1028,7 @@ mod tests { } builder.kernel_data.end.new_commitments = new_commitments_vec; let mut expected_commitments_tree = NonEmptyMerkleTree::new( - [0; MAX_NEW_COMMITMENTS_PER_TX * 2], + [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT - 1], [0; NOTE_HASH_SUBTREE_HEIGHT + 1] @@ -1037,19 +1037,19 @@ mod tests { let outputs = builder.execute(); let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), - next_available_leaf_index: MAX_NEW_COMMITMENTS_PER_TX as u32 + next_available_leaf_index: MAX_NEW_NOTE_HASHES_PER_TX as u32 }; assert(outputs.start.note_hash_tree.eq(expected_start_note_hash_tree_snapshot)); for i in 0..new_commitments.len() { expected_commitments_tree.update_leaf( - (i as u64) + (MAX_NEW_COMMITMENTS_PER_TX as u64), + (i as u64) + (MAX_NEW_NOTE_HASHES_PER_TX as u64), new_commitments[i] ); } let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), - next_available_leaf_index: (MAX_NEW_COMMITMENTS_PER_TX * 2) as u32 + next_available_leaf_index: (MAX_NEW_NOTE_HASHES_PER_TX * 2) as u32 }; assert(outputs.end.note_hash_tree.eq(expected_end_note_hash_tree_snapshot)); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index 330e003ceb9..6c948e8ca6f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -11,7 +11,7 @@ use crate::{ } }; use crate::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, + MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, @@ -31,7 +31,7 @@ struct CombinedAccumulatedData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], + new_commitments: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr index 69fc1ccffba..f89362374bb 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr @@ -16,7 +16,7 @@ use crate::{ } }; use crate::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, + MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, @@ -36,7 +36,7 @@ struct CombinedAccumulatedDataBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_commitments: BoundedVec, new_nullifiers: BoundedVec, private_call_stack: BoundedVec, @@ -156,7 +156,7 @@ impl CombinedAccumulatedDataBuilder { let mut non_revertible_builder: AccumulatedNonRevertibleDataBuilder = unsafe::zeroed(); let mut revertible_builder: AccumulatedRevertibleDataBuilder = unsafe::zeroed(); - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { let commitment = self.new_commitments.storage[i]; // TODO(fees) we shouldn't need to check is_empty here, // but we do because new_commitments is bounded to MAX_REVERTIBLE_COMMITMENTS_PER_TX diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 2a2fab60fb0..cec0e44dacc 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -9,14 +9,14 @@ global RETURN_VALUES_LENGTH: Field = 4; * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as * commitment, or nullifier, e.g.,: * - MAX_NEW_NULLIFIERS_PER_CALL - * - MAX_NEW_COMMITMENTS_PER_TX + * - MAX_NEW_NOTE_HASHES_PER_TX * * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a * transaction. Therefore, we always must have: * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL * * For instance: - * MAX_NEW_COMMITMENTS_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL + * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL * */ @@ -34,7 +34,7 @@ global MAX_READ_REQUESTS_PER_CALL: Field = 32; global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: Field = 1; // "PER TRANSACTION" CONSTANTS -global MAX_NEW_COMMITMENTS_PER_TX: Field = 64; +global MAX_NEW_NOTE_HASHES_PER_TX: Field = 64; global MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX: Field = 8; global MAX_REVERTIBLE_COMMITMENTS_PER_TX: Field = 56; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr index 7eb785d088e..27e12108be0 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr @@ -16,7 +16,7 @@ use crate::{ tests::{fixtures, testing_harness::build_tx_context}, transaction::tx_context::TxContext }; use crate::constants::{ - MAX_NEW_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUM_FIELDS_PER_SHA256, VK_TREE_HEIGHT }; @@ -122,7 +122,7 @@ impl PreviousKernelDataBuilder { pub fn append_new_commitments(&mut self, num_new_commitments: Field) { let mocked_value_offset = self.end.new_commitments.len() + 1; - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { if i as u64 < num_new_commitments as u64 { // The default value is its index + 1. self.end.new_commitments.push( diff --git a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr index 974c17dfbc9..2bcbea156b1 100644 --- a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr +++ b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr @@ -1,6 +1,6 @@ // Tests a performance regression found in aztec-packages with brillig cow optimization -global MAX_NEW_COMMITMENTS_PER_TX: Field = 64; +global MAX_NEW_NOTE_HASHES_PER_TX: Field = 64; global MAX_NEW_NULLIFIERS_PER_TX: Field = 64; global MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2; global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16; @@ -30,7 +30,7 @@ impl NewContractData { } struct DataToHash { - new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_TX], + new_commitments: [Field; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_TX], public_data_update_requests: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], @@ -47,54 +47,54 @@ struct U256 { } impl U256 { - pub fn from_bytes32(bytes : [u8;32]) -> U256 { + pub fn from_bytes32(bytes: [u8; 32]) -> U256 { // We use addition rather than a bitwise OR as the bitshifts ensure that none of the bytes overlap each other. let high_0 = ((bytes[0] as u64) << 56) - + ((bytes[1] as u64) << 48) - + ((bytes[2] as u64) << 40) - + ((bytes[3] as u64) << 32) - + ((bytes[4] as u64) << 24) - + ((bytes[5] as u64) << 16) - + ((bytes[6] as u64) << 8) - + (bytes[7] as u64); - + + ((bytes[1] as u64) << 48) + + ((bytes[2] as u64) << 40) + + ((bytes[3] as u64) << 32) + + ((bytes[4] as u64) << 24) + + ((bytes[5] as u64) << 16) + + ((bytes[6] as u64) << 8) + + (bytes[7] as u64); + let high_1 = ((bytes[8] as u64) << 56) - + ((bytes[9] as u64) << 48) - + ((bytes[10] as u64) << 40) - + ((bytes[11] as u64) << 32) - + ((bytes[12] as u64) << 24) - + ((bytes[13] as u64) << 16) - + ((bytes[14] as u64) << 8) - + (bytes[15] as u64); - + + ((bytes[9] as u64) << 48) + + ((bytes[10] as u64) << 40) + + ((bytes[11] as u64) << 32) + + ((bytes[12] as u64) << 24) + + ((bytes[13] as u64) << 16) + + ((bytes[14] as u64) << 8) + + (bytes[15] as u64); + let low_0 = ((bytes[16] as u64) << 56) - + ((bytes[17] as u64) << 48) - + ((bytes[18] as u64) << 40) - + ((bytes[19] as u64) << 32) - + ((bytes[20] as u64) << 24) - + ((bytes[21] as u64) << 16) - + ((bytes[22] as u64) << 8) - + (bytes[23] as u64); - + + ((bytes[17] as u64) << 48) + + ((bytes[18] as u64) << 40) + + ((bytes[19] as u64) << 32) + + ((bytes[20] as u64) << 24) + + ((bytes[21] as u64) << 16) + + ((bytes[22] as u64) << 8) + + (bytes[23] as u64); + let low_1 = ((bytes[24] as u64) << 56) - + ((bytes[25] as u64) << 48) - + ((bytes[26] as u64) << 40) - + ((bytes[27] as u64) << 32) - + ((bytes[28] as u64) << 24) - + ((bytes[29] as u64) << 16) - + ((bytes[30] as u64) << 8) - + (bytes[31] as u64); - - U256{inner : [high_0, high_1, low_0, low_1]} + + ((bytes[25] as u64) << 48) + + ((bytes[26] as u64) << 40) + + ((bytes[27] as u64) << 32) + + ((bytes[28] as u64) << 24) + + ((bytes[29] as u64) << 16) + + ((bytes[30] as u64) << 8) + + (bytes[31] as u64); + + U256 { inner: [high_0, high_1, low_0, low_1] } } - pub fn to_u128_limbs(self) -> [Field;2] { + pub fn to_u128_limbs(self) -> [Field; 2] { let two_pow_64 = 2.pow_32(64); let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field; let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; - - [high,low] + + [high, low] } } @@ -110,10 +110,10 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA let mut offset = 0; - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { + for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { calldata_hash_inputs[offset + j] = new_commitments[j]; } - offset += MAX_NEW_COMMITMENTS_PER_TX ; + offset += MAX_NEW_NOTE_HASHES_PER_TX ; for j in 0..MAX_NEW_NULLIFIERS_PER_TX { calldata_hash_inputs[offset + j] = new_nullifiers[j]; diff --git a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts index 46e31cac924..5562b919cd4 100644 --- a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts +++ b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts @@ -369,8 +369,6 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch await expect(store.getContractData(block.body.txEffects[0].contractData[0].contractAddress)).resolves.toEqual( block.body.txEffects[0].contractData[0], ); - - expect(block.body.txEffects[0].contractData[1]).toBe(undefined); }); it('returns undefined if contract data is not found', async () => { diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index b82cf11e7f6..985ed87729e 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -1,6 +1,6 @@ import { ContractData, L2BlockL2Logs, PublicDataWrite, TxEffect } from '@aztec/circuit-types'; import { - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -8,7 +8,7 @@ import { } from '@aztec/circuits.js'; import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; export class Body { constructor(public l1ToL2Messages: Fr[], public txEffects: TxEffect[]) {} @@ -81,19 +81,20 @@ export class Body { const numberOfTxsIncludingEmpty = newNullifiers.length / MAX_NEW_NULLIFIERS_PER_TX; for (let i = 0; i < numberOfTxsIncludingEmpty; i += 1) { + // TODO(benesjan): this should use TxEffect.fromBuffer txEffects.push( new TxEffect( - newNoteHashes.slice(i * MAX_NEW_COMMITMENTS_PER_TX, (i + 1) * MAX_NEW_COMMITMENTS_PER_TX), - newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX), - newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX), + newNoteHashes.slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple, + newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX) as Tuple, + newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX) as Tuple, newPublicDataWrites.slice( i * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, (i + 1) * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - ), - newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX), - newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX), - newEncryptedLogs!.txLogs[i], - newUnencryptedLogs!.txLogs[i], + ) as Tuple, + newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple, + newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple, + newEncryptedLogs.txLogs[i], + newUnencryptedLogs.txLogs[i], ), ); } diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts index 93e115f9e28..9d83c056619 100644 --- a/yarn-project/circuit-types/src/l2_block.ts +++ b/yarn-project/circuit-types/src/l2_block.ts @@ -2,7 +2,7 @@ import { Body, ContractData, L2Tx, LogType, PublicDataWrite, TxEffect, TxHash, T import { AppendOnlyTreeSnapshot, Header, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -16,6 +16,7 @@ import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { makeTuple } from '@aztec/foundation/array'; /** * The data that makes up the rollup proof, with encoder decoder functions. @@ -127,12 +128,12 @@ export class L2Block { const txEffects = [...new Array(txsPerBlock)].map( _ => new TxEffect( - times(MAX_NEW_COMMITMENTS_PER_TX, Fr.random), - times(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), - times(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.random), - times(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.random), - times(MAX_NEW_CONTRACTS_PER_TX, Fr.random), - times(MAX_NEW_CONTRACTS_PER_TX, ContractData.random), + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, Fr.random), + makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), + makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.random), + makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.random), + makeTuple(MAX_NEW_CONTRACTS_PER_TX, Fr.random), + makeTuple(MAX_NEW_CONTRACTS_PER_TX, ContractData.random), TxL2Logs.random(numPrivateCallsPerTx, numEncryptedLogsPerCall, LogType.ENCRYPTED), TxL2Logs.random(numPublicCallsPerTx, numUnencryptedLogsPerCall, LogType.UNENCRYPTED), ), diff --git a/yarn-project/circuit-types/src/l2_tx.ts b/yarn-project/circuit-types/src/l2_tx.ts index 593f85d7b81..8df7457de44 100644 --- a/yarn-project/circuit-types/src/l2_tx.ts +++ b/yarn-project/circuit-types/src/l2_tx.ts @@ -1,5 +1,5 @@ import { - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -121,7 +121,7 @@ export class L2Tx { static random() { const rand = (min: number, max: number) => Math.floor(Math.random() * max) + min; return new L2Tx( - times(rand(0, MAX_NEW_COMMITMENTS_PER_TX), Fr.random), + times(rand(0, MAX_NEW_NOTE_HASHES_PER_TX), Fr.random), times(rand(1, MAX_NEW_NULLIFIERS_PER_TX), Fr.random), times(rand(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX), PublicDataWrite.random), times(rand(0, MAX_NEW_L2_TO_L1_MSGS_PER_TX), Fr.random), diff --git a/yarn-project/circuit-types/src/tx_effect.ts b/yarn-project/circuit-types/src/tx_effect.ts index 89a18aa25a8..77b49552673 100644 --- a/yarn-project/circuit-types/src/tx_effect.ts +++ b/yarn-project/circuit-types/src/tx_effect.ts @@ -1,43 +1,47 @@ import { ContractData, PublicDataWrite, TxL2Logs } from '@aztec/circuit-types'; -import { Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { + Fr, + MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '@aztec/circuits.js'; import { sha256 } from '@aztec/foundation/crypto'; +import { Tuple } from '@aztec/foundation/serialize'; export class TxEffect { constructor( /** - * The commitments to be inserted into the note hash tree. + * The note hashes to be inserted into the note hash tree. */ - public newNoteHashes: Fr[], + public newNoteHashes: Tuple, /** * The nullifiers to be inserted into the nullifier tree. */ - public newNullifiers: Fr[], + public newNullifiers: Tuple, /** * The L2 to L1 messages to be inserted into the messagebox on L1. */ - public newL2ToL1Msgs: Fr[], + public newL2ToL1Msgs: Tuple, /** * The public data writes to be inserted into the public data tree. */ - public newPublicDataWrites: PublicDataWrite[], + public newPublicDataWrites: Tuple, /** * The leaves of the new contract data that will be inserted into the contracts tree. */ - public contractLeaves: Fr[], + public contractLeaves: Tuple, /** - * The the contracts data of the new contracts. + * The contract data of the new contracts. */ - public contractData: ContractData[], + public contractData: Tuple, /** * The logs of the txEffect */ public encryptedLogs: TxL2Logs, public unencryptedLogs: TxL2Logs, - ) { - if (newNoteHashes.length % MAX_NEW_COMMITMENTS_PER_TX !== 0) { - throw new Error(`The number of new commitments must be a multiple of ${MAX_NEW_COMMITMENTS_PER_TX}.`); - } - } + ) {} hash() { const noteHashesBuffer = Buffer.concat(this.newNoteHashes.map(x => x.toBuffer())); @@ -47,11 +51,8 @@ export class TxEffect { const encryptedLogsHashKernel0 = this.encryptedLogs.hash(); const unencryptedLogsHashKernel0 = this.unencryptedLogs.hash(); - if ( - (this.contractLeaves.length > 1 && !this.contractLeaves[1].isZero()) || - (this.contractData.length > 1 && !this.contractData[1].isEmpty()) - ) { - throw new Error('We only support max one new contract per tx'); + if (MAX_NEW_CONTRACTS_PER_TX !== 1) { + throw new Error('Only one contract per transaction is supported for now.'); } const inputValue = Buffer.concat([ diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 317ea220c43..0bbc6214601 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -11,7 +11,7 @@ export const MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL = 16; export const MAX_PUBLIC_DATA_READS_PER_CALL = 16; export const MAX_READ_REQUESTS_PER_CALL = 32; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; -export const MAX_NEW_COMMITMENTS_PER_TX = 64; +export const MAX_NEW_NOTE_HASHES_PER_TX = 64; export const MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; export const MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; export const MAX_NEW_NULLIFIERS_PER_TX = 64; diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 811685523c0..2e1b49e29ba 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -4,7 +4,7 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, @@ -163,7 +163,7 @@ export class CombinedAccumulatedData { /** * The new commitments made in this transaction. */ - public newCommitments: Tuple, + public newCommitments: Tuple, /** * The new nullifiers made in this transaction. */ @@ -245,7 +245,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( reader.readArray(MAX_READ_REQUESTS_PER_TX, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext), - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -273,7 +273,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - makeTuple(MAX_NEW_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -301,7 +301,7 @@ export class CombinedAccumulatedData { const newCommitments = padArrayEnd( [...nonRevertible.newCommitments, ...revertible.newCommitments].filter(x => !x.isEmpty()), SideEffect.empty(), - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, ); const newNullifiers = padArrayEnd( diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index a3e2a3edc7b..e7de614fa31 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -1,7 +1,7 @@ import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, @@ -23,11 +23,11 @@ export class PrivateKernelTailCircuitPrivateInputs { /** * The sorted new commitments. */ - public sortedNewCommitments: Tuple, + public sortedNewCommitments: Tuple, /** * The sorted new commitments indexes. Maps original to sorted. */ - public sortedNewCommitmentsIndexes: Tuple, + public sortedNewCommitmentsIndexes: Tuple, /** * Contains hints for the transient read requests to localize corresponding commitments. */ @@ -76,8 +76,8 @@ export class PrivateKernelTailCircuitPrivateInputs { const reader = BufferReader.asReader(buffer); return new PrivateKernelTailCircuitPrivateInputs( reader.readObject(PrivateKernelInnerData), - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX, SideEffect), - reader.readNumbers(MAX_NEW_COMMITMENTS_PER_TX), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), + reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_TX), reader.readArray(MAX_READ_REQUESTS_PER_TX, Fr), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readNumbers(MAX_NEW_NULLIFIERS_PER_TX), diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 3bd6887749b..9b0cece6c48 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -35,7 +35,7 @@ import { L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L2ToL1Message, MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, @@ -262,7 +262,7 @@ export function makeAccumulatedData(seed = 1, full = false): CombinedAccumulated makeNullifierKeyValidationRequestContext, seed + 0x100, ), - tupleGenerator(MAX_NEW_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x120), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), tupleGenerator(MAX_NEW_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 218fe5adbfc..ddb5a411dfa 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -25,7 +25,7 @@ import { GrumpkinScalar, Header, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -879,7 +879,7 @@ export function mapCombinedAccumulatedDataFromNoir( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, mapNullifierKeyValidationRequestContextFromNoir, ), - mapTupleFromNoir(combinedAccumulatedData.new_commitments, MAX_NEW_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(combinedAccumulatedData.new_commitments, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(combinedAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir( combinedAccumulatedData.private_call_stack, diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index c52785c4743..935080c6e35 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -3,7 +3,7 @@ import { FunctionData, FunctionSelector, MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_READ_REQUESTS_PER_CALL, MAX_REVERTIBLE_COMMITMENTS_PER_TX, MembershipWitness, @@ -83,7 +83,7 @@ describe('Kernel Prover', () => { const createProofOutput = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelInnerCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 2f6f1eb2444..5b6a9a6ee85 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -3,7 +3,7 @@ import { CallRequest, Fr, GrumpkinScalar, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, @@ -177,7 +177,7 @@ export class KernelProver { const [sortedCommitments, sortedCommitmentsIndexes] = this.sortSideEffects< SideEffect, - typeof MAX_NEW_COMMITMENTS_PER_TX + typeof MAX_NEW_NOTE_HASHES_PER_TX >(output.publicInputs.end.newCommitments); const [sortedNullifiers, sortedNullifiersIndexes] = this.sortSideEffects< @@ -329,7 +329,7 @@ export class KernelProver { */ private getReadRequestHints( readRequests: Tuple, - commitments: Tuple, + commitments: Tuple, ): Tuple { const hints = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero); for (let i = 0; i < MAX_READ_REQUESTS_PER_TX && !readRequests[i].isEmpty(); i++) { @@ -360,7 +360,7 @@ export class KernelProver { */ private getNullifierHints( nullifiedCommitments: Tuple, - commitments: Tuple, + commitments: Tuple, ): Tuple { const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero); const alreadyUsed = new Set(); diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts index 6c66111c2b0..87c08b286a9 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -11,7 +11,7 @@ import { Note, TxL2Logs, } from '@aztec/circuit-types'; -import { Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { Fr, MAX_NEW_NOTE_HASHES_PER_TX } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { pedersenHash } from '@aztec/foundation/crypto'; import { Point } from '@aztec/foundation/fields'; @@ -26,6 +26,7 @@ import { PxeDatabase } from '../database/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; import { NoteDao } from '../database/note_dao.js'; import { NoteProcessor } from './note_processor.js'; +import { Tuple } from '@aztec/foundation/serialize'; const TXS_PER_BLOCK = 4; @@ -39,7 +40,7 @@ describe('Note Processor', () => { let keyStore: MockProxy; let simulator: MockProxy; const firstBlockNum = 123; - const numCommitmentsPerBlock = TXS_PER_BLOCK * MAX_NEW_COMMITMENTS_PER_TX; + const numCommitmentsPerBlock = TXS_PER_BLOCK * MAX_NEW_NOTE_HASHES_PER_TX; const firstBlockDataStartIndex = (firstBlockNum - 1) * numCommitmentsPerBlock; const firstBlockDataEndIndex = firstBlockNum * numCommitmentsPerBlock; @@ -53,12 +54,12 @@ describe('Note Processor', () => { let usedOwnedNote = 0; for (let i = 0; i < TXS_PER_BLOCK; ++i) { const ownedDataIndices = ownedData[i] || []; - if (ownedDataIndices.some(index => index >= MAX_NEW_COMMITMENTS_PER_TX)) { - throw new Error(`Data index should be less than ${MAX_NEW_COMMITMENTS_PER_TX}.`); + if (ownedDataIndices.some(index => index >= MAX_NEW_NOTE_HASHES_PER_TX)) { + throw new Error(`Data index should be less than ${MAX_NEW_NOTE_HASHES_PER_TX}.`); } const logs: FunctionL2Logs[] = []; - for (let noteIndex = 0; noteIndex < MAX_NEW_COMMITMENTS_PER_TX; ++noteIndex) { + for (let noteIndex = 0; noteIndex < MAX_NEW_NOTE_HASHES_PER_TX; ++noteIndex) { const isOwner = ownedDataIndices.includes(noteIndex); const publicKey = isOwner ? owner.getPublicKey() : Point.random(); const note = (isOwner && ownedNotes[usedOwnedNote]) || L1NotePayload.random(); @@ -108,7 +109,7 @@ describe('Note Processor', () => { for (let i = 0; i < TXS_PER_BLOCK; i++) { block.body.txEffects[i].newNoteHashes = newNotes .map(n => computeMockNoteHash(n.note)) - .slice(i * MAX_NEW_COMMITMENTS_PER_TX, (i + 1) * MAX_NEW_COMMITMENTS_PER_TX); + .slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple; } const randomBlockContext = new L2BlockContext(block); @@ -183,17 +184,17 @@ describe('Note Processor', () => { expect.objectContaining({ ...ownedL1NotePayloads[0], // Index 1 log in the 2nd tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (2 - 1) + 1), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (2 - 1) + 1), }), expect.objectContaining({ ...ownedL1NotePayloads[1], // Index 0 log in the 4th tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 0), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (4 - 1) + 0), }), expect.objectContaining({ ...ownedL1NotePayloads[2], // Index 2 log in the 4th tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 2), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (4 - 1) + 2), }), ]); }, 30_000); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 31ce051d2ac..b64e60cbfc2 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -7,7 +7,7 @@ import { L2BlockL2Logs, } from '@aztec/circuit-types'; import { NoteProcessorStats } from '@aztec/circuit-types/stats'; -import { MAX_NEW_COMMITMENTS_PER_TX, PublicKey } from '@aztec/circuits.js'; +import { MAX_NEW_NOTE_HASHES_PER_TX, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -123,7 +123,7 @@ export class NoteProcessor { for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { this.stats.txs++; const dataStartIndexForTx = - dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_COMMITMENTS_PER_TX; + dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_NOTE_HASHES_PER_TX; const newCommitments = block.body.txEffects[indexOfTxInABlock].newNoteHashes; // Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding // to the index of a tx in a block. diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index 6196bc52879..d490a08ab71 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -19,12 +19,15 @@ import { Fr, GlobalVariables, Header, + MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, @@ -39,7 +42,7 @@ import { RootRollupPublicInputs, SideEffect, SideEffectLinkedToNoteHash, - StateReference, + StateReference } from '@aztec/circuits.js'; import { fr, @@ -55,12 +58,12 @@ import { import { makeTuple, range } from '@aztec/foundation/array'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { times } from '@aztec/foundation/collection'; -import { to2Fields } from '@aztec/foundation/serialize'; +import { Tuple, to2Fields } from '@aztec/foundation/serialize'; import { openTmpStore } from '@aztec/kv-store/utils'; import { MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; import { MockProxy, mock } from 'jest-mock-extended'; -import { type MemDown, default as memdown } from 'memdown'; +import { default as memdown, type MemDown } from 'memdown'; import { VerificationKeys, getVerificationKeys } from '../mocks/verification_keys.js'; import { EmptyRollupProver } from '../prover/empty.js'; @@ -231,12 +234,12 @@ describe('sequencer/solo_block_builder', () => { const txEffects: TxEffect[] = txs.map( tx => new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value), - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value), + tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value) as Tuple, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), - tx.data.combinedData.newContracts.map(cd => cd.hash()), - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)), + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple, + tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, + tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index 903b51a40d6..17f86272f4a 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -10,6 +10,8 @@ import { GlobalVariables, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, + MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, @@ -103,13 +105,14 @@ export class SoloBlockBuilder implements BlockBuilder { // Collect all new nullifiers, commitments, and contracts from all txs in this block const txEffects: TxEffect[] = txs.map( tx => + // TODO(benesjan): Combined data should most likely contain the tx effect directly new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value), - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value), + tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value) as Tuple, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), - tx.data.combinedData.newContracts.map(cd => cd.hash()), - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)), + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple, + tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, + tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), diff --git a/yellow-paper/docs/constants.md b/yellow-paper/docs/constants.md index 496eb93b1c5..0e1789ae22c 100644 --- a/yellow-paper/docs/constants.md +++ b/yellow-paper/docs/constants.md @@ -56,7 +56,7 @@ The statically-sized nature the kernel & rollup circuits will restrict the quant | Name | Value | Description | |---|---|---| -| `MAX_NEW_COMMITMENTS_PER_TX` | 128 | +| `MAX_NEW_NOTE_HASHES_PER_TX` | 128 | | `MAX_NEW_NULLIFIERS_PER_TX` | 128 | | `MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX` | 32 | | `MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX` | 32 | From e6f8114449c447c372c8f102ec86d9230d2705a9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 14:43:07 +0000 Subject: [PATCH 02/11] renaming note commitment --- .../src/contracts/target/blank-Blank.json | 2 +- .../src/core/libraries/ConstantsGen.sol | 8 +- .../src/core/libraries/decoders/Decoder.sol | 10 +- .../libraries/decoders/MessagesDecoder.sol | 4 +- .../core/libraries/decoders/TxsDecoder.sol | 10 +- .../aztec/src/context/private_context.nr | 12 +- .../aztec/src/context/public_context.nr | 10 +- .../crates/private-kernel-lib/src/common.nr | 32 ++--- .../src/private_kernel_init.nr | 2 +- .../src/private_kernel_inner.nr | 16 +-- .../src/private_kernel_tail.nr | 112 +++++++++--------- .../crates/public-kernel-lib/src/common.nr | 52 ++++---- .../src/public_kernel_app_logic.nr | 20 ++-- .../rollup-lib/src/base/base_rollup_inputs.nr | 26 ++-- ...accumulated_non_revertible_data_builder.nr | 8 +- .../accumulated_revertible_data_builder.nr | 8 +- .../combined_accumulated_data.nr | 16 +-- .../combined_accumulated_data_builder.nr | 22 ++-- ...private_accumulated_non_revertible_data.nr | 4 +- .../private_accumulated_revertible_data.nr | 4 +- .../public_accumulated_non_revertible_data.nr | 4 +- .../public_accumulated_revertible_data.nr | 4 +- .../src/abis/private_circuit_public_inputs.nr | 12 +- .../types/src/abis/public_call_stack_item.nr | 4 +- .../src/abis/public_circuit_public_inputs.nr | 10 +- .../src/crates/types/src/constants.nr | 12 +- .../src/crates/types/src/hash.nr | 2 +- .../types/src/tests/kernel_data_builder.nr | 10 +- .../private_circuit_public_inputs_builder.nr | 6 +- .../public_circuit_public_inputs_builder.nr | 6 +- .../brillig_cow_regression/Prover.toml | 2 +- .../brillig_cow_regression/src/main.nr | 6 +- yarn-project/aztec.js/src/contract/sent_tx.ts | 2 +- yarn-project/circuit-types/src/body.ts | 27 ++++- yarn-project/circuit-types/src/l2_block.ts | 4 +- yarn-project/circuit-types/src/l2_tx.ts | 6 +- yarn-project/circuit-types/src/tx/tx.ts | 4 +- .../circuit-types/src/tx/tx_receipt.ts | 2 +- .../fixtures/Benchmarking.test.json | 16 +-- yarn-project/circuits.js/src/constants.gen.ts | 8 +- .../circuits.js/src/hash/hash.test.ts | 4 +- yarn-project/circuits.js/src/hash/hash.ts | 2 +- .../kernel/combined_accumulated_data.ts | 52 ++++---- ...vate_kernel_tail_circuit_private_inputs.ts | 8 +- .../structs/private_circuit_public_inputs.ts | 14 +-- .../structs/public_call_stack_item.test.ts | 4 +- .../structs/public_circuit_public_inputs.ts | 16 +-- .../read_request_membership_witness.ts | 6 +- .../circuits.js/src/tests/factories.ts | 20 ++-- .../src/e2e_inclusion_proofs_contract.test.ts | 10 +- .../src/e2e_non_contract_account.test.ts | 2 +- .../end-to-end/src/e2e_state_vars.test.ts | 10 +- .../src/integration_l1_publisher.test.ts | 4 +- .../src/__snapshots__/index.test.ts.snap | 6 +- .../src/type_conversion.ts | 36 +++--- .../src/database/deferred_note_dao.test.ts | 4 +- .../pxe/src/database/deferred_note_dao.ts | 4 +- .../src/kernel_prover/kernel_prover.test.ts | 16 +-- .../pxe/src/kernel_prover/kernel_prover.ts | 8 +- .../pxe/src/kernel_prover/proof_creator.ts | 4 +- .../src/note_processor/note_processor.test.ts | 7 +- .../pxe/src/note_processor/note_processor.ts | 10 +- .../src/note_processor/produce_note_dao.ts | 6 +- .../pxe/src/pxe_service/pxe_service.ts | 12 +- .../block_builder/solo_block_builder.test.ts | 37 ++++-- .../src/block_builder/solo_block_builder.ts | 25 ++-- .../src/sequencer/abstract_phase_manager.ts | 4 +- .../src/sequencer/public_processor.test.ts | 4 +- .../src/avm/temporary_executor_migration.ts | 4 +- .../src/client/client_execution_context.ts | 6 +- .../src/client/private_execution.test.ts | 56 ++++----- .../simulator/src/client/simulator.test.ts | 4 +- .../simulator/src/public/execution.ts | 6 +- yarn-project/simulator/src/public/executor.ts | 8 +- .../simulator/src/public/index.test.ts | 4 +- .../src/public/public_execution_context.ts | 2 +- yellow-paper/docs/calls/static-calls.md | 2 +- yellow-paper/docs/constants.md | 2 +- yellow-paper/docs/state/note-hash-tree.md | 4 +- yellow-paper/docs/transactions/tx-object.md | 4 +- 80 files changed, 501 insertions(+), 461 deletions(-) diff --git a/boxes/blank/src/contracts/target/blank-Blank.json b/boxes/blank/src/contracts/target/blank-Blank.json index b22620056b0..182ddde6cc5 100644 --- a/boxes/blank/src/contracts/target/blank-Blank.json +++ b/boxes/blank/src/contracts/target/blank-Blank.json @@ -1 +1 @@ -{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_commitments","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_commitments","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"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","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file +{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"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","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index eed1cc5937a..6f1202c6c09 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -16,7 +16,7 @@ library Constants { uint256 internal constant ARGS_LENGTH = 16; uint256 internal constant RETURN_VALUES_LENGTH = 4; - uint256 internal constant MAX_NEW_COMMITMENTS_PER_CALL = 16; + uint256 internal constant MAX_NEW_NOTE_HASHES_PER_CALL = 16; uint256 internal constant MAX_NEW_NULLIFIERS_PER_CALL = 16; uint256 internal constant MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL = 4; uint256 internal constant MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL = 4; @@ -26,8 +26,8 @@ library Constants { uint256 internal constant MAX_READ_REQUESTS_PER_CALL = 32; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; uint256 internal constant MAX_NEW_NOTE_HASHES_PER_TX = 64; - uint256 internal constant MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; - uint256 internal constant MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; + uint256 internal constant MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; + uint256 internal constant MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX = 64; uint256 internal constant MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; uint256 internal constant MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; @@ -113,7 +113,7 @@ library Constants { uint256 internal constant TX_CONTEXT_DATA_LENGTH = 11; uint256 internal constant TX_REQUEST_LENGTH = 17; uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674; - uint256 internal constant COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; + uint256 internal constant NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; diff --git a/l1-contracts/src/core/libraries/decoders/Decoder.sol b/l1-contracts/src/core/libraries/decoders/Decoder.sol index 81d41999b84..91fcc16ada9 100644 --- a/l1-contracts/src/core/libraries/decoders/Decoder.sol +++ b/l1-contracts/src/core/libraries/decoders/Decoder.sol @@ -50,8 +50,8 @@ import {Hash} from "../Hash.sol"; * | 0x0208 | 0x04 | endL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex * | 0x020c | 0x20 | endArchiveSnapshot.root * | 0x022c | 0x04 | endArchiveSnapshot.nextAvailableLeafIndex - * | 0x0230 | 0x04 | len(newCommitments) (denoted a) - * | 0x0234 | a * 0x20 | newCommitments + * | 0x0230 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x0234 | a * 0x20 | newNoteHashes * | 0x0234 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x0238 + a * 0x20 | b * 0x20 | newNullifiers * | 0x0238 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) @@ -226,7 +226,7 @@ library Decoder { /* * Compute the leaf to insert. * Leaf_i = ( - * newCommitmentsKernel, + * newNoteHashesKernel, * newNullifiersKernel, * newPublicDataWritesKernel, * newL2ToL1MsgsKernel, @@ -253,7 +253,7 @@ library Decoder { // Insertions are split into multiple `bytes.concat` to work around stack too deep. vars.baseLeaf = bytes.concat( bytes.concat( - slice(_body, offsets.commitment, Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP), + slice(_body, offsets.commitment, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.nullifier, Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.publicData, Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.l2ToL1Msgs, Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP), @@ -267,7 +267,7 @@ library Decoder { bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); - offsets.commitment += Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP; + offsets.commitment += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; offsets.nullifier += Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP; offsets.publicData += Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP; offsets.l2ToL1Msgs += Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol index 3c632b234b9..6fb589ac23e 100644 --- a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol @@ -21,8 +21,8 @@ import {Hash} from "../Hash.sol"; * * | byte start | num bytes | name * | --- | --- | --- - * | 0x00 | 0x04 | len(newCommitments) (denoted a) - * | 0x04 | a * 0x20 | newCommitments + * | 0x00 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x04 | a * 0x20 | newNoteHashes * | 0x04 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x08 + a * 0x20 | b * 0x20 | newNullifiers * | 0x08 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index 79c6595fd28..3a221121a0c 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -21,8 +21,8 @@ import {Hash} from "../Hash.sol"; * * | byte start | num bytes | name * | --- | --- | --- - * | 0x00 | 0x04 | len(newCommitments) (denoted a) - * | 0x04 | a * 0x20 | newCommitments + * | 0x00 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x04 | a * 0x20 | newNoteHashes * | 0x04 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x08 + a * 0x20 | b * 0x20 | newNullifiers * | 0x08 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) @@ -128,7 +128,7 @@ library TxsDecoder { /* * Compute the leaf to insert. * Leaf_i = ( - * newCommitmentsKernel, + * newNoteHashesKernel, * newNullifiersKernel, * newPublicDataWritesKernel, * newL2ToL1MsgsKernel, @@ -155,7 +155,7 @@ library TxsDecoder { // Insertions are split into multiple `bytes.concat` to work around stack too deep. vars.baseLeaf = bytes.concat( bytes.concat( - slice(_body, offsets.commitment, Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP), + slice(_body, offsets.commitment, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.nullifier, Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.publicData, Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.l2ToL1Msgs, Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP), @@ -169,7 +169,7 @@ library TxsDecoder { bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); - offsets.commitment += Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP; + offsets.commitment += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; offsets.nullifier += Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP; offsets.publicData += Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP; offsets.l2ToL1Msgs += Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 6e019069b59..3a5d178af07 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -20,7 +20,7 @@ use dep::protocol_types::{ }, address::{AztecAddress, EthAddress}, constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, @@ -49,7 +49,7 @@ struct PrivateContext { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack_hashes : BoundedVec, @@ -83,7 +83,7 @@ impl PrivateContext { return_values: BoundedVec::new(0), read_requests: BoundedVec::new(SideEffect::empty()), nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()), - new_commitments: BoundedVec::new(SideEffect::empty()), + new_note_hashes: BoundedVec::new(SideEffect::empty()), new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()), historical_header: inputs.historical_header, private_call_stack_hashes: BoundedVec::new(0), @@ -151,7 +151,7 @@ impl PrivateContext { min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack_hashes: self.private_call_stack_hashes.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, @@ -181,7 +181,7 @@ impl PrivateContext { pub fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; - self.new_commitments.push(side_effect); + self.new_note_hashes.push(side_effect); self.side_effect_counter = self.side_effect_counter + 1; } @@ -444,7 +444,7 @@ impl PrivateContext { contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL], new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256], diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 272b574b00a..9b82f578464 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -12,7 +12,7 @@ use dep::protocol_types::{ }, address::{AztecAddress, EthAddress}, constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH @@ -32,7 +32,7 @@ struct PublicContext { contract_storage_reads: BoundedVec, public_call_stack_hashes: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, @@ -58,7 +58,7 @@ impl PublicContext { contract_storage_update_requests: BoundedVec::new(empty_storage_update), contract_storage_reads: BoundedVec::new(empty_storage_read), public_call_stack_hashes: BoundedVec::new(0), - new_commitments: BoundedVec::new(SideEffect::empty()), + new_note_hashes: BoundedVec::new(SideEffect::empty()), new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()), new_l2_to_l1_msgs: BoundedVec::new(L2ToL1Message::empty()), unencrypted_logs_hash: BoundedVec::new(0), @@ -122,7 +122,7 @@ impl PublicContext { contract_storage_update_requests: self.contract_storage_update_requests.storage, contract_storage_reads: self.contract_storage_reads.storage, return_values: self.return_values.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, @@ -136,7 +136,7 @@ impl PublicContext { pub fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; - self.new_commitments.push(side_effect); + self.new_note_hashes.push(side_effect); self.side_effect_counter = self.side_effect_counter + 1; } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index ba8476925e9..c5a7589de63 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -13,7 +13,7 @@ use dep::types::{ address::{AztecAddress, EthAddress, PartialAddress, compute_initialization_hash}, contract_class_id::ContractClassId, contrakt::contract_deployment_data::ContractDeploymentData, constants::{ - MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL }, @@ -22,7 +22,7 @@ use dep::types::{ compute_constructor_hash, compute_l2_to_l1_hash, compute_logs_hash, compute_new_contract_address_hash, contract_tree_root_from_siblings, function_tree_root_from_siblings, pedersen_hash, private_functions_root_from_siblings, - read_request_root_from_siblings, silo_commitment, silo_nullifier, + read_request_root_from_siblings, silo_note_hash, silo_nullifier, stdlib_recursion_verification_key_compress_native_vk }, utils::{arrays::{array_length, array_to_bounded_vec, validate_array}}, @@ -31,13 +31,13 @@ use dep::types::{ pub fn validate_arrays(app_public_inputs: PrivateCircuitPublicInputs) { // Each of the following arrays is expected to be zero-padded. - // In addition, some of the following arrays (new_commitments, etc...) are passed + // In addition, some of the following arrays (new_note_hashes, etc...) are passed // to extend_from_array_to_array() routines which rely on the passed arrays to be well-formed. validate_array(app_public_inputs.return_values); validate_array(app_public_inputs.read_requests); validate_array(app_public_inputs.nullifier_key_validation_requests); - validate_array(app_public_inputs.new_commitments); + validate_array(app_public_inputs.new_note_hashes); validate_array(app_public_inputs.new_nullifiers); validate_array(app_public_inputs.private_call_stack_hashes); validate_array(app_public_inputs.public_call_stack_hashes); @@ -95,7 +95,7 @@ pub fn initialize_end_values( public_inputs.end.read_requests = array_to_bounded_vec(start.read_requests); public_inputs.end.nullifier_key_validation_requests = array_to_bounded_vec(start.nullifier_key_validation_requests); - public_inputs.end.new_commitments = array_to_bounded_vec(start.new_commitments); + public_inputs.end.new_note_hashes = array_to_bounded_vec(start.new_note_hashes); public_inputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); public_inputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); @@ -117,7 +117,7 @@ fn perform_static_call_checks(private_call: PrivateCallData) { if is_static_call { // No state changes are allowed for static calls: assert( - is_empty_array(public_inputs.new_commitments), "new_commitments must be empty for static calls" + is_empty_array(public_inputs.new_note_hashes), "new_note_hashes must be empty for static calls" ); assert( is_empty_array(public_inputs.new_nullifiers), "new_nullifiers must be empty for static calls" @@ -180,7 +180,7 @@ pub fn update_end_values( let nullifier_key_validation_requests = private_call_public_inputs.nullifier_key_validation_requests; - let new_commitments = private_call_public_inputs.new_commitments; + let new_note_hashes = private_call_public_inputs.new_note_hashes; let new_nullifiers = private_call_public_inputs.new_nullifiers; let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; @@ -193,7 +193,7 @@ pub fn update_end_values( let witness = read_request_membership_witnesses[i]; if witness.is_transient & (read_request != 0) { // only forward transient to public inputs siloed_read_requests.push( - SideEffect { counter: read_requests[i].counter, value: silo_commitment(storage_contract_address, read_request) } + SideEffect { counter: read_requests[i].counter, value: silo_note_hash(storage_contract_address, read_request) } ) } } @@ -217,7 +217,7 @@ pub fn update_end_values( let siloed_note_hash = if new_nullifier.note_hash == 0 { 0 } else { - silo_commitment(storage_contract_address, new_nullifier.note_hash) + silo_note_hash(storage_contract_address, new_nullifier.note_hash) }; siloed_new_nullifiers.push( SideEffectLinkedToNoteHash { @@ -231,16 +231,16 @@ pub fn update_end_values( public_inputs.end.new_nullifiers.extend_from_bounded_vec(siloed_new_nullifiers); // commitments - let mut siloed_new_commitments: BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - siloed_new_commitments.push( - SideEffect { value: silo_commitment(storage_contract_address, new_commitment), counter: new_commitments[i].counter } + let mut siloed_new_note_hashes: BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + siloed_new_note_hashes.push( + SideEffect { value: silo_note_hash(storage_contract_address, new_note_hash), counter: new_note_hashes[i].counter } ); } } - public_inputs.end.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + public_inputs.end.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); // Call stacks // Private call stack. diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr index 5758d7550b5..066072019e1 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr @@ -277,7 +277,7 @@ mod tests { fn input_validation_malformed_arrays_commitments() { let mut builder = PrivateKernelInitInputsBuilder::new_constructor(); - builder.private_call.public_inputs.new_commitments.extend_from_array( + builder.private_call.public_inputs.new_note_hashes.extend_from_array( [ SideEffect { value: 0, counter: 0 }, SideEffect { value: 9123, counter: 1 } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index 870eeac8bb2..de289d4d41d 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -455,7 +455,7 @@ mod tests { fn input_validation_malformed_arrays_commitments() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.private_call.public_inputs.new_commitments.extend_from_array( + builder.private_call.public_inputs.new_note_hashes.extend_from_array( [ SideEffect { value: 0, counter: 0 }, SideEffect { value: 9123, counter: 1 } @@ -516,17 +516,17 @@ mod tests { let mut builder = PrivateKernelInnerInputsBuilder::new(); // The current call stack has 1 commitment; - builder.private_call.public_inputs.new_commitments.push(SideEffect { value: 4321, counter: 0 }); + builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 4321, counter: 0 }); // Mock the previous new commitments to be full, therefore no more commitments can be added. - let mut full_new_commitments = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; + let mut full_new_note_hashes = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - full_new_commitments[i] = SideEffect { + full_new_note_hashes[i] = SideEffect { value: i + 1, counter: i as u32, }; } - builder.previous_kernel.end.new_commitments.extend_from_array(full_new_commitments); + builder.previous_kernel.end.new_note_hashes.extend_from_array(full_new_note_hashes); builder.failed(); } @@ -728,11 +728,11 @@ mod tests { assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); } - #[test(should_fail_with="new_commitments must be empty for static calls")] - fn creating_new_commitments_on_static_call_fails() { + #[test(should_fail_with="new_note_hashes must be empty for static calls")] + fn creating_new_note_hashes_on_static_call_fails() { let mut builder = PrivateKernelInnerInputsBuilder::new().is_static_call(); - builder.private_call.public_inputs.new_commitments.push(SideEffect { value: 1, counter: 0 }); + builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 1, counter: 0 }); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 8bb8196ca01..89280d2a62c 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -19,8 +19,8 @@ use dep::types::{ struct PrivateKernelTailCircuitPrivateInputs { previous_kernel: PrivateKernelInnerData, - sorted_new_commitments: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], - sorted_new_commitments_indexes: [u32; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_new_note_hashes_indexes: [u32; MAX_NEW_NOTE_HASHES_PER_TX], read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], sorted_new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_TX], @@ -58,7 +58,7 @@ impl PrivateKernelTailCircuitPrivateInputs { } fn match_reads_to_commitments(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - let new_commitments = public_inputs.end.new_commitments; + let new_note_hashes = public_inputs.end.new_note_hashes; let read_requests = public_inputs.end.read_requests; // match reads to commitments from the previous call(s) @@ -67,7 +67,7 @@ impl PrivateKernelTailCircuitPrivateInputs { let read_commitment_hint = self.read_commitment_hints[rr_idx] as u64; if (read_request.value != 0) { - let commitment = new_commitments.get_unchecked(read_commitment_hint as Field); + let commitment = new_note_hashes.get_unchecked(read_commitment_hint as Field); assert_eq( read_request.value, commitment.value, "Hinted commitment does not match read request" ); @@ -105,23 +105,23 @@ impl PrivateKernelTailCircuitPrivateInputs { fn sort_arrays(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( - public_inputs.end.new_commitments.storage, - self.sorted_new_commitments, - self.sorted_new_commitments_indexes + public_inputs.end.new_note_hashes.storage, + self.sorted_new_note_hashes, + self.sorted_new_note_hashes_indexes ); PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( public_inputs.end.new_nullifiers.storage, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes ); - public_inputs.end.new_commitments.storage = self.sorted_new_commitments; + public_inputs.end.new_note_hashes.storage = self.sorted_new_note_hashes; public_inputs.end.new_nullifiers.storage = self.sorted_new_nullifiers; } fn match_nullifiers_to_commitments_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // Match nullifiers/nullified_commitments to commitments from the previous call(s) - let mut new_commitments = public_inputs.end.new_commitments.storage; + let mut new_note_hashes = public_inputs.end.new_note_hashes.storage; let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { @@ -138,7 +138,7 @@ impl PrivateKernelTailCircuitPrivateInputs { assert( hint_pos < MAX_NEW_NOTE_HASHES_PER_TX as u64, "New nullifier is transient but hint is invalid" ); - let commitment = new_commitments[hint_pos]; + let commitment = new_note_hashes[hint_pos]; assert_eq(nullified_commitment, commitment.value, "Hinted commitment does not match"); assert( nullifier.counter > commitment.counter, "Nullifier counter must be greater than commitment counter" @@ -146,7 +146,7 @@ impl PrivateKernelTailCircuitPrivateInputs { // match found! // squash both the nullifier and the commitment // (set to 0 here and then rearrange array after loop) - new_commitments[hint_pos] = SideEffect::empty(); + new_note_hashes[hint_pos] = SideEffect::empty(); new_nullifiers[n_idx as u64] = SideEffectLinkedToNoteHash::empty(); } // non-transient (persistable) nullifiers are just kept in new_nullifiers array and forwarded @@ -155,15 +155,15 @@ impl PrivateKernelTailCircuitPrivateInputs { // Move all zero-ed (removed) entries of these arrays to the end and preserve ordering of other entries - let mut new_commitments_vec = BoundedVec::new(SideEffect::empty()); + let mut new_note_hashes_vec = BoundedVec::new(SideEffect::empty()); for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { - if new_commitments[c_idx].value != 0 { - new_commitments_vec.push(new_commitments[c_idx]); + if new_note_hashes[c_idx].value != 0 { + new_note_hashes_vec.push(new_note_hashes[c_idx]); } } - public_inputs.end.new_commitments = new_commitments_vec; + public_inputs.end.new_note_hashes = new_note_hashes_vec; let mut new_nullifiers_vec = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); @@ -180,11 +180,11 @@ impl PrivateKernelTailCircuitPrivateInputs { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // tx hash let first_nullifier = public_inputs.end.new_nullifiers.get(0); - let mut unique_commitments = public_inputs.end.new_commitments.storage; + let mut unique_commitments = public_inputs.end.new_note_hashes.storage; for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { // Apply nonce to all non-zero/non-empty commitments - // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_commitments array + // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_note_hashes array let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); let commitment = unique_commitments[c_idx]; if commitment.value != 0 { @@ -196,7 +196,7 @@ impl PrivateKernelTailCircuitPrivateInputs { } } - public_inputs.end.new_commitments.storage = unique_commitments; + public_inputs.end.new_note_hashes.storage = unique_commitments; } pub fn native_private_kernel_circuit_ordering(self) -> PrivateKernelTailCircuitPublicInputs { @@ -229,7 +229,7 @@ mod tests { use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; use dep::types::constants::{ MAX_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX }; use dep::types::{ abis::{ @@ -255,8 +255,8 @@ mod tests { } } - pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.previous_kernel.end.new_commitments.storage + pub fn get_new_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { + self.previous_kernel.end.new_note_hashes.storage } pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { @@ -264,7 +264,7 @@ mod tests { } pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) + self.compute_unique_siloed_commitments(self.previous_kernel.end.new_note_hashes.storage) } // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed @@ -276,7 +276,7 @@ mod tests { pub fn append_transient_commitments(&mut self, num_commitments: Field) { // All new commitments aggregated in the previous kernel are transient commitments. - self.previous_kernel.append_new_commitments(num_commitments); + self.previous_kernel.append_new_note_hashes(num_commitments); } pub fn add_transient_read(&mut self, commitment_index: Field) { @@ -289,7 +289,7 @@ mod tests { } pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { - self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; + self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_note_hashes.get(commitment_index).value; self.nullifier_commitment_hints[nullifier_index] = commitment_index; } @@ -321,10 +321,10 @@ mod tests { } pub fn execute(&mut self) -> PrivateKernelTailCircuitPublicInputs { - let (sorted_new_commitments, sorted_new_commitments_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); + let (sorted_new_note_hashes, sorted_new_note_hashes_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_note_hashes()); let mut sorted_read_commitment_hints = [0; MAX_READ_REQUESTS_PER_TX]; for i in 0..sorted_read_commitment_hints.len() { - sorted_read_commitment_hints[i] = sorted_new_commitments_indexes[self.read_commitment_hints[i]] as Field; + sorted_read_commitment_hints[i] = sorted_new_note_hashes_indexes[self.read_commitment_hints[i]] as Field; } let (sorted_new_nullifiers, sorted_new_nullifiers_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_nullifiers()); let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; @@ -334,8 +334,8 @@ mod tests { let kernel = PrivateKernelTailCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_inner_data(), - sorted_new_commitments, - sorted_new_commitments_indexes, + sorted_new_note_hashes, + sorted_new_note_hashes_indexes, read_commitment_hints: sorted_read_commitment_hints, sorted_new_nullifiers, sorted_new_nullifiers_indexes, @@ -368,27 +368,27 @@ mod tests { let unique_siloed_commitments = builder.get_unique_siloed_commitments(); let public_inputs = builder.execute(); - assert(array_length(public_inputs.end.new_commitments) == 1); - assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); + assert(array_length(public_inputs.end.new_note_hashes) == 1); + assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_commitments[0])); } #[test] unconstrained fn native_matching_some_read_requests_to_commitments_works() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(MAX_NEW_NOTE_HASHES_PER_TX); - // prepare for the split: first MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX are added to end_non_revertible_accumulted_data + // prepare for the split: first MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX are added to end_non_revertible_accumulted_data // neeed to take the counter of the side effect at the given index because - builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_commitments.get(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX).counter; + builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_note_hashes.get(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX).counter; // Read the commitment at index 1; builder.add_transient_read(1); // Read the commitment at index 3; builder.add_transient_read(3); let unique_siloed_commitments = builder.get_unique_siloed_commitments(); let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_commitments), MAX_REVERTIBLE_COMMITMENTS_PER_TX); - for i in 0..MAX_REVERTIBLE_COMMITMENTS_PER_TX { + assert_eq(array_length(public_inputs.end.new_note_hashes), MAX_REVERTIBLE_NOTE_HASHES_PER_TX); + for i in 0..MAX_REVERTIBLE_NOTE_HASHES_PER_TX { assert( - public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX + i]) + public_inputs.end.new_note_hashes[i].eq(unique_siloed_commitments[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) ); } } @@ -413,7 +413,7 @@ mod tests { builder.nullify_transient_commitment(1, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); // The nullifier at index 1 is chopped. assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[2]])); @@ -433,14 +433,14 @@ mod tests { builder.append_nullifiers(2); // The nullifier at index 1 is nullifying the commitment at index 0; builder.nullify_transient_commitment(1, 0); - let new_commitments = builder.get_new_commitments(); + let new_note_hashes = builder.get_new_note_hashes(); // The 0th commitment will be chopped. - let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); + let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_note_hashes[1]]); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); assert( array_eq( - public_inputs.end.new_commitments, + public_inputs.end.new_note_hashes, [unique_siloed_commitments[0]] ) ); @@ -469,7 +469,7 @@ mod tests { let public_inputs = builder.execute(); // app logic will be completely empty after squashing - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); assert(is_empty_array(public_inputs.end.new_nullifiers)); // and the 0th nullifier will be moved to the non-revertible array @@ -485,16 +485,16 @@ mod tests { unconstrained fn ordering_of_commitments_and_nullifiers() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - let mut sorted_new_commitments = [SideEffect::empty(); 10]; + let mut sorted_new_note_hashes = [SideEffect::empty(); 10]; let mut sorted_new_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; for i in 0..10 { - sorted_new_commitments[i] = SideEffect { value: (i + 1) as Field, counter: builder.previous_kernel.next_sideffect_counter() }; + sorted_new_note_hashes[i] = SideEffect { value: (i + 1) as Field, counter: builder.previous_kernel.next_sideffect_counter() }; sorted_new_nullifiers[i] = SideEffectLinkedToNoteHash { value: (i + 11) as Field, counter: builder.previous_kernel.next_sideffect_counter(), note_hash: 0 }; } for i in 0..10 { - builder.previous_kernel.end.new_commitments.push(sorted_new_commitments[9 - i]); + builder.previous_kernel.end.new_note_hashes.push(sorted_new_note_hashes[9 - i]); builder.previous_kernel.end.new_nullifiers.push(sorted_new_nullifiers[9 - i]); } @@ -503,11 +503,11 @@ mod tests { let sorted_unique_commitments = compute_unique_siloed_commitments( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, - sorted_new_commitments + sorted_new_note_hashes ); for i in 0..10 { - assert(public_inputs.end.new_commitments[i].eq(sorted_unique_commitments[i])); + assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_commitments[i])); assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); } } @@ -518,7 +518,7 @@ mod tests { builder.append_transient_commitments(2); builder.append_nullifiers(2); let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_commitments), 2); + assert_eq(array_length(public_inputs.end.new_note_hashes), 2); assert_eq(array_length(public_inputs.end.new_nullifiers), 2); assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } @@ -530,7 +530,7 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_nullifiers(2); let public_inputs = builder.execute(); - assert(array_length(public_inputs.end.new_commitments) == 0); + assert(array_length(public_inputs.end.new_note_hashes) == 0); assert(array_length(public_inputs.end.new_nullifiers) == 2); assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } @@ -608,31 +608,31 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); // expect 2 non-revertible commitments - builder.previous_kernel.append_new_commitments(2); + builder.previous_kernel.append_new_note_hashes(2); builder.previous_kernel.capture_min_revertible_side_effect_counter(); // expect 2 revertible commitments - builder.previous_kernel.append_new_commitments(2); + builder.previous_kernel.append_new_note_hashes(2); - let new_commitments = builder.previous_kernel.end.new_commitments.storage; + let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; let public_inputs = builder.execute(); let unique_commitments = compute_unique_siloed_commitments( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, - new_commitments + new_note_hashes ); assert( array_eq( - public_inputs.end_non_revertible.new_commitments, + public_inputs.end_non_revertible.new_note_hashes, [unique_commitments[0], unique_commitments[1]] ) ); assert( array_eq( - public_inputs.end.new_commitments, + public_inputs.end.new_note_hashes, [unique_commitments[2], unique_commitments[3]] ) ); @@ -643,7 +643,7 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); // add one commitment in non-revertible part - builder.previous_kernel.append_new_commitments(1); + builder.previous_kernel.append_new_note_hashes(1); builder.previous_kernel.capture_min_revertible_side_effect_counter(); // nullify it in revertible part @@ -653,8 +653,8 @@ mod tests { let public_inputs = builder.execute(); assert(!is_empty_array(public_inputs.end_non_revertible.new_nullifiers)); - assert(is_empty_array(public_inputs.end_non_revertible.new_commitments)); - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end_non_revertible.new_note_hashes)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); assert(is_empty_array(public_inputs.end.new_nullifiers)); } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr index 61828e9f813..a6842068219 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr @@ -11,13 +11,13 @@ use dep::types::{ address::AztecAddress, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, constants::{ - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_CALL, NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX }, - hash::{silo_commitment, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, + hash::{silo_note_hash, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, utils::{arrays::{array_length, array_to_bounded_vec}}, traits::{is_empty, is_empty_array} }; use crate::hash::{compute_public_data_tree_index, compute_public_data_tree_value}; @@ -53,7 +53,7 @@ pub fn initialize_end_values( // functions within this circuit: let start = previous_kernel.public_inputs.end; - circuit_outputs.end.new_commitments = array_to_bounded_vec(start.new_commitments); + circuit_outputs.end.new_note_hashes = array_to_bounded_vec(start.new_note_hashes); circuit_outputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); circuit_outputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); @@ -70,7 +70,7 @@ pub fn initialize_end_values( circuit_outputs.end.new_contracts = array_to_bounded_vec(previous_kernel.public_inputs.end.new_contracts); let start_non_revertible = previous_kernel.public_inputs.end_non_revertible; - circuit_outputs.end_non_revertible.new_commitments = array_to_bounded_vec(start_non_revertible.new_commitments); + circuit_outputs.end_non_revertible.new_note_hashes = array_to_bounded_vec(start_non_revertible.new_note_hashes); circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers); circuit_outputs.end_non_revertible.public_call_stack = array_to_bounded_vec(start_non_revertible.public_call_stack); @@ -82,8 +82,8 @@ fn perform_static_call_checks(public_call: PublicCallData) { let public_inputs = public_call.call_stack_item.public_inputs; if public_inputs.call_context.is_static_call { // No state changes are allowed for static calls: - let new_commitments_length = array_length(public_inputs.new_commitments); - assert(new_commitments_length == 0, "new_commitments must be empty for static calls"); + let new_note_hashes_length = array_length(public_inputs.new_note_hashes); + assert(new_note_hashes_length == 0, "new_note_hashes must be empty for static calls"); let new_nullifiers_length = array_length(public_inputs.new_nullifiers); assert(new_nullifiers_length == 0, "new_nullifiers must be empty for static calls"); @@ -148,7 +148,7 @@ pub fn update_public_end_non_revertible_values( circuit_outputs.end_non_revertible.public_call_stack.extend_from_bounded_vec(public_call_requests); propagate_new_nullifiers_non_revertible(public_call, circuit_outputs); - propagate_new_commitments_non_revertible(public_call, circuit_outputs); + propagate_new_note_hashes_non_revertible(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_update_requests(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_reads(public_call, circuit_outputs); // TODO(fees) propagate the following to non-revertible @@ -168,7 +168,7 @@ pub fn update_public_end_values(public_call: PublicCallData, circuit_outputs: &m circuit_outputs.end.public_call_stack.extend_from_bounded_vec(public_call_requests); propagate_new_nullifiers(public_call, circuit_outputs); - propagate_new_commitments(public_call, circuit_outputs); + propagate_new_note_hashes(public_call, circuit_outputs); propagate_new_l2_to_l1_messages(public_call, circuit_outputs); @@ -268,44 +268,44 @@ fn propagate_valid_non_revertible_public_data_reads( circuit_outputs.end_non_revertible.public_data_reads.extend_from_bounded_vec(public_data_reads); } -fn propagate_new_commitments_non_revertible( +fn propagate_new_note_hashes_non_revertible( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder ) { let public_call_public_inputs = public_call.call_stack_item.public_inputs; - let new_commitments = public_call.call_stack_item.public_inputs.new_commitments; + let new_note_hashes = public_call.call_stack_item.public_inputs.new_note_hashes; let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; - let mut siloed_new_commitments : BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - let siloed_new_commitment = silo_commitment(storage_contract_address, new_commitment); - siloed_new_commitments.push(SideEffect { value: siloed_new_commitment, counter: new_commitments[i].counter }); + let mut siloed_new_note_hashes : BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + let siloed_new_note_hash = silo_note_hash(storage_contract_address, new_note_hash); + siloed_new_note_hashes.push(SideEffect { value: siloed_new_note_hash, counter: new_note_hashes[i].counter }); } } - circuit_outputs.end_non_revertible.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + circuit_outputs.end_non_revertible.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); } -fn propagate_new_commitments( +fn propagate_new_note_hashes( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder ) { let public_call_public_inputs = public_call.call_stack_item.public_inputs; - let new_commitments = public_call.call_stack_item.public_inputs.new_commitments; + let new_note_hashes = public_call.call_stack_item.public_inputs.new_note_hashes; let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; - let mut siloed_new_commitments : BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - let siloed_new_commitment = silo_commitment(storage_contract_address, new_commitment); - siloed_new_commitments.push(SideEffect { value: siloed_new_commitment, counter: new_commitments[i].counter }); + let mut siloed_new_note_hashes : BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + let siloed_new_note_hash = silo_note_hash(storage_contract_address, new_note_hash); + siloed_new_note_hashes.push(SideEffect { value: siloed_new_note_hash, counter: new_note_hashes[i].counter }); } } - circuit_outputs.end.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + circuit_outputs.end.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); } fn propagate_new_nullifiers_non_revertible( diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr index 9a656d26859..066ec75de4a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -66,7 +66,7 @@ mod tests { side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, - hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_commitment, silo_nullifier}, + hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_note_hash, silo_nullifier}, messaging::l2_to_l1_message::L2ToL1Message, tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::array_eq} @@ -169,22 +169,22 @@ mod tests { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); let contract_address = builder.public_call.contract_address; // Setup 2 new commitments on the previous kernel. - builder.previous_kernel.append_new_commitments(2); - let previous = builder.previous_kernel.end.new_commitments.storage; + builder.previous_kernel.append_new_note_hashes(2); + let previous = builder.previous_kernel.end.new_note_hashes.storage; // Setup 2 new commitments on the current public inputs. let current = [ SideEffect { value: previous[1].value + 1, counter: 3 }, SideEffect { value: previous[1].value + 2, counter: 4 } ]; - builder.public_call.public_inputs.new_commitments.extend_from_array(current); - let siloed = current.map(|c: SideEffect| silo_commitment(contract_address, c.value)); - let new_commitments = [ + builder.public_call.public_inputs.new_note_hashes.extend_from_array(current); + let siloed = current.map(|c: SideEffect| silo_note_hash(contract_address, c.value)); + let new_note_hashes = [ previous[0], previous[1], SideEffect { value: siloed[0], counter: 3 }, SideEffect { value: siloed[1], counter: 4 } ]; let public_inputs = builder.execute(); - assert(array_eq(public_inputs.end.new_commitments, new_commitments)); + assert(array_eq(public_inputs.end.new_note_hashes, new_note_hashes)); } #[test] @@ -326,11 +326,11 @@ mod tests { builder.failed(); } - #[test(should_fail_with="new_commitments must be empty for static calls")] - fn public_kernel_fails_creating_new_commitments_on_static_call() { + #[test(should_fail_with="new_note_hashes must be empty for static calls")] + fn public_kernel_fails_creating_new_note_hashes_on_static_call() { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); builder.public_call.public_inputs.call_context.is_static_call = true; - builder.public_call.public_inputs.new_commitments.push(SideEffect { value: 1, counter: 0 }); + builder.public_call.public_inputs.new_note_hashes.push(SideEffect { value: 1, counter: 0 }); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 7c9840c0190..9d9433400ce 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -26,8 +26,8 @@ use dep::types::{ NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_HEIGHT, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX }, mocked::{AggregationObject, Proof}, partial_state_reference::PartialStateReference, @@ -164,7 +164,7 @@ impl BaseRollupInputs { // TODO(Kev): This should say calculate_commitments_subtree_root // Cpp code says calculate_commitments_subtree, so I'm leaving it as is for now fn calculate_commitments_subtree(self, combined: CombinedAccumulatedData) -> Field { - calculate_subtree(combined.new_commitments.map(|c: SideEffect| c.value)) + calculate_subtree(combined.new_note_hashes.map(|c: SideEffect| c.value)) } fn check_nullifier_tree_non_membership_and_insert_to_tree(self, combined: CombinedAccumulatedData) -> AppendOnlyTreeSnapshot { @@ -265,7 +265,7 @@ impl BaseRollupInputs { // 1 unencrypted logs hashes -> 2 fields --> 2 sha256 hashes --> 64 bytes let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - let new_commitments = combined.new_commitments; + let new_note_hashes = combined.new_note_hashes; let new_nullifiers = combined.new_nullifiers; let public_data_update_requests = combined.public_data_update_requests; let newL2ToL1msgs = combined.new_l2_to_l1_msgs; @@ -275,7 +275,7 @@ impl BaseRollupInputs { let mut offset = 0; for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { - calldata_hash_inputs[offset + j] = new_commitments[j].value; + calldata_hash_inputs[offset + j] = new_note_hashes[j].value; } offset += MAX_NEW_NOTE_HASHES_PER_TX ; @@ -1018,15 +1018,15 @@ mod tests { } #[test] - unconstrained fn new_commitments_tree() { + unconstrained fn new_note_hashes_tree() { let mut builder = BaseRollupInputsBuilder::new(); - let new_commitments = [27, 28, 29, 30, 31, 32]; - let mut new_commitments_vec = builder.kernel_data.end.new_commitments; - for i in 0..new_commitments.len() { - new_commitments_vec.push(SideEffect { value: new_commitments[i], counter: 0 }); + let new_note_hashes = [27, 28, 29, 30, 31, 32]; + let mut new_note_hashes_vec = builder.kernel_data.end.new_note_hashes; + for i in 0..new_note_hashes.len() { + new_note_hashes_vec.push(SideEffect { value: new_note_hashes[i], counter: 0 }); } - builder.kernel_data.end.new_commitments = new_commitments_vec; + builder.kernel_data.end.new_note_hashes = new_note_hashes_vec; let mut expected_commitments_tree = NonEmptyMerkleTree::new( [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], @@ -1041,10 +1041,10 @@ mod tests { }; assert(outputs.start.note_hash_tree.eq(expected_start_note_hash_tree_snapshot)); - for i in 0..new_commitments.len() { + for i in 0..new_note_hashes.len() { expected_commitments_tree.update_leaf( (i as u64) + (MAX_NEW_NOTE_HASHES_PER_TX as u64), - new_commitments[i] + new_note_hashes[i] ); } let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr index 372a3f77eb6..fea3f3bde43 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr @@ -10,13 +10,13 @@ use crate::{ } }; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; struct AccumulatedNonRevertibleDataBuilder { - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, public_call_stack: BoundedVec, public_data_update_requests: BoundedVec, @@ -26,14 +26,14 @@ struct AccumulatedNonRevertibleDataBuilder { impl AccumulatedNonRevertibleDataBuilder { pub fn to_private(self) -> PrivateAccumulatedNonRevertibleData { PrivateAccumulatedNonRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack: self.public_call_stack.storage } } pub fn to_public(self) -> PublicAccumulatedNonRevertibleData { PublicAccumulatedNonRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack: self.public_call_stack.storage, public_data_update_requests: self.public_data_update_requests.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr index 8ee73738459..656c8e259c4 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr @@ -13,7 +13,7 @@ use crate::{ use crate::constants::{ MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, - NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; @@ -22,7 +22,7 @@ struct AccumulatedRevertibleDataBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack: BoundedVec, @@ -46,7 +46,7 @@ struct AccumulatedRevertibleDataBuilder { impl AccumulatedRevertibleDataBuilder { pub fn to_private(self) -> PrivateAccumulatedRevertibleData { PrivateAccumulatedRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, public_call_stack: self.public_call_stack.storage, @@ -62,7 +62,7 @@ impl AccumulatedRevertibleDataBuilder { pub fn to_public(self) -> PublicAccumulatedRevertibleData { PublicAccumulatedRevertibleData { read_requests: self.read_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index 6c948e8ca6f..0fcd4d9ad58 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -15,8 +15,8 @@ use crate::constants::{ MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -31,7 +31,7 @@ struct CombinedAccumulatedData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], - new_commitments: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], @@ -66,7 +66,7 @@ impl CombinedAccumulatedData { CombinedAccumulatedData { read_requests: revertible.read_requests, nullifier_key_validation_requests: revertible.nullifier_key_validation_requests, - new_commitments: array_concat(non_revertible.new_commitments, revertible.new_commitments), + new_note_hashes: array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes), new_nullifiers: array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers), private_call_stack: revertible.private_call_stack, public_call_stack: array_concat( @@ -154,8 +154,8 @@ mod tests { } ]; - builder.new_commitments.extend_from_array(non_revertible_commitments); - builder.new_commitments.extend_from_array(revertible_commitments); + builder.new_note_hashes.extend_from_array(non_revertible_commitments); + builder.new_note_hashes.extend_from_array(revertible_commitments); builder.new_nullifiers.extend_from_array(non_revertible_nullifiers); builder.new_nullifiers.extend_from_array(revertible_nullifiers); @@ -165,11 +165,11 @@ mod tests { let (non_revertible, revertible) = builder.split(7); - assert(array_eq(non_revertible.new_commitments, non_revertible_commitments)); + assert(array_eq(non_revertible.new_note_hashes, non_revertible_commitments)); assert(array_eq(non_revertible.new_nullifiers, non_revertible_nullifiers)); assert(array_eq(non_revertible.public_call_stack, non_revertible_public_stack)); - assert(array_eq(revertible.new_commitments, revertible_commitments)); + assert(array_eq(revertible.new_note_hashes, revertible_commitments)); assert(array_eq(revertible.new_nullifiers, revertible_nullifiers)); assert(array_eq(revertible.public_call_stack, revertible_public_call_stack)); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr index f89362374bb..39595d5a945 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr @@ -20,8 +20,8 @@ use crate::constants::{ MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -36,7 +36,7 @@ struct CombinedAccumulatedDataBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack: BoundedVec, @@ -66,7 +66,7 @@ impl CombinedAccumulatedDataBuilder { CombinedAccumulatedDataBuilder { read_requests: array_to_bounded_vec(revertible.read_requests), nullifier_key_validation_requests: array_to_bounded_vec(revertible.nullifier_key_validation_requests), - new_commitments: array_to_bounded_vec(array_concat(non_revertible.new_commitments, revertible.new_commitments)), + new_note_hashes: array_to_bounded_vec(array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes)), new_nullifiers: array_to_bounded_vec(array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers)), private_call_stack: array_to_bounded_vec(revertible.private_call_stack), public_call_stack: array_to_bounded_vec( @@ -100,7 +100,7 @@ impl CombinedAccumulatedDataBuilder { CombinedAccumulatedData { read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, public_call_stack: self.public_call_stack.storage, @@ -117,7 +117,7 @@ impl CombinedAccumulatedDataBuilder { pub fn to_private_accumulated_revertible_data(self) -> PrivateAccumulatedRevertibleData { PrivateAccumulatedRevertibleData { - new_commitments: array_cp(self.new_commitments.storage), + new_note_hashes: array_cp(self.new_note_hashes.storage), new_nullifiers: array_cp(self.new_nullifiers.storage), private_call_stack: self.private_call_stack.storage, public_call_stack: array_cp(self.public_call_stack.storage), @@ -134,7 +134,7 @@ impl CombinedAccumulatedDataBuilder { PublicAccumulatedRevertibleData { read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: array_cp(self.new_commitments.storage), + new_note_hashes: array_cp(self.new_note_hashes.storage), new_nullifiers: array_cp(self.new_nullifiers.storage), private_call_stack: self.private_call_stack.storage, public_call_stack: array_cp(self.public_call_stack.storage), @@ -157,14 +157,14 @@ impl CombinedAccumulatedDataBuilder { let mut revertible_builder: AccumulatedRevertibleDataBuilder = unsafe::zeroed(); for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - let commitment = self.new_commitments.storage[i]; + let commitment = self.new_note_hashes.storage[i]; // TODO(fees) we shouldn't need to check is_empty here, - // but we do because new_commitments is bounded to MAX_REVERTIBLE_COMMITMENTS_PER_TX + // but we do because new_note_hashes is bounded to MAX_REVERTIBLE_NOTE_HASHES_PER_TX if !is_empty(commitment) { if commitment.counter < min_revertible_side_effect_counter { - non_revertible_builder.new_commitments.push(commitment); + non_revertible_builder.new_note_hashes.push(commitment); } else { - revertible_builder.new_commitments.push(commitment); + revertible_builder.new_note_hashes.push(commitment); } } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr index 8b61a1030f2..017df083bb3 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr @@ -1,11 +1,11 @@ use crate::{abis::{call_request::CallRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX }; struct PrivateAccumulatedNonRevertibleData { - new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr index 739121715fb..16d6028d74f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr @@ -5,13 +5,13 @@ use crate::{ } }; use crate::constants::{ - MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_FIELDS_PER_SHA256, MAX_NEW_CONTRACTS_PER_TX }; struct PrivateAccumulatedRevertibleData { - new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr index bc0f8c5b98c..4df61024f02 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr @@ -6,7 +6,7 @@ use crate::{ } }; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; @@ -17,7 +17,7 @@ use crate::traits::is_empty; use crate::utils::arrays::{array_cp, array_concat, array_to_bounded_vec}; struct PublicAccumulatedNonRevertibleData { - new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], public_data_update_requests: [PublicDataUpdateRequest; MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr index 44b803e38b5..e1c2fb8440a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr @@ -8,7 +8,7 @@ use crate::{ }; use crate::constants::{ MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_FIELDS_PER_SHA256, MAX_NEW_CONTRACTS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX @@ -18,7 +18,7 @@ struct PublicAccumulatedRevertibleData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], - new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 064b4d1977e..afff569ec71 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -5,7 +5,7 @@ use crate::{ }, constants::{ MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS @@ -26,7 +26,7 @@ struct PrivateCircuitPublicInputs { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_CALL], nullifier_key_validation_requests: [NullifierKeyValidationRequest; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_CALL], private_call_stack_hashes: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], @@ -60,7 +60,7 @@ impl Eq for PrivateCircuitPublicInputs { (self.return_values == other.return_values) & (self.read_requests == other.read_requests) & (self.nullifier_key_validation_requests == other.nullifier_key_validation_requests) & - (self.new_commitments == other.new_commitments) & + (self.new_note_hashes == other.new_note_hashes) & (self.new_nullifiers == other.new_nullifiers) & (self.private_call_stack_hashes == other.private_call_stack_hashes) & (self.public_call_stack_hashes == other.public_call_stack_hashes) & @@ -92,8 +92,8 @@ impl Serialize for PrivateCircuitPublicInp for i in 0..MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL{ fields.extend_from_array(self.nullifier_key_validation_requests[i].serialize()); } - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL{ - fields.extend_from_array(self.new_commitments[i].serialize()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL{ + fields.extend_from_array(self.new_note_hashes[i].serialize()); } for i in 0..MAX_NEW_NULLIFIERS_PER_CALL{ fields.extend_from_array(self.new_nullifiers[i].serialize()); @@ -130,7 +130,7 @@ impl Deserialize for PrivateCircuitPublicI min_revertible_side_effect_counter: reader.read() as u32, read_requests: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]), nullifier_key_validation_requests: reader.read_struct_array(NullifierKeyValidationRequest::deserialize, [NullifierKeyValidationRequest::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL]), - new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), + new_note_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]), new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialize, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr index 1fe1f24f3b6..6ea95afbd7e 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr @@ -61,7 +61,7 @@ mod tests { let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, is_private: false, is_constructor: false }; let mut public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed(); - public_inputs.new_commitments[0] = SideEffect{ + public_inputs.new_note_hashes[0] = SideEffect{ value: 1, counter: 0, }; @@ -78,7 +78,7 @@ mod tests { let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, is_private: false, is_constructor: false }; let mut public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed(); - public_inputs.new_commitments[0] = SideEffect{ + public_inputs.new_note_hashes[0] = SideEffect{ value: 1, counter: 0, }; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr index 87229aecac6..afbfe068e8b 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr @@ -2,7 +2,7 @@ use crate::{ abis::{call_context::CallContext, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}, address::AztecAddress, constants::{ - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH @@ -23,7 +23,7 @@ struct PublicCircuitPublicInputs{ // todo: add sideeffect ranges for the input to these hashes public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_CALL], new_l2_to_l1_msgs: [L2ToL1Message; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], @@ -60,8 +60,8 @@ impl Serialize for PublicCircuitPublicInput } fields.extend_from_array(self.public_call_stack_hashes); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - fields.extend_from_array(self.new_commitments[i].serialize()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + fields.extend_from_array(self.new_note_hashes[i].serialize()); } for i in 0..MAX_NEW_NULLIFIERS_PER_CALL { fields.extend_from_array(self.new_nullifiers[i].serialize()); @@ -88,7 +88,7 @@ impl Deserialize for PublicCircuitPublicInp contract_storage_update_requests: reader.read_struct_array(StorageUpdateRequest::deserialize, [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL]), contract_storage_reads: reader.read_struct_array(StorageRead::deserialize, [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), - new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), + new_note_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]), new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialize, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), new_l2_to_l1_msgs: reader.read_struct_array(L2ToL1Message::deserialize, [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index cec0e44dacc..2e3905fdeca 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -11,19 +11,19 @@ global RETURN_VALUES_LENGTH: Field = 4; * - MAX_NEW_NULLIFIERS_PER_CALL * - MAX_NEW_NOTE_HASHES_PER_TX * - * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a + * In the kernel circuits, we accumulate elements such as note hashes and the nullifiers from all functions calls in a * transaction. Therefore, we always must have: * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL * * For instance: - * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL + * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL * */ // docs:start:constants // "PER CALL" CONSTANTS -global MAX_NEW_COMMITMENTS_PER_CALL: Field = 16; +global MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16; global MAX_NEW_NULLIFIERS_PER_CALL: Field = 16; global MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4; global MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4; @@ -35,8 +35,8 @@ global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: Field = 1; // "PER TRANSACTION" CONSTANTS global MAX_NEW_NOTE_HASHES_PER_TX: Field = 64; -global MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX: Field = 8; -global MAX_REVERTIBLE_COMMITMENTS_PER_TX: Field = 56; +global MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX: Field = 8; +global MAX_REVERTIBLE_NOTE_HASHES_PER_TX: Field = 56; global MAX_NEW_NULLIFIERS_PER_TX: Field = 64; global MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX: Field = 8; @@ -167,7 +167,7 @@ global TX_CONTEXT_DATA_LENGTH: Field = 11; global TX_REQUEST_LENGTH: Field = 17; global GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674; -global COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; +global NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr index 76bb40ccbb9..4fc79ed9af9 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -158,7 +158,7 @@ pub fn read_request_root_from_siblings( root_from_sibling_path(read_request, leaf_index, sibling_path) } -pub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field { +pub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field { pedersen_hash( [ address.to_field(), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr index 27e12108be0..ccf24bb261f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr @@ -114,18 +114,18 @@ impl PreviousKernelDataBuilder { pub fn add_read_request_for_transient_commitment(&mut self, commitment_index: Field) -> Field { let new_read_request_index = self.end.read_requests.len(); - let commitment = self.end.new_commitments.get(commitment_index); + let commitment = self.end.new_note_hashes.get(commitment_index); let read_request = SideEffect { value: commitment.value, counter: self.next_sideffect_counter() }; self.end.read_requests.push(read_request); new_read_request_index } - pub fn append_new_commitments(&mut self, num_new_commitments: Field) { - let mocked_value_offset = self.end.new_commitments.len() + 1; + pub fn append_new_note_hashes(&mut self, num_new_note_hashes: Field) { + let mocked_value_offset = self.end.new_note_hashes.len() + 1; for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - if i as u64 < num_new_commitments as u64 { + if i as u64 < num_new_note_hashes as u64 { // The default value is its index + 1. - self.end.new_commitments.push( + self.end.new_note_hashes.push( SideEffect { value: i + mocked_value_offset, counter: self.next_sideffect_counter() } ); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr index d001cb9dfb4..27db9171226 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr @@ -12,7 +12,7 @@ use crate::{ }; use crate::constants::{ MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH }; @@ -28,7 +28,7 @@ struct PrivateCircuitPublicInputsBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack_hashes: BoundedVec, @@ -109,7 +109,7 @@ impl PrivateCircuitPublicInputsBuilder { min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack_hashes: self.private_call_stack_hashes.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr index 5ad58fd1bae..8e4e7923f1f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr @@ -8,7 +8,7 @@ use crate::{ messaging::l2_to_l1_message::L2ToL1Message, tests::fixtures }; use crate::constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH }; @@ -20,7 +20,7 @@ struct PublicCircuitPublicInputsBuilder { contract_storage_update_requests: BoundedVec, contract_storage_reads: BoundedVec, public_call_stack_hashes: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], @@ -45,7 +45,7 @@ impl PublicCircuitPublicInputsBuilder { contract_storage_update_requests: self.contract_storage_update_requests.storage, contract_storage_reads: self.contract_storage_reads.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, unencrypted_logs_hash: self.unencrypted_logs_hash, diff --git a/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml b/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml index f0a4dc2485d..44813823448 100644 --- a/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml +++ b/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml @@ -3,7 +3,7 @@ encrypted_logs_hash = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", ] -new_commitments = [ +new_note_hashes = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr index 2bcbea156b1..457abde32d5 100644 --- a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr +++ b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr @@ -30,7 +30,7 @@ impl NewContractData { } struct DataToHash { - new_commitments: [Field; MAX_NEW_NOTE_HASHES_PER_TX], + new_note_hashes: [Field; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_TX], public_data_update_requests: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], @@ -101,7 +101,7 @@ impl U256 { unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA256] { let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - let new_commitments = kernel_data.new_commitments; + let new_note_hashes = kernel_data.new_note_hashes; let new_nullifiers = kernel_data.new_nullifiers; let public_data_update_requests = kernel_data.public_data_update_requests; let newL2ToL1msgs = kernel_data.new_l2_to_l1_msgs; @@ -111,7 +111,7 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA let mut offset = 0; for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { - calldata_hash_inputs[offset + j] = new_commitments[j]; + calldata_hash_inputs[offset + j] = new_note_hashes[j]; } offset += MAX_NEW_NOTE_HASHES_PER_TX ; diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index e40b65b3a00..1b544f10b4f 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -71,7 +71,7 @@ export class SentTx { const tx = (await this.pxe.getTx(txHash))!; const visibleNotes = await this.pxe.getNotes({ txHash }); receipt.debugInfo = { - newCommitments: tx.newCommitments, + newNoteHashes: tx.newNoteHashes, newNullifiers: tx.newNullifiers, newPublicDataWrites: tx.newPublicDataWrites, newL2ToL1Msgs: tx.newL2ToL1Msgs, diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index 985ed87729e..3a82c4696be 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -1,8 +1,8 @@ import { ContractData, L2BlockL2Logs, PublicDataWrite, TxEffect } from '@aztec/circuit-types'; import { - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, } from '@aztec/circuits.js'; @@ -84,15 +84,30 @@ export class Body { // TODO(benesjan): this should use TxEffect.fromBuffer txEffects.push( new TxEffect( - newNoteHashes.slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple, - newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX) as Tuple, - newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX) as Tuple, + newNoteHashes.slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, + newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_L2_TO_L1_MSGS_PER_TX + >, newPublicDataWrites.slice( i * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, (i + 1) * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ) as Tuple, - newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple, - newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple, + newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_CONTRACTS_PER_TX + >, + newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple< + ContractData, + typeof MAX_NEW_CONTRACTS_PER_TX + >, newEncryptedLogs.txLogs[i], newUnencryptedLogs.txLogs[i], ), diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts index 9d83c056619..c9efbb09ab8 100644 --- a/yarn-project/circuit-types/src/l2_block.ts +++ b/yarn-project/circuit-types/src/l2_block.ts @@ -2,21 +2,21 @@ import { Body, ContractData, L2Tx, LogType, PublicDataWrite, TxEffect, TxHash, T import { AppendOnlyTreeSnapshot, Header, - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, STRING_ENCODING, } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot, makeHeader } from '@aztec/circuits.js/factories'; +import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { makeTuple } from '@aztec/foundation/array'; /** * The data that makes up the rollup proof, with encoder decoder functions. diff --git a/yarn-project/circuit-types/src/l2_tx.ts b/yarn-project/circuit-types/src/l2_tx.ts index 8df7457de44..8acce0c4b03 100644 --- a/yarn-project/circuit-types/src/l2_tx.ts +++ b/yarn-project/circuit-types/src/l2_tx.ts @@ -1,7 +1,7 @@ import { - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, Vector, @@ -33,7 +33,7 @@ export class L2Tx { /** * New commitments created by the transaction. */ - public newCommitments: Fr[], + public newNoteHashes: Fr[], /** * New nullifiers created by the transaction. */ @@ -100,7 +100,7 @@ export class L2Tx { */ toBuffer() { return Buffer.concat([ - new Vector(this.newCommitments).toBuffer(), + new Vector(this.newNoteHashes).toBuffer(), new Vector(this.newNullifiers).toBuffer(), new Vector(this.newPublicDataWrites).toBuffer(), new Vector(this.newL2ToL1Msgs).toBuffer(), diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 23a2d232209..e36bf56e085 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -176,8 +176,8 @@ export class Tx { newContractDataSize: this.newContracts.map(c => c.toBuffer().length).reduce((a, b) => a + b, 0), newCommitmentCount: - arrayNonEmptyLength(this.data!.endNonRevertibleData.newCommitments, SideEffect.isEmpty) + - arrayNonEmptyLength(this.data!.end.newCommitments, SideEffect.isEmpty), + arrayNonEmptyLength(this.data!.endNonRevertibleData.newNoteHashes, SideEffect.isEmpty) + + arrayNonEmptyLength(this.data!.end.newNoteHashes, SideEffect.isEmpty), newNullifierCount: arrayNonEmptyLength(this.data!.endNonRevertibleData.newNullifiers, SideEffectLinkedToNoteHash.isEmpty) + diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.ts b/yarn-project/circuit-types/src/tx/tx_receipt.ts index 00c8334f1d2..a4ec87dd097 100644 --- a/yarn-project/circuit-types/src/tx/tx_receipt.ts +++ b/yarn-project/circuit-types/src/tx/tx_receipt.ts @@ -90,7 +90,7 @@ interface DebugInfo { /** * New commitments created by the transaction. */ - newCommitments: Fr[]; + newNoteHashes: Fr[]; /** * New nullifiers created by the transaction. */ diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index dc23d9e8c0d..be58b328b32 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -428,7 +428,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -1099,7 +1099,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -1671,7 +1671,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -2384,7 +2384,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -3098,7 +3098,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -3388,7 +3388,7 @@ "path": "/home/santiago/Projects/aztec3-packages/noir-contracts/contracts/benchmarking_contract/src/main.nr" }, "40": { - "source": "use crate::{\n abi::{\n PrivateContextInputs,\n PublicContextInputs,\n },\n key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n get_block_header::get_block_header,\n nullifier_key::get_nullifier_key_pair,\n },\n types::vec::BoundedVec,\n utils::Reader,\n};\nuse dep::protocol_types::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_data::FunctionData,\n function_selector::FunctionSelector,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n call_stack_item::PrivateCallStackItem,\n call_stack_item::PublicCallStackItem,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash},\n },\n address::{\n AztecAddress,\n EthAddress,\n },\n constants::{\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n },\n contrakt::{\n deployment_data::ContractDeploymentData,\n storage_read::StorageRead,\n storage_update_request::StorageUpdateRequest,\n },\n hash::hash_args,\n grumpkin_point::GrumpkinPoint,\n};\nuse dep::std::{\n grumpkin_scalar::GrumpkinScalar,\n option::Option,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_header: BlockHeader,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(SideEffect::empty()),\n\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n block_header: inputs.block_header,\n\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_block_header(self, block_number: u32) -> BlockHeader {\n get_block_header(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.block_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect {\n value: read_request,\n counter: self.side_effect_counter,\n };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter,\n };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: nullified_commitment,\n counter: self.side_effect_counter,\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinScalar {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key, key_pair.secret_key);\n // TODO: Add request to context.\n // self.context.push_nullifier_key_validation_request(public_key, secret_key);\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address,\n function_selector, \n args_hash,\n self.side_effect_counter,\n );\n let mut reader = Reader::new(fields);\n\n let item = PrivateCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1\n read_requests: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]),\n new_commitments: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]),\n new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialise, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]),\n private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]),\n public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]),\n new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]),\n end_side_effect_counter: reader.read() as u32,\n encrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n encrypted_log_preimages_length: reader.read(),\n unencrypted_log_preimages_length: reader.read(),\n block_header: BlockHeader{\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : reader.read(),\n nullifier_tree_root : reader.read(),\n contract_tree_root : reader.read(),\n l1_to_l2_message_tree_root : reader.read(),\n archive_root : reader.read(),\n public_data_tree_root: reader.read(),\n global_variables_hash: reader.read(),\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: GrumpkinPoint {\n x: reader.read(), \n y: reader.read()\n },\n constructor_vk_hash : reader.read(),\n function_tree_root : reader.read(),\n contract_address_salt : reader.read(),\n portal_contract_address : EthAddress::from_field(reader.read()),\n },\n chain_id: reader.read(),\n version: reader.read(),\n },\n is_execution_request: reader.read() as bool,\n };\n\n reader.finish();\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n \n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_header: BlockHeader::empty(),\n prover_address: AztecAddress::zero(),\n },\n is_execution_request: true,\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n\nstruct PublicContext {\n inputs: PublicContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_reads: BoundedVec,\n public_call_stack_hashes: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_header: BlockHeader,\n prover_address: AztecAddress,\n}\n\nimpl PublicContext {\n pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = StorageRead::empty();\n let empty_storage_update = StorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_reads: BoundedVec::new(empty_storage_read),\n public_call_stack_hashes: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_header: inputs.block_header,\n prover_address: AztecAddress::zero(),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_reads: self.contract_storage_reads.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.inputs.block_header,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter\n };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: 0, // cannot nullify pending notes in public context\n counter: self.side_effect_counter\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}\n", + "source": "use crate::{\n abi::{\n PrivateContextInputs,\n PublicContextInputs,\n },\n key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n get_block_header::get_block_header,\n nullifier_key::get_nullifier_key_pair,\n },\n types::vec::BoundedVec,\n utils::Reader,\n};\nuse dep::protocol_types::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_data::FunctionData,\n function_selector::FunctionSelector,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n call_stack_item::PrivateCallStackItem,\n call_stack_item::PublicCallStackItem,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash},\n },\n address::{\n AztecAddress,\n EthAddress,\n },\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n },\n contrakt::{\n deployment_data::ContractDeploymentData,\n storage_read::StorageRead,\n storage_update_request::StorageUpdateRequest,\n },\n hash::hash_args,\n grumpkin_point::GrumpkinPoint,\n};\nuse dep::std::{\n grumpkin_scalar::GrumpkinScalar,\n option::Option,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_header: BlockHeader,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(SideEffect::empty()),\n\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n block_header: inputs.block_header,\n\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_block_header(self, block_number: u32) -> BlockHeader {\n get_block_header(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.block_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect {\n value: read_request,\n counter: self.side_effect_counter,\n };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter,\n };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: nullified_commitment,\n counter: self.side_effect_counter,\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinScalar {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key, key_pair.secret_key);\n // TODO: Add request to context.\n // self.context.push_nullifier_key_validation_request(public_key, secret_key);\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address,\n function_selector, \n args_hash,\n self.side_effect_counter,\n );\n let mut reader = Reader::new(fields);\n\n let item = PrivateCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1\n read_requests: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]),\n new_note_hashes: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]),\n new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialise, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]),\n private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]),\n public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]),\n new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]),\n end_side_effect_counter: reader.read() as u32,\n encrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n encrypted_log_preimages_length: reader.read(),\n unencrypted_log_preimages_length: reader.read(),\n block_header: BlockHeader{\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : reader.read(),\n nullifier_tree_root : reader.read(),\n contract_tree_root : reader.read(),\n l1_to_l2_message_tree_root : reader.read(),\n archive_root : reader.read(),\n public_data_tree_root: reader.read(),\n global_variables_hash: reader.read(),\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: GrumpkinPoint {\n x: reader.read(), \n y: reader.read()\n },\n constructor_vk_hash : reader.read(),\n function_tree_root : reader.read(),\n contract_address_salt : reader.read(),\n portal_contract_address : EthAddress::from_field(reader.read()),\n },\n chain_id: reader.read(),\n version: reader.read(),\n },\n is_execution_request: reader.read() as bool,\n };\n\n reader.finish();\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n \n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_header: BlockHeader::empty(),\n prover_address: AztecAddress::zero(),\n },\n is_execution_request: true,\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n\nstruct PublicContext {\n inputs: PublicContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_reads: BoundedVec,\n public_call_stack_hashes: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_header: BlockHeader,\n prover_address: AztecAddress,\n}\n\nimpl PublicContext {\n pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = StorageRead::empty();\n let empty_storage_update = StorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_reads: BoundedVec::new(empty_storage_read),\n public_call_stack_hashes: BoundedVec::new(0),\n\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_header: inputs.block_header,\n prover_address: AztecAddress::zero(),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_reads: self.contract_storage_reads.storage,\n return_values: self.return_values.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.inputs.block_header,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter\n };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: 0, // cannot nullify pending notes in public context\n counter: self.side_effect_counter\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/context.nr" }, "43": { @@ -3476,11 +3476,11 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr" }, "105": { - "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_COMMITMENTS_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_COMMITMENTS_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_COMMITMENTS_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_COMMITMENTS_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__COMMITMENT_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_COMMITMENT = 3;\nglobal GENERATOR_INDEX__SILOED_COMMITMENT = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", + "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_NOTE_HASHES_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__COMMITMENT_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_COMMITMENT = 3;\nglobal GENERATOR_INDEX__SILOED_COMMITMENT = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/constants.nr" }, "111": { - "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE,\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", + "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE,\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "126": { diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 0bbc6214601..7159f96c75e 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -2,7 +2,7 @@ // GENERATED FILE - DO NOT EDIT, RUN yarn remake-constants export const ARGS_LENGTH = 16; export const RETURN_VALUES_LENGTH = 4; -export const MAX_NEW_COMMITMENTS_PER_CALL = 16; +export const MAX_NEW_NOTE_HASHES_PER_CALL = 16; export const MAX_NEW_NULLIFIERS_PER_CALL = 16; export const MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL = 4; export const MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL = 4; @@ -12,8 +12,8 @@ export const MAX_PUBLIC_DATA_READS_PER_CALL = 16; export const MAX_READ_REQUESTS_PER_CALL = 32; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; export const MAX_NEW_NOTE_HASHES_PER_TX = 64; -export const MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; -export const MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; +export const MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; +export const MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; export const MAX_NEW_NULLIFIERS_PER_TX = 64; export const MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; export const MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; @@ -99,7 +99,7 @@ export const STATE_REFERENCE_LENGTH = 10; export const TX_CONTEXT_DATA_LENGTH = 11; export const TX_REQUEST_LENGTH = 17; export const GET_NOTES_ORACLE_RETURN_LENGTH = 674; -export const COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; +export const NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; diff --git a/yarn-project/circuits.js/src/hash/hash.test.ts b/yarn-project/circuits.js/src/hash/hash.test.ts index 1839ba3e475..3f56b4167e3 100644 --- a/yarn-project/circuits.js/src/hash/hash.test.ts +++ b/yarn-project/circuits.js/src/hash/hash.test.ts @@ -14,7 +14,7 @@ import { computeVarArgsHash, hashConstructor, hashVK, - siloCommitment, + siloNoteHash, siloNullifier, } from './hash.js'; @@ -55,7 +55,7 @@ describe('hash', () => { it('computes siloed commitment', () => { const contractAddress = new AztecAddress(new Fr(123n).toBuffer()); const uniqueCommitment = new Fr(456); - const res = siloCommitment(contractAddress, uniqueCommitment); + const res = siloNoteHash(contractAddress, uniqueCommitment); expect(res).toMatchSnapshot(); }); diff --git a/yarn-project/circuits.js/src/hash/hash.ts b/yarn-project/circuits.js/src/hash/hash.ts index c9407b2b1e9..a723547c489 100644 --- a/yarn-project/circuits.js/src/hash/hash.ts +++ b/yarn-project/circuits.js/src/hash/hash.ts @@ -125,7 +125,7 @@ export function computeCommitmentNonce(nullifierZero: Fr, commitmentIndex: numbe * @param innerCommitment - The commitment to silo. * @returns A siloed commitment. */ -export function siloCommitment(contract: AztecAddress, innerCommitment: Fr): Fr { +export function siloNoteHash(contract: AztecAddress, innerCommitment: Fr): Fr { return pedersenHash([contract.toBuffer(), innerCommitment.toBuffer()], GeneratorIndex.SILOED_COMMITMENT); } diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 2e1b49e29ba..6c2f24f1107 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -4,12 +4,12 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -20,7 +20,7 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -163,7 +163,7 @@ export class CombinedAccumulatedData { /** * The new commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -216,7 +216,7 @@ export class CombinedAccumulatedData { return serializeToBuffer( this.readRequests, this.nullifierKeyValidationRequests, - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -298,8 +298,8 @@ export class CombinedAccumulatedData { nonRevertible: PublicAccumulatedNonRevertibleData, revertible: PublicAccumulatedRevertibleData, ): CombinedAccumulatedData { - const newCommitments = padArrayEnd( - [...nonRevertible.newCommitments, ...revertible.newCommitments].filter(x => !x.isEmpty()), + const newNoteHashes = padArrayEnd( + [...nonRevertible.newNoteHashes, ...revertible.newNoteHashes].filter(x => !x.isEmpty()), SideEffect.empty(), MAX_NEW_NOTE_HASHES_PER_TX, ); @@ -331,7 +331,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( revertible.readRequests, revertible.nullifierKeyValidationRequests, - newCommitments, + newNoteHashes, newNullifiers, revertible.privateCallStack, publicCallStack, @@ -363,7 +363,7 @@ export class PublicAccumulatedRevertibleData { /** * The new commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -419,7 +419,7 @@ export class PublicAccumulatedRevertibleData { return serializeToBuffer( this.readRequests, this.nullifierKeyValidationRequests, - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -448,7 +448,7 @@ export class PublicAccumulatedRevertibleData { return new this( reader.readArray(MAX_READ_REQUESTS_PER_TX, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext), - reader.readArray(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -467,7 +467,7 @@ export class PublicAccumulatedRevertibleData { return new this( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - padArrayEnd(finalData.newCommitments, SideEffect.empty(), MAX_REVERTIBLE_COMMITMENTS_PER_TX), + padArrayEnd(finalData.newNoteHashes, SideEffect.empty(), MAX_REVERTIBLE_NOTE_HASHES_PER_TX), padArrayEnd(finalData.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_REVERTIBLE_NULLIFIERS_PER_TX), finalData.privateCallStack, padArrayEnd(finalData.publicCallStack, CallRequest.empty(), MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX), @@ -495,7 +495,7 @@ export class PublicAccumulatedRevertibleData { return new this( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -520,7 +520,7 @@ export class PrivateAccumulatedRevertibleData { /** * The new commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -564,7 +564,7 @@ export class PrivateAccumulatedRevertibleData { toBuffer() { return serializeToBuffer( - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -589,7 +589,7 @@ export class PrivateAccumulatedRevertibleData { static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedRevertibleData { const reader = BufferReader.asReader(buffer); return new PrivateAccumulatedRevertibleData( - reader.readArray(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -613,7 +613,7 @@ export class PrivateAccumulatedRevertibleData { static empty() { return new PrivateAccumulatedRevertibleData( - makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -632,7 +632,7 @@ export class PrivateAccumulatedNonRevertibleData { /** * The new non-revertible commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new non-revertible nullifiers made in this transaction. */ @@ -644,13 +644,13 @@ export class PrivateAccumulatedNonRevertibleData { ) {} toBuffer() { - return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); + return serializeToBuffer(this.newNoteHashes, this.newNullifiers, this.publicCallStack); } static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedNonRevertibleData { const reader = BufferReader.asReader(buffer); return new PrivateAccumulatedNonRevertibleData( - reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), ); @@ -666,7 +666,7 @@ export class PrivateAccumulatedNonRevertibleData { static empty() { return new PrivateAccumulatedNonRevertibleData( - makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), ); @@ -678,7 +678,7 @@ export class PublicAccumulatedNonRevertibleData { /** * The new non-revertible commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new non-revertible nullifiers made in this transaction. */ @@ -701,13 +701,13 @@ export class PublicAccumulatedNonRevertibleData { ) {} toBuffer() { - return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); + return serializeToBuffer(this.newNoteHashes, this.newNullifiers, this.publicCallStack); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new this( - reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), @@ -725,7 +725,7 @@ export class PublicAccumulatedNonRevertibleData { static empty() { return new this( - makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), @@ -735,7 +735,7 @@ export class PublicAccumulatedNonRevertibleData { static fromPrivateAccumulatedNonRevertibleData(data: PrivateAccumulatedNonRevertibleData) { return new this( - data.newCommitments, + data.newNoteHashes, data.newNullifiers, data.publicCallStack, makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index e7de614fa31..43e3b4dfa39 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -23,11 +23,11 @@ export class PrivateKernelTailCircuitPrivateInputs { /** * The sorted new commitments. */ - public sortedNewCommitments: Tuple, + public sortedNewNoteHashes: Tuple, /** * The sorted new commitments indexes. Maps original to sorted. */ - public sortedNewCommitmentsIndexes: Tuple, + public sortedNewNoteHashesIndexes: Tuple, /** * Contains hints for the transient read requests to localize corresponding commitments. */ @@ -57,8 +57,8 @@ export class PrivateKernelTailCircuitPrivateInputs { toBuffer() { return serializeToBuffer( this.previousKernel, - this.sortedNewCommitments, - this.sortedNewCommitmentsIndexes, + this.sortedNewNoteHashes, + this.sortedNewNoteHashesIndexes, this.readCommitmentHints, this.sortedNewNullifiers, this.sortedNewNullifiersIndexes, diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index cdf55d91df2..5976faac386 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -7,8 +7,8 @@ import { FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, @@ -61,7 +61,7 @@ export class PrivateCircuitPublicInputs { /** * New commitments created by the corresponding function call. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * New nullifiers created by the corresponding function call. */ @@ -147,7 +147,7 @@ export class PrivateCircuitPublicInputs { reader.readObject(Fr), reader.readArray(MAX_READ_REQUESTS_PER_CALL, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr), @@ -173,7 +173,7 @@ export class PrivateCircuitPublicInputs { reader.readField(), reader.readArray(MAX_READ_REQUESTS_PER_CALL, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readFieldArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL), reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL), @@ -202,7 +202,7 @@ export class PrivateCircuitPublicInputs { Fr.ZERO, makeTuple(MAX_READ_REQUESTS_PER_CALL, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest.empty), - makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr.zero), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr.zero), @@ -231,7 +231,7 @@ export class PrivateCircuitPublicInputs { this.minRevertibleSideEffectCounter.isZero() && isEmptyArray(this.readRequests) && isEmptyArray(this.nullifierKeyValidationRequests) && - isEmptyArray(this.newCommitments) && + isEmptyArray(this.newNoteHashes) && isEmptyArray(this.newNullifiers) && isZeroArray(this.privateCallStackHashes) && isZeroArray(this.publicCallStackHashes) && @@ -260,7 +260,7 @@ export class PrivateCircuitPublicInputs { fields.minRevertibleSideEffectCounter, fields.readRequests, fields.nullifierKeyValidationRequests, - fields.newCommitments, + fields.newNoteHashes, fields.newNullifiers, fields.privateCallStackHashes, fields.publicCallStackHashes, diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts index dace12f6fe7..c615bc6f77d 100644 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts +++ b/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts @@ -24,7 +24,7 @@ describe('PublicCallStackItem', () => { callStack.contractAddress = AztecAddress.fromField(new Fr(1)); callStack.functionData = new FunctionData(new FunctionSelector(2), false, false, false); callStack.isExecutionRequest = true; - callStack.publicInputs.newCommitments[0] = new SideEffect(new Fr(1), new Fr(0)); + callStack.publicInputs.newNoteHashes[0] = new SideEffect(new Fr(1), new Fr(0)); const hash = callStack.hash(); expect(hash.toString()).toMatchSnapshot(); @@ -38,7 +38,7 @@ describe('PublicCallStackItem', () => { callStack.contractAddress = AztecAddress.fromField(new Fr(1)); callStack.functionData = new FunctionData(new FunctionSelector(2), false, false, false); - callStack.publicInputs.newCommitments[0] = new SideEffect(new Fr(1), new Fr(0)); + callStack.publicInputs.newNoteHashes[0] = new SideEffect(new Fr(1), new Fr(0)); const hash = callStack.hash(); expect(hash.toString()).toMatchSnapshot(); diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index 4bf4d0140f6..b0412432048 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -8,8 +8,8 @@ import { FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, @@ -58,9 +58,9 @@ export class PublicCircuitPublicInputs { */ public publicCallStackHashes: Tuple, /** - * New commitments created within a public execution call + * New note hashes created within a public execution call */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * New nullifiers created within a public execution call */ @@ -110,7 +110,7 @@ export class PublicCircuitPublicInputs { makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest.empty), makeTuple(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr.zero), - makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message.empty), makeTuple(2, Fr.zero), @@ -132,7 +132,7 @@ export class PublicCircuitPublicInputs { isArrayEmpty(this.contractStorageUpdateRequests, item => item.isEmpty()) && isArrayEmpty(this.contractStorageReads, item => item.isEmpty()) && isFrArrayEmpty(this.publicCallStackHashes) && - isSideEffectArrayEmpty(this.newCommitments) && + isSideEffectArrayEmpty(this.newNoteHashes) && isSideEffectLinkedArrayEmpty(this.newNullifiers) && isArrayEmpty(this.newL2ToL1Msgs, item => item.isEmpty()) && isFrArrayEmpty(this.unencryptedLogsHash) && @@ -155,7 +155,7 @@ export class PublicCircuitPublicInputs { fields.contractStorageUpdateRequests, fields.contractStorageReads, fields.publicCallStackHashes, - fields.newCommitments, + fields.newNoteHashes, fields.newNullifiers, fields.newL2ToL1Msgs, fields.unencryptedLogsHash, @@ -197,7 +197,7 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest), reader.readArray(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readArray(NUM_FIELDS_PER_SHA256, Fr), @@ -217,7 +217,7 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest), reader.readArray(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead), reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readFieldArray(NUM_FIELDS_PER_SHA256), diff --git a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts index 008fc02ace0..ccad2b68bb2 100644 --- a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts +++ b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts @@ -3,7 +3,7 @@ import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { MAX_NEW_COMMITMENTS_PER_CALL, NOTE_HASH_TREE_HEIGHT } from '../constants.gen.js'; +import { MAX_NEW_NOTE_HASHES_PER_CALL, NOTE_HASH_TREE_HEIGHT } from '../constants.gen.js'; import { MembershipWitness } from './membership_witness.js'; /** @@ -32,9 +32,9 @@ export class ReadRequestMembershipWitness { */ public hintToCommitment: Fr, ) { - if (hintToCommitment.toBigInt() > MAX_NEW_COMMITMENTS_PER_CALL) { + if (hintToCommitment.toBigInt() > MAX_NEW_NOTE_HASHES_PER_CALL) { throw new Error( - `Expected ReadRequestMembershipWitness' hintToCommitment(${hintToCommitment}) to be <= NEW_COMMITMENTS_LENGTH(${MAX_NEW_COMMITMENTS_PER_CALL})`, + `Expected ReadRequestMembershipWitness' hintToCommitment(${hintToCommitment}) to be <= NEW_COMMITMENTS_LENGTH(${MAX_NEW_NOTE_HASHES_PER_CALL})`, ); } } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 9b0cece6c48..edb18d5a2f5 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -34,14 +34,14 @@ import { GrumpkinScalar, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -58,7 +58,7 @@ import { MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -292,7 +292,7 @@ export function makeCombinedAccumulatedRevertibleData(seed = 1, full = false): P makeNullifierKeyValidationRequestContext, seed + 0x100, ), - tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x120), + tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), @@ -316,7 +316,7 @@ export function makeFinalAccumulatedData(seed = 1, full = false): PrivateAccumul const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PrivateAccumulatedRevertibleData( - tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x100), + tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x100), tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), @@ -338,7 +338,7 @@ export function makeAccumulatedNonRevertibleData(seed = 1, full = false): Privat const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PrivateAccumulatedNonRevertibleData( - tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x101), + tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), ); @@ -348,7 +348,7 @@ export function makeCombinedAccumulatedNonRevertibleData(seed = 1, full = false) const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PublicAccumulatedNonRevertibleData( - tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x101), + tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0x601), @@ -418,7 +418,7 @@ export function makePublicCircuitPublicInputs( tupleGenerator(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, makeContractStorageUpdateRequest, seed + 0x400), tupleGenerator(MAX_PUBLIC_DATA_READS_PER_CALL, makeContractStorageRead, seed + 0x500), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), - tupleGenerator(MAX_NEW_COMMITMENTS_PER_CALL, makeNewSideEffect, seed + 0x700), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_CALL, makeNewSideEffect, seed + 0x700), tupleGenerator(MAX_NEW_NULLIFIERS_PER_CALL, makeNewSideEffectLinkedToNoteHash, seed + 0x800), tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x900), tupleGenerator(2, fr, seed + 0x901), @@ -821,7 +821,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn makeNullifierKeyValidationRequest, seed + 0x300, ), - newCommitments: makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, sideEffectFromNumber, seed + 0x400), + newNoteHashes: makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, sideEffectFromNumber, seed + 0x400), newNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, sideEffectLinkedFromNumber, seed + 0x500), privateCallStackHashes: makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), publicCallStackHashes: makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x700), diff --git a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts index 0fe30e0b8af..f1baba3cc46 100644 --- a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts @@ -54,7 +54,7 @@ describe('e2e_inclusion_proofs_contract', () => { describe('proves note existence and its nullifier non-existence and nullifier non-existence failure case', () => { // Owner of a note let noteCreationBlockNumber: number; - let newCommitments, visibleNotes: any; + let newNoteHashes, visibleNotes: any; const value = 100n; let validNoteBlockNumber: any; @@ -63,11 +63,11 @@ describe('e2e_inclusion_proofs_contract', () => { const receipt = await contract.methods.create_note(owner, value).send().wait({ debug: true }); noteCreationBlockNumber = receipt.blockNumber!; - ({ newCommitments, visibleNotes } = receipt.debugInfo!); + ({ newNoteHashes, visibleNotes } = receipt.debugInfo!); }); it('should return the correct values for creating a note', () => { - expect(newCommitments.length).toBe(1); + expect(newNoteHashes.length).toBe(1); expect(visibleNotes.length).toBe(1); const [receivedValue, receivedOwner, _randomness] = visibleNotes[0].note.items; expect(receivedValue.toBigInt()).toBe(value); @@ -158,9 +158,9 @@ describe('e2e_inclusion_proofs_contract', () => { const receipt = await contract.methods.create_note(owner, value).send().wait({ debug: true }); noteCreationBlockNumber = receipt.blockNumber!; - const { newCommitments, visibleNotes } = receipt.debugInfo!; + const { newNoteHashes, visibleNotes } = receipt.debugInfo!; - expect(newCommitments.length).toBe(1); + expect(newNoteHashes.length).toBe(1); expect(visibleNotes.length).toBe(1); const [receivedValue, receivedOwner, _randomness] = visibleNotes[0].note.items; expect(receivedValue.toBigInt()).toBe(value); diff --git a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts index 40ea8166bf9..597fe7e944e 100644 --- a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts +++ b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts @@ -77,7 +77,7 @@ describe('e2e_non_contract_account', () => { // check that 1 commitment was created const tx = await pxe.getTx(receipt.txHash); - const nonZeroCommitments = tx?.newCommitments.filter(c => c.value > 0); + const nonZeroCommitments = tx?.newNoteHashes.filter(c => c.value > 0); expect(nonZeroCommitments?.length).toBe(1); // Add the note diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 8b545859d32..ef720e7ca05 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -49,7 +49,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(tx?.newNullifiers.length).toEqual(2); expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); @@ -75,7 +75,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -99,7 +99,7 @@ describe('e2e_state_vars', () => { .wait(); expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -114,7 +114,7 @@ describe('e2e_state_vars', () => { const receipt = await contract.methods.increase_legendary_points().send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -136,7 +136,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(tx?.newNullifiers.length).toEqual(2); expect(await contract.methods.is_imm_initialized().view()).toEqual(true); diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index c363a71278f..49fe9f2705a 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -14,7 +14,7 @@ import { Header, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, @@ -179,7 +179,7 @@ describe('L1Publisher integration', () => { const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, makeNewSideEffect, seed + 0x100); + processedTx.data.end.newNoteHashes = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100); processedTx.data.end.newNullifiers = makeTuple( MAX_REVERTIBLE_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap index 1bbae4a36d1..84296c76d5e 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap @@ -1055,7 +1055,7 @@ PrivateKernelInnerCircuitPublicInputs { }, }, ], - "newCommitments": [ + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 0n, @@ -35914,7 +35914,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, ], - "newCommitments": [ + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 3n, @@ -50835,7 +50835,7 @@ PrivateKernelTailCircuitPublicInputs { ], }, "endNonRevertibleData": PrivateAccumulatedNonRevertibleData { - "newCommitments": [ + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 0n, diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index ddb5a411dfa..a75e80d7212 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -25,11 +25,11 @@ import { GrumpkinScalar, Header, L2ToL1Message, - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -40,7 +40,7 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -663,7 +663,7 @@ export function mapPrivateCircuitPublicInputsToNoir( privateCircuitPublicInputs.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestToNoir, ), - new_commitments: mapTuple(privateCircuitPublicInputs.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(privateCircuitPublicInputs.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(privateCircuitPublicInputs.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack_hashes: mapTuple(privateCircuitPublicInputs.privateCallStackHashes, mapFieldToNoir), public_call_stack_hashes: mapTuple(privateCircuitPublicInputs.publicCallStackHashes, mapFieldToNoir), @@ -879,7 +879,7 @@ export function mapCombinedAccumulatedDataFromNoir( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, mapNullifierKeyValidationRequestContextFromNoir, ), - mapTupleFromNoir(combinedAccumulatedData.new_commitments, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(combinedAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(combinedAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir( combinedAccumulatedData.private_call_stack, @@ -919,7 +919,7 @@ export function mapFinalAccumulatedDataFromNoir( finalAccumulatedData: PrivateAccumulatedRevertibleDataNoir, ): PrivateAccumulatedRevertibleData { return new PrivateAccumulatedRevertibleData( - mapTupleFromNoir(finalAccumulatedData.new_commitments, MAX_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(finalAccumulatedData.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir( finalAccumulatedData.new_nullifiers, MAX_REVERTIBLE_NULLIFIERS_PER_TX, @@ -953,7 +953,7 @@ export function mapAccumulatedNonRevertibleDataFromNoir( accumulatedMetaData: PrivateAccumulatedNonRevertibleDataNoir, ): PrivateAccumulatedNonRevertibleData { return new PrivateAccumulatedNonRevertibleData( - mapTupleFromNoir(accumulatedMetaData.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(accumulatedMetaData.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir( accumulatedMetaData.new_nullifiers, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, @@ -976,7 +976,7 @@ export function mapAccumulatedNonRevertibleDataToNoir( accumulatedMetaData: PrivateAccumulatedNonRevertibleData, ): PrivateAccumulatedNonRevertibleDataNoir { return { - new_commitments: mapTuple(accumulatedMetaData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(accumulatedMetaData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(accumulatedMetaData.newNullifiers, mapSideEffectLinkedToNoir), public_call_stack: mapTuple(accumulatedMetaData.publicCallStack, mapCallRequestToNoir), }; @@ -986,7 +986,7 @@ export function mapPrivateAccumulatedRevertibleDataToNoir( data: PrivateAccumulatedRevertibleData, ): PrivateAccumulatedRevertibleDataNoir { return { - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), @@ -1013,7 +1013,7 @@ export function mapCombinedAccumulatedDataToNoir( combinedAccumulatedData.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestContextToNoir, ), - new_commitments: mapTuple(combinedAccumulatedData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(combinedAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(combinedAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(combinedAccumulatedData.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(combinedAccumulatedData.publicCallStack, mapCallRequestToNoir), @@ -1092,7 +1092,7 @@ export function mapPublicAccumulatedRevertibleDataToNoir( data.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestContextToNoir, ), - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), @@ -1111,7 +1111,7 @@ export function mapPublicAccumulatedNonRevertibleDataToNoir( data: PublicAccumulatedNonRevertibleData, ): PublicAccumulatedNonRevertibleDataNoir { return { - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), public_data_reads: mapTuple(data.publicDataReads, mapPublicDataReadToNoir), @@ -1184,7 +1184,7 @@ export function mapFinalAccumulatedDataToNoir( finalAccumulatedData: PrivateAccumulatedRevertibleData, ): PrivateAccumulatedRevertibleDataNoir { return { - new_commitments: mapTuple(finalAccumulatedData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(finalAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(finalAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(finalAccumulatedData.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(finalAccumulatedData.publicCallStack, mapCallRequestToNoir), @@ -1249,8 +1249,8 @@ export function mapPrivateKernelTailCircuitPrivateInputsToNoir( ): PrivateKernelTailCircuitPrivateInputsNoir { return { previous_kernel: mapPrivateKernelInnerDataToNoir(inputs.previousKernel), - sorted_new_commitments: mapTuple(inputs.sortedNewCommitments, mapSideEffectToNoir), - sorted_new_commitments_indexes: mapTuple(inputs.sortedNewCommitmentsIndexes, mapNumberToNoir), + sorted_new_note_hashes: mapTuple(inputs.sortedNewNoteHashes, mapSideEffectToNoir), + sorted_new_note_hashes_indexes: mapTuple(inputs.sortedNewNoteHashesIndexes, mapNumberToNoir), read_commitment_hints: mapTuple(inputs.readCommitmentHints, mapFieldToNoir), sorted_new_nullifiers: mapTuple(inputs.sortedNewNullifiers, mapSideEffectLinkedToNoir), sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), @@ -1286,7 +1286,7 @@ export function mapPublicAccumulatedNonRevertibleDataFromNoir( data: PublicAccumulatedNonRevertibleDataNoir, ): PublicAccumulatedNonRevertibleData { return new PublicAccumulatedNonRevertibleData( - mapTupleFromNoir(data.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(data.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(data.new_nullifiers, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir( data.public_call_stack, @@ -1312,7 +1312,7 @@ export function mapPublicAccumulatedRevertibleDataFromNoir( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, mapNullifierKeyValidationRequestContextFromNoir, ), - mapTupleFromNoir(data.new_commitments, MAX_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(data.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(data.new_nullifiers, MAX_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir(data.private_call_stack, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), mapTupleFromNoir(data.public_call_stack, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), @@ -1421,7 +1421,7 @@ export function mapPublicCircuitPublicInputsToNoir( ), contract_storage_reads: mapTuple(publicInputs.contractStorageReads, mapStorageReadToNoir), public_call_stack_hashes: mapTuple(publicInputs.publicCallStackHashes, mapFieldToNoir), - new_commitments: mapTuple(publicInputs.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(publicInputs.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(publicInputs.newNullifiers, mapSideEffectLinkedToNoir), new_l2_to_l1_msgs: mapTuple(publicInputs.newL2ToL1Msgs, mapL2ToL1MessageToNoir), unencrypted_logs_hash: mapTuple(publicInputs.unencryptedLogsHash, mapFieldToNoir), diff --git a/yarn-project/pxe/src/database/deferred_note_dao.test.ts b/yarn-project/pxe/src/database/deferred_note_dao.test.ts index 457da7d81a4..757aad9100d 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.test.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.test.ts @@ -10,7 +10,7 @@ export const randomDeferredNoteDao = ({ txHash = randomTxHash(), storageSlot = Fr.random(), noteTypeId = Fr.random(), - newCommitments = [Fr.random(), Fr.random()], + newNoteHashes = [Fr.random(), Fr.random()], dataStartIndexForTx = Math.floor(Math.random() * 100), }: Partial = {}) => { return new DeferredNoteDao( @@ -20,7 +20,7 @@ export const randomDeferredNoteDao = ({ storageSlot, noteTypeId, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, ); }; diff --git a/yarn-project/pxe/src/database/deferred_note_dao.ts b/yarn-project/pxe/src/database/deferred_note_dao.ts index 97f6a41bd21..f48d88d84d9 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.ts @@ -22,7 +22,7 @@ export class DeferredNoteDao { /** The hash of the tx the note was created in. Equal to the first nullifier */ public txHash: TxHash, /** New commitments in this transaction, one of which belongs to this note */ - public newCommitments: Fr[], + public newNoteHashes: Fr[], /** The next available leaf index for the note hash tree for this transaction */ public dataStartIndexForTx: number, ) {} @@ -35,7 +35,7 @@ export class DeferredNoteDao { this.storageSlot.toBuffer(), this.noteTypeId.toBuffer(), this.txHash.toBuffer(), - new Vector(this.newCommitments), + new Vector(this.newNoteHashes), this.dataStartIndexForTx, ); } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index 935080c6e35..fd3049681f3 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -2,10 +2,10 @@ import { FunctionL2Logs, Note } from '@aztec/circuit-types'; import { FunctionData, FunctionSelector, - MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX, MAX_READ_REQUESTS_PER_CALL, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MembershipWitness, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -52,8 +52,8 @@ describe('Kernel Prover', () => { const createExecutionResult = (fnName: string, newNoteIndices: number[] = []): ExecutionResult => { const publicInputs = PrivateCircuitPublicInputs.empty(); - publicInputs.newCommitments = makeTuple( - MAX_NEW_COMMITMENTS_PER_CALL, + publicInputs.newNoteHashes = makeTuple( + MAX_NEW_NOTE_HASHES_PER_CALL, i => i < newNoteIndices.length ? new SideEffect(generateFakeCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO) @@ -88,7 +88,7 @@ describe('Kernel Prover', () => { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } - publicInputs.end.newCommitments = commitments; + publicInputs.end.newNoteHashes = commitments; return { publicInputs, proof: makeEmptyProof(), @@ -97,12 +97,12 @@ describe('Kernel Prover', () => { const createProofOutputFinal = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelTailCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } - publicInputs.end.newCommitments = commitments; + publicInputs.end.newNoteHashes = commitments; return { publicInputs, proof: makeEmptyProof(), @@ -153,7 +153,7 @@ describe('Kernel Prover', () => { proofCreator = mock(); proofCreator.getSiloedCommitments.mockImplementation(publicInputs => - Promise.resolve(publicInputs.newCommitments.map(com => createFakeSiloedCommitment(com.value))), + Promise.resolve(publicInputs.newNoteHashes.map(com => createFakeSiloedCommitment(com.value))), ); proofCreator.createProofInit.mockResolvedValue(createProofOutput([])); proofCreator.createProofInner.mockResolvedValue(createProofOutput([])); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 5b6a9a6ee85..85e96b9fe7f 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -178,7 +178,7 @@ export class KernelProver { const [sortedCommitments, sortedCommitmentsIndexes] = this.sortSideEffects< SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX - >(output.publicInputs.end.newCommitments); + >(output.publicInputs.end.newNoteHashes); const [sortedNullifiers, sortedNullifiersIndexes] = this.sortSideEffects< SideEffectLinkedToNoteHash, @@ -214,7 +214,7 @@ export class KernelProver { const outputFinal = await this.proofCreator.createProofTail(privateInputs); // Only return the notes whose commitment is in the commitments of the final proof. - const finalNewCommitments = outputFinal.publicInputs.end.newCommitments; + const finalNewCommitments = outputFinal.publicInputs.end.newNoteHashes; const outputNotes = finalNewCommitments.map(c => newNotes[c.value.toString()]).filter(c => !!c); return { ...outputFinal, outputNotes }; @@ -308,11 +308,11 @@ export class KernelProver { } = executionResult; const contractAddress = publicInputs.callContext.storageContractAddress; // Assuming that for each new commitment there's an output note added to the execution result. - const newCommitments = await this.proofCreator.getSiloedCommitments(publicInputs); + const newNoteHashes = await this.proofCreator.getSiloedCommitments(publicInputs); return newNotes.map((data, i) => ({ contractAddress, data, - commitment: newCommitments[i], + commitment: newNoteHashes[i], })); } diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index bd53ce0e56e..b2e30de0e22 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -9,7 +9,7 @@ import { Proof, makeEmptyProof, } from '@aztec/circuits.js'; -import { siloCommitment } from '@aztec/circuits.js/hash'; +import { siloNoteHash } from '@aztec/circuits.js/hash'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; @@ -97,7 +97,7 @@ export class KernelProofCreator implements ProofCreator { const contractAddress = publicInputs.callContext.storageContractAddress; return Promise.resolve( - publicInputs.newCommitments.map(commitment => siloCommitment(contractAddress, commitment.value)), + publicInputs.newNoteHashes.map(commitment => siloNoteHash(contractAddress, commitment.value)), ); } diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts index 87c08b286a9..73ea1f08a27 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -15,6 +15,7 @@ import { Fr, MAX_NEW_NOTE_HASHES_PER_TX } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { pedersenHash } from '@aztec/foundation/crypto'; import { Point } from '@aztec/foundation/fields'; +import { Tuple } from '@aztec/foundation/serialize'; import { ConstantKeyPair } from '@aztec/key-store'; import { openTmpStore } from '@aztec/kv-store/utils'; import { AcirSimulator } from '@aztec/simulator'; @@ -26,7 +27,6 @@ import { PxeDatabase } from '../database/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; import { NoteDao } from '../database/note_dao.js'; import { NoteProcessor } from './note_processor.js'; -import { Tuple } from '@aztec/foundation/serialize'; const TXS_PER_BLOCK = 4; @@ -109,7 +109,10 @@ describe('Note Processor', () => { for (let i = 0; i < TXS_PER_BLOCK; i++) { block.body.txEffects[i].newNoteHashes = newNotes .map(n => computeMockNoteHash(n.note)) - .slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple; + .slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >; } const randomBlockContext = new L2BlockContext(block); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index b64e60cbfc2..b5f349278f1 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -124,7 +124,7 @@ export class NoteProcessor { this.stats.txs++; const dataStartIndexForTx = dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_NOTE_HASHES_PER_TX; - const newCommitments = block.body.txEffects[indexOfTxInABlock].newNoteHashes; + const newNoteHashes = block.body.txEffects[indexOfTxInABlock].newNoteHashes; // Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding // to the index of a tx in a block. const txFunctionLogs = txLogs[indexOfTxInABlock].functionLogs; @@ -142,7 +142,7 @@ export class NoteProcessor { this.publicKey, payload, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, excludedIndices, ); @@ -159,7 +159,7 @@ export class NoteProcessor { payload.storageSlot, payload.noteTypeId, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, ); deferredNoteDaos.push(deferredNoteDao); @@ -254,7 +254,7 @@ export class NoteProcessor { const excludedIndices: Set = new Set(); const noteDaos: NoteDao[] = []; for (const deferredNote of deferredNoteDaos) { - const { note, contractAddress, storageSlot, noteTypeId, txHash, newCommitments, dataStartIndexForTx } = + const { note, contractAddress, storageSlot, noteTypeId, txHash, newNoteHashes, dataStartIndexForTx } = deferredNote; const payload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId); @@ -264,7 +264,7 @@ export class NoteProcessor { this.publicKey, payload, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, excludedIndices, ); diff --git a/yarn-project/pxe/src/note_processor/produce_note_dao.ts b/yarn-project/pxe/src/note_processor/produce_note_dao.ts index 23823c7d5fe..2a0a6d99be2 100644 --- a/yarn-project/pxe/src/note_processor/produce_note_dao.ts +++ b/yarn-project/pxe/src/note_processor/produce_note_dao.ts @@ -14,7 +14,7 @@ import { NoteDao } from '../database/note_dao.js'; * @param publicKey - The public counterpart to the private key to be used in note decryption. * @param payload - An instance of l1NotePayload. * @param txHash - The hash of the transaction that created the note. Equivalent to the first nullifier of the transaction. - * @param newCommitments - New commitments in this transaction, one of which belongs to this note. + * @param newNoteHashes - New commitments in this transaction, one of which belongs to this note. * @param dataStartIndexForTx - The next available leaf index for the note hash tree for this transaction. * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same l1NotePayload, we need to find a different index for each replicate. * @param simulator - An instance of AcirSimulator. @@ -25,13 +25,13 @@ export async function produceNoteDao( publicKey: PublicKey, payload: L1NotePayload, txHash: TxHash, - newCommitments: Fr[], + newNoteHashes: Fr[], dataStartIndexForTx: number, excludedIndices: Set, ): Promise { const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier( simulator, - newCommitments, + newNoteHashes, txHash, payload, excludedIndices, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 926c989f68b..34619026f70 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -338,10 +338,10 @@ export class PXEService implements PXE { const nonces: Fr[] = []; const firstNullifier = tx.newNullifiers[0]; - const commitments = tx.newCommitments; - for (let i = 0; i < commitments.length; ++i) { - const commitment = commitments[i]; - if (commitment.equals(Fr.ZERO)) { + const hashes = tx.newNoteHashes; + for (let i = 0; i < hashes.length; ++i) { + const hash = hashes[i]; + if (hash.equals(Fr.ZERO)) { break; } @@ -355,11 +355,11 @@ export class PXEService implements PXE { ); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Remove this once notes added from public also include nonces. - if (commitment.equals(siloedNoteHash)) { + if (hash.equals(siloedNoteHash)) { nonces.push(Fr.ZERO); break; } - if (commitment.equals(uniqueSiloedNoteHash)) { + if (hash.equals(uniqueSiloedNoteHash)) { nonces.push(nonce); } } diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index d490a08ab71..3565613b9b4 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -23,12 +23,12 @@ import { MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, @@ -42,7 +42,7 @@ import { RootRollupPublicInputs, SideEffect, SideEffectLinkedToNoteHash, - StateReference + StateReference, } from '@aztec/circuits.js'; import { fr, @@ -63,7 +63,7 @@ import { openTmpStore } from '@aztec/kv-store/utils'; import { MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; import { MockProxy, mock } from 'jest-mock-extended'; -import { default as memdown, type MemDown } from 'memdown'; +import { type MemDown, default as memdown } from 'memdown'; import { VerificationKeys, getVerificationKeys } from '../mocks/verification_keys.js'; import { EmptyRollupProver } from '../prover/empty.js'; @@ -144,7 +144,7 @@ describe('sequencer/solo_block_builder', () => { [ MerkleTreeId.NOTE_HASH_TREE, txs.flatMap(tx => - [...tx.data.endNonRevertibleData.newCommitments, ...tx.data.end.newCommitments].map(l => l.value.toBuffer()), + [...tx.data.endNonRevertibleData.newNoteHashes, ...tx.data.end.newNoteHashes].map(l => l.value.toBuffer()), ), ], [MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer())], @@ -234,12 +234,23 @@ describe('sequencer/solo_block_builder', () => { const txEffects: TxEffect[] = txs.map( tx => new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value) as Tuple, - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple, + tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple, + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple< + PublicDataWrite, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + >, tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)) as Tuple, + tx.data.combinedData.newContracts.map( + cd => new ContractData(cd.contractAddress, cd.portalContractAddress), + ) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), @@ -320,13 +331,13 @@ describe('sequencer/solo_block_builder', () => { const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple( - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + processedTx.data.end.newNoteHashes = makeTuple( + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100, ); - processedTx.data.endNonRevertibleData.newCommitments = makeTuple( - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + processedTx.data.endNonRevertibleData.newNoteHashes = makeTuple( + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100, ); diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index 17f86272f4a..c9dd5ab95bf 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -105,14 +105,25 @@ export class SoloBlockBuilder implements BlockBuilder { // Collect all new nullifiers, commitments, and contracts from all txs in this block const txEffects: TxEffect[] = txs.map( tx => - // TODO(benesjan): Combined data should most likely contain the tx effect directly + // TODO(benesjan): Combined data should most likely contain the tx effect directly new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value) as Tuple, - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple, + tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple, + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple< + PublicDataWrite, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + >, tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)) as Tuple, + tx.data.combinedData.newContracts.map( + cd => new ContractData(cd.contractAddress, cd.portalContractAddress), + ) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), @@ -606,14 +617,14 @@ export class SoloBlockBuilder implements BlockBuilder { // Update the contract and note hash trees with the new items being inserted to get the new roots // that will be used by the next iteration of the base rollup circuit, skipping the empty ones const newContracts = tx.data.combinedData.newContracts.map(cd => cd.hash()); - const newCommitments = tx.data.combinedData.newCommitments.map(x => x.value.toBuffer()); + const newNoteHashes = tx.data.combinedData.newNoteHashes.map(x => x.value.toBuffer()); await this.db.appendLeaves( MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer()), ); - await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newCommitments); + await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newNoteHashes); // The read witnesses for a given TX should be generated before the writes of the same TX are applied. // All reads that refer to writes in the same tx are transient and can be simplified out. diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index e3914d58263..980f5de1e8f 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -8,8 +8,8 @@ import { GlobalVariables, Header, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, @@ -310,7 +310,7 @@ export abstract class AbstractPhaseManager { callContext: result.execution.callContext, proverAddress: AztecAddress.ZERO, argsHash: computeVarArgsHash(result.execution.args), - newCommitments: padArrayEnd(result.newCommitments, SideEffect.empty(), MAX_NEW_COMMITMENTS_PER_CALL), + newNoteHashes: padArrayEnd(result.newNoteHashes, SideEffect.empty(), MAX_NEW_NOTE_HASHES_PER_CALL), newNullifiers: padArrayEnd(result.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_NEW_NULLIFIERS_PER_CALL), newL2ToL1Msgs: padArrayEnd(result.newL2ToL1Messages, L2ToL1Message.empty(), MAX_NEW_L2_TO_L1_MSGS_PER_CALL), returnValues: padArrayEnd(result.returnValues, Fr.ZERO, RETURN_VALUES_LENGTH), diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index b9855e6e4ef..284da77cecf 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -374,7 +374,7 @@ function makePublicExecutionResultFromRequest(item: PublicCallRequest): PublicEx execution: item, nestedExecutions: [], returnValues: [new Fr(1n)], - newCommitments: [], + newNoteHashes: [], newL2ToL1Messages: [], newNullifiers: [], contractStorageReads: [], @@ -399,7 +399,7 @@ function makePublicExecutionResult( execution, nestedExecutions, returnValues: [], - newCommitments: [], + newNoteHashes: [], newNullifiers: [], newL2ToL1Messages: [], contractStorageReads: [], diff --git a/yarn-project/simulator/src/avm/temporary_executor_migration.ts b/yarn-project/simulator/src/avm/temporary_executor_migration.ts index db955dfe61d..ad66c6b9885 100644 --- a/yarn-project/simulator/src/avm/temporary_executor_migration.ts +++ b/yarn-project/simulator/src/avm/temporary_executor_migration.ts @@ -60,7 +60,7 @@ export function temporaryConvertAvmResults( newWorldState: JournalData, result: AvmContractCallResults, ): PublicExecutionResult { - const newCommitments = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); + const newNoteHashes = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); const contractStorageReads: ContractStorageRead[] = []; const reduceStorageReadRequests = (contractAddress: bigint, storageReads: Map) => { @@ -97,7 +97,7 @@ export function temporaryConvertAvmResults( return { execution, - newCommitments, + newNoteHashes, newL2ToL1Messages, newNullifiers, contractStorageReads, diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index 3759622933f..d62b92aba68 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -19,7 +19,7 @@ import { TxContext, } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; -import { computePublicDataTreeLeafSlot, computeUniqueCommitment, siloCommitment } from '@aztec/circuits.js/hash'; +import { computePublicDataTreeLeafSlot, computeUniqueCommitment, siloNoteHash } from '@aztec/circuits.js/hash'; import { FunctionAbi, FunctionArtifact, countArgumentsSize } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; @@ -232,7 +232,7 @@ export class ClientExecutionContext extends ViewDataOracle { notes.forEach(n => { if (n.index !== undefined) { - const siloedNoteHash = siloCommitment(n.contractAddress, n.innerNoteHash); + const siloedNoteHash = siloNoteHash(n.contractAddress, n.innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(n.nonce, siloedNoteHash); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Should always be uniqueSiloedNoteHash when publicly created notes include nonces. @@ -309,7 +309,7 @@ export class ClientExecutionContext extends ViewDataOracle { #checkValidStaticCall(childExecutionResult: ExecutionResult) { if ( - childExecutionResult.callStackItem.publicInputs.newCommitments.some(item => !item.isEmpty()) || + childExecutionResult.callStackItem.publicInputs.newNoteHashes.some(item => !item.isEmpty()) || childExecutionResult.callStackItem.publicInputs.newNullifiers.some(item => !item.isEmpty()) || childExecutionResult.callStackItem.publicInputs.newL2ToL1Msgs.some(item => !item.isEmpty()) || !childExecutionResult.callStackItem.publicInputs.encryptedLogPreimagesLength.equals(new Fr(4)) || diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index a8e03dcdfc5..ffe9b61561e 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -7,7 +7,7 @@ import { FunctionData, Header, L1_TO_L2_MSG_TREE_HEIGHT, - MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, NOTE_HASH_TREE_HEIGHT, PartialStateReference, PublicCallRequest, @@ -24,7 +24,7 @@ import { computeCommitmentNonce, computeMessageSecretHash, computeVarArgsHash, - siloCommitment, + siloNoteHash, } from '@aztec/circuits.js/hash'; import { FunctionArtifact, @@ -232,8 +232,8 @@ describe('Private Execution test suite', () => { const txContext = { isContractDeploymentTx: true, contractDeploymentData }; const result = await runSimulator({ artifact, txContext }); - const emptyCommitments = new Array(MAX_NEW_COMMITMENTS_PER_CALL).fill(Fr.ZERO); - expect(sideEffectArrayToValueArray(result.callStackItem.publicInputs.newCommitments)).toEqual(emptyCommitments); + const emptyCommitments = new Array(MAX_NEW_NOTE_HASHES_PER_CALL).fill(Fr.ZERO); + expect(sideEffectArrayToValueArray(result.callStackItem.publicInputs.newNoteHashes)).toEqual(emptyCommitments); expect(result.callStackItem.publicInputs.contractDeploymentData).toEqual(contractDeploymentData); }); @@ -320,12 +320,12 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(new Fr(869710811710178111116101n)); // ValueNote - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const [commitment] = newCommitments; + const [commitment] = newNoteHashes; expect(commitment).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, @@ -346,12 +346,12 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(new Fr(869710811710178111116101n)); // ValueNote - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const [commitment] = newCommitments; + const [commitment] = newNoteHashes; expect(commitment).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, @@ -394,12 +394,12 @@ describe('Private Execution test suite', () => { expect(recipientNote.storageSlot).toEqual(recipientStorageSlot); expect(recipientNote.noteTypeId).toEqual(noteTypeId); - const newCommitments = sideEffectArrayToValueArray(result.callStackItem.publicInputs.newCommitments).filter( + const newNoteHashes = sideEffectArrayToValueArray(result.callStackItem.publicInputs.newNoteHashes).filter( field => !field.equals(Fr.ZERO), ); - expect(newCommitments).toHaveLength(2); + expect(newNoteHashes).toHaveLength(2); - const [changeNoteCommitment, recipientNoteCommitment] = newCommitments; + const [changeNoteCommitment, recipientNoteCommitment] = newNoteHashes; expect(recipientNoteCommitment).toEqual( await acirSimulator.computeInnerNoteHash(contractAddress, recipientStorageSlot, noteTypeId, recipientNote.note), ); @@ -797,7 +797,7 @@ describe('Private Execution test suite', () => { const noteHash = hashFields(note.items); const storageSlot = new Fr(5); const innerNoteHash = hashFields([storageSlot, noteHash]); - const siloedNoteHash = siloCommitment(contractAddress, innerNoteHash); + const siloedNoteHash = siloNoteHash(contractAddress, innerNoteHash); oracle.getNotes.mockResolvedValue([ { contractAddress, @@ -936,12 +936,12 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; + const commitment = newNoteHashes[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner); const noteTypeId = new Fr(869710811710178111116101n); // ValueNote @@ -1028,12 +1028,12 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(execInsert.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(execInsert.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; + const commitment = newNoteHashes[0]; const innerNoteHash = await acirSimulator.computeInnerNoteHash( contractAddress, noteAndSlot.storageSlot, @@ -1092,12 +1092,12 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; + const commitment = newNoteHashes[0]; expect(commitment).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index b8192633373..cff1858a008 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -1,6 +1,6 @@ import { AztecNode, Note } from '@aztec/circuit-types'; import { CompleteAddress } from '@aztec/circuits.js'; -import { computeUniqueCommitment, siloCommitment } from '@aztec/circuits.js/hash'; +import { computeUniqueCommitment, siloNoteHash } from '@aztec/circuits.js/hash'; import { ABIParameterVisibility, FunctionArtifactWithDebugMetadata, getFunctionArtifact } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { pedersenHash } from '@aztec/foundation/crypto'; @@ -52,7 +52,7 @@ describe('Simulator', () => { const note = createNote(); const tokenNoteHash = hashFields(note.items); const innerNoteHash = hashFields([storageSlot, tokenNoteHash]); - const siloedNoteHash = siloCommitment(contractAddress, innerNoteHash); + const siloedNoteHash = siloNoteHash(contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(nonce, siloedNoteHash); const innerNullifier = hashFields([ uniqueSiloedNoteHash, diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 419c7d3a1be..835de73ed61 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -23,7 +23,7 @@ export interface PublicExecutionResult { /** The return values of the function. */ returnValues: Fr[]; /** The new commitments to be inserted into the commitments tree. */ - newCommitments: SideEffect[]; + newNoteHashes: SideEffect[]; /** The new l2 to l1 messages generated in this call. */ newL2ToL1Messages: L2ToL1Message[]; /** The new nullifiers to be inserted into the nullifier tree. */ @@ -143,7 +143,7 @@ function contractStorageUpdateRequestToPublicDataUpdateRequest( */ export function checkValidStaticCall( - newCommitments: SideEffect[], + newNoteHashes: SideEffect[], newNullifiers: SideEffectLinkedToNoteHash[], contractStorageUpdateRequests: ContractStorageUpdateRequest[], newL2ToL1Messages: L2ToL1Message[], @@ -151,7 +151,7 @@ export function checkValidStaticCall( ) { if ( contractStorageUpdateRequests.length > 0 || - newCommitments.length > 0 || + newNoteHashes.length > 0 || newNullifiers.length > 0 || newL2ToL1Messages.length > 0 || unencryptedLogs.logs.length > 0 diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index e59feed7444..087c7372bc8 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -52,12 +52,12 @@ export async function executePublicFunction( const { returnValues, newL2ToL1Msgs, - newCommitments: newCommitmentsPadded, + newNoteHashes: newNoteHashesPadded, newNullifiers: newNullifiersPadded, } = PublicCircuitPublicInputs.fromFields(returnWitness); const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isEmpty()); - const newCommitments = newCommitmentsPadded.filter(v => !v.isEmpty()); + const newNoteHashes = newNoteHashesPadded.filter(v => !v.isEmpty()); const newNullifiers = newNullifiersPadded.filter(v => !v.isEmpty()); const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData(); @@ -72,7 +72,7 @@ export async function executePublicFunction( return { execution, - newCommitments, + newNoteHashes, newL2ToL1Messages, newNullifiers, contractStorageReads, @@ -134,7 +134,7 @@ export class PublicExecutor { if (executionResult.execution.callContext.isStaticCall) { checkValidStaticCall( - executionResult.newCommitments, + executionResult.newNoteHashes, executionResult.newNullifiers, executionResult.contractStorageUpdateRequests, executionResult.newL2ToL1Messages, diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index 7171d3656de..88ef7c35125 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -328,12 +328,12 @@ describe('ACIR public execution simulator', () => { const result = await executor.simulate(execution, GlobalVariables.empty()); // Assert the commitment was created - expect(result.newCommitments.length).toEqual(1); + expect(result.newNoteHashes.length).toEqual(1); const expectedNoteHash = pedersenHash([amount.toBuffer(), secretHash.toBuffer()]); const storageSlot = new Fr(5); // for pending_shields const expectedInnerNoteHash = pedersenHash([storageSlot, expectedNoteHash].map(f => f.toBuffer())); - expect(result.newCommitments[0].value).toEqual(expectedInnerNoteHash); + expect(result.newNoteHashes[0].value).toEqual(expectedInnerNoteHash); }); it('Should be able to create a L2 to L1 message from the public context', async () => { diff --git a/yarn-project/simulator/src/public/public_execution_context.ts b/yarn-project/simulator/src/public/public_execution_context.ts index 434a02be59c..1e48202703c 100644 --- a/yarn-project/simulator/src/public/public_execution_context.ts +++ b/yarn-project/simulator/src/public/public_execution_context.ts @@ -213,7 +213,7 @@ export class PublicExecutionContext extends TypedOracle { if (isStaticCall) { checkValidStaticCall( - childExecutionResult.newCommitments, + childExecutionResult.newNoteHashes, childExecutionResult.newNullifiers, childExecutionResult.contractStorageUpdateRequests, childExecutionResult.newL2ToL1Messages, diff --git a/yellow-paper/docs/calls/static-calls.md b/yellow-paper/docs/calls/static-calls.md index 61756cfb413..cb1b2c789c6 100644 --- a/yellow-paper/docs/calls/static-calls.md +++ b/yellow-paper/docs/calls/static-calls.md @@ -13,7 +13,7 @@ I think the options are: Thoughts? Ethereum does the latter. We should write about whichever we choose in this page. --> -- `new_commitments` +- `new_note_hashes` - `new_nullifiers` - `nullified_commitments` - `new_l2_to_l1_msgs` diff --git a/yellow-paper/docs/constants.md b/yellow-paper/docs/constants.md index 0e1789ae22c..1106acd4aa3 100644 --- a/yellow-paper/docs/constants.md +++ b/yellow-paper/docs/constants.md @@ -41,7 +41,7 @@ The statically-sized nature the kernel & rollup circuits will restrict the quant | Name | Value | Description | |---|---|---| -| `MAX_NEW_COMMITMENTS_PER_CALL` | 128 | +| `MAX_NEW_NOTE_HASHES_PER_CALL` | 128 | | `MAX_NEW_NULLIFIERS_PER_CALL` | 128 | | `MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL` | 32 | | `MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL` | 32 | diff --git a/yellow-paper/docs/state/note-hash-tree.md b/yellow-paper/docs/state/note-hash-tree.md index 78bab7bb6e3..a11c0eddda2 100644 --- a/yellow-paper/docs/state/note-hash-tree.md +++ b/yellow-paper/docs/state/note-hash-tree.md @@ -4,7 +4,7 @@ The Note Hash tree is an [append-only Merkle tree](./tree-implementations.md#app Note commitments are immutable once created. Still, notes can be consumed ("read") by functions. To preserve privacy, a consumed note is not removed from the tree, otherwise it would be possible to link the transaction that created a note with the one that consumed it. Instead, a note is consumed by emitting a deterministic [nullifier](./nullifier-tree.md). -Contracts emit new note commitments via the `new_commitments` in the `CircuitPublicInputs` , which are subsequently [siloed](./tree-implementations.md#siloing-leaves) by contract address by the Kernel circuit. Siloing the commitment ensures that a malicious contract cannot create notes for (that is, modify the state of) another contract. +Contracts emit new note commitments via the `new_note_hashes` in the `CircuitPublicInputs` , which are subsequently [siloed](./tree-implementations.md#siloing-leaves) by contract address by the Kernel circuit. Siloing the commitment ensures that a malicious contract cannot create notes for (that is, modify the state of) another contract. The Kernel circuit also guarantees uniqueness of commitments by further hashing them with a nonce, derived from the transaction identifier and the index of the commitment within the transaction's array of newly-created note hashes. Uniqueness means that a note with the same contents can be emitted more than once, and each instance can be independently nullified. Without uniqueness, two notes with the same content would yield the same commitment and nullifier, so nullifying one of them would render the second one as nullified as well. @@ -22,4 +22,4 @@ The unique siloed commitment of a note is included in the [transaction `data`](. The protocol does not enforce any constraints on any note hashes emitted by an application. This means that applications are responsible for including a `randomness` field in the note hash to make the commitment _hiding_ in addition to _binding_. If an application does not include randomness, and the note preimage can be guessed by an attacker, it makes the note vulnerable to preimage attacks, since the siloing and uniqueness steps do not provide hiding. -Furthermore, since there are no constraints to the commitment emitted by an application, an application can emit any value whatsoever as a `new_commitment`, including values that do not map to a note hash. +Furthermore, since there are no constraints to the commitment emitted by an application, an application can emit any value whatsoever as a `new_note_hash`, including values that do not map to a note hash. diff --git a/yellow-paper/docs/transactions/tx-object.md b/yellow-paper/docs/transactions/tx-object.md index 29c6c9d33a6..c269239cad0 100644 --- a/yellow-paper/docs/transactions/tx-object.md +++ b/yellow-paper/docs/transactions/tx-object.md @@ -42,9 +42,9 @@ Output of the last iteration of the private kernel circuit. Includes _accumulate | Field | Type | Description | |-------|------|-------------| | aggregationObject | AggregationObject | Aggregated proof of all the previous kernel iterations. | -| newCommitments | Field[] | The new commitments made in this transaction. | +| newNoteHashes | Field[] | The new note hashes made in this transaction. | | newNullifiers | Field[] | The new nullifiers made in this transaction. | -| nullifiedCommitments | Field[] | The commitments which are nullified by a nullifier in the above list. | +| nullifiedNoteHashes | Field[] | The note hashes which are nullified by a nullifier in the above list. | | privateCallStack | Field[] | Current private call stack. | | publicCallStack | Field[] | Current public call stack. | | newL2ToL1Msgs | Field[] | All the new L2 to L1 messages created in this transaction. | From 8ec8cd97cb440eaf7116f0cc521a3fb0ed28029b Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 14:56:06 +0000 Subject: [PATCH 03/11] WIP --- l1-contracts/slither_output.md | 20 +++-- .../libraries/decoders/MessagesDecoder.sol | 2 +- .../core/libraries/decoders/TxsDecoder.sol | 8 +- .../crates/private-kernel-lib/src/common.nr | 2 +- .../src/private_kernel_tail.nr | 74 +++++++++---------- yarn-project/circuit-types/src/body.ts | 2 +- .../src/block_builder/solo_block_builder.ts | 2 +- 7 files changed, 57 insertions(+), 53 deletions(-) diff --git a/l1-contracts/slither_output.md b/l1-contracts/slither_output.md index 81c96c9ab12..b9669bc5038 100644 --- a/l1-contracts/slither_output.md +++ b/l1-contracts/slither_output.md @@ -10,7 +10,7 @@ Summary - [dead-code](#dead-code) (13 results) (Informational) - [solc-version](#solc-version) (1 results) (Informational) - [low-level-calls](#low-level-calls) (1 results) (Informational) - - [similar-names](#similar-names) (2 results) (Informational) + - [similar-names](#similar-names) (3 results) (Informational) - [unused-state](#unused-state) (2 results) (Informational) - [constable-states](#constable-states) (1 results) (Optimization) - [pess-multiple-storage-read](#pess-multiple-storage-read) (2 results) (Optimization) @@ -353,12 +353,18 @@ src/core/messagebridge/Inbox.sol#L148-L153 Impact: Informational Confidence: Medium - [ ] ID-41 +Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L123) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L116) + +src/core/libraries/ConstantsGen.sol#L123 + + + - [ ] ID-42 Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L104) src/core/libraries/ConstantsGen.sol#L103 - - [ ] ID-42 + - [ ] ID-43 Variable [Rollup.AVAILABILITY_ORACLE](src/core/Rollup.sol#L30) is too similar to [Rollup.constructor(IRegistry,IAvailabilityOracle)._availabilityOracle](src/core/Rollup.sol#L39) src/core/Rollup.sol#L30 @@ -367,13 +373,13 @@ src/core/Rollup.sol#L30 ## unused-state Impact: Informational Confidence: High - - [ ] ID-43 + - [ ] ID-44 [Decoder.END_TREES_BLOCK_HEADER_OFFSET](src/core/libraries/decoders/Decoder.sol#L103-L104) is never used in [Decoder](src/core/libraries/decoders/Decoder.sol#L72-L418) src/core/libraries/decoders/Decoder.sol#L103-L104 - - [ ] ID-44 + - [ ] ID-45 [Decoder.BLOCK_HEADER_OFFSET](src/core/libraries/decoders/Decoder.sol#L107-L108) is never used in [Decoder](src/core/libraries/decoders/Decoder.sol#L72-L418) src/core/libraries/decoders/Decoder.sol#L107-L108 @@ -382,7 +388,7 @@ src/core/libraries/decoders/Decoder.sol#L107-L108 ## constable-states Impact: Optimization Confidence: High - - [ ] ID-45 + - [ ] ID-46 [Rollup.lastWarpedBlockTs](src/core/Rollup.sol#L37) should be constant src/core/Rollup.sol#L37 @@ -391,13 +397,13 @@ src/core/Rollup.sol#L37 ## pess-multiple-storage-read Impact: Optimization Confidence: High - - [ ] ID-46 + - [ ] ID-47 In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72) variable [FrontierMerkle.DEPTH](src/core/messagebridge/frontier_tree/Frontier.sol#L8) is read multiple times src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72 - - [ ] ID-47 + - [ ] ID-48 In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72) variable [FrontierMerkle.frontier](src/core/messagebridge/frontier_tree/Frontier.sol#L13) is read multiple times src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72 diff --git a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol index 6fb589ac23e..80e254a6b68 100644 --- a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol @@ -63,7 +63,7 @@ library MessagesDecoder { uint256 offset = 0; - // Commitments + // Note hashes uint256 count = read4(_body, offset); offset += 0x4 + count * 0x20; diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index 3a221121a0c..361ebec149c 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -42,7 +42,7 @@ import {Hash} from "../Hash.sol"; */ library TxsDecoder { struct ArrayOffsets { - uint256 commitment; + uint256 noteHash; uint256 nullifier; uint256 publicData; uint256 l2ToL1Msgs; @@ -78,7 +78,7 @@ library TxsDecoder { // Commitments uint256 count = read4(_body, offset); vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_NOTE_HASHES_PER_TX); - offsets.commitment = 0x4; + offsets.noteHash = 0x4; offset += 0x4 + count * 0x20; offsets.nullifier = offset + 0x4; // + 0x4 to offset by next read4 @@ -155,7 +155,7 @@ library TxsDecoder { // Insertions are split into multiple `bytes.concat` to work around stack too deep. vars.baseLeaf = bytes.concat( bytes.concat( - slice(_body, offsets.commitment, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), + slice(_body, offsets.noteHash, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.nullifier, Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.publicData, Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.l2ToL1Msgs, Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP), @@ -169,7 +169,7 @@ library TxsDecoder { bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); - offsets.commitment += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; + offsets.noteHash += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; offsets.nullifier += Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP; offsets.publicData += Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP; offsets.l2ToL1Msgs += Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index c5a7589de63..4ab6c14417f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -230,7 +230,7 @@ pub fn update_end_values( } public_inputs.end.new_nullifiers.extend_from_bounded_vec(siloed_new_nullifiers); - // commitments + // note hashes let mut siloed_new_note_hashes: BoundedVec = BoundedVec::new(SideEffect::empty()); for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { let new_note_hash = new_note_hashes[i].value; diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 89280d2a62c..356f374833a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -67,12 +67,10 @@ impl PrivateKernelTailCircuitPrivateInputs { let read_commitment_hint = self.read_commitment_hints[rr_idx] as u64; if (read_request.value != 0) { - let commitment = new_note_hashes.get_unchecked(read_commitment_hint as Field); - assert_eq( - read_request.value, commitment.value, "Hinted commitment does not match read request" - ); + let hash = new_note_hashes.get_unchecked(read_commitment_hint as Field); + assert_eq(read_request.value, hash.value, "Hinted hash does not match read request"); assert( - read_request.counter > commitment.counter, "Read request counter must be greater than commitment counter" + read_request.counter > hash.counter, "Read request counter must be greater than hash counter" ); } } @@ -131,20 +129,20 @@ impl PrivateKernelTailCircuitPrivateInputs { let hint_pos = self.nullifier_commitment_hints[n_idx] as u64; // Nullified_commitment of value `0` implies non-transient (persistable) - // nullifier in which case no attempt will be made to match it to a commitment. - // Non-empty nullified_commitment implies transient nullifier which MUST be matched to a commitment below! + // nullifier in which case no attempt will be made to match it to a hash. + // Non-empty nullified_commitment implies transient nullifier which MUST be matched to a hash below! // 0-valued nullified_commitment is empty and will be ignored if nullified_commitment != 0 { assert( hint_pos < MAX_NEW_NOTE_HASHES_PER_TX as u64, "New nullifier is transient but hint is invalid" ); - let commitment = new_note_hashes[hint_pos]; - assert_eq(nullified_commitment, commitment.value, "Hinted commitment does not match"); + let hash = new_note_hashes[hint_pos]; + assert_eq(nullified_commitment, hash.value, "Hinted hash does not match"); assert( - nullifier.counter > commitment.counter, "Nullifier counter must be greater than commitment counter" + nullifier.counter > hash.counter, "Nullifier counter must be greater than hash counter" ); // match found! - // squash both the nullifier and the commitment + // squash both the nullifier and the hash // (set to 0 here and then rearrange array after loop) new_note_hashes[hint_pos] = SideEffect::empty(); new_nullifiers[n_idx as u64] = SideEffectLinkedToNoteHash::empty(); @@ -180,23 +178,23 @@ impl PrivateKernelTailCircuitPrivateInputs { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // tx hash let first_nullifier = public_inputs.end.new_nullifiers.get(0); - let mut unique_commitments = public_inputs.end.new_note_hashes.storage; + let mut unique_note_hashes = public_inputs.end.new_note_hashes.storage; for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { - // Apply nonce to all non-zero/non-empty commitments - // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_note_hashes array + // Apply nonce to all non-zero/non-empty note hashes + // Nonce is the hash of the first (0th) nullifier and the note hash's index into new_note_hashes array let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); - let commitment = unique_commitments[c_idx]; - if commitment.value != 0 { - let unique_commitment = compute_unique_siloed_commitment(nonce, commitment.value); - unique_commitments[c_idx] = SideEffect{ + let hash = unique_note_hashes[c_idx]; + if hash.value != 0 { + let unique_commitment = compute_unique_siloed_commitment(nonce, hash.value); + unique_note_hashes[c_idx] = SideEffect{ value: unique_commitment, - counter: commitment.counter + counter: hash.counter }; } } - public_inputs.end.new_note_hashes.storage = unique_commitments; + public_inputs.end.new_note_hashes.storage = unique_note_hashes; } pub fn native_private_kernel_circuit_ordering(self) -> PrivateKernelTailCircuitPublicInputs { @@ -379,9 +377,9 @@ mod tests { // prepare for the split: first MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX are added to end_non_revertible_accumulted_data // neeed to take the counter of the side effect at the given index because builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_note_hashes.get(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX).counter; - // Read the commitment at index 1; + // Read the hash at index 1; builder.add_transient_read(1); - // Read the commitment at index 3; + // Read the hash at index 3; builder.add_transient_read(3); let unique_siloed_commitments = builder.get_unique_siloed_commitments(); let public_inputs = builder.execute(); @@ -393,12 +391,12 @@ mod tests { } } - #[test(should_fail_with="Hinted commitment does not match read request")] + #[test(should_fail_with="Hinted hash does not match read request")] unconstrained fn native_read_request_unknown_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.add_transient_read(0); - // Tweak the read request so that it does not match the commitment at index 0; + // Tweak the read request so that it does not match the hash at index 0; let read_request = builder.previous_kernel.end.read_requests.pop(); builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); builder.failed(); @@ -409,7 +407,7 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); @@ -431,10 +429,10 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); let new_note_hashes = builder.get_new_note_hashes(); - // The 0th commitment will be chopped. + // The 0th hash will be chopped. let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_note_hashes[1]]); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); @@ -461,9 +459,9 @@ mod tests { builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; + // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; + // The nullifier at index 2 is nullifying the hash at index 0; builder.nullify_transient_commitment(2, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); @@ -540,23 +538,23 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.append_nullifiers(1); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); // Change the hint to be out of bounds. builder.nullifier_commitment_hints[1] = MAX_NEW_NOTE_HASHES_PER_TX; builder.failed(); } - #[test(should_fail_with="Hinted commitment does not match")] + #[test(should_fail_with="Hinted hash does not match")] unconstrained fn wrong_nullifier_commitment_hint_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; + // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; + // The nullifier at index 2 is nullifying the hash at index 0; builder.nullify_transient_commitment(2, 0); - // Tweak the hint to be for the commitment at index 1. + // Tweak the hint to be for the hash at index 1. builder.nullifier_commitment_hints[2] = 1; builder.failed(); } @@ -617,7 +615,7 @@ mod tests { let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; let public_inputs = builder.execute(); - let unique_commitments = compute_unique_siloed_commitments( + let unique_note_hashes = compute_unique_siloed_commitments( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, new_note_hashes @@ -626,14 +624,14 @@ mod tests { assert( array_eq( public_inputs.end_non_revertible.new_note_hashes, - [unique_commitments[0], unique_commitments[1]] + [unique_note_hashes[0], unique_note_hashes[1]] ) ); assert( array_eq( public_inputs.end.new_note_hashes, - [unique_commitments[2], unique_commitments[3]] + [unique_note_hashes[2], unique_note_hashes[3]] ) ); } @@ -642,7 +640,7 @@ mod tests { unconstrained fn split_side_effect_squashing() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - // add one commitment in non-revertible part + // add one hash in non-revertible part builder.previous_kernel.append_new_note_hashes(1); builder.previous_kernel.capture_min_revertible_side_effect_counter(); diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index 3a82c4696be..1a61dc5fa9b 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -81,7 +81,7 @@ export class Body { const numberOfTxsIncludingEmpty = newNullifiers.length / MAX_NEW_NULLIFIERS_PER_TX; for (let i = 0; i < numberOfTxsIncludingEmpty; i += 1) { - // TODO(benesjan): this should use TxEffect.fromBuffer + // TODO(#4720): this should use TxEffect.fromBuffer txEffects.push( new TxEffect( newNoteHashes.slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index c9dd5ab95bf..1d38330567d 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -105,7 +105,7 @@ export class SoloBlockBuilder implements BlockBuilder { // Collect all new nullifiers, commitments, and contracts from all txs in this block const txEffects: TxEffect[] = txs.map( tx => - // TODO(benesjan): Combined data should most likely contain the tx effect directly + // TODO(#4720): Combined data should most likely contain the tx effect directly new TxEffect( tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple< Fr, From ddcbdcb70c94843a795e734a6c16058656bb9dc0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 15:18:13 +0000 Subject: [PATCH 04/11] more updates --- .../writing_contracts/functions/context.md | 6 ++--- .../developers/debugging/sandbox-errors.md | 10 ++++----- docs/docs/developers/limitations/main.md | 2 +- docs/docs/developers/privacy/main.md | 4 ++-- .../concepts/circuits/rollup_circuits/main.md | 2 +- .../public_private_calls/main.md | 6 ++--- docs/docs/misc/roadmap/engineering_roadmap.md | 4 ++-- .../src/core/libraries/decoders/Decoder.sol | 2 +- .../core/libraries/decoders/TxsDecoder.sol | 2 +- .../src/private_kernel_inner.nr | 2 +- .../src/private_kernel_tail.nr | 2 +- .../src/public_kernel_app_logic.nr | 6 ++--- yarn-project/circuit-types/src/l2_tx.ts | 2 +- .../circuit-types/src/tx/tx_receipt.ts | 2 +- .../kernel/combined_accumulated_data.ts | 6 ++--- ...vate_kernel_tail_circuit_private_inputs.ts | 4 ++-- .../structs/private_circuit_public_inputs.ts | 2 +- .../pxe/src/database/deferred_note_dao.ts | 2 +- .../pxe/src/kernel_prover/kernel_prover.ts | 22 +++++++++---------- .../pxe/src/kernel_prover/proof_creator.ts | 2 +- .../src/note_processor/produce_note_dao.ts | 2 +- .../scripts/src/benchmarks/aggregate.ts | 2 +- .../scripts/src/benchmarks/markdown.ts | 2 +- .../block_builder/solo_block_builder.test.ts | 2 +- .../src/client/private_execution.test.ts | 12 +++++----- .../simulator/src/public/execution.ts | 2 +- .../simulator/src/public/index.test.ts | 4 ++-- .../server_world_state_synchronizer.ts | 6 ++--- .../world-state-db/merkle_tree_operations.ts | 2 +- .../merkle_tree_operations_facade.ts | 2 +- .../src/world-state-db/merkle_trees.ts | 4 ++-- .../docs/calls/public-private-messaging.md | 2 +- .../index.md | 2 +- 33 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/docs/developers/contracts/writing_contracts/functions/context.md b/docs/docs/developers/contracts/writing_contracts/functions/context.md index 99b692ffe25..70630aa5d0f 100644 --- a/docs/docs/developers/contracts/writing_contracts/functions/context.md +++ b/docs/docs/developers/contracts/writing_contracts/functions/context.md @@ -15,7 +15,7 @@ On this page, you'll learn - The details and functionalities of the private context in Aztec.nr - Difference between the private and public contexts and their unified APIs - Components of the private context, such as inputs, block header, and contract deployment data -- Elements like return values, read requests, new commitments, and nullifiers in transaction processing +- Elements like return values, read requests, new note hashes, and nullifiers in transaction processing - Differences between the private and public contexts, especially the unique features and variables in the public context ## Two contexts, one API @@ -105,9 +105,9 @@ The return values are a set of values that are returned from an applications exe -### New Commitments +### New note hashes -New commitments contains an array of all of the commitments created in the current execution context. +New note hashes contains an array of all of the commitments created in the current execution context. ### New Nullifiers diff --git a/docs/docs/developers/debugging/sandbox-errors.md b/docs/docs/developers/debugging/sandbox-errors.md index e107e71e693..e81574b8470 100644 --- a/docs/docs/developers/debugging/sandbox-errors.md +++ b/docs/docs/developers/debugging/sandbox-errors.md @@ -24,7 +24,7 @@ This error may also happen when you deploy a new contract and the contract data #### 2005 - PRIVATE_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL -For static calls, new commitments aren't allowed +For static calls, new note hashes aren't allowed #### 2006 - PRIVATE_KERNEL\_\_NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL @@ -122,11 +122,11 @@ Same as [3022](#3022---public_kernel__public_call_stack_contract_storage_updates #### 3026 - PUBLIC_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL -For static calls, no new commitments or nullifiers can be added to the state. +For static calls, no new note hashes or nullifiers can be added to the state. #### 3027 - PUBLIC_KERNEL\_\_NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL -For static calls, no new commitments or nullifiers can be added to the state. +For static calls, no new note hashes or nullifiers can be added to the state. ### Rollup circuit errors @@ -148,7 +148,7 @@ Some scary bugs like `4003 - BASE__INVALID_NULLIFIER_SUBTREE` and `4004 - BASE__ Circuits work by having a fixed size array. As such, we have limits on how many UTXOs can be created (aka "commitments") or destroyed/nullified (aka "nullifiers") in a transaction. Similarly we have limits on many reads or writes you can do, how many contracts you can create in a transaction. This error typically says that you have reached the current limits of what you can do in a transaction. Some examples when you may hit this error are: -- too many new commitments in one tx +- too many new note hashes in one tx - too many new nullifiers in one tx - Note: Nullifiers may be created even outside the context of your Aztec.nr code. Eg, when creating a contract, we add a nullifier for its address to prevent same address from ever occurring. Similarly, we add a nullifier for your transaction hash too. - too many private function calls in one tx (i.e. call stack size exceeded) @@ -170,7 +170,7 @@ Users may create a proof against a historical state in Aztec. The rollup circuit - using invalid historical contracts data tree state - using invalid historical L1 to L2 message data tree state - inserting a subtree into the greater tree - - we make a smaller merkle tree of all the new commitments/nullifiers etc that were created in a transaction or in a rollup and add it to the bigger state tree. Before inserting, we do a merkle membership check to ensure that the index to insert at is indeed an empty subtree (otherwise we would be overwriting state). This can happen when `next_available_leaf_index` in the state tree's snapshot is wrong (it is fetched by the sequencer from the archiver). The error message should reveal which tree is causing this issue + - we make a smaller merkle tree of all the new note hashes/nullifiers etc that were created in a transaction or in a rollup and add it to the bigger state tree. Before inserting, we do a merkle membership check to ensure that the index to insert at is indeed an empty subtree (otherwise we would be overwriting state). This can happen when `next_available_leaf_index` in the state tree's snapshot is wrong (it is fetched by the sequencer from the archiver). The error message should reveal which tree is causing this issue - nullifier tree related errors - The nullifier tree uses an [Indexed Merkle Tree](../../learn/concepts/storage/trees/indexed_merkle_tree.md). It requires additional data from the archiver to know which is the nullifier in the tree that is just below the current nullifier before it can perform batch insertion. If the low nullifier is wrong, or the nullifier is in incorrect range, you may receive this error. --- diff --git a/docs/docs/developers/limitations/main.md b/docs/docs/developers/limitations/main.md index 971690e07e0..1c0854c06ed 100644 --- a/docs/docs/developers/limitations/main.md +++ b/docs/docs/developers/limitations/main.md @@ -38,7 +38,7 @@ Help shape and define: - The initial `msg_sender` is 0, which can be problematic for some contracts, see [function visibility](../contracts/writing_contracts/functions/visibility.md). - Unencrypted logs don't link to the contract that emitted it, so essentially just a `debug_log`` that you can match values against. - A note that is created and nullified in the same transaction will still emit an encrypted log. -- A limited amount of new commitments, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). +- A limited amount of new note hashes, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). ## Limitations diff --git a/docs/docs/developers/privacy/main.md b/docs/docs/developers/privacy/main.md index d7d2997df55..066aeb570f9 100644 --- a/docs/docs/developers/privacy/main.md +++ b/docs/docs/developers/privacy/main.md @@ -78,7 +78,7 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi - All unencrypted logs (topics and arguments). - The roots of all trees which have been read from. - The _number_ of ['side effects'](): - - \# new commitments + - \# new note hashes - \# new nullifiers - \# bytes of encrypted logs - \# public function calls @@ -91,7 +91,7 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi #### Standardizing Fingerprints -If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new commitments, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. +If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new note hashes, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. ### Data queries diff --git a/docs/docs/learn/concepts/circuits/rollup_circuits/main.md b/docs/docs/learn/concepts/circuits/rollup_circuits/main.md index d5ac8be56c8..871a7ead96a 100644 --- a/docs/docs/learn/concepts/circuits/rollup_circuits/main.md +++ b/docs/docs/learn/concepts/circuits/rollup_circuits/main.md @@ -25,7 +25,7 @@ For both transactions, it: - Updates the public data tree in line with the requested state transitions. - Checks that the nullifiers haven't previously been inserted into the [indexed nullifier tree](../../storage/trees/indexed_merkle_tree.md#primer-on-nullifier-trees). - Batch-inserts new nullifiers into the nullifier tree. -- Batch-inserts new commitments into the note hash tree +- Batch-inserts new note hashes into the note hash tree - Batch-inserts any new contract deployments into the contract tree. - Hashes all the new nullifiers, commitments, public state transitions, and new contract deployments, to prevent exponential growth in public inputs with each later layer of recursion. - Verifies the input kernel proof. diff --git a/docs/docs/learn/concepts/communication/public_private_calls/main.md b/docs/docs/learn/concepts/communication/public_private_calls/main.md index 15ae6df1c8b..eca7d2ccb54 100644 --- a/docs/docs/learn/concepts/communication/public_private_calls/main.md +++ b/docs/docs/learn/concepts/communication/public_private_calls/main.md @@ -32,7 +32,7 @@ This works perfectly well when everything is public and a single builder is awar To avoid this issue, we permit the use of historical data as long as the data has not been nullified previously. Note, that because this must include nullifiers that were inserted after the proof generation, but before execution we need to nullify (and insert the data again) to prove that it was not nullified. Without emitting the nullifier we would need our proof to point to the current head of the nullifier tree to have the same effect, e.g., back to the race conditions we were trying to avoid. -In this model, instead of informing the builder of our intentions, we construct the proof $\pi$ and then provide them with the transaction results (new commitments and nullifiers, contract deployments and cross-chain messages) in addition to $\pi$. The builder will then be responsible for inserting these new commitments and nullifiers into the state. They will be aware of the intermediates and can discard transactions that try to produce existing nullifiers (double spend), as doing so would invalidate the rollup proof. +In this model, instead of informing the builder of our intentions, we construct the proof $\pi$ and then provide them with the transaction results (new note hashes and nullifiers, contract deployments and cross-chain messages) in addition to $\pi$. The builder will then be responsible for inserting these new note hashes and nullifiers into the state. They will be aware of the intermediates and can discard transactions that try to produce existing nullifiers (double spend), as doing so would invalidate the rollup proof. On the left-hand side of the diagram below, we see the fully public world where storage is shared, while on the right-hand side, we see the private world where all reads are historical. @@ -56,11 +56,11 @@ Be mindful that if part of a transaction is reverting, say the public part of a To summarize: -- _Private_ function calls are fully "prepared" and proven by the user, which provides the kernel proof along with new commitments and nullifiers to the sequencer. +- _Private_ function calls are fully "prepared" and proven by the user, which provides the kernel proof along with new note hashes and nullifiers to the sequencer. - _Public_ functions altering public state (updatable storage) must be executed at the current "head" of the chain, which only the sequencer can ensure, so these must be executed separately to the _private_ functions. - _Private_ and _public_ functions within an Aztec transaction are therefore ordered such that first _private_ functions are executed, and then _public_. -A more comprehensive overview of the interplay between private and public functions and their ability to manipulate data is presented below. It is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new commitments, potentially as part of transferring funds from the public domain to the secret domain). +A more comprehensive overview of the interplay between private and public functions and their ability to manipulate data is presented below. It is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new note hashes, potentially as part of transferring funds from the public domain to the secret domain). diff --git a/docs/docs/misc/roadmap/engineering_roadmap.md b/docs/docs/misc/roadmap/engineering_roadmap.md index 4b5163f90ad..48986906d0b 100644 --- a/docs/docs/misc/roadmap/engineering_roadmap.md +++ b/docs/docs/misc/roadmap/engineering_roadmap.md @@ -52,7 +52,7 @@ The engineering roadmap is long. There are no timings assigned here. In a loose - Just emit the initially-enqueued public function request data? (The 'inputs' of the tx); - I.e. contract address, function selector, args, call_context. - OR, Just emit the final state transitions? (The 'outputs' of the tx) - - I.e. the leaf indices and new values of the public data tree; and the new commitments/nullifiers of the note hash tree; and logs; and l2->L1 messages. + - I.e. the leaf indices and new values of the public data tree; and the new note hashes/nullifiers of the note hash tree; and logs; and l2->L1 messages. ## Proper specs @@ -195,7 +195,7 @@ We often pack data in circuit A, and then unpack it again in circuit B. Also, for logs in particular, we allow arbitrary-sized logs. But this requires sha256 packing inside an app circuit (which is slow) (and sha256 unpacking in Solidity (which is relatively cheap)). Perhaps we also use the bus ideas for logs, to give _some_ variability in log length, but up to an upper bound. -Also, we do a lot of sha256-compressing in our kernel and rollup circuits for data which must be checked on-chain, but grows exponentially with every round of iteration. E.g.: new contract deployment data, new nullifiers, new commitments, public state transition data, etc. This might be unavoidable. Maybe all we can do is use polynomial commitments when the EIP-4844 work is done. But maybe we can use the bus for this stuff too. +Also, we do a lot of sha256-compressing in our kernel and rollup circuits for data which must be checked on-chain, but grows exponentially with every round of iteration. E.g.: new contract deployment data, new nullifiers, new note hashes, public state transition data, etc. This might be unavoidable. Maybe all we can do is use polynomial commitments when the EIP-4844 work is done. But maybe we can use the bus for this stuff too. ### Write proper circuits diff --git a/l1-contracts/src/core/libraries/decoders/Decoder.sol b/l1-contracts/src/core/libraries/decoders/Decoder.sol index 91fcc16ada9..437a6c6c92a 100644 --- a/l1-contracts/src/core/libraries/decoders/Decoder.sol +++ b/l1-contracts/src/core/libraries/decoders/Decoder.sol @@ -156,7 +156,7 @@ library Decoder { /** * @notice Computes consumables for the block * @param _body - The L2 block body. - * @return diffRoot - The root of the diff tree (new commitments, nullifiers etc) + * @return diffRoot - The root of the diff tree (new note hashes, nullifiers etc) * @return l1ToL2MsgsHash - The hash of the L1 to L2 messages * @return l2ToL1Msgs - The L2 to L1 messages of the block * @return l1ToL2Msgs - The L1 to L2 messages of the block diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index 361ebec149c..a593024d418 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -66,7 +66,7 @@ library TxsDecoder { /** * @notice Computes consumables for the block * @param _body - The L2 block calldata. - * @return diffRoot - The root of the diff tree (new commitments, nullifiers etc) + * @return diffRoot - The root of the diff tree (new note hashes, nullifiers etc) */ function decode(bytes calldata _body) internal pure returns (bytes32) { ArrayOffsets memory offsets; diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index de289d4d41d..d4234a022fd 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -518,7 +518,7 @@ mod tests { // The current call stack has 1 commitment; builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 4321, counter: 0 }); - // Mock the previous new commitments to be full, therefore no more commitments can be added. + // Mock the previous new note hashes to be full, therefore no more commitments can be added. let mut full_new_note_hashes = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { full_new_note_hashes[i] = SideEffect { diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 356f374833a..6e6a4fcd220 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -273,7 +273,7 @@ mod tests { } pub fn append_transient_commitments(&mut self, num_commitments: Field) { - // All new commitments aggregated in the previous kernel are transient commitments. + // All new note hashes aggregated in the previous kernel are transient commitments. self.previous_kernel.append_new_note_hashes(num_commitments); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr index 066ec75de4a..8fb3ddf3c57 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -168,10 +168,10 @@ mod tests { fn circuit_outputs_should_be_correctly_populated_with_previous_commitments() { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); let contract_address = builder.public_call.contract_address; - // Setup 2 new commitments on the previous kernel. + // Setup 2 new note hashes on the previous kernel. builder.previous_kernel.append_new_note_hashes(2); let previous = builder.previous_kernel.end.new_note_hashes.storage; - // Setup 2 new commitments on the current public inputs. + // Setup 2 new note hashes on the current public inputs. let current = [ SideEffect { value: previous[1].value + 1, counter: 3 }, SideEffect { value: previous[1].value + 2, counter: 4 } @@ -232,7 +232,7 @@ mod tests { // Setup 2 new nullifiers on the previous kernel. builder.previous_kernel.append_new_nullifiers_from_public(2); let previous = builder.previous_kernel.end.new_nullifiers.storage; - // Setup 2 new commitments on the current public inputs. + // Setup 2 new note hashes on the current public inputs. let current = [ SideEffectLinkedToNoteHash { value: previous[1].value + 1, note_hash: 0, counter: 4 }, SideEffectLinkedToNoteHash { value: previous[1].value + 2, note_hash: 0, counter: 5 } diff --git a/yarn-project/circuit-types/src/l2_tx.ts b/yarn-project/circuit-types/src/l2_tx.ts index 8acce0c4b03..4c5d9514cd3 100644 --- a/yarn-project/circuit-types/src/l2_tx.ts +++ b/yarn-project/circuit-types/src/l2_tx.ts @@ -31,7 +31,7 @@ export class L2Tx { constructor( /** - * New commitments created by the transaction. + * New note hashes created by the transaction. */ public newNoteHashes: Fr[], /** diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.ts b/yarn-project/circuit-types/src/tx/tx_receipt.ts index a4ec87dd097..0bcd900acc7 100644 --- a/yarn-project/circuit-types/src/tx/tx_receipt.ts +++ b/yarn-project/circuit-types/src/tx/tx_receipt.ts @@ -88,7 +88,7 @@ export class TxReceipt { */ interface DebugInfo { /** - * New commitments created by the transaction. + * New note hashes created by the transaction. */ newNoteHashes: Fr[]; /** diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 6c2f24f1107..d707423fb87 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -161,7 +161,7 @@ export class CombinedAccumulatedData { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX >, /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ public newNoteHashes: Tuple, /** @@ -361,7 +361,7 @@ export class PublicAccumulatedRevertibleData { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX >, /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ public newNoteHashes: Tuple, /** @@ -518,7 +518,7 @@ export class PublicAccumulatedRevertibleData { export class PrivateAccumulatedRevertibleData { constructor( /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ public newNoteHashes: Tuple, /** diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index 43e3b4dfa39..81bdee22ede 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -21,11 +21,11 @@ export class PrivateKernelTailCircuitPrivateInputs { */ public previousKernel: PrivateKernelInnerData, /** - * The sorted new commitments. + * The sorted new note hashes. */ public sortedNewNoteHashes: Tuple, /** - * The sorted new commitments indexes. Maps original to sorted. + * The sorted new note hashes indexes. Maps original to sorted. */ public sortedNewNoteHashesIndexes: Tuple, /** diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 5976faac386..49fbd831180 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -59,7 +59,7 @@ export class PrivateCircuitPublicInputs { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL >, /** - * New commitments created by the corresponding function call. + * New note hashes created by the corresponding function call. */ public newNoteHashes: Tuple, /** diff --git a/yarn-project/pxe/src/database/deferred_note_dao.ts b/yarn-project/pxe/src/database/deferred_note_dao.ts index f48d88d84d9..af0ee6a89b2 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.ts @@ -21,7 +21,7 @@ export class DeferredNoteDao { public noteTypeId: Fr, /** The hash of the tx the note was created in. Equal to the first nullifier */ public txHash: TxHash, - /** New commitments in this transaction, one of which belongs to this note */ + /** New note hashes in this transaction, one of which belongs to this note */ public newNoteHashes: Fr[], /** The next available leaf index for the note hash tree for this transaction */ public dataStartIndexForTx: number, diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 85e96b9fe7f..aa8aa944e63 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -323,18 +323,18 @@ export class KernelProver { * to return more than one hint with the same index (contrary to getNullifierHints). * * @param readRequests - The array of read requests. - * @param commitments - The array of commitments. + * @param noteHashes - The array of commitments. * @returns An array of hints where each element is the index of the commitment in commitments array * corresponding to the read request. In other words we have readRequests[i] == commitments[hints[i]]. */ private getReadRequestHints( readRequests: Tuple, - commitments: Tuple, + noteHashes: Tuple, ): Tuple { const hints = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero); for (let i = 0; i < MAX_READ_REQUESTS_PER_TX && !readRequests[i].isEmpty(); i++) { const equalToRR = (cmt: SideEffect) => cmt.value.equals(readRequests[i].value); - const result = commitments.findIndex(equalToRR); + const result = noteHashes.findIndex(equalToRR); if (result == -1) { throw new Error( `The read request at index ${i} with value ${readRequests[i].toString()} does not match to any commitment.`, @@ -353,26 +353,26 @@ export class KernelProver { * (resp. nullified commitments) array. It is crucial in this case that each hint points to a different index * of the nullified commitments array. Otherwise, the private kernel will fail to validate. * - * @param nullifiedCommitments - The array of nullified commitments. - * @param commitments - The array of commitments. + * @param nullifiedNoteHashes - The array of nullified note hashes. + * @param noteHashes - The array of note hasshes. * @returns An array of hints where each element is the index of the commitment in commitments array * corresponding to the nullified commitments. In other words we have nullifiedCommitments[i] == commitments[hints[i]]. */ private getNullifierHints( - nullifiedCommitments: Tuple, - commitments: Tuple, + nullifiedNoteHashes: Tuple, + noteHashes: Tuple, ): Tuple { const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero); const alreadyUsed = new Set(); for (let i = 0; i < MAX_NEW_NULLIFIERS_PER_TX; i++) { - if (!nullifiedCommitments[i].isZero()) { + if (!nullifiedNoteHashes[i].isZero()) { const equalToCommitment = (cmt: SideEffect, index: number) => - cmt.value.equals(nullifiedCommitments[i]) && !alreadyUsed.has(index); - const result = commitments.findIndex(equalToCommitment); + cmt.value.equals(nullifiedNoteHashes[i]) && !alreadyUsed.has(index); + const result = noteHashes.findIndex(equalToCommitment); alreadyUsed.add(result); if (result == -1) { throw new Error( - `The nullified commitment at index ${i} with value ${nullifiedCommitments[ + `The nullified commitment at index ${i} with value ${nullifiedNoteHashes[ i ].toString()} does not match to any commitment.`, ); diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index b2e30de0e22..b2174736b07 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -53,7 +53,7 @@ export interface ProofCreator { /** * Computes the siloed commitments for a given set of public inputs. * - * @param publicInputs - The public inputs containing the contract address and new commitments to be used in generating siloed commitments. + * @param publicInputs - The public inputs containing the contract address and new note hashes to be used in generating siloed commitments. * @returns An array of Fr (finite field) elements representing the siloed commitments. */ getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs): Promise; diff --git a/yarn-project/pxe/src/note_processor/produce_note_dao.ts b/yarn-project/pxe/src/note_processor/produce_note_dao.ts index 2a0a6d99be2..396012a4ee9 100644 --- a/yarn-project/pxe/src/note_processor/produce_note_dao.ts +++ b/yarn-project/pxe/src/note_processor/produce_note_dao.ts @@ -14,7 +14,7 @@ import { NoteDao } from '../database/note_dao.js'; * @param publicKey - The public counterpart to the private key to be used in note decryption. * @param payload - An instance of l1NotePayload. * @param txHash - The hash of the transaction that created the note. Equivalent to the first nullifier of the transaction. - * @param newNoteHashes - New commitments in this transaction, one of which belongs to this note. + * @param newNoteHashes - New note hashes in this transaction, one of which belongs to this note. * @param dataStartIndexForTx - The next available leaf index for the note hash tree for this transaction. * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same l1NotePayload, we need to find a different index for each replicate. * @param simulator - An instance of AcirSimulator. diff --git a/yarn-project/scripts/src/benchmarks/aggregate.ts b/yarn-project/scripts/src/benchmarks/aggregate.ts index 1b2235765d9..d3e027f3e6f 100644 --- a/yarn-project/scripts/src/benchmarks/aggregate.ts +++ b/yarn-project/scripts/src/benchmarks/aggregate.ts @@ -154,7 +154,7 @@ function processTxAddedToPool(entry: TxAddedToPoolStats, results: BenchmarkColle append(results, 'tx_size_in_bytes', entry.newContractCount, entry.size); } -/** Process entries for events tx-private-part-processed, grouped by new commitments */ +/** Process entries for events tx-private-part-processed, grouped by new note hashes */ function processTxPXEProcessingStats(entry: TxPXEProcessingStats, results: BenchmarkCollectedResults) { append(results, 'tx_pxe_processing_time_ms', entry.newCommitmentCount, entry.duration); } diff --git a/yarn-project/scripts/src/benchmarks/markdown.ts b/yarn-project/scripts/src/benchmarks/markdown.ts index 4db86e19e23..2fb3ddec168 100644 --- a/yarn-project/scripts/src/benchmarks/markdown.ts +++ b/yarn-project/scripts/src/benchmarks/markdown.ts @@ -243,7 +243,7 @@ Transaction sizes based on how many contracts are deployed in the tx. ${getTableContent(pick(benchmark, metricsByContractCount), baseBenchmark, 'deployed contracts')} Transaction processing duration by data writes. -${getTableContent(pick(benchmark, metricsTxPxeProcessing), baseBenchmark, 'new commitments')} +${getTableContent(pick(benchmark, metricsTxPxeProcessing), baseBenchmark, 'new note hashes')} ${getTableContent(pick(benchmark, metricsTxSeqProcessing), baseBenchmark, 'public data writes')} diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index 3565613b9b4..8b52b4a3fd3 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -137,7 +137,7 @@ describe('sequencer/solo_block_builder', () => { return makeEmptyProcessedTxFromHistoricalTreeRoots(header, chainId, version); }; - // Updates the expectedDb trees based on the new commitments, contracts, and nullifiers from these txs + // Updates the expectedDb trees based on the new note hashes, contracts, and nullifiers from these txs const updateExpectedTreesFromTxs = async (txs: ProcessedTx[]) => { const newContracts = txs.flatMap(tx => tx.data.end.newContracts.map(cd => cd.hash())); for (const [tree, leaves] of [ diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index ffe9b61561e..6bc50d148e0 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -941,7 +941,7 @@ describe('Private Execution test suite', () => { ); expect(newNoteHashes).toHaveLength(1); - const commitment = newNoteHashes[0]; + const noteHash = newNoteHashes[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner); const noteTypeId = new Fr(869710811710178111116101n); // ValueNote @@ -951,7 +951,7 @@ describe('Private Execution test suite', () => { noteTypeId, noteAndSlot.note, ); - expect(commitment).toEqual(innerNoteHash); + expect(noteHash).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) const readRequest = sideEffectArrayToValueArray(result.callStackItem.publicInputs.readRequests)[0]; @@ -1033,14 +1033,14 @@ describe('Private Execution test suite', () => { ); expect(newNoteHashes).toHaveLength(1); - const commitment = newNoteHashes[0]; + const noteHash = newNoteHashes[0]; const innerNoteHash = await acirSimulator.computeInnerNoteHash( contractAddress, noteAndSlot.storageSlot, noteAndSlot.noteTypeId, noteAndSlot.note, ); - expect(commitment).toEqual(innerNoteHash); + expect(noteHash).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) const readRequest = execGetThenNullify.callStackItem.publicInputs.readRequests[0]; @@ -1097,8 +1097,8 @@ describe('Private Execution test suite', () => { ); expect(newNoteHashes).toHaveLength(1); - const commitment = newNoteHashes[0]; - expect(commitment).toEqual( + const noteHash = newNoteHashes[0]; + expect(noteHash).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, storageSlot, diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 835de73ed61..370c02c6ff4 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -22,7 +22,7 @@ export interface PublicExecutionResult { execution: PublicExecution; /** The return values of the function. */ returnValues: Fr[]; - /** The new commitments to be inserted into the commitments tree. */ + /** The new note hashes to be inserted into the commitments tree. */ newNoteHashes: SideEffect[]; /** The new l2 to l1 messages generated in this call. */ newL2ToL1Messages: L2ToL1Message[]; diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index 88ef7c35125..9070b0e1938 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -302,7 +302,7 @@ describe('ACIR public execution simulator', () => { params = [amount, new Fr(1)]; }); - it('Should be able to create a commitment from the public context', async () => { + it('Should be able to create a note hash from the public context', async () => { const shieldArtifact = TokenContractArtifact.functions.find(f => f.name === 'shield')!; const msgSender = AztecAddress.random(); const secretHash = Fr.random(); @@ -327,7 +327,7 @@ describe('ACIR public execution simulator', () => { const execution: PublicExecution = { contractAddress, functionData, args, callContext }; const result = await executor.simulate(execution, GlobalVariables.empty()); - // Assert the commitment was created + // Assert the note hash was created expect(result.newNoteHashes.length).toEqual(1); const expectedNoteHash = pedersenHash([amount.toBuffer(), secretHash.toBuffer()]); diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index 3c25882bfed..783523d6808 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -13,7 +13,7 @@ import { WorldStateRunningState, WorldStateStatus, WorldStateSynchronizer } from /** * Synchronizes the world state with the L2 blocks from a L2BlockSource. - * The synchronizer will download the L2 blocks from the L2BlockSource and insert the new commitments into the merkle + * The synchronizer will download the L2 blocks from the L2BlockSource and insert the new note hashes into the merkle * tree. */ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { @@ -171,7 +171,7 @@ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { } /** - * Handles a list of L2 blocks (i.e. Inserts the new commitments into the merkle tree). + * Handles a list of L2 blocks (i.e. Inserts the new note hashes into the merkle tree). * @param l2Blocks - The L2 blocks to handle. * @returns Whether the block handled was produced by this same node. */ @@ -188,7 +188,7 @@ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param l2Block - The L2 block to handle. */ private async handleL2Block(l2Block: L2Block): Promise { diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts index 560906b4d69..4beda52eed7 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts @@ -138,7 +138,7 @@ export interface MerkleTreeOperations { ): Promise>; /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. */ handleL2Block(block: L2Block): Promise; diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts index 26c3cceb896..446a2c501da 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts @@ -141,7 +141,7 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. * @returns Whether the block handled was produced by this same node. */ 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 29c98b8b805..4d72a6035e7 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 @@ -352,7 +352,7 @@ export class MerkleTrees implements MerkleTreeDb { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. * @returns Whether the block handled was produced by this same node. */ @@ -483,7 +483,7 @@ export class MerkleTrees implements MerkleTreeDb { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param l2Block - The L2 block to handle. */ async #handleL2Block(l2Block: L2Block): Promise { diff --git a/yellow-paper/docs/calls/public-private-messaging.md b/yellow-paper/docs/calls/public-private-messaging.md index b75cc6f622d..9d8e164625c 100644 --- a/yellow-paper/docs/calls/public-private-messaging.md +++ b/yellow-paper/docs/calls/public-private-messaging.md @@ -79,6 +79,6 @@ Since public functions execute after private functions, it isn't possible for a To elaborate, a public function may not have read access to encrypted private state in the Note Hash Tree, but it can write to it. You could create a note in the public domain, compute its note hash which gets passed to the inputs of the public VM which adds the hash to the note hash tree. The user who wants to redeem the note can add the note preimage to their PXE and then redeem/nullify the note in the private domain at a later time. -In the picture below, it is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new commitments, potentially as part of transferring funds from the public domain to the private domain). +In the picture below, it is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new note hashes, potentially as part of transferring funds from the public domain to the private domain). ![Public - Private Messaging](./images/calls/pub_pvt_messaging.png) diff --git a/yellow-paper/docs/data-publication-and-availability/index.md b/yellow-paper/docs/data-publication-and-availability/index.md index 4e5aed122a5..fc601823a9b 100644 --- a/yellow-paper/docs/data-publication-and-availability/index.md +++ b/yellow-paper/docs/data-publication-and-availability/index.md @@ -182,7 +182,7 @@ Someone: 787 bytes Total: 1098 bytes ``` -For a more liberal estimation, lets suppose we emit 4 nullifiers, 4 new commitments, and 4 public data writes instead per transaction. +For a more liberal estimation, lets suppose we emit 4 nullifiers, 4 new note hashes, and 4 public data writes instead per transaction. ```python Tx ((512, 1036) bytes): comms=4, nulls=4, pubs=4, l2_to_l1=0, e_logs=988, u_logs=48 From fe9b6403e6919fa5fea057d6c6b85099c37ed3c2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 16:17:18 +0000 Subject: [PATCH 05/11] more stupid renamings --- .../src/contracts/target/blank-Blank.json | 2 +- .../learn/concepts/storage/storage_slots.md | 2 +- .../aztec-nr/aztec/src/note/utils.nr | 9 ++-- .../src/private_kernel_tail.nr | 52 +++++++++---------- .../src/crates/types/src/constants.nr | 8 +-- .../src/crates/types/src/hash.nr | 37 +++++++------ .../fixtures/Benchmarking.test.json | 6 +-- yarn-project/circuits.js/src/constants.gen.ts | 8 +-- yarn-project/circuits.js/src/hash/hash.ts | 10 ++-- yellow-paper/docs/state/note-hash-tree.md | 8 +-- 10 files changed, 69 insertions(+), 73 deletions(-) diff --git a/boxes/blank/src/contracts/target/blank-Blank.json b/boxes/blank/src/contracts/target/blank-Blank.json index 182ddde6cc5..3fa785d5018 100644 --- a/boxes/blank/src/contracts/target/blank-Blank.json +++ b/boxes/blank/src/contracts/target/blank-Blank.json @@ -1 +1 @@ -{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"H4sIAAAAAAAA/+1dCXxcxXmfXV2rY2X5li3ZfrIOH5KlXR22RIAs5j6SACGFQALIaG1EbIvIMuAkQBJCQm4IJJBAIISE3Af0btrmaJsW2gZo0zRt2oakLaRHmjTp3cbNfKv3ef8ajWRp/c3y3m80v9/seztv3sz//828b2a+NzPvjIRSbdqTo0NS+wrtA/hfGZ7z/yrjf7Xxv8a4v9b4nzb+LzP+Lzf+rzT+rw7/owspqFx4HMjsHBzM7+rPZweyo5n+kT3DQ5nBoT07h7PD2aHhobH+4YGB/PDg8K6RPSO7MiPZwYF8du/QyMDezLTrgrQyJ+gIWwowd2h/VPvO8Njl2bFH+y1hmaFctngqD5TLVjX9/LFLwPk2Nf0sqVBu7AIlVFcHM9lqSqRSWR0911XheT3ES4ZhTRDGuOu0bwzP9+WnLh49ODZx4Kzx/P4xZJa0sDUd5VhhxK+Hc75Wa0snFx4zJ+aymKa0ytkuiJMfLRYOpY0qh1x3KDSb0BPCcutWsuqUHT0yXCWrLfjZVVjOUxDvqHJTR2zybbLgdFphXRRmj4N0dyi5h8kV7x3yZZRRlgrhQqaZE3RxVBY1gLM3PPZx2uGRn9j+8DgQHge1bwjbM0ft7TC2t6ZssXXjOMSnAa4njDa4cE8YVgFhFZUzkimEVYZ/sE2vCsOqIawa8uawGkMuTYCF46XUTGWbC88zJ+hSgC8QTLcgEzXTmWUSwHk1cKuSx5N1xTOliuUmLb9qtXD5peBY40h+LnhSmnWO5JdSC5dfHciv1pH8XPCkdBscya9OLVx+DSC/ekfyc8GT0m10JL8GtXD5NYL80o7k54Kno3QLeJc5wsuDhqQw3pXyeIepHi1XC69HK6EerXBULg54FsplFfCTSpfSWA3yWW7IKQ3XV4HsVjuQXQLy5bT5/2pL3oID6YIc1hxHDmssWNaUWQ6IcQnvEt4lvNHDuyoCeCnvteJ5Z3fVG3mTm6+9XetYFm54TrcHzcBjpcEnDdexfjY74JiAfDlt/o8Yl/Au4V3Cu4R3Ce8S3iW8S3iX8C7hXcK7hHcJ7xJe3/FS3uvk8x6oN/ImlzD+B3C+zrEsHPEs2EPWA4+1Bp80XMfyXu+AYwLy5bT5P2JcwusObxquJwGPg7qXXcjzhHgSEcBTr+xzrNYZMqMwlinOoWoJz3EOVWt4jnOoNoTnOIdqY3iOc6g2qaJMOCwIz2shrC08r4OwzXDOx/bwHOeHdYTnaQjrDM8bIawrPF8GYVvC8yYI2xqeL4ewbeH5CgjbHp6vhLDu8HwNhPWE52shjOdYNkMYlw2WJZfNegjjsmmBMC6bVgjjstkAYVw2GyGMy2YThOFcGw7jsmmDMC4bLCsum3YI47LpgDAum04I47LpgjAumy0QxmWzFcK4bLZBGJfNdgjj9yTdEMa6rQfCuAy5rEh25yWK1/l+fKY4H3ymdljy67Hg4nPUI3xPoGT1COYVwH/OrwFwbI8InqQFD5d1Tg5PYc7DVnmew8SN63B1mDbj5/wqIU5lWAD8THA4Oa5T20A+3UY85JFTsn29Lkfy6TTkw/i7QD7H9IUhHw5H+WwF+Wwx4iGPnBLj0U/pdjiST7shH8bfAfLhOCsM+XA4yqcL5NNpxEMeOSU3dqF0NzuST5shH8a/GeTDcdYZ8uFwlE8HyKfdiIc8ckqMxyCuF5SWzyZDPlgOLB+OExjy4XCUz2aQT5sRD3nklBiPIUp3oyP5bDDkw/g3gnw4zhZDPhyO8glAPpuMeMgjp8R47KR0Wx3Jp8WQD+NvBflwnF5DPhyO8tkI8tlgxEMeOSXGY5ej8eswjl9ZPox/PciH4wwZ8llnkU8ryKfFiJeCeAkl2x/j/imvg+82cFVCnBcBD+wXY3+d42Jfn3ngOIHlhGMMXtOE4xNe34RjG17rhOMi7jNi35v75tjX5zEVjr14TIVjLx5T9UIYj6n6IIzHVIypVjmzm/SjLNkljP8BnKMthe/Dse56QxaEu0Ued6GerTcw8v8WwMhhKwCPK/tTlYHHrAMu864x8q4pY961Rt61Zcy73si7vox5p42802XMe5WR9yoj77lsna7wKAOPmgdPc8TwrIwYnlURw7MsYnjqIoanPmJ4KiOGpypieJZHDE85+iaLwdMYMTypiOGpjRieiojhWRcxPGsjhqcc78IXg2dNxPA0RQxPQ8TwpCOGpzpieGoihicRATxzze3g6/gemu0n+B4abbQcxvYznNvBNlmc28G2N5zbEaiiTDiM7XY4t4PfEeDcDrT58RHftXAY2wtxbge/s8K5HWxrxLkdW8NznNvB70txzga/T14FYSxLlD3LEu2LLEucd8GyRNskyxLnXbAs0a7JsgwgjGWJNlGWJc67YFmibFmWOO+CZYm2WJYlzrsw3zvjXAycd8F9cZx3wf1hli1x/WlF8Trfj3WW88E6u92S3zYLLj7H59TBO/zCc4p5BfAf3zUnDIwvNJ6aiOGpjhiedMTwNEQMT1PE8KyJGJ7VEcOzNmJ41kUMT0XE8NRGDE8qYngaI4ZnRcTwLI8YnqqI4amMGJ76iOGpixieZRHDsypieFZGDE9zxPAky4iHx6Octjmnm/J2MM+4ME+9U5xTdhdxYnuBOc+Y86uEOB2hsPmZ5XByPH7HecZbjXhueExvot9hlM1Wg0fSgicwMOXkMBXmzreLc50uM7YFcZmZ87krIU6vUWYcTm67IaMGNXsedUo5mcNdeJ5WAJYA/tvyltyLEdfUcvrUjxlKFvPtks93hk6jsrsVcOC6B45zerKIbSRZLCNz3h7afPF93gaQbU6QA+fFafN/zg/nsKK91Fzjibhtczlt6+M4Ps+zdLA+JYPlxGmb5ZSE8y0QzyzjAOKx/sEyPhfK+EshSUf1bwixJi2cUGcJ5lv4FAGu2Wk35JZUs9fs5EI8baooWxk80zo0UDPLiPNvgzLiOBcbOpTDyW03uFDd32zES8G59MdZsJ52GvkmgQ/Hy4V4NkFcGTzTcsV3SoGavVakEuJcYciVwxXItQ3kusWIl4LzhJJ9/tsAS8KSN9bZNoinjHtta60c9IHm7Z92WuQlmHc/vr9DmSkDjzJk6KiNGsB3mwvBg+t05J+L6b6gA56FcQG3h9J7VbdYyos5pNXs9j2l3K0d2GCUm7l+aAmvW7yEp9PAinMKOiOCkcPwPXuzIUfqZ90K/XwH/Z0Bwst9Ku7nMw4co3GcL1cUsd0G/XxzLI7zLlDmAcglJ8Mha7aBgZrZF2OMtrWyrtq3dgNPu0UWL2TeLIOcktXxgTynQh011wib5YtrhO8y+mq4RpjrKfbVOo14yCOnZNtWB32aAdQ5C1kjfJ8hnw0W+QQgnzKtEe7HPkIgLJ/FrBF+yJBPi0U+x1sj7GCsn8U5auzm6yviWNlFW4fz3haCx7aGWhpPyyLwYH/FxfxJtBktBA+u7+t2hGf9IvB0A54eR3i6F4GnB/DscISnZxF4GAP158w2lsL42dgEYVw/sf/MdQT3DONy2gxh5t5OacCLNh0OQ5ukbf20i2cwoeZeP437BjAXnCfM52zry6mZuisnh3MYbcPJMF1znTfqBUGbTdZR/S1w4j0AzL0ecI8EjvMktHMpCJfE5OpZpTT6gJNtLwi+/hTYrZ8Jz7Htwn0lnrVcZzefLmDZEd+sPN+CnY+/k8tlm7XkPQBYhfLOYt6J0HM+HF4J599lBQXxyLGcGTfpgYwlHp53Gfek4XrGwjsQ5o1fFQ/gP+dHdeabUL+etYzXJTEhb5RPK8iHr6PuwnY2p2bqfsbbJ4+3oJP4meR6y1jw+eU4PzB00g4HmBxxLZRNL3Bqt/Dk6z+EOvMj0DlcLlyudP2o5Tq7hfRPXgidhHlHQSf9bA6dZOqXheikVuOeKOqkn0D9Ogo6yUU/HnmjfLpBPnyd+8emnSqnZo55GK8DG5m1n2T23/FZrQ5tnq77SS7sgZQG6p8eC89je0SBbTcN66K4XNAu3Wq5zm6h/aSMPN8MPh9cthlL3qg7hPKe8WyyTuJ8OLwSzlt4ogjEI8dyZtykk3ZY4uF5t3FPGq7vsPAOhHnj8x/Af86P6kwT1K9Wy/wRSUzIG+XTDvLh6zw+RzuzCrFgH47xutrHkJ9DrreMBW2UHKfD0Eku+m6ubASUBuqfLgtPvr4N6kw36BwuFy5Xun6S5Tq7+XQSy85RfzODzweX7Q5L3qg7hPKe8WyyTuJ8OLwSzkdAJ2E/wxxfk07qtcTD83bjnrSyj1kd9E2zOO7gtHcYGKnO9EL9Ogl0kqt+Uq9FPmgf5OtsH8R3OyrEgvM+GK8De7F172vGwvnhs7rb0Eku+m6ubOOUBuqfHgtPvn421JlzQedwuXC50vXLLNfZzaeT8F2tg/5mxjYu77XkjbpDKO8ZzybrJM4H7Xd8finoJOxnsJwZN+mkPks8PN9k3INjkz4L70CYNz7/Afzn/KjOXAD167Iy9JP6LPLB9xPH+hzhkXjge5KcmjlnjPG66ifxM8n1lrHg88txrjZ0kgs9GYV+Uh7qzD7QOeY8I7p+g+U6u/l0Er4PLLdOwryjoJMOz6GTTP2yEJ20wbgnijrpOqhfN4BOcmXj7rPIpwfkw9f5/WhCzVwvlFMz+3CM18GcWWs/ibHgXHKOc0uZ+kku5gdTGqh/2i08+fptUGduB53D5YL7PN1juc5uof0kB2PgjM1W2GfJ29We972QLuoofM/A53eDTsKxD8uZceP7d4yH5z3GPWgv6bbwDoR54/MfwH/Oj+rMHVC/7ilDP6nbIp/55mfYbNybARvjddVPMudMMhZ8fjnOA4ZOcqEno9BPehjqzCOgc7hccC7A45br7ObTSTiPtNw6CfOOgk56bA6dZOqXheikzcY9UdRJj0L9ehx0kov1rcgb5YM2br6+BcLWGfHRXorzw1zoUVMnBvC/CzByGPYRHK85nbVG0VxzimuxtwCuoeOsgwiMMFd9s4SaqYcC+M/54ToIMy47Xv/RFh6TarbNMadcrdGbXptpzmfn/G3z2Z+EtkupmWPa7Rb+gREP+TUb/Mo1H932rofjPGO0zQ7mcg+4bJvxO1O2Pghf/xbozm9bbBQ4J+b5Em0YOLfTgY3fasPoseSNbahQ3lYbBudjs2E8B20z2gDMeZHYNmM8PLeN0W22Gwd2o6xpjwzgP+dHdeY7UL+eh7bEwZqcWW2zaYfDtjmAsE4jPr43wPbDhd0FxwyctvlOI61m62Ls30i3x7g2utkim2YDi7lmcqUjOc21Hwx+88dV3lVG3lVlzLvGyLumjHnP9T2wcuRdb+RdX8a800be6TLm/cLU82zhe5hrHKRL5YbfOCM3X38Bv2GxWhxPJlunivua7stPvXRiKn8oAbgY61oDa0LNxM3XGyAsCecVcF+lms2/2hKWsoTVWcIa1GzXCOfL4LwJzldCGsvDcxsPjmOWUznCjxeP8VK94rqCe/bz9dUQxuWyBsIqjPRqlQVPLjxmTswVHmwCMWjJJGnkNZDZOTiY39Wfzw5kRzP9I3uGhzKDQ3t2DmeHs0PDQ2P9wwMD+eHB4V0je0Z2ZUaygwP57N6hkYG9YWaSHdysXFoZl5y7BTkPCHLmh5orG3WOqcPWFx4z4ZHckCoqAZZPd3h9COLtDNOb66FSgrLoV7KyYLdLFTtR1Rb87Cos5ymIJ935xbxMLE0WnM4UBiYulWZ/KHjpdIeV3IPsivewfBk5VWiDgmmNKNmGbKEK7SQ1t0I7CeK9yBIvEV5/UXikHtTJaqaTlrlkPT7lBZL5qfPI/FSI9+J5ZP5ikHnOEq9fFRXv0RDXaZCGUrK65WRLuidaPkMJWT0gzfuUUKbSvHcm3Oi/CmGcuwVlKVjWWVfyM3VZ5sRctkawLE5XsrqMuFKagSrqloXotjPU3LrtDIh35iLTPWuedM+CeGeruXXm2aqoM89ZZP7nzpP/uRDvvHnyPw/yP1/NrbPPV0WdfQGkQS4XHjMn5go6+xwlr7tGYqCzL3DA+6SY6OyXCMpSsKyzkvIr18C7Ty6tDL69eGl4fFl4vDA8XhQeL1bFsRJaIwMpPIOZnYUBf+VMubFDax3HobYMvxqaCMOTeE8Yhl+NrKickcz0lzrDP/il06owjA0RTZAHfvG+SloWWhpoiWQ3n3Uc8VTK4ylYx9lKTNbxw/v3j+8dz0+enz9y4ej4JNo9GHalAds02JrXySUtYY5EnDUN8AH8R3Fy8efk8i5s0Fkjz2mQm3elipMeGH8NyJ3jsOF7GfBlVwHpkGsw5MLHGnn5FDbmqnUknzpDPoy/FuTDcTYY8qmzyKcG5JMy4iGPnBLjUdigs96RfBoM+eDHmlk+5oeDl4EMTPnUwrU6Ix7yyCnZSVRpR/JpNOTD+NMgH47Tbcin0SKfepBJgxEPP76MzRrnhc2V+QzjB5mxmVwO+XFY0pJvhcGr0EwafArNZHiOH9JmncF5OX2JppR8P4vsrGcq+T77KREfq5BN+CUOeJ8ak7HKywVlKVjWWUn5mTYI4kxj/4vD40WqaFu4RC3OZvEKNbfN4hUQ7xfC9I716cFJ1+lLVLSfucFQHko23RkvVi9VxYbG0fhtAMdvZrnaxm/YyCRgTFeD9xjpNUEY88OxycGJqfG9R3h4MkazeBY65jDPKyxhDKvKSA/p8TXnbZ4yyEilfalyo6ulbdlofz5RvX+ZIC62ZVOagZqtP6nTTHqwMzxuU0W9+Eo1t/58JcS7PEzPnEHmoj4ITqLJWOCWlPae4f492Xx2ZGgsM9qvC3JsYHAIjQ+uZNHhQBbSGDtjgHGbclOnpHFerty0x1eo4oDJUXu8C9tjc1bpQttjJ/bEwWkDhgujHg4+q+awE1db+hTVRp/CkYFu3lUDnB9h5YHzdH/m9Mn86NTs3gzfYOvhIEFytmnHqCyrLfdz/IQlHXIkzJSBBSsWX4ttT+gKFY+eEPZeTrQn9Col3xOiNANVvumpki2g7dXGq7W/Uvur1MxvMbELlJimHCzlrRiuCXGgvbOOtPeAI617zOJBzjT74ysNNlUnlOwzkIJ0E5BPCoqOz3GdD66z4nLG1w3Vlnh4Xmnck4br1RbegTDvudaocX5VEIZvV3FKt4t6FsW3q6xH9NvVCw/v2T9+jX61etrBsQtHJ6fGR/efNjY2mT90yKaMKgwCc7XYx3vPinYNfDdh9gxstg4UKFZKZ62+OUYmjUxj4yvDI63wvlrNHktfHV6/KjzSi4xRA6PZOp9oiyrYGmVH5dIqzFkxxwVKybfGgtrU6VgvLnYOlzJ4dUzK6kol2ztYshv5ZzfCBpN1/h7tr1Ezd/tkFyixHvQo9urN1b0Ltc3gC/kkhB1rxCHsWCMOeYr3tAczQylV5COWbjhvHXfEcjCqGXbU2+xfGtUUdwdRyo9RDU+aoVFNyrA3usRm6quUga1OFe3O+QPjU2cevGbyyPXatnjBxD7srGOdUYZskQs5bDvRfFhluRflZw4YbG6uwQzx4glMgZJ7VklX2nZWQBfAuW0imyCerCOehfYZdzMxJ+al4To+1w4m1WVx0iGnjTjMvAUXdxfk0HgcOTRasDSWWQ44Ma/BwFpvXOdj0uCCfQiOH8uJeTuV/AS104QnqEnzpol5ux3w3i3Mm530xLwxQVkKlnV2d8TrDU8uk643eeWm3ki/GpPkvDcmnBOCnPfFhHNSkPO1MeFcIch5PCacKwU5XxcTzlVKjvNrVDw4Vwty3h8TzpKbMxyICeetgpwPxoRzlyDnCQ85X+8h59d6yHnSQ86HYsJ5TJDzVEw4S7bPh2PCWbJu3+Ah5xs95HyTh5yPeMj5dR5yfr2HnN/gIeebPeR8i4ecb/WQ8xs95PwmDzm/2UPOt3nI+S0ecr7dQ85v9ZDz2zzkfIeHnN/uIed3eMj5nR5yfpeHnN/tIef3eMj5vR5yvtNDznd5yPl9HnK+20PO93jI+f0ecv6Ah5zv9ZDzfR5y/qCHnD/kIef7PeT8gIecP+wh5wc95PyQh5w/4iHnhz3k/FEPOT/iIeePecj54x5yftRDzp/wkPMnPeT8KQ85f9pDzp/xkPNnPeT8OQ85f95Dzl/wkPMXPeT8mIecH/eQ8y/GhPPLBDn/Ukw4XyjI+ZdjwvkiQc6/EhPOFwty/tWYcL5ckPOvxYSz5Gejfj0mnCXbqt/wkPOXPOT8mx5y/i0POf+2h5y/7CHnr3jI+asecv6ah5x/x0POv+sh59/zkPPXPeT8+x5y/gMPOT/hIecnPeT8hx5y/iMPOf+xh5y/4SHnpzzk/LSHnJ/xkPOfeMj5Tz3k/E0POf+Zh5y/5SHnP48J50sEOX87Jpzzgpz/IiacTxfk/Jcx4Sz5PH/HQ85/5SHnv/aQ8994yPm7HnJ+1kPO3/OQ8/c95Py3HnL+Ow85/72HnJ/zkPPzHnL+gYec/8FDzv/oIed/8pDzP3vI+Ycecv4XDzn/yEPOP/aQ8796yPknHnL+qYec/81Dzv/uIef/8JDzf3rI+b885PzfHnL+Hw85/6+HnP/PQ84/85DzUQ85/7+HnFXCP84JDzknPeRc4SHnSg85V3nIudpDzjUeck55yLnWQ851HnKu95Bzg4ec0x5ybvSQ8zIPOTd5yHl5TDi/SpDzCg/LeaWHnFd5yHm1h5zXeMh5rYecm2PCOSXIeV1MONcKcl4fE851gpxbYsK5XpBza0w4Nwhy3hATzmlBzhtjwrlRkPOmmHBeJsg5iAnnJkHObTHhvFyQ8+aYcF4hyLk9JpxXCnLuiAnnVYKcO2PCebUg566YcF4jyHlLTDivFeS8NSacmwU5b4sJ53WCnLfHhPN6Qc7dMeHcIsi5JyacWwU574gJ5w2CnHtjwnmjIOe+mHDeJMg5ExPOgSDnbEw4twly7o8J582CnAdiwrldkPOgIGedlKoI0+oC/olQBnStUvsq7au1r9Ge3kPRexl6T0F2e7Jjk12X7Jxk9yM7GNmFyE5CdgMaR9O4ksZZNO6gfjj1S6mfRv0WasepXSM9T3ov0J6eC6onJLcO7TsB21Phca/2+7S/Vvtx7a/T/jXa79f+gPYHtZ/Q/nrtX6v9pPaHtJ/S/rD2N2h/o/Y3aX9E+9dp/3rt36D9zdrfov2t2r9R+zdp/2btb9P+Ldrfrv1btX+b9ndo/3bt36H9O7V/l/bv1v492r9X+zu1v0v792l/t/b3aP9+7T+g/b3a36f9B7X/kPb3a/+A9h/W/kHtH9L+I9o/rP1HtX9E+49p/3HtH9X+E9p/UvtPaf9p7T+j/We1/5z2n9f+C9p/UfvHtKfvw9P30un74fQ9bfq+NH1vmb4/TN/jpe/T0vda6ful9D1P+r4lfe/xK9p/VfuvaU/fi6Pvp9H3xL6uPX1vir6/RN8jou/z0Pdq6Pst9D2Tb4Rl9bT29D0E+j4A7ZdP+8fTfuq0vzjtt037T9N+zLQ/Me3XS/vX0n6utL8p7ff5rPbf0/772tN+gbR/Hu0n95z2tN8Y7b9F+1HR/ky0XxHt30P72dD+LrTfyY+1p/0waH8I2i+B9g+g9fS0vpzWW9P6Y1qPS+tTab0mrV+k9Xy0vo3We9HDQOuBaH0MrReh9RO0noDm19N8c5p/TfORaX4uzVel+Zs0n5Hm99F8N5r/RfOhaH4QzZeh+SM0n4LmF9D7dnr/TO9j6f0kva+j91f0Pofeb5C9n+zfZA8m+yjZC8l+RvYksq+QvYHG3zQepfEZjVeo/079WerfUX+HHnJqD6l9IH1J+qNNFd2q8HhyeHz51MTk6L58cGj/xFSQCQ7q39H9+yduzI/1BnjtUHDg8KGp4NDU6ORUsHdy4kCQ7aX7u8N0WsPj6NRU/sD1U8HURDA6NhbcOD51bTBxQ35yr06Tru9eZPxzFhGf9NjqMB6VHbl14f/TJidHjwTjB8fyNwUTh6eCib3BnonDB8cO4U11pdy0vJSbmku5aVMpN3WVctOOUm4aLOWm9mQp8Eq56aJSbrq8lJvuLOWme0u56cFSbnqilJueL+WmqooSbmov5abTSrnpqlJuurmUm+4v5aYnSrnp6cXcNBxG4psXdVNrKTe1l3LT9oXepH4Okl0jVbHLAQA=","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file +{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"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","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashs(\n first_nullifier: Field,\n siloed_note_hashs: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashs = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashs[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashs[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashs\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file diff --git a/docs/docs/learn/concepts/storage/storage_slots.md b/docs/docs/learn/concepts/storage/storage_slots.md index 3aff76c895d..55901f6dc7e 100644 --- a/docs/docs/learn/concepts/storage/storage_slots.md +++ b/docs/docs/learn/concepts/storage/storage_slots.md @@ -53,7 +53,7 @@ When reading the values for these notes, the application circuit can then constr To ensure that one contract cannot insert storage that other contracts would believe is theirs, we do a second siloing by hashing the `commitment` with the contract address. ```rust -siloed_commitment = H(contract_address, commitment); +siloed_note_hash = H(contract_address, commitment); ``` By doing this address-siloing at the kernel circuit we *force* the inserted commitments to include and not lie about the `contract_address`. diff --git a/noir-projects/aztec-nr/aztec/src/note/utils.nr b/noir-projects/aztec-nr/aztec/src/note/utils.nr index 8aa346dc16a..41af73a6ed7 100644 --- a/noir-projects/aztec-nr/aztec/src/note/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/note/utils.nr @@ -2,21 +2,18 @@ use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interf use dep::protocol_types::{ address::AztecAddress, - constants::{ - GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT, - GENERATOR_INDEX__SILOED_COMMITMENT -}, + constants::{GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH, GENERATOR_INDEX__SILOED_NOTE_HASH}, hash::pedersen_hash, utils::arr_copy_slice }; fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field { let inputs = [contract_address.to_field(), inner_note_hash]; - pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT) + pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH) } fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field { let inputs = [nonce, siloed_note_hash]; - pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT) + pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH) } fn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface { diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 6e6a4fcd220..6f8dcc7be59 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -13,7 +13,7 @@ use dep::types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX }, grumpkin_private_key::GrumpkinPrivateKey, - hash::{compute_commitment_nonce, compute_unique_siloed_commitment}, + hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, utils::{arrays::{array_length, array_eq}}, traits::{Empty, is_empty} }; @@ -174,27 +174,27 @@ impl PrivateKernelTailCircuitPrivateInputs { public_inputs.end.new_nullifiers = new_nullifiers_vec; } - fn apply_commitment_nonces(public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { + fn apply_note_hash_nonces(public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // tx hash let first_nullifier = public_inputs.end.new_nullifiers.get(0); - let mut unique_note_hashes = public_inputs.end.new_note_hashes.storage; + let mut siloed_note_hashes = public_inputs.end.new_note_hashes.storage; for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { // Apply nonce to all non-zero/non-empty note hashes // Nonce is the hash of the first (0th) nullifier and the note hash's index into new_note_hashes array - let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); - let hash = unique_note_hashes[c_idx]; + let nonce = compute_note_hash_nonce(first_nullifier.value, c_idx); + let hash = siloed_note_hashes[c_idx]; if hash.value != 0 { - let unique_commitment = compute_unique_siloed_commitment(nonce, hash.value); - unique_note_hashes[c_idx] = SideEffect{ - value: unique_commitment, + let unique_note_hash = compute_unique_siloed_note_hash(nonce, hash.value); + siloed_note_hashes[c_idx] = SideEffect{ + value: unique_note_hash, counter: hash.counter }; } } - public_inputs.end.new_note_hashes.storage = unique_note_hashes; + public_inputs.end.new_note_hashes.storage = siloed_note_hashes; } pub fn native_private_kernel_circuit_ordering(self) -> PrivateKernelTailCircuitPublicInputs { @@ -216,7 +216,7 @@ impl PrivateKernelTailCircuitPrivateInputs { self.match_nullifiers_to_commitments_and_squash(&mut public_inputs); - PrivateKernelTailCircuitPrivateInputs::apply_commitment_nonces(&mut public_inputs); + PrivateKernelTailCircuitPrivateInputs::apply_note_hash_nonces(&mut public_inputs); public_inputs.to_tail() } @@ -234,7 +234,7 @@ mod tests { kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, - hash::compute_unique_siloed_commitments, tests::kernel_data_builder::PreviousKernelDataBuilder, + hash::compute_unique_siloed_note_hashs, tests::kernel_data_builder::PreviousKernelDataBuilder, utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array} }; @@ -261,15 +261,15 @@ mod tests { self.previous_kernel.end.new_nullifiers.storage } - pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.compute_unique_siloed_commitments(self.previous_kernel.end.new_note_hashes.storage) + pub fn get_unique_siloed_note_hashs(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { + self.compute_unique_siloed_note_hashs(self.previous_kernel.end.new_note_hashes.storage) } // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // commitments for the given commitments. - pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { + pub fn compute_unique_siloed_note_hashs(self, commitments: [SideEffect; N]) -> [SideEffect; N] { let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); - compute_unique_siloed_commitments(first_nullifier.value, commitments) + compute_unique_siloed_note_hashs(first_nullifier.value, commitments) } pub fn append_transient_commitments(&mut self, num_commitments: Field) { @@ -363,11 +363,11 @@ mod tests { builder.append_transient_commitments(1); builder.add_transient_read(0); - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + let unique_siloed_note_hashs = builder.get_unique_siloed_note_hashs(); let public_inputs = builder.execute(); assert(array_length(public_inputs.end.new_note_hashes) == 1); - assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_commitments[0])); + assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_note_hashs[0])); } #[test] @@ -381,12 +381,12 @@ mod tests { builder.add_transient_read(1); // Read the hash at index 3; builder.add_transient_read(3); - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + let unique_siloed_note_hashs = builder.get_unique_siloed_note_hashs(); let public_inputs = builder.execute(); assert_eq(array_length(public_inputs.end.new_note_hashes), MAX_REVERTIBLE_NOTE_HASHES_PER_TX); for i in 0..MAX_REVERTIBLE_NOTE_HASHES_PER_TX { assert( - public_inputs.end.new_note_hashes[i].eq(unique_siloed_commitments[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) + public_inputs.end.new_note_hashes[i].eq(unique_siloed_note_hashs[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) ); } } @@ -433,13 +433,13 @@ mod tests { builder.nullify_transient_commitment(1, 0); let new_note_hashes = builder.get_new_note_hashes(); // The 0th hash will be chopped. - let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_note_hashes[1]]); + let unique_siloed_note_hashs = builder.compute_unique_siloed_note_hashs([new_note_hashes[1]]); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); assert( array_eq( public_inputs.end.new_note_hashes, - [unique_siloed_commitments[0]] + [unique_siloed_note_hashs[0]] ) ); // The nullifier at index 1 is chopped. @@ -498,14 +498,14 @@ mod tests { let public_inputs = builder.execute(); - let sorted_unique_commitments = compute_unique_siloed_commitments( + let sorted_unique_note_hashs = compute_unique_siloed_note_hashs( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, sorted_new_note_hashes ); for i in 0..10 { - assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_commitments[i])); + assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashs[i])); assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); } } @@ -615,7 +615,7 @@ mod tests { let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; let public_inputs = builder.execute(); - let unique_note_hashes = compute_unique_siloed_commitments( + let siloed_note_hashes = compute_unique_siloed_note_hashs( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, new_note_hashes @@ -624,14 +624,14 @@ mod tests { assert( array_eq( public_inputs.end_non_revertible.new_note_hashes, - [unique_note_hashes[0], unique_note_hashes[1]] + [siloed_note_hashes[0], siloed_note_hashes[1]] ) ); assert( array_eq( public_inputs.end.new_note_hashes, - [unique_note_hashes[2], unique_note_hashes[3]] + [siloed_note_hashes[2], siloed_note_hashes[3]] ) ); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 2e3905fdeca..be81885d059 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -192,10 +192,10 @@ global LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly. */ // Indices with size ≤ 8 -global GENERATOR_INDEX__COMMITMENT = 1; -global GENERATOR_INDEX__COMMITMENT_NONCE = 2; -global GENERATOR_INDEX__UNIQUE_COMMITMENT = 3; -global GENERATOR_INDEX__SILOED_COMMITMENT = 4; +global GENERATOR_INDEX__NOTE_HASH = 1; +global GENERATOR_INDEX__NOTE_HASH_NONCE = 2; +global GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3; +global GENERATOR_INDEX__SILOED_NOTE_HASH = 4; global GENERATOR_INDEX__NULLIFIER = 5; global GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6; global GENERATOR_INDEX__OUTER_NULLIFIER = 7; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr index 4fc79ed9af9..cedc987f0e6 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -10,11 +10,10 @@ use crate::abis::side_effect::{SideEffect}; use crate::utils::uint256::U256; use crate::constants::{ ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT, - NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT, + NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS, - GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT, - GENERATOR_INDEX__FUNCTION_ARGS + GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH, GENERATOR_INDEX__FUNCTION_ARGS }; use crate::messaging::l2_to_l1_message::L2ToL1Message; @@ -164,7 +163,7 @@ pub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field { address.to_field(), inner_commitment ], - GENERATOR_INDEX__SILOED_COMMITMENT + GENERATOR_INDEX__SILOED_NOTE_HASH ) } @@ -283,42 +282,42 @@ pub fn compute_logs_hash( ) } -pub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field { +pub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field { pedersen_hash( [ first_nullifier, commitment_index ], - GENERATOR_INDEX__COMMITMENT_NONCE + GENERATOR_INDEX__NOTE_HASH_NONCE ) } -pub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field { +pub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field { pedersen_hash( [ nonce, - siloed_commitment + siloed_note_hash ], - GENERATOR_INDEX__UNIQUE_COMMITMENT + GENERATOR_INDEX__UNIQUE_NOTE_HASH ) } -pub fn compute_unique_siloed_commitments( +pub fn compute_unique_siloed_note_hashs( first_nullifier: Field, - siloed_commitments: [SideEffect; N] + siloed_note_hashs: [SideEffect; N] ) -> [SideEffect; N] { - let mut unique_siloed_commitments = [SideEffect::empty(); N]; + let mut unique_siloed_note_hashs = [SideEffect::empty(); N]; for i in 0..N { - let siloed_commitment = siloed_commitments[i]; - if siloed_commitment.value != 0 { - let nonce = compute_commitment_nonce(first_nullifier, i); - unique_siloed_commitments[i] = SideEffect { - value: compute_unique_siloed_commitment(nonce, siloed_commitment.value), - counter: siloed_commitment.counter + let siloed_note_hash = siloed_note_hashs[i]; + if siloed_note_hash.value != 0 { + let nonce = compute_note_hash_nonce(first_nullifier, i); + unique_siloed_note_hashs[i] = SideEffect { + value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value), + counter: siloed_note_hash.counter }; } } - unique_siloed_commitments + unique_siloed_note_hashs } pub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field { diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index be58b328b32..35022771e48 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -3460,7 +3460,7 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/lifecycle.nr" }, "91": { - "source": "use dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n },\n hash::pedersen_hash,\n};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n", + "source": "use dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n },\n hash::pedersen_hash,\n};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/note_hash.nr" }, "92": { @@ -3476,11 +3476,11 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr" }, "105": { - "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_NOTE_HASHES_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__COMMITMENT_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_COMMITMENT = 3;\nglobal GENERATOR_INDEX__SILOED_COMMITMENT = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", + "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_NOTE_HASHES_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__NOTE_HASH_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3;\nglobal GENERATOR_INDEX__SILOED_NOTE_HASH = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/constants.nr" }, "111": { - "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE,\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", + "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashs(\n first_nullifier: Field,\n siloed_note_hashs: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashs = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashs[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashs[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashs\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "126": { diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 7159f96c75e..47bbff17361 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -108,10 +108,10 @@ export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 52; export const L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 64; export const LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; export enum GeneratorIndex { - COMMITMENT = 1, - COMMITMENT_NONCE = 2, - UNIQUE_COMMITMENT = 3, - SILOED_COMMITMENT = 4, + NOTE_HASH = 1, + NOTE_HASH_NONCE = 2, + UNIQUE_NOTE_HASH = 3, + SILOED_NOTE_HASH = 4, NULLIFIER = 5, INITIALIZATION_NULLIFIER = 6, OUTER_NULLIFIER = 7, diff --git a/yarn-project/circuits.js/src/hash/hash.ts b/yarn-project/circuits.js/src/hash/hash.ts index a723547c489..c545af04dfc 100644 --- a/yarn-project/circuits.js/src/hash/hash.ts +++ b/yarn-project/circuits.js/src/hash/hash.ts @@ -115,18 +115,18 @@ export function hashConstructor(functionData: FunctionData, argsHash: Fr, constr * @returns A commitment nonce. */ export function computeCommitmentNonce(nullifierZero: Fr, commitmentIndex: number): Fr { - return pedersenHash([nullifierZero.toBuffer(), numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.COMMITMENT_NONCE); + return pedersenHash([nullifierZero.toBuffer(), numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.NOTE_HASH_NONCE); } /** * Computes a siloed commitment, given the contract address and the commitment itself. * A siloed commitment effectively namespaces a commitment to a specific contract. * @param contract - The contract address - * @param innerCommitment - The commitment to silo. + * @param innerNoteHash - The commitment to silo. * @returns A siloed commitment. */ -export function siloNoteHash(contract: AztecAddress, innerCommitment: Fr): Fr { - return pedersenHash([contract.toBuffer(), innerCommitment.toBuffer()], GeneratorIndex.SILOED_COMMITMENT); +export function siloNoteHash(contract: AztecAddress, innerNoteHash: Fr): Fr { + return pedersenHash([contract.toBuffer(), innerNoteHash.toBuffer()], GeneratorIndex.SILOED_NOTE_HASH); } /** @@ -136,7 +136,7 @@ export function siloNoteHash(contract: AztecAddress, innerCommitment: Fr): Fr { * @returns A unique commitment. */ export function computeUniqueCommitment(nonce: Fr, siloedCommitment: Fr): Fr { - return pedersenHash([nonce.toBuffer(), siloedCommitment.toBuffer()], GeneratorIndex.UNIQUE_COMMITMENT); + return pedersenHash([nonce.toBuffer(), siloedCommitment.toBuffer()], GeneratorIndex.UNIQUE_NOTE_HASH); } /** diff --git a/yellow-paper/docs/state/note-hash-tree.md b/yellow-paper/docs/state/note-hash-tree.md index a11c0eddda2..788b02363ae 100644 --- a/yellow-paper/docs/state/note-hash-tree.md +++ b/yellow-paper/docs/state/note-hash-tree.md @@ -11,11 +11,11 @@ The Kernel circuit also guarantees uniqueness of commitments by further hashing The pseudocode for siloing and making a commitment unique is the following, where each `hash` operation is a Pedersen hash with a unique generator index, indicated by the constant in all caps. ``` -fn compute_unique_siloed_commitment(commitment, contract, transaction): - let siloed_commitment = hash([contract, commitment], SILOED_COMMITMENT) +fn compute_unique_siloed_note_hash(commitment, contract, transaction): + let siloed_note_hash = hash([contract, commitment], SILOED_NOTE_HASH) let index = index_of(commitment, transaction.commitments) - let nonce = hash([transaction.tx_hash, index], COMMITMENT_NONCE) - return hash([nonce, siloed_commitment], UNIQUE_COMMITMENT) + let nonce = hash([transaction.tx_hash, index], NOTE_HASH_NONCE) + return hash([nonce, siloed_note_hash], UNIQUE_NOTE_HASH) ``` The unique siloed commitment of a note is included in the [transaction `data`](../transactions/tx-object.md), and then inserted into the Note Hash tree by the sequencer as the transaction is included in a block. From 8f68ef20a69d770d0a07cdfc1498307789034366 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 16:27:55 +0000 Subject: [PATCH 06/11] stupid renamings 2 --- CHANGELOG.md | 2 +- .../historical_data/slow_updates_tree/main.md | 2 +- .../developers/debugging/sandbox-errors.md | 8 +++--- .../public_private_calls/slow_updates_tree.md | 2 +- docs/docs/misc/roadmap/engineering_roadmap.md | 2 +- .../pending_commitments_contract/src/main.nr | 6 ++--- .../crates/private-kernel-lib/src/common.nr | 6 ++--- .../types/src/abis/membership_witness.nr | 4 +-- .../types/src/tests/fixtures/read_requests.nr | 2 +- .../fixtures/Benchmarking.test.json | 2 +- .../read_request_membership_witness.ts | 26 +++++++++---------- .../src/shared/cross_chain_test_harness.ts | 2 +- .../src/type_conversion.ts | 2 +- .../src/client/private_execution.test.ts | 6 ++--- 14 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78f957daf26..533598f79b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1396,7 +1396,7 @@ * Confusing "Unknown complete address" error ([#2967](https://github.com/AztecProtocol/aztec-packages/issues/2967)) ([3a8f54a](https://github.com/AztecProtocol/aztec-packages/commit/3a8f54a8330620669380cbd1b06551aa10703ec3)) * Force jest to quit, otherwise CI can rack up to 3hrs of credits per job. ([#2899](https://github.com/AztecProtocol/aztec-packages/issues/2899)) ([ba2f671](https://github.com/AztecProtocol/aztec-packages/commit/ba2f671c79ac3c2aa19c769c3db56a27a7e0854f)) * Honk sumcheck performance ([#2925](https://github.com/AztecProtocol/aztec-packages/issues/2925)) ([5fbfe6e](https://github.com/AztecProtocol/aztec-packages/commit/5fbfe6eeccdb23f734fb36f30d1e33340f9fb07a)) -* Pending commitments contract using the wrong number of arguments ([#2959](https://github.com/AztecProtocol/aztec-packages/issues/2959)) ([655c322](https://github.com/AztecProtocol/aztec-packages/commit/655c322ab0e71074b3f747c95bfafbd6b7008217)) +* pending note hashes contract using the wrong number of arguments ([#2959](https://github.com/AztecProtocol/aztec-packages/issues/2959)) ([655c322](https://github.com/AztecProtocol/aztec-packages/commit/655c322ab0e71074b3f747c95bfafbd6b7008217)) * Prettierignore in boxes ([#2902](https://github.com/AztecProtocol/aztec-packages/issues/2902)) ([8f7a200](https://github.com/AztecProtocol/aztec-packages/commit/8f7a200e809a9dc6ac8e1beaf3bbf1fd83e5a1fb)) * Randomness in `AddressNote` ([#2965](https://github.com/AztecProtocol/aztec-packages/issues/2965)) ([4dc49a9](https://github.com/AztecProtocol/aztec-packages/commit/4dc49a92428216928d918d893c40745957e5b983)) * Yarn lock ([#2923](https://github.com/AztecProtocol/aztec-packages/issues/2923)) ([7042bc6](https://github.com/AztecProtocol/aztec-packages/commit/7042bc6130f8473b6c59bf9a0146ea8b2c3c7483)) diff --git a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md index 170981942d9..235f450ac3c 100644 --- a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md +++ b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md @@ -69,7 +69,7 @@ graph TD CurrentM --> Value1[Current Value 1] CurrentM --> Value2[Current Value 2] CurrentM --> ValueN[Current Value N] - Pending --> PendingM[Pending Commitment 1] + Pending --> PendingM[pending note hash 1] PendingM --> PValue1[Pending Value 1] PendingM --> PValue2[Pending Value 2] PendingM --> PValueN[Pending Value N] diff --git a/docs/docs/developers/debugging/sandbox-errors.md b/docs/docs/developers/debugging/sandbox-errors.md index e81574b8470..c321da86048 100644 --- a/docs/docs/developers/debugging/sandbox-errors.md +++ b/docs/docs/developers/debugging/sandbox-errors.md @@ -67,13 +67,13 @@ For a non transient read, we fetch the merkle root from the membership witnesses #### 2019 - PRIVATE_KERNEL\_\_TRANSIENT_READ_REQUEST_NO_MATCH -A pending commitment is the one that is not yet added to note hash tree. -A transient read is when we try to "read" a pending commitment. -This error happens when you try to read a pending commitment that doesn't exist. +A pending note hash is the one that is not yet added to note hash tree. +A transient read is when we try to "read" a pending note hash. +This error happens when you try to read a pending note hash that doesn't exist. #### 2021 - PRIVATE_KERNEL\_\_UNRESOLVED_NON_TRANSIENT_READ_REQUEST -For a transient read request we skip merkle membership checks since pending commitments aren't inserted into the note hash tree yet. +For a transient read request we skip merkle membership checks since pending note hashes aren't inserted into the note hash tree yet. But for non transient reads, we do a merkle membership check. Reads are done at the kernel circuit. So this checks that there are no already unresolved reads from a previous kernel iteration (other than non transient ones). #### 3001 - PUBLIC_KERNEL\_\_UNSUPPORTED_OP diff --git a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md index 64ced6272fd..21e04e42523 100644 --- a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md +++ b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md @@ -41,7 +41,7 @@ graph TD; CurrentM --> Value1[Current Value 1] CurrentM --> Value2[Current Value 2] CurrentM --> ValueN[Current Value n] - Pending --> PendingM[Pending Commitment 1] + Pending --> PendingM[pending note hash 1] PendingM --> PValue1[Pending Value 1] PendingM --> PValue2[Pending Value 2] PendingM --> PValueN[Pending Value n] diff --git a/docs/docs/misc/roadmap/engineering_roadmap.md b/docs/docs/misc/roadmap/engineering_roadmap.md index 48986906d0b..2e232a2c023 100644 --- a/docs/docs/misc/roadmap/engineering_roadmap.md +++ b/docs/docs/misc/roadmap/engineering_roadmap.md @@ -177,7 +177,7 @@ Some example features: - This would give much more flexibility over the sizes of various arrays that a circuit can output. Without it, if one array of an app circuit needs to be size 2000, but other arrays aren't used, we'd use a kernel where every array is size 2048, meaning a huge amount of unnecessary loops of computation for those empty arrays. - Improvements - We can definitely change how call stacks are processed within a kernel, to reduce hashing. - - Squash pending commitments/nullifiers in every kernel iteration, to enable a deeper nested call depth. + - Squash pending note hashes/nullifiers in every kernel iteration, to enable a deeper nested call depth. - Topology of a rollup - Revisit the current topology: - We can make the rollup trees 'wonky' (rather than balanced), meaning a sequencer doesn't need to prove a load of pointless 'padding' proofs? diff --git a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr index 69b504d2c6d..894fccf454c 100644 --- a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -23,7 +23,7 @@ contract PendingCommitments { #[aztec(private)] fn constructor() {} - // Confirm can access pending commitments by creating / inserting a note and then + // Confirm can access pending note hashes by creating / inserting a note and then // getting / reading that note all in the same contract function // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" #[aztec(private)] @@ -107,7 +107,7 @@ contract PendingCommitments { assert(maybe_notes[1].is_none()); } - // Test pending commitments with note insertion done in a nested call + // Test pending note hashes with note insertion done in a nested call // and "read" / get of that pending note/commitment in another nested call // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" #[aztec(private)] @@ -244,7 +244,7 @@ contract PendingCommitments { [owner.to_field()] ); } - // Confirm cannot get/read a pending commitment in a nested call + // Confirm cannot get/read a pending note hash in a nested call // that is created/inserted later in execution but in the parent. // NOTE: This test is especially important in an end-to-end context because the parent call // (and therefore the insertion) will be processed in an earlier kernel iteration, but the diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index 4ab6c14417f..3a9adffd96b 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -63,11 +63,11 @@ pub fn validate_read_requests( let read_request = read_requests[rr_idx].value; let witness = read_request_membership_witnesses[rr_idx]; - // A pending commitment is the one that is not yet added to note hash tree - // A "transient read" is when we try to "read" a pending commitment within a transaction + // A pending note hash is the one that is not yet added to note hash tree + // A "transient read" is when we try to "read" a pending note hash within a transaction // between function calls, as opposed to reading the outputs of a previous transaction // which is a "pending read". - // A transient read is when we try to "read" a pending commitment + // A transient read is when we try to "read" a pending note hash // We determine if it is a transient read depending on the leaf index from the membership witness // Note that the Merkle membership proof would be null and void in case of an transient read // but we use the leaf index as a placeholder to detect a 'pending note read'. diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr index 38d6777a31b..68781ba8e8e 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr @@ -45,9 +45,9 @@ struct ArchiveRootMembershipWitness{ struct ReadRequestMembershipWitness { leaf_index: Field, sibling_path: [Field; NOTE_HASH_TREE_HEIGHT], - // whether or not the read request corresponds to a pending commitment + // whether or not the read request corresponds to a pending note hash // In case we change the default to true, we have to adapt is_empty() method // hint to point kernel to the commitment this rr corresponds to is_transient: bool, - hint_to_commitment: Field, + hint_to_note_hash: Field, } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr index 3b655178474..5c1eacf6658 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr @@ -24,7 +24,7 @@ pub fn generate_read_requests_with_config( leaf_index: i, sibling_path: fixtures::note_hash_tree::SIBLING_PATHS[i], is_transient, - hint_to_commitment: hints_to_commitment[i] + hint_to_note_hash: hints_to_commitment[i] }; read_request_membership_witnesses.push(witness); } diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index 35022771e48..b88c41f001e 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -3456,7 +3456,7 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/note_getter.nr" }, "88": { - "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let serialized_note = serialize(*note);\n assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = 0;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note, context);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}\n", + "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let serialized_note = serialize(*note);\n assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = 0;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note, context);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/lifecycle.nr" }, "91": { diff --git a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts index ccad2b68bb2..e77b32692ab 100644 --- a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts +++ b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts @@ -22,19 +22,19 @@ export class ReadRequestMembershipWitness { */ public siblingPath: Tuple, /** - * Whether or not the read request corresponds to a pending commitment. + * Whether or not the read request corresponds to a pending note hash. */ public isTransient = false, /** - * When transient, the commitment being read was created by some app circuit in the current TX. - * The kernel will need some hint to efficiently find that commitment for a given read request. + * When transient, the note hash being read was created by some app circuit in the current TX. + * The kernel will need some hint to efficiently find that note hash for a given read request. * When not transient, this can be 0. */ - public hintToCommitment: Fr, + public hintToNoteHash: Fr, ) { - if (hintToCommitment.toBigInt() > MAX_NEW_NOTE_HASHES_PER_CALL) { + if (hintToNoteHash.toBigInt() > MAX_NEW_NOTE_HASHES_PER_CALL) { throw new Error( - `Expected ReadRequestMembershipWitness' hintToCommitment(${hintToCommitment}) to be <= NEW_COMMITMENTS_LENGTH(${MAX_NEW_NOTE_HASHES_PER_CALL})`, + `Expected ReadRequestMembershipWitness' hintToNoteHash(${hintToNoteHash}) to be <= NEW_NOTE_HASHES_LENGTH(${MAX_NEW_NOTE_HASHES_PER_CALL})`, ); } } @@ -44,7 +44,7 @@ export class ReadRequestMembershipWitness { toBufferBE(this.leafIndex.toBigInt(), 32), ...this.siblingPath, this.isTransient, - this.hintToCommitment, + this.hintToNoteHash, ); } @@ -93,26 +93,26 @@ export class ReadRequestMembershipWitness { leafIndex: Fr, siblingPath: Tuple, isTransient: boolean, - hintToCommitment: Fr, + hintToNoteHash: Fr, ): ReadRequestMembershipWitness { return new ReadRequestMembershipWitness( leafIndex, siblingPath.map(x => Fr.fromBuffer(x)) as Tuple, isTransient, - hintToCommitment, + hintToNoteHash, ); } static fromMembershipWitness( membershipWitness: MembershipWitness, isTransient: boolean, - hintToCommitment: Fr, + hintToNoteHash: Fr, ): ReadRequestMembershipWitness { return new ReadRequestMembershipWitness( new Fr(membershipWitness.leafIndex), membershipWitness.siblingPath as Tuple, isTransient, - hintToCommitment, + hintToNoteHash, ); } @@ -126,7 +126,7 @@ export class ReadRequestMembershipWitness { const leafIndex = Fr.fromBuffer(reader); const siblingPath = reader.readArray(NOTE_HASH_TREE_HEIGHT, Fr); const isTransient = reader.readBoolean(); - const hintToCommitment = Fr.fromBuffer(reader); - return new ReadRequestMembershipWitness(leafIndex, siblingPath, isTransient, hintToCommitment); + const hintToNoteHash = Fr.fromBuffer(reader); + return new ReadRequestMembershipWitness(leafIndex, siblingPath, isTransient, hintToNoteHash); } } diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 6944399b88f..14b245ef065 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -440,7 +440,7 @@ export class CrossChainTestHarness { } async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { - this.logger('Spending commitment in private call'); + this.logger('Spending note hash in private call'); const privateTx = this.l2Token.methods.redeem_shield(this.ownerAddress, shieldAmount, secret).send(); const privateReceipt = await privateTx.wait(); expect(privateReceipt.status).toBe(TxStatus.MINED); diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index a75e80d7212..fb32ea07a6d 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -720,7 +720,7 @@ export function mapReadRequestMembershipWitnessToNoir( leaf_index: mapFieldToNoir(readRequestMembershipWitness.leafIndex), sibling_path: mapTuple(readRequestMembershipWitness.siblingPath, mapFieldToNoir), is_transient: readRequestMembershipWitness.isTransient, - hint_to_commitment: mapFieldToNoir(readRequestMembershipWitness.hintToCommitment), + hint_to_note_hash: mapFieldToNoir(readRequestMembershipWitness.hintToNoteHash), }; } diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 6bc50d148e0..63d3b4d09e5 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -893,7 +893,7 @@ describe('Private Execution test suite', () => { }); }); - describe('pending commitments contract', () => { + describe('pending note hashes contract', () => { beforeEach(() => { oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { if (address.equals(owner)) { @@ -912,7 +912,7 @@ describe('Private Execution test suite', () => { ); }); - it('should be able to insert, read, and nullify pending commitments in one call', async () => { + it('should be able to insert, read, and nullify pending note hashes in one call', async () => { oracle.getNotes.mockResolvedValue([]); const amountToTransfer = 100n; @@ -973,7 +973,7 @@ describe('Private Execution test suite', () => { expect(nullifier.value).toEqual(expectedNullifier); }); - it('should be able to insert, read, and nullify pending commitments in nested calls', async () => { + it('should be able to insert, read, and nullify pending note hashes in nested calls', async () => { oracle.getNotes.mockResolvedValue([]); const amountToTransfer = 100n; From 62996a6e0a06f85822092a8f42d0fd5279bd5735 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 16:55:22 +0000 Subject: [PATCH 07/11] updated snap --- .../src/__snapshots__/index.test.ts.snap | 694 +++++++++--------- 1 file changed, 347 insertions(+), 347 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap index 84296c76d5e..6e46b38bd9f 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap @@ -1055,9 +1055,9 @@ PrivateKernelInnerCircuitPublicInputs { }, }, ], - "newNoteHashes": [ - SideEffect { - "counter": Fr { + "newContracts": [ + NewContractData { + "contractAddress": AztecAddress { "asBigInt": 0n, "asBuffer": { "data": [ @@ -1097,7 +1097,7 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + "contractClassId": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -1137,11 +1137,8 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { + "portalContractAddress": EthAddress { + "buffer": { "data": [ 0, 0, @@ -1163,63 +1160,95 @@ PrivateKernelInnerCircuitPublicInputs { 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, ], "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, + }, + ], + "newL2ToL1Msgs": [ + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", }, }, + ], + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 0n, @@ -6304,10 +6333,8 @@ PrivateKernelInnerCircuitPublicInputs { }, }, }, - ], - "newContracts": [ - NewContractData { - "contractAddress": AztecAddress { + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -6347,7 +6374,7 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "contractClassId": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -6387,8 +6414,11 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "portalContractAddress": EthAddress { - "buffer": { + }, + SideEffect { + "counter": Fr { + "asBigInt": 0n, + "asBuffer": { "data": [ 0, 0, @@ -6410,97 +6440,67 @@ PrivateKernelInnerCircuitPublicInputs { 0, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, ], "type": "Buffer", }, }, - }, - ], - "newL2ToL1Msgs": [ - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr { + "value": Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + ], + "newNullifiers": [ + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -35914,6 +35914,199 @@ PrivateKernelTailCircuitPublicInputs { }, }, ], + "newContracts": [ + NewContractData { + "contractAddress": AztecAddress { + "asBigInt": 7667752348302703004105847231271989658843538975557179704689760117635404498899n, + "asBuffer": { + "data": [ + 16, + 243, + 203, + 69, + 185, + 4, + 96, + 183, + 89, + 171, + 13, + 30, + 15, + 188, + 64, + 63, + 182, + 216, + 212, + 55, + 181, + 74, + 72, + 194, + 224, + 79, + 40, + 42, + 36, + 239, + 135, + 211, + ], + "type": "Buffer", + }, + }, + "contractClassId": Fr { + "asBigInt": 14382725657784677548089422063797280690497459898548737366354813204068709973929n, + "asBuffer": { + "data": [ + 31, + 204, + 85, + 144, + 188, + 44, + 12, + 186, + 124, + 105, + 137, + 241, + 157, + 212, + 243, + 50, + 29, + 209, + 56, + 100, + 241, + 88, + 182, + 78, + 71, + 162, + 226, + 76, + 31, + 100, + 63, + 169, + ], + "type": "Buffer", + }, + }, + "portalContractAddress": EthAddress { + "buffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + ], + "newL2ToL1Msgs": [ + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + ], "newNoteHashes": [ SideEffect { "counter": Fr { @@ -40508,199 +40701,6 @@ PrivateKernelTailCircuitPublicInputs { }, }, ], - "newContracts": [ - NewContractData { - "contractAddress": AztecAddress { - "asBigInt": 7667752348302703004105847231271989658843538975557179704689760117635404498899n, - "asBuffer": { - "data": [ - 16, - 243, - 203, - 69, - 185, - 4, - 96, - 183, - 89, - 171, - 13, - 30, - 15, - 188, - 64, - 63, - 182, - 216, - 212, - 55, - 181, - 74, - 72, - 194, - 224, - 79, - 40, - 42, - 36, - 239, - 135, - 211, - ], - "type": "Buffer", - }, - }, - "contractClassId": Fr { - "asBigInt": 14382725657784677548089422063797280690497459898548737366354813204068709973929n, - "asBuffer": { - "data": [ - 31, - 204, - 85, - 144, - 188, - 44, - 12, - 186, - 124, - 105, - 137, - 241, - 157, - 212, - 243, - 50, - 29, - 209, - 56, - 100, - 241, - 88, - 182, - 78, - 71, - 162, - 226, - 76, - 31, - 100, - 63, - 169, - ], - "type": "Buffer", - }, - }, - "portalContractAddress": EthAddress { - "buffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - ], - "newL2ToL1Msgs": [ - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - ], "newNullifiers": [ SideEffectLinkedToNoteHash { "counter": Fr { From bccd4f30755389b9691edc9a08f62952c066fbdf Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 17:22:43 +0000 Subject: [PATCH 08/11] trying triggering a rebuilt --- .../private-kernel-lib/src/private_kernel_tail.nr | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 6f8dcc7be59..e0c1ef48138 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -116,7 +116,7 @@ impl PrivateKernelTailCircuitPrivateInputs { public_inputs.end.new_nullifiers.storage = self.sorted_new_nullifiers; } - fn match_nullifiers_to_commitments_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { + fn match_nullifiers_to_note_hashes_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // Match nullifiers/nullified_commitments to commitments from the previous call(s) let mut new_note_hashes = public_inputs.end.new_note_hashes.storage; @@ -125,19 +125,19 @@ impl PrivateKernelTailCircuitPrivateInputs { for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { let nullifier = new_nullifiers[n_idx]; // TODO - should not be able to squash the first nullifier. - let nullified_commitment = nullifier.note_hash; + let nullified_note_hash = nullifier.note_hash; let hint_pos = self.nullifier_commitment_hints[n_idx] as u64; // Nullified_commitment of value `0` implies non-transient (persistable) // nullifier in which case no attempt will be made to match it to a hash. - // Non-empty nullified_commitment implies transient nullifier which MUST be matched to a hash below! - // 0-valued nullified_commitment is empty and will be ignored - if nullified_commitment != 0 { + // Non-empty nullified_note_hash implies transient nullifier which MUST be matched to a hash below! + // 0-valued nullified_note_hash is empty and will be ignored + if nullified_note_hash != 0 { assert( hint_pos < MAX_NEW_NOTE_HASHES_PER_TX as u64, "New nullifier is transient but hint is invalid" ); let hash = new_note_hashes[hint_pos]; - assert_eq(nullified_commitment, hash.value, "Hinted hash does not match"); + assert_eq(nullified_note_hash, hash.value, "Hinted hash does not match"); assert( nullifier.counter > hash.counter, "Nullifier counter must be greater than hash counter" ); @@ -214,7 +214,7 @@ impl PrivateKernelTailCircuitPrivateInputs { self.match_reads_to_commitments(&mut public_inputs); - self.match_nullifiers_to_commitments_and_squash(&mut public_inputs); + self.match_nullifiers_to_note_hashes_and_squash(&mut public_inputs); PrivateKernelTailCircuitPrivateInputs::apply_note_hash_nonces(&mut public_inputs); From 569e9c425208babf77d5f196938558f34cdbfd68 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 18:07:06 +0000 Subject: [PATCH 09/11] diff cleanup --- CHANGELOG.md | 2 +- .../contracts/writing_contracts/functions/context.md | 10 +++++----- .../historical_data/slow_updates_tree/main.md | 2 +- docs/docs/developers/debugging/sandbox-errors.md | 4 ++-- docs/docs/learn/concepts/storage/storage_slots.md | 5 ++--- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 533598f79b1..78f957daf26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1396,7 +1396,7 @@ * Confusing "Unknown complete address" error ([#2967](https://github.com/AztecProtocol/aztec-packages/issues/2967)) ([3a8f54a](https://github.com/AztecProtocol/aztec-packages/commit/3a8f54a8330620669380cbd1b06551aa10703ec3)) * Force jest to quit, otherwise CI can rack up to 3hrs of credits per job. ([#2899](https://github.com/AztecProtocol/aztec-packages/issues/2899)) ([ba2f671](https://github.com/AztecProtocol/aztec-packages/commit/ba2f671c79ac3c2aa19c769c3db56a27a7e0854f)) * Honk sumcheck performance ([#2925](https://github.com/AztecProtocol/aztec-packages/issues/2925)) ([5fbfe6e](https://github.com/AztecProtocol/aztec-packages/commit/5fbfe6eeccdb23f734fb36f30d1e33340f9fb07a)) -* pending note hashes contract using the wrong number of arguments ([#2959](https://github.com/AztecProtocol/aztec-packages/issues/2959)) ([655c322](https://github.com/AztecProtocol/aztec-packages/commit/655c322ab0e71074b3f747c95bfafbd6b7008217)) +* Pending commitments contract using the wrong number of arguments ([#2959](https://github.com/AztecProtocol/aztec-packages/issues/2959)) ([655c322](https://github.com/AztecProtocol/aztec-packages/commit/655c322ab0e71074b3f747c95bfafbd6b7008217)) * Prettierignore in boxes ([#2902](https://github.com/AztecProtocol/aztec-packages/issues/2902)) ([8f7a200](https://github.com/AztecProtocol/aztec-packages/commit/8f7a200e809a9dc6ac8e1beaf3bbf1fd83e5a1fb)) * Randomness in `AddressNote` ([#2965](https://github.com/AztecProtocol/aztec-packages/issues/2965)) ([4dc49a9](https://github.com/AztecProtocol/aztec-packages/commit/4dc49a92428216928d918d893c40745957e5b983)) * Yarn lock ([#2923](https://github.com/AztecProtocol/aztec-packages/issues/2923)) ([7042bc6](https://github.com/AztecProtocol/aztec-packages/commit/7042bc6130f8473b6c59bf9a0146ea8b2c3c7483)) diff --git a/docs/docs/developers/contracts/writing_contracts/functions/context.md b/docs/docs/developers/contracts/writing_contracts/functions/context.md index 70630aa5d0f..e1a18f4f0f5 100644 --- a/docs/docs/developers/contracts/writing_contracts/functions/context.md +++ b/docs/docs/developers/contracts/writing_contracts/functions/context.md @@ -105,18 +105,18 @@ The return values are a set of values that are returned from an applications exe -### New note hashes +### New Note Hashes -New note hashes contains an array of all of the commitments created in the current execution context. +New note hashes contains an array of all of the note hashes created in the current execution context. ### New Nullifiers New nullifiers contains an array of the new nullifiers emitted from the current execution context. -### Nullified Commitments +### Nullified Note Hashes -Nullified commitments is an optimization for introduced to help reduce state growth. There are often cases where commitments are created and nullified within the same transaction. -In these cases there is no reason that these commitments should take up space on the node's commitment/nullifier trees. Keeping track of nullified commitments allows us to "cancel out" and prove these cases. +Nullified note hashes is an optimization for introduced to help reduce state growth. There are often cases where note hashes are created and nullified within the same transaction. +In these cases there is no reason that these note hashes should take up space on the node's commitment/nullifier trees. Keeping track of nullified note hashes allows us to "cancel out" and prove these cases. ### Private Call Stack diff --git a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md index 235f450ac3c..170981942d9 100644 --- a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md +++ b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md @@ -69,7 +69,7 @@ graph TD CurrentM --> Value1[Current Value 1] CurrentM --> Value2[Current Value 2] CurrentM --> ValueN[Current Value N] - Pending --> PendingM[pending note hash 1] + Pending --> PendingM[Pending Commitment 1] PendingM --> PValue1[Pending Value 1] PendingM --> PValue2[Pending Value 2] PendingM --> PValueN[Pending Value N] diff --git a/docs/docs/developers/debugging/sandbox-errors.md b/docs/docs/developers/debugging/sandbox-errors.md index c321da86048..9fc8f60cd0e 100644 --- a/docs/docs/developers/debugging/sandbox-errors.md +++ b/docs/docs/developers/debugging/sandbox-errors.md @@ -22,7 +22,7 @@ Remember that for each function call (i.e. each item in the call stack), there i Cannot call contract at address(0x0) privately. This error may also happen when you deploy a new contract and the contract data hash is inconsistent to the expected contract address. -#### 2005 - PRIVATE_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL +#### 2005 - PRIVATE_KERNEL\_\_NEW_NOTE_HASHES_PROHIBITED_IN_STATIC_CALL For static calls, new note hashes aren't allowed @@ -120,7 +120,7 @@ For static calls, no contract storage change requests are allowed. Same as [3022](#3022---public_kernel__public_call_stack_contract_storage_updates_prohibited_for_static_call), no contract changes are allowed for static calls. -#### 3026 - PUBLIC_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL +#### 3026 - PUBLIC_KERNEL\_\_NOTE_HASHES_PROHIBITED_IN_STATIC_CALL For static calls, no new note hashes or nullifiers can be added to the state. diff --git a/docs/docs/learn/concepts/storage/storage_slots.md b/docs/docs/learn/concepts/storage/storage_slots.md index 55901f6dc7e..9afb68ae05d 100644 --- a/docs/docs/learn/concepts/storage/storage_slots.md +++ b/docs/docs/learn/concepts/storage/storage_slots.md @@ -39,8 +39,7 @@ If we include the storage slot, as part of the note whose commitment is stored i Similarly to how we siloed the public storage slots, we can silo our private storage by hashing the logical storage slot together with the note content. ```rust -note_hash = H(...note_content); -commitment = H(logical_storage_slot, note_hash); +note_hash = H(logical_storage_slot, note_content_hash); ``` This siloing (there will be more) is done in the application circuit, since it is not necessary for security of the network (but only the application). @@ -53,7 +52,7 @@ When reading the values for these notes, the application circuit can then constr To ensure that one contract cannot insert storage that other contracts would believe is theirs, we do a second siloing by hashing the `commitment` with the contract address. ```rust -siloed_note_hash = H(contract_address, commitment); +siloed_note_hash = H(contract_address, note_hash); ``` By doing this address-siloing at the kernel circuit we *force* the inserted commitments to include and not lie about the `contract_address`. From 5763d552a394275d1192d1e29637aac333529d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Thu, 22 Feb 2024 19:49:06 +0100 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: esau <152162806+sklppy88@users.noreply.github.com> --- .../communication/public_private_calls/slow_updates_tree.md | 2 +- .../noir-protocol-circuits/src/crates/types/src/hash.nr | 2 +- yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts | 2 +- yarn-project/pxe/src/kernel_prover/proof_creator.ts | 2 +- yarn-project/simulator/src/public/execution.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md index 21e04e42523..1e0d44ae666 100644 --- a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md +++ b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md @@ -41,7 +41,7 @@ graph TD; CurrentM --> Value1[Current Value 1] CurrentM --> Value2[Current Value 2] CurrentM --> ValueN[Current Value n] - Pending --> PendingM[pending note hash 1] + Pending --> PendingM[Pending Note Hash 1] PendingM --> PValue1[Pending Value 1] PendingM --> PValue2[Pending Value 2] PendingM --> PValueN[Pending Value n] diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr index cedc987f0e6..e276b3d4ebd 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -302,7 +302,7 @@ pub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> ) } -pub fn compute_unique_siloed_note_hashs( +pub fn compute_unique_siloed_note_hashes( first_nullifier: Field, siloed_note_hashs: [SideEffect; N] ) -> [SideEffect; N] { diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 14b245ef065..301417ce4a1 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -440,7 +440,7 @@ export class CrossChainTestHarness { } async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { - this.logger('Spending note hash in private call'); + this.logger('Spending note in private call'); const privateTx = this.l2Token.methods.redeem_shield(this.ownerAddress, shieldAmount, secret).send(); const privateReceipt = await privateTx.wait(); expect(privateReceipt.status).toBe(TxStatus.MINED); diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index b2174736b07..6dfabdc0642 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -53,7 +53,7 @@ export interface ProofCreator { /** * Computes the siloed commitments for a given set of public inputs. * - * @param publicInputs - The public inputs containing the contract address and new note hashes to be used in generating siloed commitments. + * @param publicInputs - The public inputs containing the contract address and new note hashes to be used in generating siloed note hashes. * @returns An array of Fr (finite field) elements representing the siloed commitments. */ getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs): Promise; diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 370c02c6ff4..6d6bca3ee1c 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -22,7 +22,7 @@ export interface PublicExecutionResult { execution: PublicExecution; /** The return values of the function. */ returnValues: Fr[]; - /** The new note hashes to be inserted into the commitments tree. */ + /** The new note hashes to be inserted into the note hashes tree. */ newNoteHashes: SideEffect[]; /** The new l2 to l1 messages generated in this call. */ newL2ToL1Messages: L2ToL1Message[]; From 331567e70ea913c83b35fe887d4d03ed40b06471 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 22 Feb 2024 18:50:12 +0000 Subject: [PATCH 11/11] fix --- .../src/contracts/target/blank-Blank.json | 2 +- .../src/private_kernel_tail.nr | 28 +++++++++---------- .../src/crates/types/src/hash.nr | 10 +++---- .../fixtures/Benchmarking.test.json | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/boxes/blank/src/contracts/target/blank-Blank.json b/boxes/blank/src/contracts/target/blank-Blank.json index 3fa785d5018..df045ffe5d9 100644 --- a/boxes/blank/src/contracts/target/blank-Blank.json +++ b/boxes/blank/src/contracts/target/blank-Blank.json @@ -1 +1 @@ -{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"1d3djqTpdeX3e+ExYcT+3lu3YvhAtmVAgKAZjAQDhsB7dxDTlU1BkazWnx0xS0dqCrn4vOxa71NZv8xV+W9/+Kf/9n/9/b/+43/753/5w9/92x8e/5v5H/7uf/+3P/zLf//7f/7z/+Nf/vXv/8e//uHvHn/8wz/88//9/L9/+uMf/p9//Kd/+MPfZfzpj//hw7r6lw/s+fVDt158qM388qH++PVDw/70f/zxz08REk+REk9REk/REk8xEk+xEk9xCk/hD4mnMImnkLg7XeLudIm70yXuTpe4O13i7nSJu9Ml7s6QuDtD4u4MibszJO7OkLg7Q+LuDIm7MyTuzpC4O0Pi7kyJuzMl7s6UuDtT4u5MibszJe7OlLg7U+LuTIm7MyXuzpK4O0vi7iyJu7Mk7s6SuDtL4u4sibuzJO7Okrg7S+LubIm7syXuzpa4O1vi7myJu7Ml7s6WuDtb4u5sibuzJe7Okbg7R+LuHIm7cyTuzpG4O0fi7hyJu3Mk7s6RuDtH4u5cibtzJe7Olbg7V+LuXIm7cyXuzpW4O1fi7lyJu3Ml7s6TuDtP4u48ibvzJO7Ok7g7T+LuPIm78yTuzpO4O0/i7rSHxOVpD4nb0x4a3x7/0Pj++IfEBWoPje+Qf2h8i/xD43vkHxrfJP/QuEVN4xY1jVtUZGQksjISmRmJ7IxEhkYiSyORqZHG1sg0xkamsTYyjbmRaeyNTGNwZBqLI9OYHJnG5sg0RkemsToyjdmRaeyOTGN4ZBrLI9OYHpnG9sg0xkemsT4yjfmRaeyPTGOAZBoLJNOYIJnGBsk0RkimsUIyjRmSaeyQTGOIZBpLJNOYIpnGFsk0xkimsUYyjTmSaeyRTGOQZBqLJNOYJJnGJsk0RkmmsUoyjVmSaeySTGOYZBrLJNOYJpnGNsk0xkmmsU4yjXmSaeyTTGOgZBoLJdOYKJnGRsk0RkqmsVIyjZmSaeyUTGOoZBpLJdOYKpnGVsk0xkqmsVYyjbmSaeyVTGOwZBqLJdOYLJnGZsk0RkumsVoyjdmSaeyWTGO4ZBrLJdOYLpnGdsk1tkuusV1yje2Sa2yX/CFxi7rGdsk1tkuusV1yje2Sa2yXXGO75BrbJdfYLrnGdsk1tkuusV1yje2Sa2yXXGO75CI/J0nkByWp/KQkjVtU5GclifywJJGfliTy45JEfl6SyA9M0tguucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7vkGtsl19guucZ2yTW2S66xXXKN7ZJrbJdcY7sUGtul0NguhcZ2KTS2S/GQuEVDY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJobJdCY7sUGtul0NguhcZ2KTS2S6GxXQqN7VJqbJdSY7uUGtul1Ngu5UPiFk2N7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6mxXUqN7VJqbJdSY7uUGtul1NgupcZ2KTW2S6WxXSqN7VJpbJdKY7tUD4lbtDS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgulcZ2qTS2S6WxXSqN7VJpbJdKY7tUGtul0tgutcZ2qTW2S62xXWqN7VI/JG7R1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7vUGtul1tgutcZ2qTW2S62xXWqN7VJrbJdaY7s0Gtul0dgujcZ2aTS2S/OQuEVHY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJobJdGY7s0Gtul0dgujcZ2aTS2S6OxXRqN7dJqbJdWY7u0Gtul1dgu7UPiFl2N7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6uxXVqN7dJqbJdWY7u0Gtul1dgurcZ2aTW2S6exXTqN7dJpbJdOY7t0D4lb9DS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09guncZ26TS2S6exXTqN7dJpbJdOY7t0Gtul09gu2UNjvPR8Dol79PkcEhfp8zkkbtLnc0hcpc/nkLhLn88hcZk+n0PiNn0+h8R1+nwOkftUY8b0fA6R+1RjyPR8DpH7VGPK9HwOkftUY8z0fA6R+1RjzvR8DpH7VGPQ9HwOkftUY9L0fA6R+1Rj1PR8DpH7VGPW9HwOkftUY9j0fA6R+1Rj2vR8DpH7VGPc9HwOkftUY970fA6R+1Rj4PR8DpH7VGPi9HwOkftUY+T0fA6R+1Rj5vR8DpH7VGPo9HwOkftUY+r0fA6R+1Rj7PR8DpH7VGPu9HwOkftUY/D0fA6R+1Rj8vR8DpH7VGP09HwOkftUY/b0fA6R+1Rj+PR8DpH7VGP69HwOkftUY/z0fA6R+1Rj/vR8DpH7VGMA9XwOkftUYwL1fA6R+1RjBPV8DpH7VGMG9XwOkftUYwj1fA6R+1RjCvV8DpH7VGMM9XwOkftUYw71fA6R+1RjEPV8DpH7VGMS9XwOkftUYxT1fA6R+1RjFvV8DpH7VGMY9XwOkftUYxr1fA6R+1RjHPV8DpH7VGMe9XwOjfvURPZRJrKPMpF9lInso55fOBV5Do371ET2USayjzKRfZSJ7KNMZB9lIvsoE9lHmcg+ykT2USayjzKRfZSJ7KNMZB9lIvsoE9lHmcg+ykT2USayjzKRfZSJ7KNMZB9lIvsoE9lHmcg+ykT2USayjzKRfZSJ7KNMZB9lIvsoE9lHmcg+ykT2USayjzKRfZSJ7KNMZB9lIvsoE9lH2et91J/d7JfYnz91/OtPc1m/fOzdfn3o3auned6b9fVfnH5fH249X4/Ueo80eo+0eo90co/0elb1v/aRTO+RXO+RQu+RUu+R9G7v0ru9S+/2Lr3bu/Ru79a7vftvv73//E37Xx8cj7/+UL/xM8KNH5/mbeWv/42/Prb/13zs+K/52Plf87F//rtJ7F8e8SPXMDcwtzB3LDcPmDOYc5gLmEuYg30Z2JeBfRnYl4F9WdiXhX1Z2JeFfVnYl4V9WdiXhX1Z2JeFfTnYl4N9OdiXg3052JeDfTnYl4N9OdiXY33xxwPmDOYc5gLmEuYK5hrmBuYW5mBfDPbFYF8M9sVgXwz2xWBfDPbFYF8M9sVgXxz2xWFfHPbFYV8c9sVhXxz2xWFfHPbFYV8C9iVgXwL2JWBfAvYlYF8C9iVgXwL2JWBfEvYlYV8S9iVhXxL2JWFfEvYlYV8S9iVhXwr2pWBfCvalYF8K9qVgXwr2pWBfCvalYF8a9qVhXxr2pWFfGvYF+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"H4sIAAAAAAAA/+1dCXxcxXmfXV2rY2X5li3ZfrIOH5KlXR22RIAs5j6SACGFQALIaG1EbIvIMuAkQBJCQm4IJJBAIISE3Af0btrmaJsW2gZo0zRt2oakLaRHmjTp3cbNfKv3ef8ajWRp/c3y3m80v9/seztv3sz//828b2a+NzPvjIRSbdqTo0NS+wrtA/hfGZ7z/yrjf7Xxv8a4v9b4nzb+LzP+Lzf+rzT+rw7/owspqFx4HMjsHBzM7+rPZweyo5n+kT3DQ5nBoT07h7PD2aHhobH+4YGB/PDg8K6RPSO7MiPZwYF8du/QyMDezLTrgrQyJ+gIWwowd2h/VPvO8Njl2bFH+y1hmaFctngqD5TLVjX9/LFLwPk2Nf0sqVBu7AIlVFcHM9lqSqRSWR0911XheT3ES4ZhTRDGuOu0bwzP9+WnLh49ODZx4Kzx/P4xZJa0sDUd5VhhxK+Hc75Wa0snFx4zJ+aymKa0ytkuiJMfLRYOpY0qh1x3KDSb0BPCcutWsuqUHT0yXCWrLfjZVVjOUxDvqHJTR2zybbLgdFphXRRmj4N0dyi5h8kV7x3yZZRRlgrhQqaZE3RxVBY1gLM3PPZx2uGRn9j+8DgQHge1bwjbM0ft7TC2t6ZssXXjOMSnAa4njDa4cE8YVgFhFZUzkimEVYZ/sE2vCsOqIawa8uawGkMuTYCF46XUTGWbC88zJ+hSgC8QTLcgEzXTmWUSwHk1cKuSx5N1xTOliuUmLb9qtXD5peBY40h+LnhSmnWO5JdSC5dfHciv1pH8XPCkdBscya9OLVx+DSC/ekfyc8GT0m10JL8GtXD5NYL80o7k54Kno3QLeJc5wsuDhqQw3pXyeIepHi1XC69HK6EerXBULg54FsplFfCTSpfSWA3yWW7IKQ3XV4HsVjuQXQLy5bT5/2pL3oID6YIc1hxHDmssWNaUWQ6IcQnvEt4lvNHDuyoCeCnvteJ5Z3fVG3mTm6+9XetYFm54TrcHzcBjpcEnDdexfjY74JiAfDlt/o8Yl/Au4V3Cu4R3Ce8S3iW8S3iX8C7hXcK7hHcJ7xJe3/FS3uvk8x6oN/ImlzD+B3C+zrEsHPEs2EPWA4+1Bp80XMfyXu+AYwLy5bT5P2JcwusObxquJwGPg7qXXcjzhHgSEcBTr+xzrNYZMqMwlinOoWoJz3EOVWt4jnOoNoTnOIdqY3iOc6g2qaJMOCwIz2shrC08r4OwzXDOx/bwHOeHdYTnaQjrDM8bIawrPF8GYVvC8yYI2xqeL4ewbeH5CgjbHp6vhLDu8HwNhPWE52shjOdYNkMYlw2WJZfNegjjsmmBMC6bVgjjstkAYVw2GyGMy2YThOFcGw7jsmmDMC4bLCsum3YI47LpgDAum04I47LpgjAumy0QxmWzFcK4bLZBGJfNdgjj9yTdEMa6rQfCuAy5rEh25yWK1/l+fKY4H3ymdljy67Hg4nPUI3xPoGT1COYVwH/OrwFwbI8InqQFD5d1Tg5PYc7DVnmew8SN63B1mDbj5/wqIU5lWAD8THA4Oa5T20A+3UY85JFTsn29Lkfy6TTkw/i7QD7H9IUhHw5H+WwF+Wwx4iGPnBLj0U/pdjiST7shH8bfAfLhOCsM+XA4yqcL5NNpxEMeOSU3dqF0NzuST5shH8a/GeTDcdYZ8uFwlE8HyKfdiIc8ckqMxyCuF5SWzyZDPlgOLB+OExjy4XCUz2aQT5sRD3nklBiPIUp3oyP5bDDkw/g3gnw4zhZDPhyO8glAPpuMeMgjp8R47KR0Wx3Jp8WQD+NvBflwnF5DPhyO8tkI8tlgxEMeOSXGY5ej8eswjl9ZPox/PciH4wwZ8llnkU8ryKfFiJeCeAkl2x/j/imvg+82cFVCnBcBD+wXY3+d42Jfn3ngOIHlhGMMXtOE4xNe34RjG17rhOMi7jNi35v75tjX5zEVjr14TIVjLx5T9UIYj6n6IIzHVIypVjmzm/SjLNkljP8BnKMthe/Dse56QxaEu0Ued6GerTcw8v8WwMhhKwCPK/tTlYHHrAMu864x8q4pY961Rt61Zcy73si7vox5p42802XMe5WR9yoj77lsna7wKAOPmgdPc8TwrIwYnlURw7MsYnjqIoanPmJ4KiOGpypieJZHDE85+iaLwdMYMTypiOGpjRieiojhWRcxPGsjhqcc78IXg2dNxPA0RQxPQ8TwpCOGpzpieGoihicRATxzze3g6/gemu0n+B4abbQcxvYznNvBNlmc28G2N5zbEaiiTDiM7XY4t4PfEeDcDrT58RHftXAY2wtxbge/s8K5HWxrxLkdW8NznNvB70txzga/T14FYSxLlD3LEu2LLEucd8GyRNskyxLnXbAs0a7JsgwgjGWJNlGWJc67YFmibFmWOO+CZYm2WJYlzrsw3zvjXAycd8F9cZx3wf1hli1x/WlF8Trfj3WW88E6u92S3zYLLj7H59TBO/zCc4p5BfAf3zUnDIwvNJ6aiOGpjhiedMTwNEQMT1PE8KyJGJ7VEcOzNmJ41kUMT0XE8NRGDE8qYngaI4ZnRcTwLI8YnqqI4amMGJ76iOGpixieZRHDsypieFZGDE9zxPAky4iHx6Octjmnm/J2MM+4ME+9U5xTdhdxYnuBOc+Y86uEOB2hsPmZ5XByPH7HecZbjXhueExvot9hlM1Wg0fSgicwMOXkMBXmzreLc50uM7YFcZmZ87krIU6vUWYcTm67IaMGNXsedUo5mcNdeJ5WAJYA/tvyltyLEdfUcvrUjxlKFvPtks93hk6jsrsVcOC6B45zerKIbSRZLCNz3h7afPF93gaQbU6QA+fFafN/zg/nsKK91Fzjibhtczlt6+M4Ps+zdLA+JYPlxGmb5ZSE8y0QzyzjAOKx/sEyPhfK+EshSUf1bwixJi2cUGcJ5lv4FAGu2Wk35JZUs9fs5EI8baooWxk80zo0UDPLiPNvgzLiOBcbOpTDyW03uFDd32zES8G59MdZsJ52GvkmgQ/Hy4V4NkFcGTzTcsV3SoGavVakEuJcYciVwxXItQ3kusWIl4LzhJJ9/tsAS8KSN9bZNoinjHtta60c9IHm7Z92WuQlmHc/vr9DmSkDjzJk6KiNGsB3mwvBg+t05J+L6b6gA56FcQG3h9J7VbdYyos5pNXs9j2l3K0d2GCUm7l+aAmvW7yEp9PAinMKOiOCkcPwPXuzIUfqZ90K/XwH/Z0Bwst9Ku7nMw4co3GcL1cUsd0G/XxzLI7zLlDmAcglJ8Mha7aBgZrZF2OMtrWyrtq3dgNPu0UWL2TeLIOcktXxgTynQh011wib5YtrhO8y+mq4RpjrKfbVOo14yCOnZNtWB32aAdQ5C1kjfJ8hnw0W+QQgnzKtEe7HPkIgLJ/FrBF+yJBPi0U+x1sj7GCsn8U5auzm6yviWNlFW4fz3haCx7aGWhpPyyLwYH/FxfxJtBktBA+u7+t2hGf9IvB0A54eR3i6F4GnB/DscISnZxF4GAP158w2lsL42dgEYVw/sf/MdQT3DONy2gxh5t5OacCLNh0OQ5ukbf20i2cwoeZeP437BjAXnCfM52zry6mZuisnh3MYbcPJMF1znTfqBUGbTdZR/S1w4j0AzL0ecI8EjvMktHMpCJfE5OpZpTT6gJNtLwi+/hTYrZ8Jz7Htwn0lnrVcZzefLmDZEd+sPN+CnY+/k8tlm7XkPQBYhfLOYt6J0HM+HF4J599lBQXxyLGcGTfpgYwlHp53Gfek4XrGwjsQ5o1fFQ/gP+dHdeabUL+etYzXJTEhb5RPK8iHr6PuwnY2p2bqfsbbJ4+3oJP4meR6y1jw+eU4PzB00g4HmBxxLZRNL3Bqt/Dk6z+EOvMj0DlcLlyudP2o5Tq7hfRPXgidhHlHQSf9bA6dZOqXheikVuOeKOqkn0D9Ogo6yUU/HnmjfLpBPnyd+8emnSqnZo55GK8DG5m1n2T23/FZrQ5tnq77SS7sgZQG6p8eC89je0SBbTcN66K4XNAu3Wq5zm6h/aSMPN8MPh9cthlL3qg7hPKe8WyyTuJ8OLwSzlt4ogjEI8dyZtykk3ZY4uF5t3FPGq7vsPAOhHnj8x/Af86P6kwT1K9Wy/wRSUzIG+XTDvLh6zw+RzuzCrFgH47xutrHkJ9DrreMBW2UHKfD0Eku+m6ubASUBuqfLgtPvr4N6kw36BwuFy5Xun6S5Tq7+XQSy85RfzODzweX7Q5L3qg7hPKe8WyyTuJ8OLwSzkdAJ2E/wxxfk07qtcTD83bjnrSyj1kd9E2zOO7gtHcYGKnO9EL9Ogl0kqt+Uq9FPmgf5OtsH8R3OyrEgvM+GK8De7F172vGwvnhs7rb0Eku+m6ubOOUBuqfHgtPvn421JlzQedwuXC50vXLLNfZzaeT8F2tg/5mxjYu77XkjbpDKO8ZzybrJM4H7Xd8finoJOxnsJwZN+mkPks8PN9k3INjkz4L70CYNz7/Afzn/KjOXAD167Iy9JP6LPLB9xPH+hzhkXjge5KcmjlnjPG66ifxM8n1lrHg88txrjZ0kgs9GYV+Uh7qzD7QOeY8I7p+g+U6u/l0Er4PLLdOwryjoJMOz6GTTP2yEJ20wbgnijrpOqhfN4BOcmXj7rPIpwfkw9f5/WhCzVwvlFMz+3CM18GcWWs/ibHgXHKOc0uZ+kku5gdTGqh/2i08+fptUGduB53D5YL7PN1juc5uof0kB2PgjM1W2GfJ29We972QLuoofM/A53eDTsKxD8uZceP7d4yH5z3GPWgv6bbwDoR54/MfwH/Oj+rMHVC/7ilDP6nbIp/55mfYbNybARvjddVPMudMMhZ8fjnOA4ZOcqEno9BPehjqzCOgc7hccC7A45br7ObTSTiPtNw6CfOOgk56bA6dZOqXheikzcY9UdRJj0L9ehx0kov1rcgb5YM2br6+BcLWGfHRXorzw1zoUVMnBvC/CzByGPYRHK85nbVG0VxzimuxtwCuoeOsgwiMMFd9s4SaqYcC+M/54ToIMy47Xv/RFh6TarbNMadcrdGbXptpzmfn/G3z2Z+EtkupmWPa7Rb+gREP+TUb/Mo1H932rofjPGO0zQ7mcg+4bJvxO1O2Pghf/xbozm9bbBQ4J+b5Em0YOLfTgY3fasPoseSNbahQ3lYbBudjs2E8B20z2gDMeZHYNmM8PLeN0W22Gwd2o6xpjwzgP+dHdeY7UL+eh7bEwZqcWW2zaYfDtjmAsE4jPr43wPbDhd0FxwyctvlOI61m62Ls30i3x7g2utkim2YDi7lmcqUjOc21Hwx+88dV3lVG3lVlzLvGyLumjHnP9T2wcuRdb+RdX8a800be6TLm/cLU82zhe5hrHKRL5YbfOCM3X38Bv2GxWhxPJlunivua7stPvXRiKn8oAbgY61oDa0LNxM3XGyAsCecVcF+lms2/2hKWsoTVWcIa1GzXCOfL4LwJzldCGsvDcxsPjmOWUznCjxeP8VK94rqCe/bz9dUQxuWyBsIqjPRqlQVPLjxmTswVHmwCMWjJJGnkNZDZOTiY39Wfzw5kRzP9I3uGhzKDQ3t2DmeHs0PDQ2P9wwMD+eHB4V0je0Z2ZUaygwP57N6hkYG9YWaSHdysXFoZl5y7BTkPCHLmh5orG3WOqcPWFx4z4ZHckCoqAZZPd3h9COLtDNOb66FSgrLoV7KyYLdLFTtR1Rb87Cos5ymIJ935xbxMLE0WnM4UBiYulWZ/KHjpdIeV3IPsivewfBk5VWiDgmmNKNmGbKEK7SQ1t0I7CeK9yBIvEV5/UXikHtTJaqaTlrlkPT7lBZL5qfPI/FSI9+J5ZP5ikHnOEq9fFRXv0RDXaZCGUrK65WRLuidaPkMJWT0gzfuUUKbSvHcm3Oi/CmGcuwVlKVjWWVfyM3VZ5sRctkawLE5XsrqMuFKagSrqloXotjPU3LrtDIh35iLTPWuedM+CeGeruXXm2aqoM89ZZP7nzpP/uRDvvHnyPw/yP1/NrbPPV0WdfQGkQS4XHjMn5go6+xwlr7tGYqCzL3DA+6SY6OyXCMpSsKyzkvIr18C7Ty6tDL69eGl4fFl4vDA8XhQeL1bFsRJaIwMpPIOZnYUBf+VMubFDax3HobYMvxqaCMOTeE8Yhl+NrKickcz0lzrDP/il06owjA0RTZAHfvG+SloWWhpoiWQ3n3Uc8VTK4ylYx9lKTNbxw/v3j+8dz0+enz9y4ej4JNo9GHalAds02JrXySUtYY5EnDUN8AH8R3Fy8efk8i5s0Fkjz2mQm3elipMeGH8NyJ3jsOF7GfBlVwHpkGsw5MLHGnn5FDbmqnUknzpDPoy/FuTDcTYY8qmzyKcG5JMy4iGPnBLjUdigs96RfBoM+eDHmlk+5oeDl4EMTPnUwrU6Ix7yyCnZSVRpR/JpNOTD+NMgH47Tbcin0SKfepBJgxEPP76MzRrnhc2V+QzjB5mxmVwO+XFY0pJvhcGr0EwafArNZHiOH9JmncF5OX2JppR8P4vsrGcq+T77KREfq5BN+CUOeJ8ak7HKywVlKVjWWUn5mTYI4kxj/4vD40WqaFu4RC3OZvEKNbfN4hUQ7xfC9I716cFJ1+lLVLSfucFQHko23RkvVi9VxYbG0fhtAMdvZrnaxm/YyCRgTFeD9xjpNUEY88OxycGJqfG9R3h4MkazeBY65jDPKyxhDKvKSA/p8TXnbZ4yyEilfalyo6ulbdlofz5RvX+ZIC62ZVOagZqtP6nTTHqwMzxuU0W9+Eo1t/58JcS7PEzPnEHmoj4ITqLJWOCWlPae4f492Xx2ZGgsM9qvC3JsYHAIjQ+uZNHhQBbSGDtjgHGbclOnpHFerty0x1eo4oDJUXu8C9tjc1bpQttjJ/bEwWkDhgujHg4+q+awE1db+hTVRp/CkYFu3lUDnB9h5YHzdH/m9Mn86NTs3gzfYOvhIEFytmnHqCyrLfdz/IQlHXIkzJSBBSsWX4ttT+gKFY+eEPZeTrQn9Col3xOiNANVvumpki2g7dXGq7W/Uvur1MxvMbELlJimHCzlrRiuCXGgvbOOtPeAI617zOJBzjT74ysNNlUnlOwzkIJ0E5BPCoqOz3GdD66z4nLG1w3Vlnh4Xmnck4br1RbegTDvudaocX5VEIZvV3FKt4t6FsW3q6xH9NvVCw/v2T9+jX61etrBsQtHJ6fGR/efNjY2mT90yKaMKgwCc7XYx3vPinYNfDdh9gxstg4UKFZKZ62+OUYmjUxj4yvDI63wvlrNHktfHV6/KjzSi4xRA6PZOp9oiyrYGmVH5dIqzFkxxwVKybfGgtrU6VgvLnYOlzJ4dUzK6kol2ztYshv5ZzfCBpN1/h7tr1Ezd/tkFyixHvQo9urN1b0Ltc3gC/kkhB1rxCHsWCMOeYr3tAczQylV5COWbjhvHXfEcjCqGXbU2+xfGtUUdwdRyo9RDU+aoVFNyrA3usRm6quUga1OFe3O+QPjU2cevGbyyPXatnjBxD7srGOdUYZskQs5bDvRfFhluRflZw4YbG6uwQzx4glMgZJ7VklX2nZWQBfAuW0imyCerCOehfYZdzMxJ+al4To+1w4m1WVx0iGnjTjMvAUXdxfk0HgcOTRasDSWWQ44Ma/BwFpvXOdj0uCCfQiOH8uJeTuV/AS104QnqEnzpol5ux3w3i3Mm530xLwxQVkKlnV2d8TrDU8uk643eeWm3ki/GpPkvDcmnBOCnPfFhHNSkPO1MeFcIch5PCacKwU5XxcTzlVKjvNrVDw4Vwty3h8TzpKbMxyICeetgpwPxoRzlyDnCQ85X+8h59d6yHnSQ86HYsJ5TJDzVEw4S7bPh2PCWbJu3+Ah5xs95HyTh5yPeMj5dR5yfr2HnN/gIeebPeR8i4ecb/WQ8xs95PwmDzm/2UPOt3nI+S0ecr7dQ85v9ZDz2zzkfIeHnN/uIed3eMj5nR5yfpeHnN/tIef3eMj5vR5yvtNDznd5yPl9HnK+20PO93jI+f0ecv6Ah5zv9ZDzfR5y/qCHnD/kIef7PeT8gIecP+wh5wc95PyQh5w/4iHnhz3k/FEPOT/iIeePecj54x5yftRDzp/wkPMnPeT8KQ85f9pDzp/xkPNnPeT8OQ85f95Dzl/wkPMXPeT8mIecH/eQ8y/GhPPLBDn/Ukw4XyjI+ZdjwvkiQc6/EhPOFwty/tWYcL5ckPOvxYSz5Gejfj0mnCXbqt/wkPOXPOT8mx5y/i0POf+2h5y/7CHnr3jI+asecv6ah5x/x0POv+sh59/zkPPXPeT8+x5y/gMPOT/hIecnPeT8hx5y/iMPOf+xh5y/4SHnpzzk/LSHnJ/xkPOfeMj5Tz3k/E0POf+Zh5y/5SHnP48J50sEOX87Jpzzgpz/IiacTxfk/Jcx4Sz5PH/HQ85/5SHnv/aQ8994yPm7HnJ+1kPO3/OQ8/c95Py3HnL+Ow85/72HnJ/zkPPzHnL+gYec/8FDzv/oIed/8pDzP3vI+Ycecv4XDzn/yEPOP/aQ8796yPknHnL+qYec/81Dzv/uIef/8JDzf3rI+b885PzfHnL+Hw85/6+HnP/PQ84/85DzUQ85/7+HnFXCP84JDzknPeRc4SHnSg85V3nIudpDzjUeck55yLnWQ851HnKu95Bzg4ec0x5ybvSQ8zIPOTd5yHl5TDi/SpDzCg/LeaWHnFd5yHm1h5zXeMh5rYecm2PCOSXIeV1MONcKcl4fE851gpxbYsK5XpBza0w4Nwhy3hATzmlBzhtjwrlRkPOmmHBeJsg5iAnnJkHObTHhvFyQ8+aYcF4hyLk9JpxXCnLuiAnnVYKcO2PCebUg566YcF4jyHlLTDivFeS8NSacmwU5b4sJ53WCnLfHhPN6Qc7dMeHcIsi5JyacWwU574gJ5w2CnHtjwnmjIOe+mHDeJMg5ExPOgSDnbEw4twly7o8J582CnAdiwrldkPOgIGedlKoI0+oC/olQBnStUvsq7au1r9Ge3kPRexl6T0F2e7Jjk12X7Jxk9yM7GNmFyE5CdgMaR9O4ksZZNO6gfjj1S6mfRv0WasepXSM9T3ov0J6eC6onJLcO7TsB21Phca/2+7S/Vvtx7a/T/jXa79f+gPYHtZ/Q/nrtX6v9pPaHtJ/S/rD2N2h/o/Y3aX9E+9dp/3rt36D9zdrfov2t2r9R+zdp/2btb9P+Ldrfrv1btX+b9ndo/3bt36H9O7V/l/bv1v492r9X+zu1v0v792l/t/b3aP9+7T+g/b3a36f9B7X/kPb3a/+A9h/W/kHtH9L+I9o/rP1HtX9E+49p/3HtH9X+E9p/UvtPaf9p7T+j/We1/5z2n9f+C9p/UfvHtKfvw9P30un74fQ9bfq+NH1vmb4/TN/jpe/T0vda6ful9D1P+r4lfe/xK9p/VfuvaU/fi6Pvp9H3xL6uPX1vir6/RN8jou/z0Pdq6Pst9D2Tb4Rl9bT29D0E+j4A7ZdP+8fTfuq0vzjtt037T9N+zLQ/Me3XS/vX0n6utL8p7ff5rPbf0/772tN+gbR/Hu0n95z2tN8Y7b9F+1HR/ky0XxHt30P72dD+LrTfyY+1p/0waH8I2i+B9g+g9fS0vpzWW9P6Y1qPS+tTab0mrV+k9Xy0vo3We9HDQOuBaH0MrReh9RO0noDm19N8c5p/TfORaX4uzVel+Zs0n5Hm99F8N5r/RfOhaH4QzZeh+SM0n4LmF9D7dnr/TO9j6f0kva+j91f0Pofeb5C9n+zfZA8m+yjZC8l+RvYksq+QvYHG3zQepfEZjVeo/079WerfUX+HHnJqD6l9IH1J+qNNFd2q8HhyeHz51MTk6L58cGj/xFSQCQ7q39H9+yduzI/1BnjtUHDg8KGp4NDU6ORUsHdy4kCQ7aX7u8N0WsPj6NRU/sD1U8HURDA6NhbcOD51bTBxQ35yr06Tru9eZPxzFhGf9NjqMB6VHbl14f/TJidHjwTjB8fyNwUTh6eCib3BnonDB8cO4U11pdy0vJSbmku5aVMpN3WVctOOUm4aLOWm9mQp8Eq56aJSbrq8lJvuLOWme0u56cFSbnqilJueL+WmqooSbmov5abTSrnpqlJuurmUm+4v5aYnSrnp6cXcNBxG4psXdVNrKTe1l3LT9oXepH4Okl0jVbHLAQA=","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashs(\n first_nullifier: Field,\n siloed_note_hashs: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashs = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashs[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashs[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashs\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file +{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"H4sIAAAAAAAA/+2deXAdx33n5+EGHx5xEDcIYgAQAEmAIB7AUyKlR1kUJfGQRMoiZUmkeJPiAR4gKVG3fCe2Y8dyLMeO49iOHTs+c9hOYslxDjuHZdmxFSeOd1O1teutSv6Ls7Vb2VrVeh76K3zR6AdhkOmnH5LfqyLxm2/3TH/6Nz3dPT3dM5VBEKSCyV8p2fyDljN/R/59v2yCxxqpdHCWUH6iX5n5W27+Vpi/0b7PN03aVXScMCm+tSMbKwjA9m2aWBEnYqqh8FTZ9Dzl9ymbnr9IKy2bdpi8VlY2Pd+RVl423QeRVkFpQ6ssm+6XOmJBvCpKLwySKx9pyht+tu9CssscPK8kxzOSCWaWpSryYZhw3suDuecdDBnajxkrPTFWxGCsJMYKB2OVJ8bKGIxVfnnyZajSkdYiT3mvDuae90UOnlTCea92pFXjKe/pYO55B0OG9mPGjCfGmhiMGfpb42Bc7IkxE4NxMTFmiA1/az0xLo7BWEuM2I/roTpPjLUxGOuIsZbY8Lc+ecbRNKU7F8Z64lniiac+Bs8S4mlInifrKZ8j0TEag5l+RVoZCudy2ughjylKF8fGNjMuJN6Ip85iTVO8OiGM0Bo886Qtnug323XlYuTz2uSJsTEGYxMxNhIb/jZ7YmyKwdhMjNiP/djiibE5BmMLMTYTG/62emJsicHYSozYj/3Y5omxNQZjGzG2Ehv+tntibIvB2E6M2I/92OGJsT0GYwcxthMb/i71xNgRg3EpMWI/9mOnJ8alMRg7iXEpseHvMk+MnTEYlxEj9mM/dnliXBaDsYsYlzkYQ0+MXTEYQ2LscjB2e2IMYzB2E2PoYOzxxNgdg7GHGLsdjL2eGHtiMPYSY4+Dcbknxt4YjMuJsdfB2OeJcXkMxj5iXO5g7PfE2BeDsZ8Y+xyMA54Y+2MwDhBjv4NxhSfGgRiMK4hxwMG40hPjihiMK4lxhYNxlSfGlTEYVxHjSgfjoCfGVTEYB4lxlYNxyBPjYAzGIWIcJDb8Xe2JcSgG42piHHIwDntiXB2DcZgYsR+f6zXJM+bHKIdjMK4hnmzyPGvTlMZceLLEM5I8T9ZTPvOoo8FMvyKtDIVzGRj1kMcUpYtjY5sZlVd5R4ln2GJNU7xhIYzQRjzzpC2e6DdbveVi5PM65olxNAbjGDG6yt7a5Bnz7dFYDMa1xLM+cZ61I2lKYy4864lnXeI8k+1R8vmcbI82BDP9irQyFM5lYIOHPKYoXRwb28w4V96qBcar/lX/qn/Vv4V41b/qX/Wv+rcQr/pX/av+Vf8W4lX/qn/Vv+rfQrzqX/Wv+lf9W4hX/av+Vf+qfwvxqn/Vv+pf9W8hXvWv+lf9q/4txKv+Vf+qf9W/hXjVv+pf9a/6txCv+jc+b8QzZrGmKd6YEEZo6zzzpC2e6JeytkOyXYxcDjd6YtwQg3EjMbqulU2eGDfGYNxEjBuJDX+vS54xv+ZgUwzG64hnc/I8+TVw18Xg2Uw81yfPk/WUz/yagy3BTL8irQyFcznd4iGPKUoXx8Y2Myqv8m4hnk0Wa5ribRLCCO16zzxpiyf6zVZvuRj5vN7giXFLDMYbiNFV9m70xHhDDMYbifEGB2POE+ONMRhzxHijg3GrJ8ZcDMatxJhzMN6UPGO+77E1BuNNxHNz4jyj+fWON8XguZl43pA4z2TfI/l8TvY9tgUz/Yq0MhTOZWCbhzymKF0cG9vMOFfeqgXGq/5V/6p/1b+FeNW/6l/1r/q3EK/6V/2r/lX/FuJV/6p/1b/q30K86l/1r/r3P5d/I56tFmua4m0VwgjtDZ550hZP9EtZ2yHZLkYuh7d4YtwWg/EWYnRdK9s9Md4Sg3E7Md5CbPh7a/KM+WdO22Mw3ko8tyfOM5Z/5nRrDJ7biee2xHkmnzkln8/JZ047gpl+RVoZCudyusNDHlOULo6NbWb8j8pbtcB4tTz45dXyoLxaHpS3EK+WB+XV8qC8hXi1PCivlgflLcSr5UF5tTwobyFeLQ/Kq+VBeQvxanlQXi0PyluIV8uD8mp5UN5CvBLKQ8Sz3WJNU7ztQhih3eaZJ23xRL+UtR2S7WLkcrjTE+OOGIw7idF1rezyxLgzBuMuYtzpYNztiXFXDMbdxLiL2PD3juQZ8/PCdsdgvIN47kqeJ/8epDti8NxFPHcmz5P1lM/8vLA9wUy/Iq0MhXM53eMhjylKF8fGNjMqr/LuIZ7dFmua4u0WwgjtTs88aYsn+s1Wb7kY+bzu9cS4JwbjXmJ0lb27k2fMt0d7YzDeTTz3JM+Tb4/ujsFzD/G8MXmerKd85tujfcFMvyKtDIVzGdjnIY8pShfHxjYzKq/y7iOevRZrmuLtFcII7Y2eedIWT/Sbrd5yMfJ53e+JcV8Mxv3E6Cp79ybPmG+P9sdgvJd47vPEc28MnvuI503J82Q95TPfHt0fzPQr0spQOJeB+z3kMUXp4tjYZsaFxBvx7LdY0xRvvxBGaG/yzJO2eKLfbNeVi5HP6wOeGO+PwfgAMbrK3gFPjA/EYDxAjA84GA96YjwQg/EgMR4gNvx9MHnGfD1/MAbjg8Rz2BPPgzF4DhPPoeR5sp7ymW93jgQz/Yq0MhTO5fSIhzymKF0cG9vMuJB4I56DFmua4h0UwgjtkGeetMUT/Wa7rlyMfF6PemI8EoPxKDEeITb8PeaJ8WgMxmPEiP3Yj8c9MR6LwXicGI8RG/6e8MR4PAbjCWLEfuzHk54YT8RgPEmMJ4gNf095YjwZg/EUMWI/9uNDnhhPxWB8iBhPERv+nvbE+FAMxtPEiP3Yj2c8MZ6OwXiGGE8TG/6e9cR4JgbjWWLEfuzHc54Yz8ZgPEeMZx2M454Yz8VgHCfGcw7G854Yx2MwnifGcQfjBU+M52MwXiDG8w7Gi54YL8RgvEiMFxyMlzwxXozBeIkYsd8iYpzwxHgpBuMEMWI/9uNlT4wTMRgvE+OEg/GKJ8bLMRivEONlB+NVT4xXYjBeJcYrDsaHPTFejcH4MDFedTBeS54xP97ycAzGa8TzSPI8WU/5HImO+6g51isJ8kbHeCyYeQ6v0blE+KPku8c8+C5F6eLY2GbGufKWCOD1lPbo4p8fo5ryz+kFFtfj5m8Z6bguozw8Yexys434iygu4rzb7FgbTPoaP/6e2+PJ5zc72zWN9JgnK4xnpTCea8J4eoXxXBTG0ymM54wwnhZhPMeF8dQK4zkgjKdSGM89wnh2CuO5WRjPZmE8o8J4VgnjWS6M55IwnmXCeM4K42kVxnNCGE+dMJ6DwniqhfHsE8azSxjPNmE8W4TxjAnjGRTG0yeMZ0IYT5cwnnPCeNqE8ZwUxrNEGM9hYTxpYTz7hfHsFsZzizCeG4TxrBfGMySMp18Yz2VhPKEwnnFhPO3CeE4J42kUxnNEGE+NMJ77hPGUCuO5SxjPdmE8Nwrj2SCMZ7UwngFhPFeE8XQL4zkvjKdDGM9DwniahPEcFcaTEcZzvzCecmE8e4Tx3C6MJyeMZ6MwnmFhPCuE8VwVxtMjjOeCMJ6lwnhOC+NpFsZzTBjPYmE8DwjjqRDGs1cYzw5hPFuF8aQE8KSDmWst0xS+iDSsHysl7Uljl5P2lLErSHva2JWkPWPsatLeTDb+vsXYNaS91dgZ0t5m7MWkvd3YtaS9w9h1pL3T2EtI+wVjN5L2i8ZuIu1dxm4m7d3GbiHtPcZuJe2XjN1G2nuN3U7a+4zdQdovG3spae83didpzxp7GWkfMHYXab9i7JC0Dxq7m7TnjN1D2oeM3Uvarxp7OWkfNnYfaR8xdj9pv2bsAdI+auwVpP26sVeS9jFjryLtN4w9SNrHjT1E2ieMvZq0Txp7mLTfNHaWtE8Ze5S0Txt7jLTfMvZ60j5j7A2kfdbYG0n7bWNvIu1zxt5M2ueNvYW0Lxj7BtK+aOwbSfuSsXOkfdnYW0n7HWPfTNrvGnsbab9n7FtI+31jbyftK8a+nbSvGnsHaV8z9k7S/sDYu0j7Q2PvJu2PjH0XaV839h7Snjf2XtJeMPY9pH3D2PtI+2Nj7yftm8a+j7Q/Mfb9pP2psR8g7c+MfYC0Pzf2QdK+ZezDpH3b2EdI+wtjHyXtL419jLS/MvZx0v7a2CdI+46xT5L2orFPkfZdYz9E2kvGPk3a94x9hrTvG/ssaX9j7HOk/cDY46T90NjnSXvZ2BdI+1tjXyTtR8a+RNrfGXuCtL839mXSfmzsK6T9g7GvkvYTY18jDeveuZ1Gu/sEaVgD/iRpaIufIg1t8dOkoS1+hjSsPed2GO3zW0hDv+CtpKHNfhtpaLPfThra7HeQhjb7naShzf4F0tBm/yJp9cZ+F2kNxn43aWjb30Ma2vZfIg1t+3tJQ9v+PtLQtv8yaWjb308a2vZnSUPb/gHS0Lb/Cmlo2z9IGtr250hD2/4h0tC2/yppobE/TBra9o+Qhrb910hD2/5R0tC2/zppaNs/Rhra9t8gDW37x0lD2/4J0tC2f5I0tO2/SdqgsT9FGtr2T5OGtv23SEPb/hnS1hj7s6SNGPu3SUMf4HOkoQ/wedLQB/gCaWuN/UXS1hn7S6Shr/Bl0tBX+B3S0Ff4XdLQV/g90q4z9u+Tdr2xv0Ia+hRfJQ19iq+Rhj7FH5CGPsUfkpYz9h+Rhj7F10m7ydjPk/YGY79AGvoe3yANfY8/Jg19j2+Shr7Hn5B2q7H/lDR8J+/PSEMf5c9J22Hsb5GGPsq3SUMf5S9IQx/lL0nDt4b+ijR82+evSUNf5jukoS/zImnoy3yXNHw/4iXS8L2G75GGPs/3SUOf529IQ5/nB6Thnes/JA3vOH+ZNPSN/pY09I1+RBr6Rn9HGvpGf08a+kY/Ju1BY/8DaYeMjXY4ahc/XzkVDsYS2gd54Xth5LmMNPiG74/hQ74//h6lDQ3npIo0MLLfkBf2L/LM5wG+4fMFH/J5ha/5/OOcvOTg43EM7BMGyY5jcFohbSO9GuJ4SQjPVmE8O4Tx7BXGUyGM5wFhPIuF8RwTxtMsjOe0MJ6lwnguCOPpEcZzVRjPCmE8w8J4NgrjyQnjuV0Yzx5hPOXCeO4XxpMRxnNUGE+TMJ6HhPF0COM5L4ynWxjPFWE8A8J4Vgvj2SCM50ZhPNuF8dwljKdUGM99wnhqhPEcEcbTKIznlDCedmE848J4QmE8l4Xx9AvjGRLGs14Yzw3CeG4RxrNbGM9+YTxpYTyHhfEsEcZzUhhPmzCec8J4uoTxTAjj6RPGMyiMZ0wYzxZhPNuE8ewSxrNPGE+1MJ6DwnjqhPGcEMbTKoznrDCeZcJ4LgnjWS6MZ5UwnlFhPJuF8dwsjGenMJ57hPFUCuM5IIynVhjPcWE8LcJ4zgjj6RTGc1EYT68wnmvCeFYK48kK49lk8fBazp+QhnVHvOYOa394bR7Wu/AaPqw54bV+WPfBawKx9oLXDmK93lbSMMdjB2lYr8fvesBcWH4PA9YH8ftl0IbzexOwXg9M1UbDfM0wSOxcHYnSw3MJ/FLWdkg2v2P1SPI8WU/5HKkiH6cSPG50jOPkn8OWnzIUzu9nO+7BdylKF8fG9nFH2lVBsn448Rp+OOFgOVFkP5xwpP1KkKwfTr6GH046WE4W2Q8nHWmXBsn64dRr+OGUg+VUkf3AjHPlPbbAeI8vMN4TC4xXy69fXi2/fnkllN8o7YeST3tT2ko7+s3Wv33Isy885TPf3p6mfBy18pOhcL7+T3vIY4rSxbGxzYxz5T0ugJfTLgmSPW9nXsMPZxwsZ4rsB2acK++xBcZ7fIHxannwy6vlIT6vp/Yt6ylP+XEhzHNIsF7P8nu6S8g35zydl8A6L/ghvULfsZPAs0kYz5gwntXCeAaE8XQL4zkgjKdDGM9+YTxNwnj2COOpFcazUxhPtTCeW4TxlArjyQnjuU4Yz1phPMPCeFYI4+kRxnNQGM9SYTz3CuNpFsazVxhPnTCeXcJ4Fgnj2S6Mp0wYz1ZhPNcL41knjGeNMJ6Vwnh6hfE8KIynUxjPm4TxtAjjuVsYT70wnt3CeNLCeG4VxlMujOcmYTybhfGsF8YzIoxnlTCe5cJ4DgnjWSaM5z5hPK3CeN4ojKdBGM8dwnhqhPHcJoynQhjPG4TxbBHGs0EYT1YYz6Awnj5hPF3CeO4XxtMmjOceYTxLhPHcKYwnI4zndmE8lcJ4bhbGc4Mwno3CeEaF8QwJ4+kXxhMK43lAGE+7MJ59wngahfHcJYxnsTCeHcJ4qoTxbBPGkxLAkw5mrntPU/gh0saNfZi088Y+Qhq+f32CNLyjjt9nhffkHidtwrEvvhd0kjR8Q/Eoafiu9CnSHnYc7xEHyzUHy6PGPk3aY8Z+iLTHjX2GtCeMfZY0rPdj32MO/DhpmBd2njQ8K71AGsYPL5KGPv4l0nAdTpCGtQmXScN8vSuk4Rn2VdIwrvswaSjXj5CG+vEaaVgz8ihpmEf5GGmYW/A4aRhvh2+jvL64aCoc+5fQPkinlLQnHOk97uCCzdcp9gmDZK9TTiukbaRXQxyPCuHZJoynShjPDmE8i4Xx3CWMp1EYzz5hPO3CeB4QxhMK4+kXxjMkjGdUGM9GYTw3COO5WRhPpTCe24XxZITx3CmMZ4kwnnuE8bQJ47lfGE+XMJ4+YTyDwniywng2COPZIoznDcJ4KoTx3CaMp0YYzx3CeBqE8bxRGE+rMJ77hPEsE8ZzSBjPcmE8q4TxjAjjWS+MZ7MwnpuE8ZQL47lVGE9aGM9uYTz1wnjuFsbTIoznTcJ4OoXxPCiMp1cYz0phPGuE8awTxnO9MJ6twnjKhPFsF8azSBjPLmE8dcJ49grjaRbGc68wnqXCeA4K4+kRxrNCGM+wMJ61wniuE8aTE8ZTKoznFmE81cJ4dgrjqRXGs0cYT5Mwnv3CeDqE8RwQxtMtjGdAGM9qYTxjwng2CeO5URhPiYMHa+tyyfHkv334SOL5XDcS5Q1rBivMscGP9MooztvNgA7abejRD2v4rpF/HrPicT5yQXLnKzruVU/+uWL5B/xXyT+I8x7LP9DZP4+Qfx624nE+ckFi/hmNjnvZk38mLP+A/zL5B3E+YPkHOvvnKvnnihWP85ELEvPPWHTcS578c9HyD/gvkX8Q5yOWf6Czfy6TfyaseJyPXJCYf9ZGx73gyT/nLf+A/wL5B3E+YfkHOvvnEvnnohWP85ELEvPPuui44578c87yD/jHyT+I81nLP9DZPxfIP+eteJyPXJCYf9ZHx33Sk3+esvwD/ifJP4jzZcs/0Nk/4+Sfc1Y8zkcuSMw/G6LjPu3JP89Y/gH/0+QfxPma5R/o7J8nyT9PWfGqKF4qSLY/hvcBlJtjP2ZxlVGcFygf/B4Cfj8C4vK7FZAPfi8D/MTvdHizsfl9EG8xNr9L4q3Gfoo09BkfIw3jaPxuBTxbfIY0zLd6mjTMQX8zaVgH9xbSsBYfTNVGw5qnMEj2fIEfx8Y2vzPRV9ppK+20lXahb3774gksnmAWngZhPLXCeGqE8VQJ4ykXxlMvjGexMJ5FwnjSwngqhfGUCuMpE8ZTJ4wnI4ynWhhPhTCelACeQu/gQzi/uwzvKCojDc/tyknDXKYK0jC/u5I0/sYLNKy7ryYN7/5ZRFoH2fi71Ng1pGHedIY0rCVbTBrWs9eShv4y+wr+aCQN/mgiDf5oJg3+aCEN/mglDf5oIw3+aCcN/mBfwB9LSYM/OkmDP5aRBn/AFxHb9+umwpHnEtrHVU5CY3M56TY2lxPMWeJy0ktpQ+NvSUHDen8uJ3jnEJeTAbLxd4WxuZwgz3xe4Rs+//BhSBp83U0azkkPaTh3vaThHC8nDWWhjzSUmX7SULY4jyiDK0iDzfXNAOUjZ+yRf98vX99wWiFtIz1+l+AKITwVwniqhfFkhPHUCeMpE8ZTKoynUhhPWhjPImE8i4Xx1AvjKRfGUyWMp0YYT60wngZhPCVF5EH/GcfutHh8pt1hpd1RxLTbrLTbiph2i5V2SxHTbrLSbipi2lrWtKwVK20ta1rW7LT7Ek973QiPaeGXsrZDsvk7pP2J80zOR00+n5PzgJdT/pI6bnSMXvLPgOWnDIXzuGOvB9+lKF0cG9u9jrRfCZL1Q89r+KHHwdJTZD8wo/Iqr/LK412uvF55tfwqr/IqbyFerX/98mr5VV7lVd5CvFr/+uXV8qu8yqu8hXi1/vXLq+VXeZVXeQvxav3rl1fLr/Iqr/IW4tX61y+vll/lVV7lLcSr9a9fXi2/yqu8yluIV+tfv7xafpVXeZW3EK/Wv355tfwqr/IqbyFeCfVZlHZ34mkfXZu20o5+KWs7JLvbsy/85HNyPR7no8/KT4bCuXyGHvKYonRxbM5z4LCVV3mVV3lDS1de5Q2UV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDQHmVV3mVV3mVV3mVV3mVV3mVV3mVV3mDYEHzRmkvST7tsbSVdvRLWdsh2Us8+8JTPkeiYzRSPrqt/GQonM93o4c8pihdHBvbzKi8/ngzFF5CPB7KXnYu1xPzdAnjaRfG0yaMp0EYz1JhPB3CeJqF8TQJ46kXxrNMGE+nMJ5WYTwtwnjqhPGkBPCkg5n9/EhbaewS0lYZu4u0QWMvI23I2J2krTb2UtKGjd1B2hpjt5M2Yuw20rLGbiVt1NgtpI0Zu5m0tcZuIm2dsetIW2/setI2GLuBtI3GHiBtk7H7SbvO2H2kXW/sHtI2G7ubtC3GDknDuVlJWqmxV5FWZuxB0sqNPURahbFXk1Zp7GHSqoy9hrRqY4+QtsjYWdLSxh4lrcbYY6ThOllL2mJjryOt1tjrScM53EAazuFG0nAON5GG6+I60nCvcD1pKDubSUMZw7mKfPd/G6bCsT9fU0inlLQtjvQ2O7hgcz2CfcIg2XqE0wppG+nVEMd1QnjqhPG0CONpFcbTKYxnmTCeemE8TcJ4moXxdAjjWSqMp0EYT5swnnZhPF3CeEosnqhPhHO4hTT4kftq2JfvKdAHQ/xqk8cGD3nkPmlAeeVfSDaPLbKdS4ZnJEM8fHwP4/Kj3M+eS94biac5eZ4x7uPPhYfHDZuS58l6ymf+1qwlmOlXpJWhcC4DLR7ymKJ0cWxsM6Py+uONeOznYXwfu0QII7QmvzyjaYsn+s1WD/D4ZlvyPPl6qSUGDz8Pa02eJ+spnyPRcdHmvhIkW991BDPPF/KQoXB+ttnhwXcpShfHxjYzKq8/Xq5LeIwY8ZqFMEJr9cszmrZ4ot9s9Qs/v+1Mnidf33XE4OHnb0uT58l6yme+vsPYUmmQbH3XFcw8X8hDhsL5WWqXB9+lKF0cG9vMqLz+eLku4WdsiNcmhBEaPxvEcx20G9Hzqj5zgxodF3Vj9MzqSYpfRn8RZ6Bh6hgr6qfy7KsPiXTxm2sf0sO9duw+JN9r+7q39ZDPEV/jItEx2oOZ54vnDyKc02/34LtUMH2cIqRtZlRef7wRT6vFyuNHrUIYoTX55RmNO3bG9wEe+mxjPN47Fx6eI+mjz+8pnyPcNy0Jkq3vlgUzzxfykKFw7n8v8+C7FKWLY2ObGZXXHy/XJTwnC/EahTBC43tUaEmOKfH8Ihw/6lcepL4p2gX0TXlOWfQrozjvr586xmFj81wRPJPh5/88d6/B0ny2O0gLx8Z2OzGivWkgDWw8B6/d0nyOubRb3NjuIEZXXsDGzwg7LM3X2EMqmD4WEtL2UmJ05cUeP+LrlfsnHsY2Zr1eO4nRlRew8bOITkvzWc8UulddRox2Xrj/0+Lg5rmjOA7PO8V9MF/TobF5jmm3sfkawpxRrpexporL7HJj8xgA5qByGcFcVb4PLzE2nxM8J2cf4L6b5wFjjinPF8Yc05A0zDHtJg1zTHleLOaY9pKGOabLSUM9y/NsMccUecSzfV/PtcCFY2Ob7/c93F+Pxr3fBwM/m6wmvzU5uH3Mh0hRWji23ZZkSFvk14/ZJPyYXgCMNQuAMbMAGBc7GHNBcv1O7lfi2HUWT0kw83rNBdOvWd9MKPMNxNTgYLL7yblg5vXOvkwFfvqy5RYL0iujOF8zjXityQ/i1lk+bg8S9/FYyvJljtL3/Ex1E/flKoLpff4O8hPifIP8FATT+4FoU/i+oMWKx/nIBf76pDlHPjz1K/M+7LJ8aN+/llGcb1s+7HL4kPvM9vMUfpaTC5LrV8zmw64i+DCcgw8R5yXLh9AL+bDBisf35z+g+/Pehql97Pspvqfleyxf/ctC97TcrttzL0rItusuD+dtzFX2kb6r7P8XOm+enkmO+bp/xPGQpw5HPhH+36hM/Xdjcx+Ex5V+5gjHb7Y+Cl+TPcnnN9/24z4M57bHkfZyYk0o7SynnTL/kA70MrL/hSZaL58yX/UzuKNrptsRj+0Wa58MhXc78h0mnO8eYglpG+lFZeZ/Uvn6GT3v9tF35nyzf/hZFMJ5noTrGRrCPc97mnWsh+dhQYPfeHzztcaoXi9u7ld5nh815mqX7ecZXO+VmfYT9XvogcnXeGx0DK7LWxz5RHg1zTdJ0/pfuzxF4e2OcPxmq99hR/ntTj6/I1zX4Nx2O9LmejihtKfVc6jfkQ70MrLb6MFE75T5qp/BzWuYOB7bndY+GQrvcuQ7TDjfXJeGtI30ojKzmMoXyo+vOofzzf7h+h3hPE7XaMXnZ1VcT75ez6oywcx7QO7jc3uZ4PPDvD+5H2eP4fDzxRbiOkjtuI+5/ZHPSoPpPsO25/uZec+Z435ECfmvxcHto+9jj3+FwcxxJB4jLPXrx2wSfixbAIzlC4CxYgEwVi4AxioHYy5Itp/DjNFxay0eHvNtpXg+x/ptJlyXrrF+ZuJ9Ma5u10k+x9W5zWIWHldHnDvpfqCE4tZaPm4MEvfxWmbFuLo9/8DTs84jPH6HvrW9LrSM4uwjPwXB9LE/tHs87tdqxfP0/GfGOGQucK9v9XA/doTvhWe790Scg5YPOx0+5Lk/9toOni+TC5IdVy/kQ8/z/47EHZ89Yfmw6zV8uNSK5+nZxNhsPvT8bOLIbGMgrrHfccuH0Av5sMWKx+taLtF94P+mZxPYn+cUNVka16thkGydUGgeRyPly24XeGytnvxhz2PPBd7mruXLEc4ZzqV9H8vjPE9Y41k+nqH4mqcXHaOL8tTqyCfC30zl7K00XoVzwmu0nnWE4zdb34/XyxV7PIvTljCe9f4C41nwM49nhY54s42B8XhW6Mh3mHC+u4klDNzjWe+g8vUsjb/4mGfG+Wb/8HojhPOzgCVWfJ4LXIw6tdBcYOaGxnMsYDc7uJsFcHO9z88wYLvaAp4j4mkM0fns2l4HwXXkp622wNezax/jpdExuN5vcuQT4Z+ja/ULVNfbZS8Kf94Rjt9sbQH32cLk8zvC9RLObehIm+vshNKeVieiLUA60MvI/jq1BT1T5ow5K/y+So7Hdoe1T4bClznyHSac75BYQtpGelGZ+TKVr+epLfAx5s35Zv9wnYpwXp/VbMXnNQC+3w2WCgqv/+QxZ3s9Kve52xzcbQK4ud7n9gE2twV2u50L/D7ntscakL5rrOF7Vlvg417F53Nurvc7HPlE+Mt0rf6I6nq77EXhP3WE4zdbW+B5DGTEdf/uWn/JdXZCaU+rE9EW8L1P9OOxg/9BbUH3lPmqn3mdUpcjHtuN1j48T6fLke8w4XxzvRvSNtKLysyPqXz9tAj3BV0O/3CdinB+TtFmxefnj1yn+poPVOj5I9+72GOyfF/A33jhNT65BBn5eufz51pTlNiz9uzktQ0/RNd2NbHwODvi/C+qt/l9qNiHx9nYX0nPD+BnP/azKH43DtevfTQ/wNd7HuK8K4znWWA/XguJ8GJcI6+1/rfY7xgpt3jKLZ/5TLvSSruyiGlXW2lXFzHttJV2uohpZ6y0M0VMey7visGvpAg8gcUTzMJTjHcaxOEpxry1ODy1wngWCeNJC+MpE8ZTLoynTRhPvTCeYvRN4vAsFsZTJYynWhhPqTCeFmE8xXh3Xxwez+/ui83TLIynThhPjTCejDCeCmE8lcJ4UgJ40oH7e7C8hhwaxk/425X8nAAaxtHLSeN5VtAwvlpJWhhM+QQaxoj5PUV4hriINH5PFP5inWwNaXhPVIY0vCdqMWn4vmstaSuMze/4w/dYef4dvsfK48T2fD9+txY/W4Qv+b1c8CWvr4Iv+R1c8CW/gwu+DEmDL7tJgy97SIMv2bfwJb+DC77kd3DBl/xNXPiSv50LX64gDX1x/tYt+sPwbZTXTzZNhWN/LrNIh8vsKkd6Kx1csPk6xT5hkOx1ymmFtI30+HurA0J4KoXxVAjjyQjjqRHGUyeMp1kYT5MwnlZhPC3CeEqF8VQL46kSxrNYGE+DMJ56YTxtwnjKhfGUCeNJC+NZJIynVhhPozCeJcJ4SorIg/tRHHulxROljfvqXHJp578z0pd4no7m119jvADzLsGP9Moozsvm5OMa4Xey4f69n87NCiuen3xMzjFbbp2bFVY+Shw8ocWUS44p/82Z5NdzTZ4zew0d+Pm9e4jzj9Y5gx79Vlk+qiHfIF5V4G8tQqH3A7nSTvr7IfY7BPPzW5dMpduffLqHuE7Dd0nAgfTKKM6/Lpli+6clU+fInrfHY778/F7StyV47qLrGzY81lriyF+pdTx8O6A/+TyO8HnCse3zVEL2AMWzz3FI8VD/8Dn+NzrHZ8zggqfyt45ZSxx54jorwXRHo2OgjgkoDWaBzXVxxNMdTPk2GZ7JOjQMpp8jpN9N5whxSk0nzPW+gFVWXqKy32PFqyI76XnKXE77rHRLKD+Ilwt8rY2c9Ku9dh/p8zr3V9dIWH5d5vBrN/l1wIpXRXYqSPb67yaWlCNtLrPdFC+w9rXbZk99oFn7p30OfyWY9ig/v2OfBRZPYPnQUxs1xs8258LDa4x8fIPXUz7z9wU+vq8WHaPDcb743cF2+14VvH7v21Vev7wRT5/FynMK+oQw2t9h4Hff8fvcRxqneD30d/JrVdGnQj8fHHyPhjjnm6bY1hq2mmDmvTjPu2Cfh+SXXDJ5mPW9IUivhvLTTTy+2rdei6fX4YvXM234IBckW8eHyefJ+W4N+/zyuzVusvpqvE4T5ZT7an1WPM5HLki2bfX13Qx7vTn4+Z1iiHOb5Z9Oh39C8k+XFY/zkQuS65txHyFM2D8dln/s9zTwus47Lf90OPzDa6ft+t3TvX6W56jhN1tfke+VfbR1PO9tLjyub+0mzRPnvTHcX/Exf5LHjObCw+v7Bj3xtMfgGSSeIU88gzF4hohntSeeoRg8YOB3pPHcUFwbXaTZ7wnlb1EvJw3nqYc0+KqENPDymA40HpN0rZ/29R3iQuun+RtayIvrW1P2twg9fONtI48Nl5jj2uu8uV5IcMwm66f8rsuPBQ2bY9nfPUN6ZRTnUWrnqkhPksnXtRodYw3ladCRT4Q/ZfIZ3bM8Y2xuu3C9ROHvc4TjN1tdAN9F+c0mn9/8uR01x8K5zTrSHiPWhNLOctop8w/pQC8j+720iHxsynzVz+CO6oERRzy2+619MhQ+4sh3mHC+s8QS0jbSy7/jlMrX+xz360kycb7ZP/y+MYRz3cXtbC6YXveDd03ivJN1Eq5JlFuw8PWLOB+y6iQf9aSfvE6em2HKU68jnwj/KJWZj1Gdg/OC8xqFf9ERjt9c+ievR53EaUuok75QoE6y65e51ElLrX0k1kmfoPL1RaqTfPTjOd/sn0HyD8LRP7bHqXLB9Hse8CY/RubuJ9n9d75Wv1qkfpKP8cDoGFz/DDnyifCvU5l5geocnBcel37REY7fXPtJI8nnd4SvD5zbEUfaXHcklPa0axN1EtKBXkb2d6hOGp0yX/UzuKM6abUjHtuD1j4ZCl/tyHeYcL75+g9pG+lFZeabVL5epDrJx1gZ55v900v+QTjuz3mcOTAsrnefJ3/fPFkn4TpEuQULj1EizstWneSj7+ZrjCA6Btc//Y58IvzHVGZ+QnUOzgvOaxT+z45w/Gark+A7T/eqI3x94NyudqTNdUdCaU+7NlEnIR3oZWT/E9VJ3M+w76+jOmnYEY/tXmufTOC+Z/XQN83yfQeOvdpijMrMP1L5+uci9JOGHf7h8UGEY3wwygePQ+SC6fM+wJv8nI3JOgnXoT0/kN//jjg/s+okH303P3mdPDdc/ww58onw/0Nl5t+ozrG/FRuFVzfNDMdvtjqJn9Um398ccd6XDzvS5rojobSnXZuok5AOj9+92m+hD8NwPwN+BndUJ61xxGO7y9qH703WOPIdJpxvvv5D2kZ6UZn5f1S+qmmerY9nQpxv9k8/+QfheD4R5YOfk+SCmc+NffaT7GfdYHG9W73e+M/fu9WL108adOQT4c00L6eV6hz7GVQUPuAIx2+2Oomf/xe7TuK0JdRJ/QXqJLt+mUud1G/tI7FO6qDyNUB1kq8x7jUO/wyRfxCO56OuMW7uw4E3+fVB7n7SoMXH1+oaq07y1U9KPq8z+0mu75IhfC2VmfVU5+C88Bj3Nkc4fnPtJ3kY03eOFa5xpM11R0JpT7s2USchHX7OAPtmqpP43gd+BjfPWeJ4bA9Z+/B4Sacj32HC+ebrP6RtpBeVmU1UvrZRneRjXjznm/3DY9wIx/yMuY5x++on4Zq0x7j5+kWcXVad5KOeLFY/yTVuhvA9VGbupjoH54XnAhxxhOM3W50E370edRKnLaFOOlygTrLrl7nUSfZzY4l10j4qX0ccaySTZOJ8s394jBvhA6S1WfF5bILnh/kYA7PH2EPa5v6dfR9ahDWnM9Yo2mtOeS32AHH9lNY7u9ZBhJbmq41KBdProZC2kR6vg7Dj4of1H93mb0kwc8wxF/haoze5NtO+x0f6rvnsj1LbFQTTr4lVjvyHVjzOX6uVv2LNR3e1WYjzjNU2e5jLXbTvw7n6IAh/O9Wd76S2F+eJ64LnHOH4zdY289xOD/WbcwxjyJE2t6EJpe0cw0A6rjGMD1LbzGMA9v02z9fleGx3Wvvws4xBR77DhPPN94whbSO9qMy8i8rXc9SWeFiTk+V8s3/4WY99L8BrF/k9va71Wz76E/b9SkjbPB4MzbU2Oun2mNdGtzp8Y3/L0F4zucSTnwq9D4a/QeQr7XIr7fIipl1ppV1ZxLQLfQ+sGGmnrbTTRUw7Y6WdKWLar085P7o2Om6zh+PG/Z6s7+8zLwqm3mt64tjE7vGJY5dSxAXWH1qsqWA6N8JrSCshu5T2K3NoFQ6tyqEtcmg1lhb9FpNdS3Yd2UvoGPVB4XwgDue3tEh68Boc4I3KFcqK69uuTaThvDSThvQQvzqYWS4TvbA54/avksJKTNyo0EQNTYUJH3Ds/y5Tsjab7b0T4xcPnTgWXjozPhGOhOd+/v+hM2fGrx47Ohxy2KXw7OVLE+GliUMXJ8LjF8fPhtlhPu7bTKnD4MTWixcPPRKeOnf02MPh+OWJcPx4eHj88rmjl3ind89np2fns9OH57PTx+ez02fms9OX5rPTV+ez0wv189jpW/PZ6bvz2ekn89mptGEeO90zn50OzGen4/PZ6dx8dnp8Pjt9aj47vTSfnf7V7ISBhUMTE8fOnp8IJ8bDQ0ePhldPTZwMx68cu3j85/XPtAp8yTwS+6/z2amkcR47peez09b57HTrfHa6Yz47XZvPTs/NZ6evzGenH85np3+Zz051TfPYaXg+O+2cz07X5rPT03PdKfj/zFYuImetAwA=","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"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","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashes(\n first_nullifier: Field,\n siloed_note_hashes: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashes = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashes[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashes[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashes\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index e0c1ef48138..eaa0fc06353 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -234,7 +234,7 @@ mod tests { kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, - hash::compute_unique_siloed_note_hashs, tests::kernel_data_builder::PreviousKernelDataBuilder, + hash::compute_unique_siloed_note_hashes, tests::kernel_data_builder::PreviousKernelDataBuilder, utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array} }; @@ -261,15 +261,15 @@ mod tests { self.previous_kernel.end.new_nullifiers.storage } - pub fn get_unique_siloed_note_hashs(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.compute_unique_siloed_note_hashs(self.previous_kernel.end.new_note_hashes.storage) + pub fn get_unique_siloed_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { + self.compute_unique_siloed_note_hashes(self.previous_kernel.end.new_note_hashes.storage) } // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // commitments for the given commitments. - pub fn compute_unique_siloed_note_hashs(self, commitments: [SideEffect; N]) -> [SideEffect; N] { + pub fn compute_unique_siloed_note_hashes(self, commitments: [SideEffect; N]) -> [SideEffect; N] { let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); - compute_unique_siloed_note_hashs(first_nullifier.value, commitments) + compute_unique_siloed_note_hashes(first_nullifier.value, commitments) } pub fn append_transient_commitments(&mut self, num_commitments: Field) { @@ -363,11 +363,11 @@ mod tests { builder.append_transient_commitments(1); builder.add_transient_read(0); - let unique_siloed_note_hashs = builder.get_unique_siloed_note_hashs(); + let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); let public_inputs = builder.execute(); assert(array_length(public_inputs.end.new_note_hashes) == 1); - assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_note_hashs[0])); + assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_note_hashes[0])); } #[test] @@ -381,12 +381,12 @@ mod tests { builder.add_transient_read(1); // Read the hash at index 3; builder.add_transient_read(3); - let unique_siloed_note_hashs = builder.get_unique_siloed_note_hashs(); + let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); let public_inputs = builder.execute(); assert_eq(array_length(public_inputs.end.new_note_hashes), MAX_REVERTIBLE_NOTE_HASHES_PER_TX); for i in 0..MAX_REVERTIBLE_NOTE_HASHES_PER_TX { assert( - public_inputs.end.new_note_hashes[i].eq(unique_siloed_note_hashs[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) + public_inputs.end.new_note_hashes[i].eq(unique_siloed_note_hashes[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) ); } } @@ -433,13 +433,13 @@ mod tests { builder.nullify_transient_commitment(1, 0); let new_note_hashes = builder.get_new_note_hashes(); // The 0th hash will be chopped. - let unique_siloed_note_hashs = builder.compute_unique_siloed_note_hashs([new_note_hashes[1]]); + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes([new_note_hashes[1]]); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); assert( array_eq( public_inputs.end.new_note_hashes, - [unique_siloed_note_hashs[0]] + [unique_siloed_note_hashes[0]] ) ); // The nullifier at index 1 is chopped. @@ -498,14 +498,14 @@ mod tests { let public_inputs = builder.execute(); - let sorted_unique_note_hashs = compute_unique_siloed_note_hashs( + let sorted_unique_note_hashes = compute_unique_siloed_note_hashes( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, sorted_new_note_hashes ); for i in 0..10 { - assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashs[i])); + assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashes[i])); assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); } } @@ -615,7 +615,7 @@ mod tests { let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; let public_inputs = builder.execute(); - let siloed_note_hashes = compute_unique_siloed_note_hashs( + let siloed_note_hashes = compute_unique_siloed_note_hashes( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, new_note_hashes diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr index e276b3d4ebd..1ba04777e9a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -304,20 +304,20 @@ pub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> pub fn compute_unique_siloed_note_hashes( first_nullifier: Field, - siloed_note_hashs: [SideEffect; N] + siloed_note_hashes: [SideEffect; N] ) -> [SideEffect; N] { - let mut unique_siloed_note_hashs = [SideEffect::empty(); N]; + let mut unique_siloed_note_hashes = [SideEffect::empty(); N]; for i in 0..N { - let siloed_note_hash = siloed_note_hashs[i]; + let siloed_note_hash = siloed_note_hashes[i]; if siloed_note_hash.value != 0 { let nonce = compute_note_hash_nonce(first_nullifier, i); - unique_siloed_note_hashs[i] = SideEffect { + unique_siloed_note_hashes[i] = SideEffect { value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value), counter: siloed_note_hash.counter }; } } - unique_siloed_note_hashs + unique_siloed_note_hashes } pub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field { diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index b88c41f001e..6bd40d7241c 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -3480,7 +3480,7 @@ "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/constants.nr" }, "111": { - "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashs(\n first_nullifier: Field,\n siloed_note_hashs: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashs = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashs[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashs[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashs\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", + "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashes(\n first_nullifier: Field,\n siloed_note_hashes: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashes = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashes[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashes[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashes\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "126": {