From 2aa7ed25ff5f3bb2773876e0e4e92005aeeaf6a7 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Thu, 23 May 2024 21:38:57 +0000 Subject: [PATCH 01/13] Verify built output for private init. --- .../private-kernel-init-simulated/src/main.nr | 2 +- .../crates/private-kernel-init/src/main.nr | 2 +- .../private-kernel-lib/src/components.nr | 1 + ...private_kernel_circuit_output_validator.nr | 421 ++++++++++++++ .../crates/private-kernel-lib/src/lib.nr | 1 + ...e_kernel_circuit_public_inputs_composer.nr | 15 +- .../src/private_kernel_init.nr | 49 +- .../src/private_kernel_inner.nr | 2 +- .../src/private_kernel_tail.nr | 2 +- .../src/private_kernel_tail_to_public.nr | 6 +- .../crates/private-kernel-lib/src/tests.nr | 1 + ...kernel_circuit_output_validator_builder.nr | 92 +++ .../validate_aggregated_values.nr | 202 +++++++ .../validate_initial_values.nr | 233 ++++++++ ...alidate_propagated_from_previous_kernel.nr | 327 +++++++++++ .../validate_propagated_from_private_call.nr | 534 ++++++++++++++++++ .../src/public_kernel_setup.nr | 2 +- .../src/reset/non_existent_read_request.nr | 32 +- .../rollup-lib/src/base/base_rollup_inputs.nr | 4 +- .../src/abis/kernel_circuit_public_inputs.nr | 2 +- .../private_kernel_circuit_public_inputs.nr | 50 +- .../types/src/abis/key_validation_request.nr | 11 +- .../crates/types/src/abis/note_hash.nr | 11 +- .../crates/types/src/abis/nullifier.nr | 11 +- .../types/src/abis/private_call_request.nr | 13 +- .../types/src/abis/public_call_stack_item.nr | 2 +- .../crates/types/src/abis/read_request.nr | 13 +- .../crates/types/src/abis/side_effect.nr | 76 +-- .../crates/types/src/constants.nr | 1 - .../types/src/messaging/l2_to_l1_message.nr | 14 +- .../crates/types/src/tests/fixture_builder.nr | 381 +++++++++---- .../crates/types/src/utils/arrays.nr | 30 +- 32 files changed, 2314 insertions(+), 229 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr index a59e08872e9..4f78ecb91b8 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr @@ -2,5 +2,5 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.native_private_kernel_circuit_initial() + input.simulate() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr index 76a82613767..b76dc1205bc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr @@ -3,5 +3,5 @@ use dep::types::PrivateKernelCircuitPublicInputs; #[recursive] fn main(input: PrivateKernelInitCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.native_private_kernel_circuit_initial() + input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr new file mode 100644 index 00000000000..39a4d96f650 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr @@ -0,0 +1 @@ +mod private_kernel_circuit_output_validator; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr new file mode 100644 index 00000000000..62ce72bd5d3 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -0,0 +1,421 @@ +use crate::private_kernel_circuit_public_inputs_composer::create_first_nullifier; +use dep::types::{ + abis::{ + call_request::CallRequest, + kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, + max_block_number::MaxBlockNumber, note_hash::ScopedNoteHash, + private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths}, + private_kernel::private_call_data::PrivateCallData, side_effect::Scoped +}, + address::AztecAddress, traits::{Empty, is_empty}, transaction::tx_request::TxRequest +}; + +fn validate_array_prepended(dest: [T; N], source: [T; N], num_source_items: u64) where T: Eq { + let mut proceed = true; + for i in 0..source.len() { + proceed &= i != num_source_items; + if proceed { + assert_eq(dest[i], source[i], "source item does not prepend to dest"); + } + } +} + +fn validate_array_appended( + dest: [T; N], + source: [T; M], + num_source_items: u64, + num_prepended_items: u64 +) where T: Empty + Eq { + let mut should_check = false; + let mut is_non_empty_item = true; + let items_propagated = num_prepended_items + num_source_items; + for i in 0..dest.len() { + should_check |= i == num_prepended_items; // Prepended items have been checked in validate_array_prepended() and can be skipped here. + if should_check { + is_non_empty_item &= i != items_propagated; + if is_non_empty_item { + assert_eq(dest[i], source[i - num_prepended_items], "source item does not append to dest"); + } else { + assert(is_empty(dest[i]), "output should be appended with empty items"); + } + } + } +} + +// Similar to validate_array_appended, except that the contract address of the dest items will also be checked. +fn validate_array_appended_scoped( + dest: [ST; N], + source: [T; M], + num_source_items: u64, + num_prepended_items: u64, + contract_address: AztecAddress +) where ST: Scoped + Empty + Eq, T: Eq { + let mut should_check = false; + let mut is_non_empty_item = true; + let items_propagated = num_prepended_items + num_source_items; + for i in 0..dest.len() { + should_check |= i == num_prepended_items; + if should_check { + is_non_empty_item &= i != items_propagated; + if is_non_empty_item { + assert_eq( + dest[i].inner(), source[i - num_prepended_items], "source item does not append to dest" + ); + assert_eq( + dest[i].contract_address(), contract_address, "propagated contract address does not match" + ); + } else { + assert(is_empty(dest[i]), "output should be appended with empty items"); + } + } + } +} + +// Similar to validate_array_appended_scoped, except that the souce items will be appended to dest in reversed order. +fn validate_array_appended_reversed_scoped( + dest: [ST; N], + source: [T; M], + num_source_items: u64, + num_prepended_items: u64, + contract_address: AztecAddress +) where ST: Scoped + Empty + Eq, T: Eq { + let mut should_check = false; + let mut is_non_empty_item = true; + let items_propagated = num_prepended_items + num_source_items; + for i in 0..dest.len() { + should_check |= i == num_prepended_items; + if should_check { + is_non_empty_item &= i != items_propagated; + if is_non_empty_item { + assert_eq( + dest[i].inner(), source[items_propagated - i - 1], "source item does not reversed append to dest" + ); + assert_eq( + dest[i].contract_address(), contract_address, "propagated contract address does not match" + ); + } else { + assert(is_empty(dest[i]), "output should be appended with empty items"); + } + } + } +} + +fn validate_note_hash_nullifier_counters( + dest: [ScopedNoteHash; N], + note_hash_nullifier_counters: [u32; M], + num_source_items: u64, + num_prepended_items: u64 +) { + let mut is_non_empty_item = true; + for i in 0..M { + is_non_empty_item &= i != num_source_items; + if is_non_empty_item { + let nullifier_counter = note_hash_nullifier_counters[i]; + let note_hash = dest[i + num_prepended_items]; + assert( + (nullifier_counter == 0) | (nullifier_counter > note_hash.counter()), "invalid nullifier counter" + ); + assert_eq( + note_hash.nullifier_counter, nullifier_counter, "incorrect nullifier counter assigned to dest" + ); + } + } +} + +fn validate_appended_public_call_requests() {} + +struct PrivateKernelCircuitOutputValidator { + output: PrivateKernelCircuitPublicInputs, +} + +impl PrivateKernelCircuitOutputValidator { + pub fn new(output: PrivateKernelCircuitPublicInputs) -> Self { + PrivateKernelCircuitOutputValidator { output } + } + + pub fn validate_as_first_call( + self, + tx_request: TxRequest, + private_call: PrivateCircuitPublicInputs, + private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, + contract_address: AztecAddress, + note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], + public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN], + public_teardown_call_request: CallRequest + ) { + self.validate_initial_values(tx_request, private_call, public_teardown_call_request); + let mut offsets = PrivateKernelCircuitPublicInputsArrayLengths::empty(); + offsets.new_nullifiers = 1; // The first nullifier is not propagated from the private call. + self.validate_propagated_from_private_call( + private_call, + private_call_array_lengths, + offsets, + 0, // num_popped_call + contract_address, + note_hash_nullifier_counters, + public_call_requests + ); + } + + pub fn validate_as_inner_call( + self, + previous_kernel: PrivateKernelCircuitPublicInputs, + previous_kernel_array_lengths: PrivateKernelCircuitPublicInputsArrayLengths, + private_call: PrivateCircuitPublicInputs, + private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, + contract_address: AztecAddress, + note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], + public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN], + public_teardown_call_request: CallRequest + ) { + self.validate_aggregated_values(previous_kernel, private_call, public_teardown_call_request); + self.validate_propagated_from_previous_kernel(previous_kernel, previous_kernel_array_lengths); + self.validate_propagated_from_private_call( + private_call, + private_call_array_lengths, + previous_kernel_array_lengths, + 1, // num_popped_call + contract_address, + note_hash_nullifier_counters, + public_call_requests + ); + } + + fn validate_initial_values( + self, + tx_request: TxRequest, + private_call: PrivateCircuitPublicInputs, + public_teardown_call_request: CallRequest + ) { + // Constants. + assert_eq(self.output.constants.tx_context, tx_request.tx_context, "mismatch tx_context"); + assert_eq( + self.output.constants.historical_header, private_call.historical_header, "mismatch historical_header" + ); + assert(is_empty(self.output.constants.global_variables), "constants.global_variables must be empty"); + + // First nullifier. + let first_nullifier = create_first_nullifier(tx_request); + assert_eq( + self.output.end.new_nullifiers[0], first_nullifier, "first nullifier must be the tx request nullifier" + ); + + // Others. + assert_eq( + self.output.min_revertible_side_effect_counter, private_call.min_revertible_side_effect_counter, "incorrect initial min_revertible_side_effect_counter" + ); + assert_eq( + self.output.validation_requests.for_rollup.max_block_number, private_call.max_block_number, "incorrect initial max_block_number" + ); + assert_eq( + self.output.public_teardown_call_request, public_teardown_call_request, "incorrect initial public_teardown_call_request" + ); + let initial_fee_payer = if private_call.is_fee_payer { + private_call.call_context.storage_contract_address + } else { + AztecAddress::zero() + }; + assert_eq(self.output.fee_payer, initial_fee_payer, "incorrect initial fee_payer"); + } + + fn validate_aggregated_values( + self, + previous_kernel: PrivateKernelCircuitPublicInputs, + private_call: PrivateCircuitPublicInputs, + public_teardown_call_request: CallRequest + ) { + // max_block_number + let max_block_number = MaxBlockNumber::min( + previous_kernel.validation_requests.for_rollup.max_block_number, + private_call.max_block_number + ); + assert_eq( + self.output.validation_requests.for_rollup.max_block_number, max_block_number, "incorrect output max_block_number" + ); + + // public_teardown_call_request + let propagated_public_teardown_call_request = if !is_empty(previous_kernel.public_teardown_call_request) { + assert(is_empty(public_teardown_call_request), "cannot overwrite public_teardown_call_request"); + previous_kernel.public_teardown_call_request + } else { + public_teardown_call_request + }; + assert_eq( + self.output.public_teardown_call_request, propagated_public_teardown_call_request, "incorrect output public_teardown_call_request" + ); + + // fee_payer + let propagated_fee_payer = if !is_empty(previous_kernel.fee_payer) { + assert(!private_call.is_fee_payer, "cannot overwrite fee_payer"); + previous_kernel.fee_payer + } else if private_call.is_fee_payer { + private_call.call_context.storage_contract_address + } else { + AztecAddress::zero() + }; + assert_eq(self.output.fee_payer, propagated_fee_payer, "incorrect output fee_payer"); + } + + fn validate_propagated_from_previous_kernel( + self, + previous_kernel: PrivateKernelCircuitPublicInputs, + array_lengths: PrivateKernelCircuitPublicInputsArrayLengths + ) { + assert_eq(self.output.constants, previous_kernel.constants, "mismatch constants"); + assert_eq( + self.output.min_revertible_side_effect_counter, previous_kernel.min_revertible_side_effect_counter, "mismatch min_revertible_side_effect_counter" + ); + + validate_array_prepended( + self.output.validation_requests.note_hash_read_requests, + previous_kernel.validation_requests.note_hash_read_requests, + array_lengths.note_hash_read_requests + ); + validate_array_prepended( + self.output.validation_requests.nullifier_read_requests, + previous_kernel.validation_requests.nullifier_read_requests, + array_lengths.nullifier_read_requests + ); + validate_array_prepended( + self.output.validation_requests.key_validation_requests, + previous_kernel.validation_requests.key_validation_requests, + array_lengths.key_validation_requests + ); + validate_array_prepended( + self.output.end.new_note_hashes, + previous_kernel.end.new_note_hashes, + array_lengths.new_note_hashes + ); + validate_array_prepended( + self.output.end.new_nullifiers, + previous_kernel.end.new_nullifiers, + array_lengths.new_nullifiers + ); + validate_array_prepended( + self.output.end.new_l2_to_l1_msgs, + previous_kernel.end.new_l2_to_l1_msgs, + array_lengths.new_l2_to_l1_msgs + ); + validate_array_prepended( + self.output.end.note_encrypted_logs_hashes, + previous_kernel.end.note_encrypted_logs_hashes, + array_lengths.note_encrypted_logs_hashes + ); + validate_array_prepended( + self.output.end.encrypted_logs_hashes, + previous_kernel.end.encrypted_logs_hashes, + array_lengths.encrypted_logs_hashes + ); + validate_array_prepended( + self.output.end.unencrypted_logs_hashes, + previous_kernel.end.unencrypted_logs_hashes, + array_lengths.unencrypted_logs_hashes + ); + // array_lengths.private_call_stack is guaranteed to be greater than 0. + // It's checked in private_kernel_inner when comparing the top item in the stack with the current private call. + validate_array_prepended( + self.output.end.private_call_stack, + previous_kernel.end.private_call_stack, + array_lengths.private_call_stack - 1 // Do not copy the top item in the stack. + ); + validate_array_prepended( + self.output.end.public_call_stack, + previous_kernel.end.public_call_stack, + array_lengths.public_call_stack + ); + } + + fn validate_propagated_from_private_call( + self, + private_call: PrivateCircuitPublicInputs, + array_lengths: PrivateCircuitPublicInputsArrayLengths, + offsets: PrivateKernelCircuitPublicInputsArrayLengths, + num_popped_call: u64, + contract_address: AztecAddress, + note_hash_nullifier_counters: [u32; NOTE_HASH_NULLIFIER_COUNTERS_LEN], + public_call_requests: [CallRequest; PUBLIC_CALL_REQUESTS_LEN] + ) { + let storage_contract_address = private_call.call_context.storage_contract_address; + validate_array_appended_scoped( + self.output.validation_requests.note_hash_read_requests, + private_call.note_hash_read_requests, + array_lengths.note_hash_read_requests, + offsets.note_hash_read_requests, + storage_contract_address + ); + validate_array_appended_scoped( + self.output.validation_requests.nullifier_read_requests, + private_call.nullifier_read_requests, + array_lengths.nullifier_read_requests, + offsets.nullifier_read_requests, + storage_contract_address + ); + validate_array_appended_scoped( + self.output.validation_requests.key_validation_requests, + private_call.key_validation_requests, + array_lengths.key_validation_requests, + offsets.key_validation_requests, + storage_contract_address + ); + validate_array_appended_scoped( + self.output.end.new_note_hashes, + private_call.new_note_hashes, + array_lengths.new_note_hashes, + offsets.new_note_hashes, + storage_contract_address + ); + validate_note_hash_nullifier_counters( + self.output.end.new_note_hashes, + note_hash_nullifier_counters, + array_lengths.new_note_hashes, + offsets.new_note_hashes + ); + validate_array_appended_scoped( + self.output.end.new_nullifiers, + private_call.new_nullifiers, + array_lengths.new_nullifiers, + offsets.new_nullifiers, + storage_contract_address + ); + validate_array_appended_scoped( + self.output.end.new_l2_to_l1_msgs, + private_call.new_l2_to_l1_msgs, + array_lengths.new_l2_to_l1_msgs, + offsets.new_l2_to_l1_msgs, + storage_contract_address + ); + validate_array_appended( + self.output.end.note_encrypted_logs_hashes, + private_call.note_encrypted_logs_hashes, + array_lengths.note_encrypted_logs_hashes, + offsets.note_encrypted_logs_hashes + ); + validate_array_appended( + self.output.end.encrypted_logs_hashes, + private_call.encrypted_logs_hashes, + array_lengths.encrypted_logs_hashes, + offsets.encrypted_logs_hashes + ); + validate_array_appended( + self.output.end.unencrypted_logs_hashes, + private_call.unencrypted_logs_hashes, + array_lengths.unencrypted_logs_hashes, + offsets.unencrypted_logs_hashes + ); + validate_array_appended_reversed_scoped( + self.output.end.private_call_stack, + private_call.private_call_requests, + array_lengths.private_call_requests, + offsets.private_call_stack - num_popped_call, + contract_address + ); + // TODO: Should push call requests instead of hashes to the accumulated data. + validate_array_appended( + self.output.end.public_call_stack, + public_call_requests, + // private_call.public_call_requests, + array_lengths.public_call_stack_hashes, + offsets.public_call_stack + ); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr index 8ba81e439c4..a5d91a004c9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr @@ -1,3 +1,4 @@ +mod components; mod kernel_circuit_public_inputs_composer; mod private_call_data_validator; mod private_kernel_circuit_public_inputs_composer; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr index 878dedef4da..07766235a5a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr @@ -2,8 +2,8 @@ use dep::types::{ abis::{ call_request::CallRequest, combined_constant_data::CombinedConstantData, kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, - max_block_number::MaxBlockNumber, nullifier::Nullifier, note_hash::ScopedNoteHash, - log_hash::NoteLogHash, + max_block_number::MaxBlockNumber, nullifier::{Nullifier, ScopedNullifier}, + note_hash::ScopedNoteHash, log_hash::NoteLogHash, private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths} }, address::AztecAddress, @@ -25,12 +25,19 @@ struct DataSource { public_teardown_call_request: CallRequest, } +pub fn create_first_nullifier(tx_request: TxRequest) -> ScopedNullifier { + Nullifier { value: tx_request.hash(), note_hash: 0, counter: 0 }.scope(AztecAddress::zero()) +} + struct PrivateKernelCircuitPublicInputsComposer { public_inputs: PrivateKernelCircuitPublicInputsBuilder, } impl PrivateKernelCircuitPublicInputsComposer { - pub fn new_from_tx_request(tx_request: TxRequest, private_call_public_inputs: PrivateCircuitPublicInputs) -> Self { + pub fn new_from_tx_request( + tx_request: TxRequest, + private_call_public_inputs: PrivateCircuitPublicInputs + ) -> Self { let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty(); public_inputs.constants = CombinedConstantData::private( @@ -41,7 +48,7 @@ impl PrivateKernelCircuitPublicInputsComposer { public_inputs.min_revertible_side_effect_counter = private_call_public_inputs.min_revertible_side_effect_counter; // Since it's the first iteration, we need to push the the tx hash nullifier into the `new_nullifiers` array - public_inputs.end.new_nullifiers.push(Nullifier { value: tx_request.hash(), note_hash: 0, counter: 0 }.scope(AztecAddress::zero())); + public_inputs.end.new_nullifiers.push(create_first_nullifier(tx_request)); // Note that we do not need to nullify the transaction request nonce anymore. // Should an account want to additionally use nonces for replay protection or handling cancellations, // they will be able to do so in the account contract logic: diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index e0dde7101af..b80c984362b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -1,4 +1,5 @@ use crate::{ + components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, private_call_data_validator::PrivateCallDataValidator, private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer }; @@ -24,24 +25,52 @@ struct PrivateKernelInitCircuitPrivateInputs { } impl PrivateKernelInitCircuitPrivateInputs { - pub fn native_private_kernel_circuit_initial(self) -> PrivateKernelCircuitPublicInputs { + unconstrained fn prepare_output( + self, + private_call_data_validator: PrivateCallDataValidator + ) -> PrivateKernelCircuitPublicInputs { + let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; + PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call_public_inputs).compose( + private_call_public_inputs, + private_call_data_validator.array_lengths, + self.private_call.call_stack_item.contract_address, + self.hints.note_hash_nullifier_counters, + self.private_call.public_call_stack, + self.private_call.public_teardown_call_request + ).finish() + } + + fn validate_inputs(self) -> PrivateCallDataValidator { + let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); + private_call_data_validator.validate(); + private_call_data_validator.validate_as_first_call(self.hints.first_revertible_private_call_request_index); + private_call_data_validator.validate_against_tx_request(self.tx_request); + private_call_data_validator + } + + pub fn simulate(self) -> PrivateKernelCircuitPublicInputs { + let private_call_data_validator = self.validate_inputs(); + self.prepare_output(private_call_data_validator) + } + + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { // verify/aggregate the private call proof verify_private_call(self.private_call); + let private_call_data_validator = self.validate_inputs(); - let privateCallDataValidator = PrivateCallDataValidator::new(self.private_call); - privateCallDataValidator.validate(); - privateCallDataValidator.validate_as_first_call(self.hints.first_revertible_private_call_request_index); - privateCallDataValidator.validate_against_tx_request(self.tx_request); - + let output = self.prepare_output(private_call_data_validator); + let output_validator = PrivateKernelCircuitOutputValidator::new(output); let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; - PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call_public_inputs).compose( + output_validator.validate_as_first_call( + self.tx_request, private_call_public_inputs, - privateCallDataValidator.array_lengths, + private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request - ).finish() + ); + output } } @@ -81,7 +110,7 @@ mod tests { pub fn execute(self) -> PrivateKernelCircuitPublicInputs { let kernel = PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call: self.private_call.finish(), hints: self.hints }; - kernel.native_private_kernel_circuit_initial() + kernel.execute() } pub fn failed(self) { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index e9c8e2b6071..744175371e4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -97,7 +97,7 @@ mod tests { // Update the previous_kernel's private_call_stack with the current call_stack_item. let hash = private_call.call_stack_item.hash(); let is_delegate_call = private_call.call_stack_item.public_inputs.call_context.is_delegate_call; - self.previous_kernel.push_private_call_request(hash, is_delegate_call); + self.previous_kernel.add_private_call_request(hash, is_delegate_call); let previous_kernel = self.previous_kernel.to_private_kernel_data(); let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call, hints: self.hints }; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index ffd088d8464..3f8ff495f46 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -297,7 +297,7 @@ mod tests { #[test(should_fail_with="Private call stack must be empty when executing the tail circuit")] unconstrained fn non_empty_private_call_stack_should_fail() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.push_private_call_request(1, false); + builder.previous_kernel.add_private_call_request(1, false); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index cc688c36dec..8e4a75aa03a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -239,21 +239,21 @@ mod tests { #[test(should_fail_with="Private call stack must be empty when executing the tail circuit")] unconstrained fn non_empty_private_call_stack_should_fail() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel.push_private_call_request(1, false); + builder.previous_kernel.add_private_call_request(1, false); builder.failed(); } #[test(should_fail_with="Must have public calls when exporting public kernel data from the tail circuit")] unconstrained fn no_public_calls_should_fail() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel.public_call_stack = BoundedVec::new(); + builder.previous_kernel.public_call_requests = BoundedVec::new(); builder.failed(); } #[test] unconstrained fn can_run_with_only_teardown() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel.public_call_stack = BoundedVec::new(); + builder.previous_kernel.public_call_requests = BoundedVec::new(); builder.previous_kernel.set_public_teardown_call_request(1, false); builder.succeeded(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr index 2a9c7d34cf3..1820a12d7a5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr @@ -1,4 +1,5 @@ mod private_call_data_validator_builder; +mod private_kernel_circuit_output_validator_builder; mod validate_against_call_request; mod validate_against_previous_kernel; mod validate_against_tx_request; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr new file mode 100644 index 00000000000..60a47c651c1 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr @@ -0,0 +1,92 @@ +mod validate_aggregated_values; +mod validate_initial_values; +mod validate_propagated_from_previous_kernel; +mod validate_propagated_from_private_call; + +use crate::{ + components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, + private_kernel_circuit_public_inputs_composer::create_first_nullifier +}; +use dep::types::{ + abis::{ + private_call_request::ScopedPrivateCallRequest, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, + private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths +}, + constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::{fixture_builder::FixtureBuilder}, + transaction::tx_request::TxRequest +}; + +struct PrivateKernelCircuitOutputValidatorBuilder { + previous_kernel: FixtureBuilder, + private_call: FixtureBuilder, + note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], + output: FixtureBuilder, + tx_request: TxRequest, +} + +impl PrivateKernelCircuitOutputValidatorBuilder { + pub fn new() -> Self { + let mut previous_kernel = FixtureBuilder::new(); + let private_call = FixtureBuilder::new(); + let note_hash_nullifier_counters = [0; MAX_NEW_NOTE_HASHES_PER_CALL]; + let mut output = FixtureBuilder::new(); + let tx_request = output.build_tx_request(); + let first_nullifier = create_first_nullifier(tx_request); + output.new_nullifiers.push(first_nullifier); + previous_kernel.new_nullifiers.push(first_nullifier); + PrivateKernelCircuitOutputValidatorBuilder { previous_kernel, private_call, note_hash_nullifier_counters, output, tx_request } + } + + pub fn offset_values(&mut self, num_prepended_items: Field) { + // Add an offset to the mock values so that the data in the private call won't be the same as those in the previous kernel. + self.private_call.value_offset = 9999; + self.private_call.counter = 777; + self.output.value_offset = 9999 - num_prepended_items; + self.output.counter = 777; + } + + pub fn validate_as_first_call(self) { + let private_call = self.private_call.to_private_circuit_public_inputs(); + let public_call_requests = self.private_call.public_call_requests.storage; + let public_teardown_call_request = self.private_call.public_teardown_call_request; + let contract_address = self.private_call.contract_address; + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call); + let output = self.output.to_private_kernel_circuit_public_inputs(); + PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( + self.tx_request, + private_call, + array_lengths, + contract_address, + self.note_hash_nullifier_counters, + public_call_requests, + public_teardown_call_request + ); + } + + pub fn validate_as_inner_call(self) { + let num_private_call_requests = self.previous_kernel.private_call_requests.len(); + let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); + // Append one private call request for the current call. + previous_kernel.end.private_call_stack[num_private_call_requests] = ScopedPrivateCallRequest::empty(); + previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432; + + let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel); + let public_call_requests = self.private_call.public_call_requests.storage; + let public_teardown_call_request = self.private_call.public_teardown_call_request; + let private_call = self.private_call.to_private_circuit_public_inputs(); + let contract_address = self.private_call.contract_address; + let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call); + let output = self.output.to_private_kernel_circuit_public_inputs(); + PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( + previous_kernel, + previous_kernel_array_lengths, + private_call, + private_call_array_lengths, + contract_address, + self.note_hash_nullifier_counters, + public_call_requests, + public_teardown_call_request + ); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr new file mode 100644 index 00000000000..f6aa54e8d20 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr @@ -0,0 +1,202 @@ +use crate::tests::private_kernel_circuit_output_validator_builder::PrivateKernelCircuitOutputValidatorBuilder; + +#[test] +fn validate_aggregated_values_empty_data_succeeds() { + let builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + builder.validate_as_inner_call(); +} + +/** + * max_block_number + */ + +#[test] +fn validate_aggregated_values_max_block_number_from_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.set_max_block_number(123); + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_max_block_number_from_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.set_max_block_number(123); + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_max_block_number_from_both_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.set_max_block_number(123); + builder.private_call.set_max_block_number(123); + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_max_block_number_from_both_pick_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.set_max_block_number(123); + builder.private_call.set_max_block_number(4567); + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_max_block_number_from_both_pick_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.set_max_block_number(4567); + builder.private_call.set_max_block_number(123); + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output max_block_number")] +fn validate_aggregated_values_max_block_number_from_both_pick_larger_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.set_max_block_number(4567); + builder.private_call.set_max_block_number(123); + builder.output.set_max_block_number(4567); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output max_block_number")] +fn validate_aggregated_values_max_block_number_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.set_max_block_number(123); + + builder.validate_as_inner_call(); +} + +/** + * public_teardown_call_request + */ + +#[test] +fn validate_aggregated_values_public_teardown_call_request_from_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_public_teardown_call_request_from_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="cannot overwrite public_teardown_call_request")] +fn validate_aggregated_values_public_teardown_call_request_from_both_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_public_teardown_call_request(); + builder.private_call.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output public_teardown_call_request")] +fn validate_aggregated_values_public_teardown_call_request_from_previous_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + // Tweak the output. + builder.output.public_teardown_call_request.hash += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output public_teardown_call_request")] +fn validate_aggregated_values_public_teardown_call_request_from_private_call_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + // Tweak the output. + builder.output.public_teardown_call_request.hash += 1; + + builder.validate_as_inner_call(); +} + +/** + * fee_payer + */ + +#[test] +fn validate_aggregated_values_fee_payer_from_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.previous_kernel.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_fee_payer_from_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="cannot overwrite fee_payer")] +fn validate_aggregated_values_fee_payer_from_both_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.previous_kernel.make_fee_payer(); + let fee_payer = builder.private_call.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output fee_payer")] +fn validate_aggregated_values_fee_payer_from_previous_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.previous_kernel.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + // Tweak the output. + builder.output.fee_payer.inner += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output fee_payer")] +fn validate_aggregated_values_fee_payer_from_private_call_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + // Tweak the output. + builder.output.fee_payer.inner += 1; + + builder.validate_as_inner_call(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr new file mode 100644 index 00000000000..7e6837d5efd --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr @@ -0,0 +1,233 @@ +use crate::tests::private_kernel_circuit_output_validator_builder::PrivateKernelCircuitOutputValidatorBuilder; +use dep::types::address::AztecAddress; + +#[test] +fn validate_initial_values_empty_data_succeeds() { + let builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + builder.validate_as_first_call(); +} + +/** + * constants + */ + +#[test(should_fail_with="mismatch tx_context")] +fn validate_initial_values_constants_mismatch_chain_id_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.tx_context.chain_id += 1; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="mismatch historical_header")] +fn validate_initial_values_constants_mismatch_txs_effects_hash_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.historical_header.content_commitment.txs_effects_hash += 1; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="constants.global_variables must be empty")] +fn validate_initial_values_constants_non_empty_global_variables_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.global_variables.block_number += 1; + + builder.validate_as_first_call(); +} + +/** + * First nullifier. + */ + +#[test(should_fail_with="first nullifier must be the tx request nullifier")] +fn validate_initial_values_constants_incorrect_first_nullifier_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.new_nullifiers.storage[0].nullifier.value += 1; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="first nullifier must be the tx request nullifier")] +fn validate_initial_values_constants_empty_first_nullifier_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.new_nullifiers = BoundedVec::new(); + + builder.validate_as_first_call(); +} + +/** + * min_revertible_side_effect_counter + */ + +#[test] +fn validate_initial_values_min_revertible_side_effect_counter_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 8989; + builder.output.min_revertible_side_effect_counter = 8989; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial min_revertible_side_effect_counter")] +fn validate_initial_values_min_revertible_side_effect_counter_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 8989; + builder.output.min_revertible_side_effect_counter = 50; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial min_revertible_side_effect_counter")] +fn validate_initial_values_min_revertible_side_effect_counter_empty_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 8989; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial min_revertible_side_effect_counter")] +fn validate_initial_values_min_revertible_side_effect_counter_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.min_revertible_side_effect_counter = 8989; + + builder.validate_as_first_call(); +} + +/** + * max_block_number + */ + +#[test] +fn validate_initial_values_max_block_number_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.set_max_block_number(123); + builder.output.set_max_block_number(123); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial max_block_number")] +fn validate_initial_values_max_block_number_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.set_max_block_number(4567); + builder.output.set_max_block_number(123); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial max_block_number")] +fn validate_initial_values_max_block_number_empty_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.set_max_block_number(4567); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial max_block_number")] +fn validate_initial_values_max_block_number_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.set_max_block_number(123); + + builder.validate_as_first_call(); +} + +/** + * public_teardown_call_request + */ + +#[test] +fn validate_initial_values_public_teardown_call_request_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial public_teardown_call_request")] +fn validate_initial_values_public_teardown_call_request_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + builder.output.append_public_teardown_call_request(); + // Tweak the output. + builder.output.public_teardown_call_request.hash += 1; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial public_teardown_call_request")] +fn validate_initial_values_public_teardown_call_request_empty_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial public_teardown_call_request")] +fn validate_initial_values_public_teardown_call_request_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.append_public_teardown_call_request(); + + builder.validate_as_first_call(); +} + +/** + * fee_payer + */ + +#[test] +fn validate_initial_values_fee_payer_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial fee_payer")] +fn validate_initial_values_fee_payer_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + builder.output.set_fee_payer(fee_payer); + // Tweak the output. + builder.output.fee_payer.inner += 1; + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial fee_payer")] +fn validate_initial_values_fee_payer_empty_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + let _ = builder.private_call.make_fee_payer(); + + builder.validate_as_first_call(); +} + +#[test(should_fail_with="incorrect initial fee_payer")] +fn validate_initial_values_fee_payer_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.set_fee_payer(AztecAddress::from_field(123)); + + builder.validate_as_first_call(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr new file mode 100644 index 00000000000..164111a2fbc --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr @@ -0,0 +1,327 @@ +use crate::tests::private_kernel_circuit_output_validator_builder::PrivateKernelCircuitOutputValidatorBuilder; + +#[test] +fn validate_propagated_from_previous_kernel_empty_data_succeeds() { + let builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + builder.validate_as_inner_call(); +} + +/** + * constants + */ + +#[test(should_fail_with="mismatch constants")] +fn validate_propagated_from_previous_kernel_constants_mismatch_chain_id_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.tx_context.chain_id += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="mismatch constants")] +fn validate_propagated_from_previous_kernel_constants_mismatch_txs_effects_hash_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.historical_header.content_commitment.txs_effects_hash += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="mismatch constants")] +fn validate_propagated_from_previous_kernel_constants_non_empty_global_variables_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.global_variables.block_number += 1; + + builder.validate_as_inner_call(); +} + +/** +* min_revertible_side_effect_counter +*/ + +#[test(should_fail_with="mismatch min_revertible_side_effect_counter")] +fn validate_propagated_from_previous_kernel_min_revertible_side_effect_counter_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 8989; + builder.output.min_revertible_side_effect_counter = 50; + + builder.validate_as_inner_call(); +} + +/** + * note_hash_read_requests + */ + +#[test] +fn validate_propagated_from_previous_kernel_note_hash_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_note_hash_read_requests_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_note_hash_read_requests(2); + // Propagate 1 less item to the output. + builder.output.append_note_hash_read_requests(1); + + builder.validate_as_inner_call(); +} + +/** + * nullifier_read_requests + */ + +#[test] +fn validate_propagated_from_previous_kernel_nullifier_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_nullifier_read_requests(2); + builder.output.append_nullifier_read_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_nullifier_read_requests_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_nullifier_read_requests(2); + // Propagate 1 less item to the output. + builder.output.append_nullifier_read_requests(1); + + builder.validate_as_inner_call(); +} + +/** + * key_validation_requests + */ + +#[test] +fn validate_propagated_from_previous_kernel_key_validation_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_key_validation_requests(2); + builder.output.append_key_validation_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_key_validation_requests_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_key_validation_requests(2); + // Propagate 1 less item to the output. + builder.output.append_key_validation_requests(1); + + builder.validate_as_inner_call(); +} + +/** + * new_note_hashes + */ + +#[test] +fn validate_propagated_from_previous_kernel_new_note_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + builder.output.append_new_note_hashes(2, false); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_new_note_hashes_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + // Propagate 1 less item to the output. + builder.output.append_new_note_hashes(1, false); + + builder.validate_as_inner_call(); +} + +/** + * new_nullifiers + */ + +#[test] +fn validate_propagated_from_previous_kernel_new_nullifiers_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(2); + builder.output.append_new_nullifiers(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_new_nullifiers_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(2); + // Propagate 1 less item to the output. + builder.output.append_new_nullifiers(1); + + builder.validate_as_inner_call(); +} + +/** + * new_l2_to_l1_msgs + */ + +#[test] +fn validate_propagated_from_previous_kernel_new_l2_to_l1_msgs_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_l2_to_l1_msgs(2); + builder.output.append_new_l2_to_l1_msgs(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_new_l2_to_l1_msgs_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_l2_to_l1_msgs(2); + // Propagate 1 less item to the output. + builder.output.append_new_l2_to_l1_msgs(1); + + builder.validate_as_inner_call(); +} + +/** + * note_encrypted_logs_hashes + */ + +#[test] +fn validate_propagated_from_previous_kernel_note_encrypted_logs_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_note_encrypted_logs_hashes(2); + builder.output.append_note_encrypted_logs_hashes(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_note_encrypted_logs_hashes_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_note_encrypted_logs_hashes(2); + // Propagate 1 less item to the output. + builder.output.append_note_encrypted_logs_hashes(1); + + builder.validate_as_inner_call(); +} + +/** + * encrypted_logs_hashes + */ + +// #[test] +// fn validate_propagated_from_previous_kernel_encrypted_logs_hashes_succeeds() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.previous_kernel.append_encrypted_logs_hashes(2); +// builder.output.append_encrypted_logs_hashes(2); + +// builder.validate_as_inner_call(); +// } + +// #[test(should_fail_with="source item does not prepend to dest")] +// fn validate_propagated_from_previous_kernel_encrypted_logs_hashes_less_than_fails() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.previous_kernel.append_encrypted_logs_hashes(2); +// // Propagate 1 less item to the output. +// builder.output.append_encrypted_logs_hashes(1); + +// builder.validate_as_inner_call(); +// } + +/** + * unencrypted_logs_hashes + */ + +// #[test] +// fn validate_propagated_from_previous_kernel_unencrypted_logs_hashes_succeeds() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.previous_kernel.append_unencrypted_logs_hashes(2); +// builder.output.append_unencrypted_logs_hashes(2); + +// builder.validate_as_inner_call(); +// } + +// #[test(should_fail_with="source item does not prepend to dest")] +// fn validate_propagated_from_previous_kernel_unencrypted_logs_hashes_less_than_fails() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.previous_kernel.append_unencrypted_logs_hashes(2); +// // Propagate 1 less item to the output. +// builder.output.append_unencrypted_logs_hashes(1); + +// builder.validate_as_inner_call(); +// } + +/** + * private_call_requests + */ + +#[test] +fn validate_propagated_from_previous_kernel_private_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_private_call_requests(2); + builder.output.append_private_call_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_private_call_requests_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_private_call_requests(2); + // Propagate 1 less item to the output. + builder.output.append_private_call_requests(1); + + builder.validate_as_inner_call(); +} + +/** + * public_call_requests + */ + +#[test] +fn validate_propagated_from_previous_kernel_public_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_public_call_requests(2); + builder.output.append_public_call_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_public_call_requests_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_public_call_requests(2); + // Propagate 1 less item to the output. + builder.output.append_public_call_requests(1); + + builder.validate_as_inner_call(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr new file mode 100644 index 00000000000..68b704dff49 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr @@ -0,0 +1,534 @@ +use crate::tests::private_kernel_circuit_output_validator_builder::PrivateKernelCircuitOutputValidatorBuilder; +use dep::types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL; + +#[test] +fn validate_propagated_from_private_call_empty_data_succeeds() { + let builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + builder.validate_as_inner_call(); +} + +/** + * note_hash_read_requests + * With private call data only. + */ + +#[test] +fn validate_propagated_from_private_call_note_hash_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not append to dest")] +fn validate_propagated_from_private_call_note_hash_read_requests_output_mismatch_value_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(1); + // Tweak the value in the output. + builder.output.note_hash_read_requests.storage[1].read_request.value += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="propagated contract address does not match")] +fn validate_propagated_from_private_call_note_hash_read_requests_mismatch_contract_address_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + // Tweak the contract address in the output. + builder.output.note_hash_read_requests.storage[1].contract_address.inner += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not append to dest")] +fn validate_propagated_from_private_call_note_hash_read_requests_output_one_less_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + // Propagate 1 less item to the output. + builder.output.append_note_hash_read_requests(1); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_note_hash_read_requests_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + // Propagate 1 more item to the output. + builder.output.append_note_hash_read_requests(3); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_note_hash_read_requests_output_extra_non_empty_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + // Add a non-empty item to the output. + builder.output.note_hash_read_requests.storage[MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = builder.output.note_hash_read_requests.storage[0]; + + builder.validate_as_inner_call(); +} + +/** + * note_hash_read_requests + * With previous kernel. + */ + +fn append_note_hash_read_requests_to_previous_kernel(builder: &mut PrivateKernelCircuitOutputValidatorBuilder) { + builder.previous_kernel.append_note_hash_read_requests(3); + builder.output.append_note_hash_read_requests(3); + builder.offset_values(3); +} + +#[test] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not append to dest")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_mismatch_value_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + // Tweak the value in the output. + builder.output.note_hash_read_requests.storage[3].read_request.value += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="propagated contract address does not match")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_mismatch_contract_address_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + // Tweak the contract address in the output. + builder.output.note_hash_read_requests.storage[3].contract_address.inner += 1; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not append to dest")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_one_less_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + // Propagate 1 less item to the output. + builder.output.append_note_hash_read_requests(1); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + // Propagate 1 more item to the output. + builder.output.append_note_hash_read_requests(3); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_extra_non_empty_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + append_note_hash_read_requests_to_previous_kernel(&mut builder); + builder.private_call.append_note_hash_read_requests(2); + builder.output.append_note_hash_read_requests(2); + // Add a non-empty item to the output. + builder.output.note_hash_read_requests.storage[MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = builder.output.note_hash_read_requests.storage[0]; + + builder.validate_as_inner_call(); +} + +// Create two tests (one succeeds and one fails) for the rest of the side effects to make sure that they are processed in the validator. + +/** + * nullifier_read_requests + */ + +#[test] +fn validate_propagated_from_private_call_nullifier_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_nullifier_read_requests(2); + builder.output.append_nullifier_read_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_nullifier_read_requests_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_nullifier_read_requests(2); + // Propagate 1 more item to the output. + builder.output.append_nullifier_read_requests(3); + + builder.validate_as_inner_call(); +} + +/** + * key_validation_requests + */ + +#[test] +fn validate_propagated_from_private_call_key_validation_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_key_validation_requests(2); + builder.output.append_key_validation_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_key_validation_requests_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_key_validation_requests(2); + // Propagate 1 more item to the output. + builder.output.append_key_validation_requests(3); + + builder.validate_as_inner_call(); +} + +/** + * new_note_hashes + */ + +#[test] +fn validate_propagated_from_private_call_new_note_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + builder.output.append_new_note_hashes(2, false); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_new_note_hashes_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + // Propagate 1 more item to the output. + builder.output.append_new_note_hashes(3, false); + + builder.validate_as_inner_call(); +} + +/** + * new_note_hashes + * With nullifier counters. + */ + +#[test] +fn validate_propagated_from_private_call_new_note_hashes_non_zero_nullifier_counters_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; + builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; + builder.output.add_new_note_hash( + note_hashes[0].value(), + builder.note_hash_nullifier_counters[0] + ); + builder.output.add_new_note_hash( + note_hashes[1].value(), + builder.note_hash_nullifier_counters[1] + ); + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_propagated_from_private_call_new_note_hashes_with_previous_non_zero_nullifier_counters_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + builder.output.append_new_note_hashes(2, false); + builder.offset_values(2); // Offset the first 2 note hashes. + + builder.private_call.append_new_note_hashes(2, false); + let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; + builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; + builder.output.add_new_note_hash( + note_hashes[0].value(), + builder.note_hash_nullifier_counters[0] + ); + builder.output.add_new_note_hash( + note_hashes[1].value(), + builder.note_hash_nullifier_counters[1] + ); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="invalid nullifier counter")] +fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_too_small_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; + builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; + // Tweak the nullifier counter to be less than the counter of the note hash. + builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() - 1; + builder.output.add_new_note_hash( + note_hashes[0].value(), + builder.note_hash_nullifier_counters[0] + ); + builder.output.add_new_note_hash( + note_hashes[1].value(), + builder.note_hash_nullifier_counters[1] + ); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect nullifier counter assigned to dest")] +fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; + builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; + builder.output.add_new_note_hash( + note_hashes[0].value(), + builder.note_hash_nullifier_counters[0] + ); + // Tweak the nullifier counter to be different. + builder.output.add_new_note_hash( + note_hashes[1].value(), + builder.note_hash_nullifier_counters[1] + 1 + ); + + builder.validate_as_inner_call(); +} + +/** + * new_nullifiers + */ + +#[test] +fn validate_propagated_from_private_call_new_nullifiers_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.offset_values(1); // Offset the first nullifier. + builder.private_call.append_new_nullifiers(2); + builder.output.append_new_nullifiers(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_new_nullifiers_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.offset_values(1); // Offset the first nullifier. + builder.private_call.append_new_nullifiers(2); + // Propagate 1 more item to the output. + builder.output.append_new_nullifiers(3); + + builder.validate_as_inner_call(); +} + +/** + * new_l2_to_l1_msgs + */ + +#[test] +fn validate_propagated_from_private_call_new_l2_to_l1_msgs_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_l2_to_l1_msgs(2); + builder.output.append_new_l2_to_l1_msgs(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_new_l2_to_l1_msgs_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_new_l2_to_l1_msgs(1); + // Propagate 1 more item to the output. + builder.output.append_new_l2_to_l1_msgs(2); + + builder.validate_as_inner_call(); +} + +/** + * note_encrypted_logs_hashes + */ + +#[test] +fn validate_propagated_from_private_call_note_encrypted_logs_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_encrypted_logs_hashes(2); + builder.output.append_note_encrypted_logs_hashes(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_note_encrypted_logs_hashes_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_note_encrypted_logs_hashes(2); + // Propagate 1 more item to the output. + builder.output.append_note_encrypted_logs_hashes(3); + + builder.validate_as_inner_call(); +} + +/** + * encrypted_logs_hashes + */ + +// #[test] +// fn validate_propagated_from_private_call_encrypted_logs_hashes_succeeds() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.private_call.append_encrypted_logs_hashes(2); +// builder.output.append_encrypted_logs_hashes(2); + +// builder.validate_as_inner_call(); +// } + +// #[test(should_fail_with="output should be appended with empty items")] +// fn validate_propagated_from_private_call_encrypted_logs_hashes_output_one_more_fails() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.private_call.append_encrypted_logs_hashes(2); +// // Propagate 1 more item to the output. +// builder.output.append_encrypted_logs_hashes(3); + +// builder.validate_as_inner_call(); +// } + +/** + * unencrypted_logs_hashes + */ + +// #[test] +// fn validate_propagated_from_private_call_unencrypted_logs_hashes_succeeds() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.private_call.append_unencrypted_logs_hashes(2); +// builder.output.append_unencrypted_logs_hashes(2); + +// builder.validate_as_inner_call(); +// } + +// #[test(should_fail_with="output should be appended with empty items")] +// fn validate_propagated_from_private_call_unencrypted_logs_hashes_output_one_more_fails() { +// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + +// builder.private_call.append_unencrypted_logs_hashes(2); +// // Propagate 1 more item to the output. +// builder.output.append_unencrypted_logs_hashes(3); + +// builder.validate_as_inner_call(); +// } + +/** + * private_call_requests + */ + +#[test] +fn validate_propagated_from_private_call_private_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_private_call_requests(2); + builder.output.append_private_call_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="source item does not reversed append to dest")] +fn validate_propagated_from_private_call_private_call_requests_not_reversed_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_private_call_requests(2); + builder.output.append_private_call_requests(2); + // Swap the call requests. + let first_call_request = builder.output.private_call_requests.storage[0]; + builder.output.private_call_requests.storage[0] = builder.output.private_call_requests.storage[1]; + builder.output.private_call_requests.storage[1] = first_call_request; + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_propagated_from_private_call_private_call_requests_with_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.append_private_call_requests(5); + let requests = builder.output.private_call_requests.storage; + // The private_call_stack in the output will be: [requests[4], requests[3], requests[2], requests[1], requests[0]]. + + // First 2 are propagated from the previous kernel. + builder.previous_kernel.private_call_requests.push(requests[3]); + builder.previous_kernel.private_call_requests.push(requests[4]); + + // Next 3 are propagated in reversed order from the private call. + builder.private_call.private_call_requests.push(requests[0]); + builder.private_call.private_call_requests.push(requests[1]); + builder.private_call.private_call_requests.push(requests[2]); + + builder.validate_as_inner_call(); +} + +/** + * public_call_requests + */ + +#[test] +fn validate_propagated_from_private_call_public_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_call_requests(2); + builder.output.append_public_call_requests(2); + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_public_call_requests_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.append_public_call_requests(2); + // Propagate 1 more item to the output. + builder.output.append_public_call_requests(3); + + builder.validate_as_inner_call(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr index 4dd94c17f6e..225163402bb 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -358,7 +358,7 @@ mod tests { builder.stub_teardown_call(); let non_revertible_call_stack = [ - builder.previous_kernel.public_call_stack.get(0), + builder.previous_kernel.public_call_requests.get(0), storage[0], storage[1] ]; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr index ec1c8afde44..f2457c4da12 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr @@ -90,11 +90,31 @@ mod tests { use dep::types::{ address::AztecAddress, - abis::{read_request::{ReadRequest, ScopedReadRequest}, side_effect::SideEffect}, + abis::{read_request::{ReadRequest, ScopedReadRequest}, side_effect::OrderedValue}, merkle_tree::{leaf_preimage::IndexedTreeLeafPreimage, membership::MembershipWitness}, tests::merkle_tree_utils::NonEmptyMerkleTree }; + struct TestValue { + value: Field, + counter: u32, + } + + impl OrderedValue for TestValue { + fn value(self) -> Field { + self.value + } + fn counter(self) -> u32 { + self.counter + } + } + + impl TestValue { + fn empty() -> Self { + TestValue { value: 0, counter: 0 } + } + } + struct TestLeafPreimage { value: Field, next_value: Field, @@ -131,11 +151,11 @@ mod tests { global sorted_pending_values = BoundedVec { storage: [ - SideEffect { value: 5, counter: 17 }, - SideEffect { value: 15, counter: 8 }, - SideEffect { value: 25, counter: 11 }, - SideEffect::empty(), - SideEffect::empty(), + TestValue { value: 5, counter: 17 }, + TestValue { value: 15, counter: 8 }, + TestValue { value: 25, counter: 11 }, + TestValue::empty(), + TestValue::empty(), ], len: 3, }; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index 451b9e07d6a..f334bbc5156 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -373,7 +373,7 @@ mod tests { append_only_tree_snapshot::AppendOnlyTreeSnapshot, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData, - side_effect::SideEffect, accumulated_data::CombinedAccumulatedData + accumulated_data::CombinedAccumulatedData }, merkle_tree::MembershipWitness, address::{AztecAddress, EthAddress}, constants::{ @@ -729,7 +729,7 @@ mod tests { let new_note_hashes = [27, 28, 29, 30, 31, 32]; for i in 0..new_note_hashes.len() { - builder.kernel_data.add_new_note_hash(new_note_hashes[i]); + builder.kernel_data.add_new_note_hash(new_note_hashes[i], 0); } let mut expected_commitments_tree = NonEmptyMerkleTree::new( [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr index 3d17e14fec4..c1b3a7dd0ca 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr @@ -6,7 +6,7 @@ mod public_kernel_circuit_public_inputs_builder; use crate::abis::kernel_circuit_public_inputs::{ kernel_circuit_public_inputs::KernelCircuitPublicInputs, - private_kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, private_kernel_circuit_public_inputs_builder::PrivateKernelCircuitPublicInputsBuilder, public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, public_kernel_circuit_public_inputs_builder::PublicKernelCircuitPublicInputsBuilder diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr index 7139411cd3c..22663e6e355 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr @@ -4,9 +4,57 @@ use crate::abis::{ }; use crate::constants::PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH; use crate::traits::{Serialize, Deserialize, Eq, Empty}; -use crate::utils::reader::Reader; +use crate::utils::{arrays::array_length, reader::Reader}; use crate::address::AztecAddress; +struct PrivateKernelCircuitPublicInputsArrayLengths { + note_hash_read_requests: u64, + nullifier_read_requests: u64, + key_validation_requests: u64, + new_note_hashes: u64, + new_nullifiers: u64, + new_l2_to_l1_msgs: u64, + note_encrypted_logs_hashes: u64, + encrypted_logs_hashes: u64, + unencrypted_logs_hashes: u64, + private_call_stack: u64, + public_call_stack: u64, +} + +impl PrivateKernelCircuitPublicInputsArrayLengths { + pub fn new(public_inputs: PrivateKernelCircuitPublicInputs) -> Self { + PrivateKernelCircuitPublicInputsArrayLengths { + note_hash_read_requests: array_length(public_inputs.validation_requests.note_hash_read_requests), + nullifier_read_requests: array_length(public_inputs.validation_requests.nullifier_read_requests), + key_validation_requests: array_length(public_inputs.validation_requests.key_validation_requests), + new_note_hashes: array_length(public_inputs.end.new_note_hashes), + new_nullifiers: array_length(public_inputs.end.new_nullifiers), + new_l2_to_l1_msgs: array_length(public_inputs.end.new_l2_to_l1_msgs), + note_encrypted_logs_hashes: array_length(public_inputs.end.note_encrypted_logs_hashes), + encrypted_logs_hashes: array_length(public_inputs.end.encrypted_logs_hashes), + unencrypted_logs_hashes: array_length(public_inputs.end.unencrypted_logs_hashes), + private_call_stack: array_length(public_inputs.end.private_call_stack), + public_call_stack: array_length(public_inputs.end.public_call_stack) + } + } + + pub fn empty() -> Self { + PrivateKernelCircuitPublicInputsArrayLengths { + note_hash_read_requests: 0, + nullifier_read_requests: 0, + key_validation_requests: 0, + new_note_hashes: 0, + new_nullifiers: 0, + new_l2_to_l1_msgs: 0, + note_encrypted_logs_hashes: 0, + encrypted_logs_hashes: 0, + unencrypted_logs_hashes: 0, + private_call_stack: 0, + public_call_stack: 0 + } + } +} + struct PrivateKernelCircuitPublicInputs { min_revertible_side_effect_counter: u32, validation_requests: ValidationRequests, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/key_validation_request.nr index 4bf6ade35d2..5a5a61c2746 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/key_validation_request.nr @@ -1,6 +1,6 @@ use dep::std::cmp::Eq; use crate::{ - address::AztecAddress, + abis::side_effect::Scoped, address::AztecAddress, constants::{SCOPED_KEY_VALIDATION_REQUEST_LENGTH, KEY_VALIDATION_REQUEST_LENGTH}, traits::{Empty, Serialize, Deserialize}, grumpkin_point::GrumpkinPoint, utils::{arrays::array_concat, reader::Reader} @@ -57,6 +57,15 @@ struct ScopedKeyValidationRequest { contract_address: AztecAddress, } +impl Scoped for ScopedKeyValidationRequest { + fn inner(self) -> KeyValidationRequest { + self.request + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Eq for ScopedKeyValidationRequest { fn eq(self, other: ScopedKeyValidationRequest) -> bool { (self.request.eq(other.request)) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr index 9155ab0ee39..fbbe653de97 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr @@ -1,6 +1,6 @@ use crate::{ abis::read_request::ScopedReadRequest, address::AztecAddress, - abis::side_effect::{Ordered, OrderedValue, Readable}, + abis::side_effect::{Ordered, OrderedValue, Readable, Scoped}, constants::{NOTE_HASH_LENGTH, SCOPED_NOTE_HASH_LENGTH}, traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader} }; @@ -60,6 +60,15 @@ struct ScopedNoteHash { contract_address: AztecAddress, } +impl Scoped for ScopedNoteHash { + fn inner(self) -> NoteHash { + self.note_hash + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Ordered for ScopedNoteHash { fn counter(self) -> u32 { self.note_hash.counter diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr index 35578309de5..c7fa50fa166 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr @@ -1,5 +1,5 @@ use crate::{ - abis::{side_effect::{Ordered, OrderedValue, Readable}, read_request::ScopedReadRequest}, + abis::{side_effect::{Ordered, OrderedValue, Readable, Scoped}, read_request::ScopedReadRequest}, address::AztecAddress, constants::{NULLIFIER_LENGTH, SCOPED_NULLIFIER_LENGTH}, hash::silo_nullifier, traits::{Empty, Hash, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader} }; @@ -82,6 +82,15 @@ struct ScopedNullifier { contract_address: AztecAddress, } +impl Scoped for ScopedNullifier { + fn inner(self) -> Nullifier { + self.nullifier + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Ordered for ScopedNullifier { fn counter(self) -> u32 { self.nullifier.counter diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr index 8638a124253..02d4de6e490 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr @@ -1,7 +1,7 @@ use dep::std::cmp::Eq; use crate::{ - abis::{caller_context::CallerContext, side_effect::{Ordered, RangeOrdered}}, address::AztecAddress, - constants::{PRIVATE_CALL_REQUEST_LENGTH, SCOPED_PRIVATE_CALL_REQUEST_LENGTH}, + abis::{caller_context::CallerContext, side_effect::{Ordered, RangeOrdered, Scoped}}, + address::AztecAddress, constants::{PRIVATE_CALL_REQUEST_LENGTH, SCOPED_PRIVATE_CALL_REQUEST_LENGTH}, traits::{Empty, Serialize, Deserialize}, utils::reader::Reader }; @@ -87,6 +87,15 @@ struct ScopedPrivateCallRequest { contract_address: AztecAddress, } +impl Scoped for ScopedPrivateCallRequest { + fn inner(self) -> PrivateCallRequest { + self.call_request + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Ordered for ScopedPrivateCallRequest { fn counter(self) -> u32 { self.call_request.counter_start() diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr index 4b63fa7b82f..aca0ef39252 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr @@ -50,7 +50,7 @@ mod tests { abis::{ function_data::FunctionData, function_selector::FunctionSelector, note_hash::NoteHash, public_circuit_public_inputs::PublicCircuitPublicInputs, - public_call_stack_item::PublicCallStackItem, side_effect::SideEffect + public_call_stack_item::PublicCallStackItem }, address::AztecAddress, constants::GENERATOR_INDEX__CALL_STACK_ITEM, traits::Hash }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr index a7fa741e761..fa5682ca079 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr @@ -1,6 +1,6 @@ use crate::{ - abis::side_effect::Ordered, traits::{Empty, Serialize, Deserialize}, address::AztecAddress, - constants::{READ_REQUEST_LENGTH, SCOPED_READ_REQUEST_LEN}, + abis::side_effect::{Ordered, Scoped}, traits::{Empty, Serialize, Deserialize}, + address::AztecAddress, constants::{READ_REQUEST_LENGTH, SCOPED_READ_REQUEST_LEN}, utils::{arrays::array_concat, reader::Reader} }; use dep::std::cmp::Eq; @@ -58,6 +58,15 @@ struct ScopedReadRequest { contract_address: AztecAddress, } +impl Scoped for ScopedReadRequest { + fn inner(self) -> ReadRequest { + self.read_request + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Eq for ScopedReadRequest { fn eq(self, other: ScopedReadRequest) -> bool { (self.read_request == other.read_request) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr index b4e9a8b5947..681df72c61b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr @@ -1,8 +1,4 @@ -use crate::{ - abis::read_request::ScopedReadRequest, address::AztecAddress, - constants::{GENERATOR_INDEX__SIDE_EFFECT, SIDE_EFFECT_LENGTH}, - traits::{Empty, Hash, Serialize, Deserialize} -}; +use crate::{abis::read_request::ScopedReadRequest, address::AztecAddress}; use dep::std::cmp::Eq; trait Ordered { @@ -19,72 +15,12 @@ trait OrderedValue where T: Eq { fn counter(self) -> u32; } -trait Readable { - fn assert_match_read_request(self, read_request: ScopedReadRequest); -} - -struct SideEffect { - value: Field, - counter: u32, -} - -impl Ordered for SideEffect { - fn counter(self) -> u32 { - self.counter - } -} - -impl OrderedValue for SideEffect { - fn value(self) -> Field { - self.value - } - fn counter(self) -> u32 { - self.counter - } -} - -impl Eq for SideEffect { - fn eq(self, side_effect: SideEffect) -> bool { - (self.value == side_effect.value) - & (self.counter == side_effect.counter) - } +trait Scoped where T: Eq { + fn contract_address(self) -> AztecAddress; + fn inner(self) -> T; } -impl Empty for SideEffect { - fn empty() -> Self { - SideEffect { - value: 0, - counter: 0, - } - } -} - -impl Hash for SideEffect { - fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator( - self.serialize() , GENERATOR_INDEX__SIDE_EFFECT) - } -} - -impl Serialize for SideEffect { - fn serialize(self) -> [Field; SIDE_EFFECT_LENGTH] { - [self.value, self.counter as Field] - } -} - -impl Deserialize for SideEffect { - fn deserialize(values: [Field; SIDE_EFFECT_LENGTH]) -> Self { - Self { - value: values[0], - counter: values[1] as u32, - } - } +trait Readable { + fn assert_match_read_request(self, read_request: ScopedReadRequest); } -#[test] -fn serialization_of_empty() { - let item = SideEffect::empty(); - let serialized = item.serialize(); - let deserialized = SideEffect::deserialize(serialized); - assert(item.eq(deserialized)); -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 72b4fe23927..d4603315cc5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -173,7 +173,6 @@ global SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1; global CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1; global PRIVATE_CALL_REQUEST_LENGTH = 3 + CALLER_CONTEXT_LENGTH; global SCOPED_PRIVATE_CALL_REQUEST_LENGTH = PRIVATE_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; -global SIDE_EFFECT_LENGTH = 2; global ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH; global STATE_REFERENCE_LENGTH: u64 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; global TX_CONTEXT_LENGTH: u64 = 2 + GAS_SETTINGS_LENGTH; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr b/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr index 8168fbf739a..2aa519cb264 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr @@ -1,7 +1,8 @@ use crate::{ address::{AztecAddress, EthAddress}, - constants::{L2_TO_L1_MESSAGE_LENGTH, SCOPED_L2_TO_L1_MESSAGE_LENGTH}, abis::side_effect::Ordered, - traits::{Deserialize, Empty, Serialize}, utils::{arrays::array_concat, reader::Reader} + constants::{L2_TO_L1_MESSAGE_LENGTH, SCOPED_L2_TO_L1_MESSAGE_LENGTH}, + abis::side_effect::{Ordered, Scoped}, traits::{Deserialize, Empty, Serialize}, + utils::{arrays::array_concat, reader::Reader} }; // Note: Not to be confused with L2ToL1Msg in Solidity @@ -60,6 +61,15 @@ struct ScopedL2ToL1Message { contract_address: AztecAddress, } +impl Scoped for ScopedL2ToL1Message { + fn inner(self) -> L2ToL1Message { + self.message + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Ordered for ScopedL2ToL1Message { fn counter(self) -> u32 { self.message.counter diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index c80959c409b..1173342d1e8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -3,15 +3,17 @@ use crate::{ gas::Gas, gas_settings::GasSettings, call_context::CallContext, call_request::{CallerContext, CallRequest}, accumulated_data::{CombinedAccumulatedData, PrivateAccumulatedData, PrivateAccumulatedDataBuilder, PublicAccumulatedData}, - global_variables::GlobalVariables, combined_constant_data::CombinedConstantData, + function_data::FunctionData, global_variables::GlobalVariables, + combined_constant_data::CombinedConstantData, kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}, kernel_data::KernelData, public_kernel_data::PublicKernelData, max_block_number::MaxBlockNumber, private_kernel_data::PrivateKernelData, note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, key_validation_request::{ScopedKeyValidationRequest, KeyValidationRequest}, private_call_request::{PrivateCallRequest, ScopedPrivateCallRequest}, - public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, - read_request::{ReadRequest, ScopedReadRequest}, log_hash::{LogHash, NoteLogHash}, + private_circuit_public_inputs::PrivateCircuitPublicInputs, public_data_read::PublicDataRead, + public_data_update_request::PublicDataUpdateRequest, read_request::{ReadRequest, ScopedReadRequest}, + log_hash::{LogHash, NoteLogHash}, validation_requests::{ValidationRequests, ValidationRequestsBuilder} }, address::{AztecAddress, EthAddress}, @@ -25,14 +27,41 @@ use crate::{ }, hash::silo_nullifier, header::Header, messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message}, - partial_state_reference::PartialStateReference, tests::fixtures, transaction::tx_context::TxContext, - traits::Empty, recursion::{verification_key::VerificationKey, proof::NestedRecursiveProof}, + partial_state_reference::PartialStateReference, tests::fixtures, + transaction::{tx_context::TxContext, tx_request::TxRequest}, traits::Empty, + recursion::{verification_key::VerificationKey, proof::NestedRecursiveProof}, grumpkin_point::GrumpkinPoint }; +fn subarray(arr: [T; N]) -> [T; M] { + assert(N >= M, "cannot call subarray on a smaller array"); + let mut new_arr = [arr[0]; M]; + for i in 0..M { + new_arr[i] = arr[i]; + } + new_arr +} + +fn vec_reverse(vec: BoundedVec) -> BoundedVec { + let mut reversed = BoundedVec::new(); + let len = vec.len(); + for i in 0..N { + if i < len { + reversed.push(vec.storage[len - i - 1]); + } + } + reversed +} + struct FixtureBuilder { contract_address: AztecAddress, storage_contract_address: AztecAddress, + msg_sender: AztecAddress, + is_delegate_call: bool, + is_static_call: bool, + + // Fees. + is_fee_payer: bool, fee_payer: AztecAddress, public_teardown_call_request: CallRequest, @@ -55,7 +84,7 @@ struct FixtureBuilder { unencrypted_log_preimages_length: Field, public_data_update_requests: BoundedVec, private_call_requests: BoundedVec, - public_call_stack: BoundedVec, + public_call_requests: BoundedVec, gas_used: Gas, non_revertible_gas_used: Gas, @@ -67,6 +96,11 @@ struct FixtureBuilder { key_validation_requests: BoundedVec, public_data_reads: BoundedVec, + // Function. + function_data: FunctionData, + args_hash: Field, + returns_hash: Field, + // Proof. proof: NestedRecursiveProof, vk: VerificationKey, @@ -76,55 +110,26 @@ struct FixtureBuilder { // Counters. min_revertible_side_effect_counter: u32, + counter_start: u32, counter: u32, // States. start_state: PartialStateReference, + + // Mock data. + value_offset: Field, } impl FixtureBuilder { pub fn new() -> Self { - let tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; - - FixtureBuilder { - contract_address: fixtures::contracts::parent_contract.address, - storage_contract_address: fixtures::contracts::parent_contract.address, - fee_payer: AztecAddress::empty(), - historical_header: Header::empty(), - tx_context, - new_note_hashes: BoundedVec::new(), - new_nullifiers: BoundedVec::new(), - new_l2_to_l1_msgs: BoundedVec::new(), - note_encrypted_logs_hashes: BoundedVec::new(), - encrypted_logs_hashes: BoundedVec::new(), - unencrypted_logs_hashes: BoundedVec::new(), - note_encrypted_logs_hash: 0, - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, - encrypted_log_preimages_length: 0, - unencrypted_log_preimages_length: 0, - public_data_update_requests: BoundedVec::new(), - private_call_requests: BoundedVec::new(), - public_call_stack: BoundedVec::new(), - max_block_number: MaxBlockNumber::empty(), - note_hash_read_requests: BoundedVec::new(), - nullifier_read_requests: BoundedVec::new(), - nullifier_non_existent_read_requests: BoundedVec::new(), - key_validation_requests: BoundedVec::new(), - public_data_reads: BoundedVec::new(), - proof: NestedRecursiveProof::empty(), - vk: VerificationKey::empty(), - vk_index: 0, - vk_path: [0; VK_TREE_HEIGHT], - revert_code: 0, - min_revertible_side_effect_counter: 0, - counter: 0, - start_state: PartialStateReference::empty(), - gas_used: Gas::empty(), - non_revertible_gas_used: Gas::empty(), - global_variables: GlobalVariables::empty(), - public_teardown_call_request: CallRequest::empty() - } + let mut builder = FixtureBuilder::empty(); + builder.tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; + builder.contract_address = fixtures::contracts::parent_contract.address; + builder.storage_contract_address = fixtures::contracts::parent_contract.address; + builder.msg_sender = fixtures::MSG_SENDER; + builder.function_data = fixtures::contract_functions::default_private_function.data; + builder.counter = 1; + builder } pub fn to_constant_data(self) -> CombinedConstantData { @@ -135,6 +140,53 @@ impl FixtureBuilder { } } + pub fn build_tx_request(self) -> TxRequest { + TxRequest { + origin: self.contract_address, + args_hash: self.args_hash, + tx_context: self.tx_context, + function_data: self.function_data + } + } + + pub fn build_call_context(self) -> CallContext { + CallContext { + msg_sender: self.msg_sender, + storage_contract_address: self.storage_contract_address, + function_selector: self.function_data.selector, + is_delegate_call: self.is_delegate_call, + is_static_call: self.is_static_call, + side_effect_counter: self.counter_start + } + } + + pub fn to_private_circuit_public_inputs(self) -> PrivateCircuitPublicInputs { + PrivateCircuitPublicInputs { + call_context: self.build_call_context(), + args_hash: self.args_hash, + returns_hash: self.returns_hash, + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, + is_fee_payer: self.is_fee_payer, + max_block_number: self.max_block_number, + note_hash_read_requests: subarray(self.note_hash_read_requests.storage.map(|r: ScopedReadRequest| r.read_request)), + nullifier_read_requests: subarray(self.nullifier_read_requests.storage.map(|r: ScopedReadRequest| r.read_request)), + key_validation_requests: subarray(self.key_validation_requests.storage.map(|r: ScopedKeyValidationRequest| r.request)), + new_note_hashes: subarray(self.new_note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash)), + new_nullifiers: subarray(self.new_nullifiers.storage.map(|n: ScopedNullifier| n.nullifier)), + private_call_requests: subarray(self.private_call_requests.storage.map(|r: ScopedPrivateCallRequest| r.call_request)), + public_call_stack_hashes: subarray(self.public_call_requests.storage.map(|c: CallRequest| c.hash)), + public_teardown_function_hash: self.public_teardown_call_request.hash, + new_l2_to_l1_msgs: subarray(self.new_l2_to_l1_msgs.storage.map(|r: ScopedL2ToL1Message| r.message)), + start_side_effect_counter: self.counter_start, + end_side_effect_counter: self.counter, + note_encrypted_logs_hashes: subarray(self.note_encrypted_logs_hashes.storage), + encrypted_logs_hashes: subarray(self.encrypted_logs_hashes.storage), + unencrypted_logs_hashes: subarray(self.unencrypted_logs_hashes.storage), + historical_header: self.historical_header, + tx_context: self.tx_context + } + } + pub fn to_private_accumulated_data(self) -> PrivateAccumulatedData { let public_inputs = PrivateAccumulatedDataBuilder { new_note_hashes: self.new_note_hashes, @@ -143,8 +195,8 @@ impl FixtureBuilder { note_encrypted_logs_hashes: self.note_encrypted_logs_hashes, encrypted_logs_hashes: self.encrypted_logs_hashes, unencrypted_logs_hashes: self.unencrypted_logs_hashes, - private_call_stack: self.private_call_requests, - public_call_stack: self.public_call_stack + private_call_stack: vec_reverse(self.private_call_requests), + public_call_stack: self.public_call_requests }; public_inputs.finish() } @@ -158,7 +210,7 @@ impl FixtureBuilder { encrypted_logs_hashes: self.encrypted_logs_hashes.storage, unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, public_data_update_requests: self.public_data_update_requests.storage, - public_call_stack: self.public_call_stack.storage, + public_call_stack: self.public_call_requests.storage, gas_used: self.gas_used } } @@ -275,27 +327,21 @@ impl FixtureBuilder { } } - pub fn add_new_note_hash(&mut self, value: Field) { - self.new_note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(0, self.storage_contract_address)); - } - - pub fn add_broadcast_new_note_hash(&mut self, value: Field) { - self.new_note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(0, self.storage_contract_address)); - self.note_encrypted_logs_hashes.push( - NoteLogHash { value: value + 1, counter: self.next_counter(), length: 64, note_hash_counter: self.counter - 2 } + pub fn add_new_note_hash(&mut self, value: Field, nullifier_counter: u32) { + self.new_note_hashes.push( + NoteHash { value, counter: self.next_counter() }.scope(nullifier_counter, self.storage_contract_address) ); - self.encrypted_log_preimages_length += 64; } pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u64, broadcast: bool) { let index_offset = self.new_note_hashes.len(); - for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + for i in 0..self.new_note_hashes.max_len() { if i < num_new_note_hashes { - let mocked_value = self.get_mocked_note_hash_value(index_offset + i); + let value = self.mock_note_hash_value(index_offset + i); + self.add_new_note_hash(value, 0); if (broadcast) { - self.add_broadcast_new_note_hash(mocked_value); - } else { - self.add_new_note_hash(mocked_value); + let log_hash = self.mock_note_encrypted_log_hash(index_offset + i); + self.add_note_encrypted_log_hash(log_hash, self.counter - 1); } } } @@ -314,20 +360,20 @@ impl FixtureBuilder { pub fn append_new_nullifiers(&mut self, num_extra_nullifier: u64) { let index_offset = self.new_nullifiers.len(); - for i in 0..MAX_NEW_NULLIFIERS_PER_TX { + for i in 0..self.new_nullifiers.max_len() { if i < num_extra_nullifier { - let mocked_value = self.get_mocked_nullifier_value(index_offset + i); - self.add_nullifier(mocked_value); + let value = self.mock_nullifier_value(index_offset + i); + self.add_nullifier(value); } } } pub fn append_siloed_nullifiers(&mut self, num_extra_nullifier: u64) { let index_offset = self.new_nullifiers.len(); - for i in 0..MAX_NEW_NULLIFIERS_PER_TX { + for i in 0..self.new_nullifiers.max_len() { if i < num_extra_nullifier { - let mocked_value = self.get_mocked_nullifier_value(index_offset + i); - self.add_siloed_nullifier(mocked_value); + let value = self.mock_nullifier_value(index_offset + i); + self.add_siloed_nullifier(value); } } } @@ -338,35 +384,36 @@ impl FixtureBuilder { ); } + pub fn append_new_l2_to_l1_msgs(&mut self, num: u64) { + let index_offset = self.new_l2_to_l1_msgs.len(); + for i in 0..self.new_l2_to_l1_msgs.max_len() { + if i < num { + let (content, recipient) = self.mock_l2_to_l1_msg(index_offset + i); + self.add_l2_to_l1_message(content, recipient); + } + } + } + pub fn add_public_data_update_request(&mut self, leaf_slot: Field, value: Field) { let update_request = PublicDataUpdateRequest { leaf_slot, new_value: value }; self.public_data_update_requests.push(update_request); } pub fn append_public_data_update_requests(&mut self, num_updates: u64) { - let value_offset = self.public_data_update_requests.len(); - for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + let index_offset = self.public_data_update_requests.len(); + for i in 0..self.public_data_update_requests.max_len() { if i < num_updates { - // The default leaf index is its index + 23. - // The default value is its index + 678. - self.add_public_data_update_request( - (value_offset + i + 23) as Field, - (value_offset + i + 678) as Field - ); + let write = self.mock_public_data_write(index_offset + i); + self.add_public_data_update_request(write.leaf_slot, write.new_value); } } } pub fn append_public_data_read_requests(&mut self, num_reads: u64) { - let value_offset = self.public_data_reads.len(); - for i in 0..MAX_PUBLIC_DATA_READS_PER_TX { + let index_offset = self.public_data_reads.len(); + for i in 0..self.public_data_reads.max_len() { if i < num_reads { - let read_request = PublicDataRead { - // The default leaf index is its index + 34. - leaf_slot: (value_offset + i + 34) as Field, - // The default value is its index + 5566. - value: (value_offset + i + 5566) as Field - }; + let read_request = self.mock_public_data_read(index_offset + i); self.public_data_reads.push(read_request); } } @@ -374,17 +421,18 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_note_hash(&mut self, note_hash_index: u64) -> u64 { let read_request_index = self.note_hash_read_requests.len(); - let value = self.get_mocked_note_hash_value(note_hash_index); + let value = self.mock_note_hash_value(note_hash_index); let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); self.note_hash_read_requests.push(read_request); read_request_index } pub fn append_note_hash_read_requests(&mut self, num_reads: u64) { - let value_offset = self.note_hash_read_requests.len(); - for i in 0..MAX_NOTE_HASH_READ_REQUESTS_PER_TX { + let index_offset = self.note_hash_read_requests.len(); + for i in 0..self.note_hash_read_requests.max_len() { if i < num_reads { - let read_request = ReadRequest { value: (value_offset + i + 789) as Field, counter: self.next_counter() }.scope(self.storage_contract_address); + let value = self.mock_note_hash_read_value(index_offset + i); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); self.note_hash_read_requests.push(read_request); } } @@ -392,7 +440,7 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_nullifier(&mut self, nullifier_index: u64) -> u64 { let read_request_index = self.nullifier_read_requests.len(); - let nullifier = self.get_mocked_nullifier_value(nullifier_index); + let nullifier = self.mock_nullifier_value(nullifier_index); let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.storage_contract_address); self.nullifier_read_requests.push(read_request); read_request_index @@ -403,6 +451,17 @@ impl FixtureBuilder { self.nullifier_non_existent_read_requests.push(read_request); } + pub fn append_nullifier_read_requests(&mut self, num_reads: u64) { + let index_offset = self.nullifier_read_requests.len(); + for i in 0..self.nullifier_read_requests.max_len() { + if i < num_reads { + let value = self.mock_nullifier_read_value(index_offset + i); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.storage_contract_address); + self.nullifier_read_requests.push(read_request); + } + } + } + pub fn add_read_request_for_pending_public_data(&mut self, public_date_update_request_index: u64) -> u64 { let new_read_request_index = self.public_data_reads.len(); let public_write = self.public_data_update_requests.get(public_date_update_request_index); @@ -419,6 +478,31 @@ impl FixtureBuilder { new_request_index } + pub fn append_key_validation_requests(&mut self, num_requests: u64) { + let index_offset = self.key_validation_requests.len(); + for i in 0..self.key_validation_requests.max_len() { + if i < num_requests { + let request = self.mock_key_validation_request(index_offset + i); + self.key_validation_requests.push(request.scope(self.storage_contract_address)); + } + } + } + + pub fn add_note_encrypted_log_hash(&mut self, value: Field, note_hash_counter: u32) { + self.note_encrypted_logs_hashes.push(NoteLogHash { value, counter: self.next_counter(), length: 64, note_hash_counter }); + self.encrypted_log_preimages_length += 64; + } + + pub fn append_note_encrypted_logs_hashes(&mut self, num: u64) { + let index_offset = self.note_encrypted_logs_hashes.len(); + for i in 0..self.note_encrypted_logs_hashes.max_len() { + if i < num { + let log_hash = self.mock_note_encrypted_log_hash(index_offset + i); + self.add_note_encrypted_log_hash(log_hash, 0); + } + } + } + pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { let side_effect = LogHash { value: hash, counter: self.next_counter(), length: preimages_length }; self.encrypted_logs_hashes.push(side_effect); @@ -441,7 +525,7 @@ impl FixtureBuilder { self.unencrypted_log_preimages_length = preimages_length; } - pub fn push_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { + pub fn add_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { let mut caller_context = CallerContext::empty(); if is_delegate_call { caller_context.msg_sender = fixtures::MSG_SENDER; @@ -455,19 +539,50 @@ impl FixtureBuilder { ); } + pub fn append_private_call_requests(&mut self, num: u64) { + let index_offset = self.private_call_requests.len(); + for i in 0..self.private_call_requests.max_len() { + if i < num { + let hash = self.mock_private_call_request_hash(index_offset + i); + self.add_private_call_request(hash, true); + } + } + } + pub fn push_public_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); - self.public_call_stack.push(call_stack_item); + let call_request = self.generate_call_request(hash, is_delegate_call); + self.public_call_requests.push(call_request); + } + + pub fn append_public_call_requests(&mut self, num: u64) { + let index_offset = self.public_call_requests.len(); + for i in 0..self.public_call_requests.max_len() { + if i < num { + let hash = self.mock_public_call_request_hash(index_offset + i); + self.push_public_call_request(hash, true); + } + } } pub fn set_fee_payer(&mut self, fee_payer: AztecAddress) { self.fee_payer = fee_payer; } + pub fn make_fee_payer(&mut self) -> AztecAddress { + self.is_fee_payer = true; + self.set_fee_payer(self.storage_contract_address); + self.storage_contract_address + } + pub fn set_public_teardown_call_request(&mut self, hash: Field, is_delegate_call: bool) { self.public_teardown_call_request = self.generate_call_request(hash, is_delegate_call); } + pub fn append_public_teardown_call_request(&mut self) { + let hash = self.mock_public_teardown_call_request_hash(0); + self.set_public_teardown_call_request(hash, true); + } + pub fn end_setup(&mut self) { self.min_revertible_side_effect_counter = self.counter; } @@ -479,7 +594,7 @@ impl FixtureBuilder { fn generate_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { let mut caller_context = CallerContext::empty(); if is_delegate_call { - caller_context.msg_sender = fixtures::MSG_SENDER; + caller_context.msg_sender = self.msg_sender; caller_context.storage_contract_address = self.contract_address; } let start_counter = self.next_counter(); @@ -494,19 +609,64 @@ impl FixtureBuilder { } } - fn get_mocked_note_hash_value(_self: Self, note_hash_index: u64) -> Field { - let value_offset = 212121; - value_offset + note_hash_index as Field + fn mock_note_hash_read_value(self, index: u64) -> Field { + 789 + self.value_offset + index as Field + } + + fn mock_nullifier_read_value(self, index: u64) -> Field { + 22334 + self.value_offset + index as Field + } + + fn mock_key_validation_request(self, index: u64) -> KeyValidationRequest { + let value_offset = 3030 + self.value_offset + index as Field; + KeyValidationRequest { pk_m: GrumpkinPoint { x: value_offset, y: 1 + value_offset }, sk_app: 2 + value_offset } + } + + fn mock_public_data_read(self, index: u64) -> PublicDataRead { + let value_offset = 4545 + self.value_offset + index as Field; + PublicDataRead { leaf_slot: value_offset, value: 1 + value_offset } + } + + fn mock_public_data_write(self, index: u64) -> PublicDataUpdateRequest { + let value_offset = 7788 + self.value_offset + index as Field; + PublicDataUpdateRequest { leaf_slot: value_offset, new_value: 1 + value_offset } + } + + fn mock_note_hash_value(self, index: u64) -> Field { + 212121 + self.value_offset + index as Field + } + + fn mock_nullifier_value(self, index: u64) -> Field { + 5678 + self.value_offset + index as Field + } + + fn mock_nullifier_value_non_revertible(self, index: u64) -> Field { + 9876 + self.value_offset + index as Field + } + + fn mock_l2_to_l1_msg(self, index: u64) -> (Field, EthAddress) { + let value_offset = 72727 + self.value_offset + index as Field; + (value_offset, EthAddress::from_field(1 + value_offset)) + } + + fn mock_note_encrypted_log_hash(self, index: u64) -> Field { + 282828 + self.value_offset + index as Field + } + + fn mock_private_call_request_hash(self, index: u64) -> Field { + 766766 + self.value_offset + index as Field + } + + fn mock_public_call_request_hash(self, index: u64) -> Field { + 636363 + self.value_offset + index as Field } - fn get_mocked_nullifier_value(_self: Self, nullifier_index: u64) -> Field { - let value_offset = 5678; - value_offset + nullifier_index as Field + fn mock_public_teardown_call_request_hash(self, index: u64) -> Field { + 54345 + self.value_offset + index as Field } - fn get_mocked_nullifier_value_non_revertible(_self: Self, nullifier_index: u64) -> Field { - let value_offset = 987; - value_offset + nullifier_index as Field + fn mock_fee_payer(self) -> AztecAddress { + AztecAddress::from_field(900900 + self.value_offset) } fn next_counter(&mut self) -> u32 { @@ -521,6 +681,10 @@ impl Empty for FixtureBuilder { FixtureBuilder { contract_address: AztecAddress::zero(), storage_contract_address: AztecAddress::zero(), + msg_sender: AztecAddress::zero(), + is_delegate_call: false, + is_static_call: false, + is_fee_payer: false, fee_payer: AztecAddress::zero(), historical_header: Header::empty(), tx_context: TxContext::empty(), @@ -538,24 +702,29 @@ impl Empty for FixtureBuilder { unencrypted_log_preimages_length: 0, public_data_update_requests: BoundedVec::new(), private_call_requests: BoundedVec::new(), - public_call_stack: BoundedVec::new(), + public_call_requests: BoundedVec::new(), max_block_number: MaxBlockNumber::empty(), note_hash_read_requests: BoundedVec::new(), nullifier_read_requests: BoundedVec::new(), nullifier_non_existent_read_requests: BoundedVec::new(), key_validation_requests: BoundedVec::new(), public_data_reads: BoundedVec::new(), + function_data: FunctionData::empty(), + args_hash: 0, + returns_hash: 0, proof: NestedRecursiveProof::empty(), vk: VerificationKey::empty(), vk_index: 0, vk_path: [0; VK_TREE_HEIGHT], revert_code: 0, min_revertible_side_effect_counter: 0, + counter_start: 0, counter: 0, start_state: PartialStateReference::empty(), gas_used: Gas::empty(), non_revertible_gas_used: Gas::empty(), - public_teardown_call_request: CallRequest::empty() + public_teardown_call_request: CallRequest::empty(), + value_offset: 0, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index 34e7f941d0d..a84e2fd564d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -55,20 +55,28 @@ pub fn validate_array(array: [T; N]) -> u64 where T: Empty + Eq { length } -// Helper method to determine the number of non-zero/empty elements in a validated array (ie, validate_array(array) -// should be true). -pub fn array_length(array: [T; N]) -> u64 where T: Empty + Eq { +unconstrained fn count_non_empty_elements(array: [T; N]) -> u64 where T: Empty + Eq { let mut length = 0; - let mut end = false; for elem in array { - end |= is_empty(elem); - if !end { + if !is_empty(elem) { length += 1; } } length } +// Helper function to count the number of non-empty elements in a validated array (ie, validate_array(array) should be true). +pub fn array_length(array: [T; N]) -> u64 where T: Empty + Eq { + let length = count_non_empty_elements(array); + if length != 0 { + assert(!is_empty(array[length - 1])); + } + if length != N { + assert(is_empty(array[length])); + } + length +} + pub fn array_eq(array: [T; N], expected: [T; S]) -> bool where T: Empty + Eq { let mut eq = array_length(array) == S; @@ -207,8 +215,6 @@ fn smoke_validate_array_invalid_case2() { #[test] fn test_empty_array_length() { - let empty_array: [Field; 0] = []; - assert_eq(array_length(empty_array), 0); assert_eq(array_length([0]), 0); assert_eq(array_length([0, 0, 0]), 0); } @@ -216,10 +222,14 @@ fn test_empty_array_length() { #[test] fn test_array_length() { assert_eq(array_length([123]), 1); + assert_eq(array_length([123, 0, 0]), 1); assert_eq(array_length([123, 456]), 2); assert_eq(array_length([123, 456, 0]), 2); - assert_eq(array_length([123, 0, 456]), 1); - assert_eq(array_length([0, 123, 0, 456]), 0); +} + +#[test(should_fail)] +fn test_array_length_invalid_fails() { + let _ = array_length([0, 0, 123]); } #[test] From 4bf7ad590c03f8d73a45e083c05f4a42f9b09820 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 24 May 2024 13:06:26 +0000 Subject: [PATCH 02/13] Tests for private kernel circuit public inputs composer. --- ...e_kernel_circuit_public_inputs_composer.nr | 17 +- .../src/private_kernel_init.nr | 113 +----- .../crates/private-kernel-lib/src/tests.nr | 1 + ...kernel_circuit_output_validator_builder.nr | 2 +- ..._circuit_public_inputs_composer_builder.nr | 77 ++++ ..._from_previous_kernel_with_private_call.nr | 334 ++++++++++++++++++ .../new_from_tx_request.nr | 41 +++ .../propagate_from_private_call.nr | 239 +++++++++++++ .../rollup-lib/src/base/base_rollup_inputs.nr | 2 +- .../private_kernel_circuit_public_inputs.nr | 16 + .../abis/private_kernel/private_call_data.nr | 2 +- .../types/src/abis/private_kernel_data.nr | 2 +- .../crates/types/src/tests/fixture_builder.nr | 65 +++- .../crates/types/src/utils/arrays.nr | 18 +- 14 files changed, 798 insertions(+), 131 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr index 07766235a5a..599c3a25529 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr @@ -47,7 +47,7 @@ impl PrivateKernelCircuitPublicInputsComposer { public_inputs.min_revertible_side_effect_counter = private_call_public_inputs.min_revertible_side_effect_counter; - // Since it's the first iteration, we need to push the the tx hash nullifier into the `new_nullifiers` array + // Since it's the first iteration, we need to push the tx hash nullifier into the `new_nullifiers` array public_inputs.end.new_nullifiers.push(create_first_nullifier(tx_request)); // Note that we do not need to nullify the transaction request nonce anymore. // Should an account want to additionally use nonces for replay protection or handling cancellations, @@ -104,7 +104,16 @@ impl PrivateKernelCircuitPublicInputsComposer { public_call_requests, public_teardown_call_request }; + self.propagate_from_private_call(source); + *self + } + + pub fn finish(self) -> PrivateKernelCircuitPublicInputs { + self.public_inputs.finish() + } + + fn propagate_from_private_call(&mut self, source: DataSource) { self.propagate_max_block_number(source); self.propagate_note_hash_read_requests(source); self.propagate_nullifier_read_requests(source); @@ -117,12 +126,6 @@ impl PrivateKernelCircuitPublicInputsComposer { self.propagate_public_call_requests(source); self.propagate_public_teardown_call_request(source); self.propagate_fee_payer(source); - - *self - } - - pub fn finish(self) -> PrivateKernelCircuitPublicInputs { - self.public_inputs.finish() } fn propagate_max_block_number(&mut self, source: DataSource) { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index b80c984362b..05227596869 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -8,8 +8,7 @@ use dep::types::{ private_kernel::private_call_data::{PrivateCallData, verify_private_call}, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs }, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, mocked::verify_private_function_proof, - transaction::tx_request::TxRequest + constants::MAX_NEW_NOTE_HASHES_PER_CALL, transaction::tx_request::TxRequest }; struct PrivateKernelInitHints { @@ -60,10 +59,9 @@ impl PrivateKernelInitCircuitPrivateInputs { let output = self.prepare_output(private_call_data_validator); let output_validator = PrivateKernelCircuitOutputValidator::new(output); - let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; output_validator.validate_as_first_call( self.tx_request, - private_call_public_inputs, + self.private_call.call_stack_item.public_inputs, private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, @@ -77,16 +75,10 @@ impl PrivateKernelInitCircuitPrivateInputs { mod tests { use crate::private_kernel_init::{PrivateKernelInitHints, PrivateKernelInitCircuitPrivateInputs}; use dep::types::{ - abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, note_hash::NoteHash, - key_validation_request::KeyValidationRequest, - private_kernel::private_call_data::PrivateCallData, read_request::ReadRequest, - nullifier::Nullifier, log_hash::{LogHash, NoteLogHash} - }, - address::{AztecAddress, EthAddress}, constants::MAX_NEW_NOTE_HASHES_PER_CALL, - grumpkin_point::GrumpkinPoint, messaging::l2_to_l1_message::L2ToL1Message, + abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::NoteLogHash}, + constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::private_call_data_builder::PrivateCallDataBuilder, transaction::tx_request::TxRequest, - utils::arrays::{array_length, array_eq} + utils::arrays::array_eq }; struct PrivateKernelInitInputsBuilder { @@ -164,85 +156,6 @@ mod tests { ); } - #[test] - fn default_max_block_number() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - let public_inputs = builder.execute(); - - assert(public_inputs.validation_requests.for_rollup.max_block_number.is_none()); - } - - #[test] - fn propagate_max_block_number_request() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - builder.private_call.public_inputs.set_tx_max_block_number(42); - let public_inputs = builder.execute(); - - assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 42); - } - - #[test] - fn propagate_note_hash_read_requests() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - let storage_contract_address = builder.private_call.public_inputs.call_context.storage_contract_address; - - builder.private_call.public_inputs.append_note_hash_read_requests(2); - let new_read_requests = builder.private_call.public_inputs.note_hash_read_requests.storage; - - let public_inputs = builder.execute(); - - let end_note_hash_read_requests = public_inputs.validation_requests.note_hash_read_requests; - assert_eq(array_length(end_note_hash_read_requests), 2); - - let request = end_note_hash_read_requests[0]; - assert_eq(request.read_request, new_read_requests[0]); - assert_eq(request.contract_address, storage_contract_address); - - let request = end_note_hash_read_requests[1]; - assert_eq(request.read_request, new_read_requests[1]); - assert_eq(request.contract_address, storage_contract_address); - } - - #[test] - fn propagate_nullifier_read_requests() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - let storage_contract_address = builder.private_call.public_inputs.call_context.storage_contract_address; - - builder.private_call.public_inputs.append_nullifier_read_requests(2); - let requests = builder.private_call.public_inputs.nullifier_read_requests.storage; - - let public_inputs = builder.execute(); - - let end_nullifier_read_requests = public_inputs.validation_requests.nullifier_read_requests; - assert_eq(array_length(end_nullifier_read_requests), 2); - - let request = end_nullifier_read_requests[0]; - assert_eq(request.read_request, requests[0]); - assert_eq(request.contract_address, storage_contract_address); - - let request = end_nullifier_read_requests[1]; - assert_eq(request.read_request, requests[1]); - assert_eq(request.contract_address, storage_contract_address); - } - - #[test] - fn propagate_key_validation_requests() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - - let request_0 = KeyValidationRequest { pk_m: GrumpkinPoint { x: 1, y: 2 }, sk_app: 3 }; - builder.private_call.public_inputs.key_validation_requests.push(request_0); - - let public_inputs = builder.execute(); - - assert_eq(array_length(public_inputs.validation_requests.key_validation_requests), 1); - - let request = public_inputs.validation_requests.key_validation_requests[0]; - assert_eq(request.request, request_0); - assert_eq( - request.contract_address, builder.private_call.public_inputs.call_context.storage_contract_address - ); - } - #[test(should_fail_with = "Could not find note hash linked to note log.")] fn input_validation_note_log_not_linked() { let mut builder = PrivateKernelInitInputsBuilder::new(); @@ -251,20 +164,4 @@ mod tests { builder.failed(); } - - #[test] - unconstrained fn propagate_fee_payer() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - let fee_payer = builder.private_call.public_inputs.call_context.storage_contract_address; - builder.private_call.public_inputs.is_fee_payer = true; - - let public_inputs = builder.execute(); - assert_eq(public_inputs.fee_payer, fee_payer); - - // Check that the fee payer is not set if is_fee_payer is false - let mut builder = PrivateKernelInitInputsBuilder::new(); - assert_eq(builder.private_call.public_inputs.is_fee_payer, false); - let public_inputs = builder.execute(); - assert_eq(public_inputs.fee_payer, AztecAddress::empty()); - } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr index 1820a12d7a5..d97b1175650 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr @@ -1,5 +1,6 @@ mod private_call_data_validator_builder; mod private_kernel_circuit_output_validator_builder; +mod private_kernel_circuit_public_inputs_composer_builder; mod validate_against_call_request; mod validate_against_previous_kernel; mod validate_against_tx_request; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr index 60a47c651c1..5a46d497193 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr @@ -65,9 +65,9 @@ impl PrivateKernelCircuitOutputValidatorBuilder { } pub fn validate_as_inner_call(self) { - let num_private_call_requests = self.previous_kernel.private_call_requests.len(); let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); // Append one private call request for the current call. + let num_private_call_requests = self.previous_kernel.private_call_requests.len(); previous_kernel.end.private_call_stack[num_private_call_requests] = ScopedPrivateCallRequest::empty(); previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr new file mode 100644 index 00000000000..68ee112fe8c --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr @@ -0,0 +1,77 @@ +mod new_from_previous_kernel_with_private_call; +mod new_from_tx_request; +mod propagate_from_private_call; + +use crate::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; +use dep::types::{ + abis::{ + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_call_request::ScopedPrivateCallRequest, + private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths +}, + constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::fixture_builder::FixtureBuilder, + transaction::tx_request::TxRequest +}; + +struct PrivateKernelCircuitPublicInputsComposerBuilder { + tx_request: TxRequest, + previous_kernel: FixtureBuilder, + private_call: FixtureBuilder, + note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], +} + +impl PrivateKernelCircuitPublicInputsComposerBuilder { + pub fn new() -> Self { + let previous_kernel = FixtureBuilder::new(); + + let mut private_call = FixtureBuilder::new(); + // Add an offset to the mock values so that the data in the private call won't be the same as those in the previous kernel. + private_call.value_offset = 9999; + private_call.counter_start = 666; + private_call.counter = 777; + + let tx_request = private_call.build_tx_request(); + let note_hash_nullifier_counters = [0; MAX_NEW_NOTE_HASHES_PER_CALL]; + PrivateKernelCircuitPublicInputsComposerBuilder { tx_request, previous_kernel, private_call, note_hash_nullifier_counters } + } + + pub fn new_from_tx_request(self) -> PrivateKernelCircuitPublicInputsComposer { + let private_call = self.private_call.to_private_circuit_public_inputs(); + PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call) + } + + pub fn new_from_previous_kernel(self) -> PrivateKernelCircuitPublicInputsComposer { + let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); + // Append one private call request for the current call. + let num_private_call_requests = self.previous_kernel.private_call_requests.len(); + previous_kernel.end.private_call_stack[num_private_call_requests] = ScopedPrivateCallRequest::empty(); + previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432; + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel) + } + + pub fn compose_from_tx_request(self) -> PrivateKernelCircuitPublicInputs { + let private_call = self.private_call.to_private_call_data(); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); + self.new_from_tx_request().compose( + private_call.call_stack_item.public_inputs, + array_lengths, + private_call.call_stack_item.contract_address, + self.note_hash_nullifier_counters, + private_call.public_call_stack, + private_call.public_teardown_call_request + ).finish() + } + + pub fn compose_from_previous_kernel(self) -> PrivateKernelCircuitPublicInputs { + let private_call = self.private_call.to_private_call_data(); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); + self.new_from_previous_kernel().compose( + private_call.call_stack_item.public_inputs, + array_lengths, + private_call.call_stack_item.contract_address, + self.note_hash_nullifier_counters, + private_call.public_call_stack, + private_call.public_teardown_call_request + ).finish() + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr new file mode 100644 index 00000000000..81291013130 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -0,0 +1,334 @@ +use crate::{tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder}; +use dep::types::{ + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, + utils::arrays::array_eq +}; + +#[test] +fn new_from_previous_kernel_with_private_call_empty_data_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + let output = builder.compose_from_previous_kernel(); + + let array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(output); + let expected_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::empty(); + assert_eq(array_lengths, expected_array_lengths); + + assert(output.validation_requests.for_rollup.max_block_number.is_none()); + assert(is_empty(output.public_teardown_call_request)); + assert(is_empty(output.fee_payer)); +} + +#[test] +fn new_from_previous_kernel_with_private_call_max_block_number_prev_empty_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.set_max_block_number(123); + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.validation_requests.for_rollup.max_block_number.unwrap(), 123); +} + +#[test] +fn new_from_previous_kernel_with_private_call_max_block_number_curr_empty_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.set_max_block_number(123); + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.validation_requests.for_rollup.max_block_number.unwrap(), 123); +} + +#[test] +fn new_from_previous_kernel_with_private_call_max_block_number_pick_prev_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.set_max_block_number(123); + builder.private_call.set_max_block_number(4567); + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.validation_requests.for_rollup.max_block_number.unwrap(), 123); +} + +#[test] +fn new_from_previous_kernel_with_private_call_max_block_number_pick_curr_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.set_max_block_number(4567); + builder.private_call.set_max_block_number(123); + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.validation_requests.for_rollup.max_block_number.unwrap(), 123); +} + +#[test] +fn new_from_previous_kernel_with_private_call_note_hash_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_note_hash_read_requests(2); + let prev = builder.previous_kernel.note_hash_read_requests.storage; + builder.private_call.append_note_hash_read_requests(2); + let curr = builder.private_call.note_hash_read_requests.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.validation_requests.note_hash_read_requests, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_nullifier_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_nullifier_read_requests(2); + let prev = builder.previous_kernel.nullifier_read_requests.storage; + builder.private_call.append_nullifier_read_requests(2); + let curr = builder.private_call.nullifier_read_requests.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.validation_requests.nullifier_read_requests, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_key_validation_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_key_validation_requests(2); + let prev = builder.previous_kernel.key_validation_requests.storage; + builder.private_call.append_key_validation_requests(2); + let curr = builder.private_call.key_validation_requests.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.validation_requests.key_validation_requests, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_new_note_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + let prev = builder.previous_kernel.new_note_hashes.storage; + builder.private_call.append_new_note_hashes(2, false); + let curr = builder.private_call.new_note_hashes.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + let prev = builder.previous_kernel.new_note_hashes.storage; + builder.private_call.append_new_note_hashes(2, false); + let mut curr = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; + + let output = builder.compose_from_previous_kernel(); + + curr[0].nullifier_counter = curr[0].counter() + 10; + curr[1].nullifier_counter = curr[1].counter() + 75; + assert( + array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + let prev = builder.previous_kernel.new_note_hashes.storage; + builder.private_call.append_new_note_hashes(2, false); + let mut curr = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; + // Add a random nullifier counter for a non-existent note hash to the hints. + builder.note_hash_nullifier_counters[2] = 323; + + let output = builder.compose_from_previous_kernel(); + + curr[0].nullifier_counter = curr[0].counter() + 10; + curr[1].nullifier_counter = curr[1].counter() + 75; + assert( + array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); + // The extra counter won't be propagated. + assert_eq(output.end.new_note_hashes[4].nullifier_counter, 0); +} + +#[test(should_fail_with="Invalid nullifier counter")] +fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(2, false); + let _ = builder.previous_kernel.new_note_hashes.storage; + builder.private_call.append_new_note_hashes(2, false); + let curr = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; + // Tweak the nullifier counter to be less than the note hash counter. + builder.note_hash_nullifier_counters[1] = curr[1].counter() - 1; + + let _ = builder.compose_from_previous_kernel(); +} + +#[test] +fn new_from_previous_kernel_with_private_call_new_nullifiers_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(2); + let prev = builder.previous_kernel.new_nullifiers.storage; + builder.private_call.append_new_nullifiers(2); + let curr = builder.private_call.new_nullifiers.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.end.new_nullifiers, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_new_l2_to_l1_msgs_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_l2_to_l1_msgs(1); + let prev = builder.previous_kernel.new_l2_to_l1_msgs.storage; + builder.private_call.append_new_l2_to_l1_msgs(1); + let curr = builder.private_call.new_l2_to_l1_msgs.storage; + + let output = builder.compose_from_previous_kernel(); + + assert(array_eq(output.end.new_l2_to_l1_msgs, [prev[0], curr[0]])); +} + +// #[test] +// fn new_from_previous_kernel_with_private_call_logs_succeeds() { +// let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + +// builder.private_call.append_logs(2); +// let res = builder.private_call.logs.storage; + +// let output = builder.compose_from_previous_kernel(); + +// assert(array_eq(output.end.logs, [res[0], res[1]])); +// } + +#[test] +fn new_from_previous_kernel_with_private_call_private_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_private_call_requests(2); + let prev = builder.previous_kernel.private_call_requests.storage; + builder.private_call.append_private_call_requests(2); + let curr = builder.private_call.private_call_requests.storage; + + let output = builder.compose_from_previous_kernel(); + + // Call requests from private call will be propagated in reversed order. + assert( + array_eq( + output.end.private_call_stack, + [prev[1], prev[0], curr[1], curr[0]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_public_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_public_call_requests(2); + let prev = builder.previous_kernel.public_call_requests.storage; + builder.private_call.append_public_call_requests(2); + let curr = builder.private_call.public_call_requests.storage; + + let output = builder.compose_from_previous_kernel(); + + assert( + array_eq( + output.end.public_call_stack, + [prev[0], prev[1], curr[0], curr[1]] + ) + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_public_teardown_call_request_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + let request = builder.private_call.public_teardown_call_request; + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.public_teardown_call_request, request); +} + +#[test(should_fail_with="Public teardown call request already set")] +fn new_from_previous_kernel_with_private_call_public_teardown_call_request_overwrite_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_public_teardown_call_request(); + builder.private_call.append_public_teardown_call_request(); + + let _ = builder.compose_from_previous_kernel(); +} + +#[test] +fn new_from_previous_kernel_with_private_call_fee_payer_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.fee_payer, fee_payer); +} + +#[test(should_fail_with="Cannot overwrite non-empty fee_payer")] +fn new_from_previous_kernel_with_private_call_fee_payer_overwrite_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + let _ = builder.previous_kernel.make_fee_payer(); + let _ = builder.private_call.make_fee_payer(); + + let _ = builder.compose_from_previous_kernel(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr new file mode 100644 index 00000000000..458f22d1984 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr @@ -0,0 +1,41 @@ +use crate::{ + private_kernel_circuit_public_inputs_composer::create_first_nullifier, + tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder +}; +use dep::types::{abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty}; + +#[test] +fn new_from_tx_request_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + // Make sure we are not testing with empty structs/data. + let tx_request = builder.tx_request; + assert(!is_empty(tx_request)); + let first_nullifier = create_first_nullifier(tx_request); + + builder.private_call.historical_header.total_fees = 979797; + builder.private_call.historical_header.content_commitment.out_hash = 122122; + let historical_header = builder.private_call.historical_header; + builder.private_call.min_revertible_side_effect_counter = 37; + + let output = builder.new_from_tx_request().public_inputs.finish(); + + // Check output constants. + assert_eq(output.constants.tx_context, tx_request.tx_context); + assert_eq(output.constants.historical_header, historical_header); + assert(is_empty(output.constants.global_variables)); + + // Check output requests and accumulated data. + assert_eq(output.min_revertible_side_effect_counter, 37); + assert_eq(output.end.new_nullifiers[0], first_nullifier); + + let array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(output); + let mut expected_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::empty(); + expected_array_lengths.new_nullifiers = 1; + assert_eq(array_lengths, expected_array_lengths); + + // Check values default to empty. + assert(output.validation_requests.for_rollup.max_block_number.is_none()); + assert(is_empty(output.public_teardown_call_request)); + assert(is_empty(output.fee_payer)); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr new file mode 100644 index 00000000000..e7788ae8d3f --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -0,0 +1,239 @@ +use crate::{ + private_kernel_circuit_public_inputs_composer::create_first_nullifier, + tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder +}; +use dep::types::{ + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, + utils::arrays::array_eq +}; + +#[test] +fn propagate_from_private_call_empty_data_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + let tx_request = builder.tx_request; + let first_nullifier = create_first_nullifier(tx_request); + + let output = builder.compose_from_tx_request(); + + assert_eq(output.end.new_nullifiers[0], first_nullifier); + + let array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(output); + let mut expected_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::empty(); + expected_array_lengths.new_nullifiers = 1; + assert_eq(array_lengths, expected_array_lengths); + + assert(output.validation_requests.for_rollup.max_block_number.is_none()); + assert(is_empty(output.public_teardown_call_request)); + assert(is_empty(output.fee_payer)); +} + +#[test] +fn propagate_from_private_call_max_block_number_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.set_max_block_number(123); + + let output = builder.compose_from_tx_request(); + + assert_eq(output.validation_requests.for_rollup.max_block_number.unwrap(), 123); +} + +#[test] +fn propagate_from_private_call_note_hash_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_note_hash_read_requests(2); + let res = builder.private_call.note_hash_read_requests.storage; + + let output = builder.compose_from_tx_request(); + + assert( + array_eq( + output.validation_requests.note_hash_read_requests, + [res[0], res[1]] + ) + ); +} + +#[test] +fn propagate_from_private_call_nullifier_read_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_nullifier_read_requests(2); + let res = builder.private_call.nullifier_read_requests.storage; + + let output = builder.compose_from_tx_request(); + + assert( + array_eq( + output.validation_requests.nullifier_read_requests, + [res[0], res[1]] + ) + ); +} + +#[test] +fn propagate_from_private_call_key_validation_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_key_validation_requests(2); + let res = builder.private_call.key_validation_requests.storage; + + let output = builder.compose_from_tx_request(); + + assert( + array_eq( + output.validation_requests.key_validation_requests, + [res[0], res[1]] + ) + ); +} + +#[test] +fn propagate_from_private_call_new_note_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let res = builder.private_call.new_note_hashes.storage; + + let output = builder.compose_from_tx_request(); + + assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); +} + +#[test] +fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let mut res = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; + + let output = builder.compose_from_tx_request(); + + res[0].nullifier_counter = res[0].counter() + 10; + res[1].nullifier_counter = res[1].counter() + 75; + assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); +} + +#[test] +fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let mut res = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; + builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; + // Add a random nullifier counter for a non-existent note hash to the hints. + builder.note_hash_nullifier_counters[2] = 323; + + let output = builder.compose_from_tx_request(); + + res[0].nullifier_counter = res[0].counter() + 10; + res[1].nullifier_counter = res[1].counter() + 75; + assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); + // The extra counter won't be propagated. + assert_eq(output.end.new_note_hashes[2].nullifier_counter, 0); +} + +#[test(should_fail_with="Invalid nullifier counter")] +fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes(2, false); + let mut res = builder.private_call.new_note_hashes.storage; + builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; + // Tweak the nullifier counter to be less than the note hash counter. + builder.note_hash_nullifier_counters[1] = res[1].counter() - 1; + + let _ = builder.compose_from_tx_request(); +} + +#[test] +fn propagate_from_private_call_new_nullifiers_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_nullifiers(2); + let res = builder.private_call.new_nullifiers.storage; + + let tx_request = builder.tx_request; + let first_nullifier = create_first_nullifier(tx_request); + + let output = builder.compose_from_tx_request(); + + assert(array_eq(output.end.new_nullifiers, [first_nullifier, res[0], res[1]])); +} + +#[test] +fn propagate_from_private_call_new_l2_to_l1_msgs_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_l2_to_l1_msgs(2); + let res = builder.private_call.new_l2_to_l1_msgs.storage; + + let output = builder.compose_from_tx_request(); + + assert(array_eq(output.end.new_l2_to_l1_msgs, [res[0], res[1]])); +} + +// #[test] +// fn propagate_from_private_call_logs_succeeds() { +// let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + +// builder.private_call.append_logs(2); +// let res = builder.private_call.logs.storage; + +// let output = builder.compose_from_tx_request(); + +// assert(array_eq(output.end.logs, [res[0], res[1]])); +// } + +#[test] +fn propagate_from_private_call_private_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_private_call_requests(2); + let res = builder.private_call.private_call_requests.storage; + + let output = builder.compose_from_tx_request(); + + // Call requests will be propagated in reversed order. + assert(array_eq(output.end.private_call_stack, [res[1], res[0]])); +} + +#[test] +fn propagate_from_private_call_public_call_requests_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_public_call_requests(2); + let res = builder.private_call.public_call_requests.storage; + + let output = builder.compose_from_tx_request(); + + assert(array_eq(output.end.public_call_stack, [res[0], res[1]])); +} + +#[test] +fn propagate_from_private_call_public_teardown_call_request_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_public_teardown_call_request(); + let res = builder.private_call.public_teardown_call_request; + + let output = builder.compose_from_tx_request(); + + assert_eq(output.public_teardown_call_request, res); +} + +#[test] +fn propagate_from_private_call_fee_payer_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + let fee_payer = builder.private_call.make_fee_payer(); + + let output = builder.compose_from_tx_request(); + + assert_eq(output.fee_payer, fee_payer); +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index f334bbc5156..307da40397d 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -248,7 +248,7 @@ impl BaseRollupInputs { } // TODO(Kev): This aggregate_proof method is duplicated in a lot of places - fn aggregate_proofs(self) -> AggregationObject { + fn aggregate_proofs(_self: Self) -> AggregationObject { // TODO: for now we simply return the aggregation object from the first proof AggregationObject {} } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr index 22663e6e355..3ab35596224 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr @@ -55,6 +55,22 @@ impl PrivateKernelCircuitPublicInputsArrayLengths { } } +impl Eq for PrivateKernelCircuitPublicInputsArrayLengths { + fn eq(self, other: Self) -> bool { + (self.note_hash_read_requests == other.note_hash_read_requests) & + (self.nullifier_read_requests == other.nullifier_read_requests) & + (self.key_validation_requests == other.key_validation_requests) & + (self.new_note_hashes == other.new_note_hashes) & + (self.new_nullifiers == other.new_nullifiers) & + (self.new_l2_to_l1_msgs == other.new_l2_to_l1_msgs) & + (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) & + (self.encrypted_logs_hashes == other.encrypted_logs_hashes) & + (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) & + (self.private_call_stack == other.private_call_stack) & + (self.public_call_stack== other.public_call_stack) + } +} + struct PrivateKernelCircuitPublicInputs { min_revertible_side_effect_counter: u32, validation_requests: ValidationRequests, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr index db120790ac0..202382d7cc1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr @@ -26,7 +26,7 @@ struct PrivateCallData { acir_hash: Field, } -fn verify_private_call(call: PrivateCallData) { +pub fn verify_private_call(call: PrivateCallData) { let inputs = PrivateCircuitPublicInputs::serialize(call.call_stack_item.public_inputs); dep::std::verify_proof( call.vk.key.as_slice(), diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr index 9e9564ebf25..ad5f9ab1dd8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr @@ -23,7 +23,7 @@ struct PrivateKernelData { vk_path: [Field; VK_TREE_HEIGHT], } -fn verify_previous_kernel_proof(previous_kernel: PrivateKernelData) { +pub fn verify_previous_kernel_proof(previous_kernel: PrivateKernelData) { let inputs = PrivateKernelCircuitPublicInputs::serialize(previous_kernel.public_inputs); dep::std::verify_proof( previous_kernel.vk.key.as_slice(), diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 1173342d1e8..59e760d6445 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -11,25 +11,27 @@ use crate::{ nullifier::{Nullifier, ScopedNullifier}, key_validation_request::{ScopedKeyValidationRequest, KeyValidationRequest}, private_call_request::{PrivateCallRequest, ScopedPrivateCallRequest}, - private_circuit_public_inputs::PrivateCircuitPublicInputs, public_data_read::PublicDataRead, + private_call_stack_item::PrivateCallStackItem, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + private_kernel::private_call_data::PrivateCallData, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, read_request::{ReadRequest, ScopedReadRequest}, log_hash::{LogHash, NoteLogHash}, validation_requests::{ValidationRequests, ValidationRequestsBuilder} }, - address::{AztecAddress, EthAddress}, + address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, constants::{ - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + FUNCTION_TREE_HEIGHT, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_TX, VK_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX }, - hash::silo_nullifier, header::Header, + hash::silo_nullifier, header::Header, merkle_tree::membership::MembershipWitness, messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message}, partial_state_reference::PartialStateReference, tests::fixtures, transaction::{tx_context::TxContext, tx_request::TxRequest}, traits::Empty, - recursion::{verification_key::VerificationKey, proof::NestedRecursiveProof}, + recursion::{verification_key::VerificationKey, proof::{NestedRecursiveProof, RecursiveProof}}, grumpkin_point::GrumpkinPoint }; @@ -101,6 +103,14 @@ struct FixtureBuilder { args_hash: Field, returns_hash: Field, + // Private call. + salted_initialization_hash: SaltedInitializationHash, + public_keys_hash: PublicKeysHash, + contract_class_artifact_hash: Field, + contract_class_public_bytecode_commitment: Field, + function_leaf_membership_witness: MembershipWitness, + acir_hash: Field, + // Proof. proof: NestedRecursiveProof, vk: VerificationKey, @@ -123,12 +133,23 @@ struct FixtureBuilder { impl FixtureBuilder { pub fn new() -> Self { let mut builder = FixtureBuilder::empty(); + + let contract_data = fixtures::contracts::default_contract; + let contract_function = fixtures::contract_functions::default_private_function; + builder.tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; builder.contract_address = fixtures::contracts::parent_contract.address; builder.storage_contract_address = fixtures::contracts::parent_contract.address; builder.msg_sender = fixtures::MSG_SENDER; - builder.function_data = fixtures::contract_functions::default_private_function.data; + builder.function_data = contract_function.data; + builder.function_leaf_membership_witness = contract_function.membership_witness; + builder.salted_initialization_hash = contract_data.salted_initialization_hash; + builder.public_keys_hash = contract_data.public_keys_hash; + builder.contract_class_artifact_hash = contract_data.artifact_hash; + builder.contract_class_public_bytecode_commitment = contract_data.public_bytecode_commitment; + builder.acir_hash = contract_function.acir_hash; builder.counter = 1; + builder } @@ -187,6 +208,30 @@ impl FixtureBuilder { } } + pub fn to_private_call_stack_item(self) -> PrivateCallStackItem { + PrivateCallStackItem { + contract_address: self.contract_address, + function_data: self.function_data, + public_inputs: self.to_private_circuit_public_inputs() + } + } + + pub fn to_private_call_data(self) -> PrivateCallData { + PrivateCallData { + call_stack_item: self.to_private_call_stack_item(), + public_call_stack: subarray(self.public_call_requests.storage), + public_teardown_call_request: self.public_teardown_call_request, + proof: RecursiveProof::empty(), + vk: self.vk, + function_leaf_membership_witness: self.function_leaf_membership_witness, + salted_initialization_hash: self.salted_initialization_hash, + public_keys_hash: self.public_keys_hash, + contract_class_artifact_hash: self.contract_class_artifact_hash, + contract_class_public_bytecode_commitment: self.contract_class_public_bytecode_commitment, + acir_hash: self.acir_hash + } + } + pub fn to_private_accumulated_data(self) -> PrivateAccumulatedData { let public_inputs = PrivateAccumulatedDataBuilder { new_note_hashes: self.new_note_hashes, @@ -712,6 +757,12 @@ impl Empty for FixtureBuilder { function_data: FunctionData::empty(), args_hash: 0, returns_hash: 0, + function_leaf_membership_witness: MembershipWitness::empty(), + salted_initialization_hash: SaltedInitializationHash::from_field(0), + public_keys_hash: PublicKeysHash::from_field(0), + contract_class_artifact_hash: 0, + contract_class_public_bytecode_commitment: 0, + acir_hash: 0, proof: NestedRecursiveProof::empty(), vk: VerificationKey::empty(), vk_index: 0, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index a84e2fd564d..5ecb0d57578 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -57,15 +57,19 @@ pub fn validate_array(array: [T; N]) -> u64 where T: Empty + Eq { unconstrained fn count_non_empty_elements(array: [T; N]) -> u64 where T: Empty + Eq { let mut length = 0; + let mut seen_empty = false; for elem in array { - if !is_empty(elem) { + if is_empty(elem) { + seen_empty = true; + } else if !seen_empty { length += 1; } } length } -// Helper function to count the number of non-empty elements in a validated array (ie, validate_array(array) should be true). +// Helper function to count the number of non-empty elements in a validated array. +// Important: Only use it for validated arrays: validate_array(array) should be true. pub fn array_length(array: [T; N]) -> u64 where T: Empty + Eq { let length = count_non_empty_elements(array); if length != 0 { @@ -227,9 +231,13 @@ fn test_array_length() { assert_eq(array_length([123, 456, 0]), 2); } -#[test(should_fail)] -fn test_array_length_invalid_fails() { - let _ = array_length([0, 0, 123]); +#[test] +fn test_array_length_invalid_arrays() { + // Result can be misleading (but correct) for invalid arrays. + assert_eq(array_length([0, 0, 123]), 0); + assert_eq(array_length([0, 123, 0]), 0); + assert_eq(array_length([0, 123, 456]), 0); + assert_eq(array_length([123, 0, 456]), 1); } #[test] From 90681c8a100a7ec52c709e86481ee9a6bfbb9e1d Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 24 May 2024 14:58:26 +0000 Subject: [PATCH 03/13] Fixes after merge. --- ...private_kernel_circuit_output_validator.nr | 24 ++++++++------- ...e_kernel_circuit_public_inputs_composer.nr | 5 +--- ...kernel_circuit_output_validator_builder.nr | 30 ++++++++----------- .../validate_aggregated_values.nr | 4 +-- .../validate_initial_values.nr | 2 +- ..._from_previous_kernel_with_private_call.nr | 8 ++--- .../propagate_from_private_call.nr | 6 ++-- .../private_kernel_circuit_public_inputs.nr | 8 ++--- .../crates/types/src/abis/log_hash.nr | 20 ++++++++++++- .../crates/types/src/tests/fixture_builder.nr | 4 +-- 10 files changed, 61 insertions(+), 50 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 62ce72bd5d3..f364340f610 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -277,9 +277,9 @@ impl PrivateKernelCircuitOutputValidator { array_lengths.nullifier_read_requests ); validate_array_prepended( - self.output.validation_requests.key_validation_requests, - previous_kernel.validation_requests.key_validation_requests, - array_lengths.key_validation_requests + self.output.validation_requests.scoped_key_validation_requests_and_generators, + previous_kernel.validation_requests.scoped_key_validation_requests_and_generators, + array_lengths.scoped_key_validation_requests_and_generators ); validate_array_prepended( self.output.end.new_note_hashes, @@ -351,10 +351,10 @@ impl PrivateKernelCircuitOutputValidator { storage_contract_address ); validate_array_appended_scoped( - self.output.validation_requests.key_validation_requests, - private_call.key_validation_requests, - array_lengths.key_validation_requests, - offsets.key_validation_requests, + self.output.validation_requests.scoped_key_validation_requests_and_generators, + private_call.key_validation_requests_and_generators, + array_lengths.key_validation_requests_and_generators, + offsets.scoped_key_validation_requests_and_generators, storage_contract_address ); validate_array_appended_scoped( @@ -390,17 +390,19 @@ impl PrivateKernelCircuitOutputValidator { array_lengths.note_encrypted_logs_hashes, offsets.note_encrypted_logs_hashes ); - validate_array_appended( + validate_array_appended_scoped( self.output.end.encrypted_logs_hashes, private_call.encrypted_logs_hashes, array_lengths.encrypted_logs_hashes, - offsets.encrypted_logs_hashes + offsets.encrypted_logs_hashes, + storage_contract_address ); - validate_array_appended( + validate_array_appended_scoped( self.output.end.unencrypted_logs_hashes, private_call.unencrypted_logs_hashes, array_lengths.unencrypted_logs_hashes, - offsets.unencrypted_logs_hashes + offsets.unencrypted_logs_hashes, + storage_contract_address ); validate_array_appended_reversed_scoped( self.output.end.private_call_stack, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr index e1c43f9fd6b..db354e908d1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr @@ -34,10 +34,7 @@ struct PrivateKernelCircuitPublicInputsComposer { } impl PrivateKernelCircuitPublicInputsComposer { - pub fn new_from_tx_request( - tx_request: TxRequest, - private_call_public_inputs: PrivateCircuitPublicInputs - ) -> Self { + pub fn new_from_tx_request(tx_request: TxRequest, private_call_public_inputs: PrivateCircuitPublicInputs) -> Self { let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty(); public_inputs.constants = CombinedConstantData::private( diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr index 5a46d497193..12ea9825282 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr @@ -47,20 +47,17 @@ impl PrivateKernelCircuitOutputValidatorBuilder { } pub fn validate_as_first_call(self) { - let private_call = self.private_call.to_private_circuit_public_inputs(); - let public_call_requests = self.private_call.public_call_requests.storage; - let public_teardown_call_request = self.private_call.public_teardown_call_request; - let contract_address = self.private_call.contract_address; - let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call); + let private_call = self.private_call.to_private_call_data(); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); let output = self.output.to_private_kernel_circuit_public_inputs(); PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( self.tx_request, - private_call, + private_call.call_stack_item.public_inputs, array_lengths, - contract_address, + private_call.call_stack_item.contract_address, self.note_hash_nullifier_counters, - public_call_requests, - public_teardown_call_request + private_call.public_call_stack, + private_call.public_teardown_call_request ); } @@ -72,21 +69,18 @@ impl PrivateKernelCircuitOutputValidatorBuilder { previous_kernel.end.private_call_stack[num_private_call_requests].call_request.hash = 98765432; let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel); - let public_call_requests = self.private_call.public_call_requests.storage; - let public_teardown_call_request = self.private_call.public_teardown_call_request; - let private_call = self.private_call.to_private_circuit_public_inputs(); - let contract_address = self.private_call.contract_address; - let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call); + let private_call = self.private_call.to_private_call_data(); + let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); let output = self.output.to_private_kernel_circuit_public_inputs(); PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( previous_kernel, previous_kernel_array_lengths, - private_call, + private_call.call_stack_item.public_inputs, private_call_array_lengths, - contract_address, + private_call.call_stack_item.contract_address, self.note_hash_nullifier_counters, - public_call_requests, - public_teardown_call_request + private_call.public_call_stack, + private_call.public_teardown_call_request ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr index f6aa54e8d20..025b987257f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr @@ -125,7 +125,7 @@ fn validate_aggregated_values_public_teardown_call_request_from_previous_mismatc builder.previous_kernel.append_public_teardown_call_request(); builder.output.append_public_teardown_call_request(); // Tweak the output. - builder.output.public_teardown_call_request.hash += 1; + builder.output.public_teardown_call_stack.storage[0].hash += 1; builder.validate_as_inner_call(); } @@ -137,7 +137,7 @@ fn validate_aggregated_values_public_teardown_call_request_from_private_call_mis builder.private_call.append_public_teardown_call_request(); builder.output.append_public_teardown_call_request(); // Tweak the output. - builder.output.public_teardown_call_request.hash += 1; + builder.output.public_teardown_call_stack.storage[0].hash += 1; builder.validate_as_inner_call(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr index 7e6837d5efd..335a0532056 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_initial_values.nr @@ -165,7 +165,7 @@ fn validate_initial_values_public_teardown_call_request_mismatch_fails() { builder.private_call.append_public_teardown_call_request(); builder.output.append_public_teardown_call_request(); // Tweak the output. - builder.output.public_teardown_call_request.hash += 1; + builder.output.public_teardown_call_stack.storage[0].hash += 1; builder.validate_as_first_call(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index 81291013130..20fd77b4bf7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -108,15 +108,15 @@ fn new_from_previous_kernel_with_private_call_key_validation_requests_succeeds() let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); builder.previous_kernel.append_key_validation_requests(2); - let prev = builder.previous_kernel.key_validation_requests.storage; + let prev = builder.previous_kernel.scoped_key_validation_requests_and_generators.storage; builder.private_call.append_key_validation_requests(2); - let curr = builder.private_call.key_validation_requests.storage; + let curr = builder.private_call.scoped_key_validation_requests_and_generators.storage; let output = builder.compose_from_previous_kernel(); assert( array_eq( - output.validation_requests.key_validation_requests, + output.validation_requests.scoped_key_validation_requests_and_generators, [prev[0], prev[1], curr[0], curr[1]] ) ); @@ -295,7 +295,7 @@ fn new_from_previous_kernel_with_private_call_public_teardown_call_request_succe let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); builder.private_call.append_public_teardown_call_request(); - let request = builder.private_call.public_teardown_call_request; + let request = builder.private_call.public_teardown_call_stack.storage[0]; let output = builder.compose_from_previous_kernel(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index e7788ae8d3f..486629ce07f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -78,13 +78,13 @@ fn propagate_from_private_call_key_validation_requests_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); builder.private_call.append_key_validation_requests(2); - let res = builder.private_call.key_validation_requests.storage; + let res = builder.private_call.scoped_key_validation_requests_and_generators.storage; let output = builder.compose_from_tx_request(); assert( array_eq( - output.validation_requests.key_validation_requests, + output.validation_requests.scoped_key_validation_requests_and_generators, [res[0], res[1]] ) ); @@ -220,7 +220,7 @@ fn propagate_from_private_call_public_teardown_call_request_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); builder.private_call.append_public_teardown_call_request(); - let res = builder.private_call.public_teardown_call_request; + let res = builder.private_call.public_teardown_call_stack.storage[0]; let output = builder.compose_from_tx_request(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr index 3ab35596224..7f74e4664c8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr @@ -10,7 +10,7 @@ use crate::address::AztecAddress; struct PrivateKernelCircuitPublicInputsArrayLengths { note_hash_read_requests: u64, nullifier_read_requests: u64, - key_validation_requests: u64, + scoped_key_validation_requests_and_generators: u64, new_note_hashes: u64, new_nullifiers: u64, new_l2_to_l1_msgs: u64, @@ -26,7 +26,7 @@ impl PrivateKernelCircuitPublicInputsArrayLengths { PrivateKernelCircuitPublicInputsArrayLengths { note_hash_read_requests: array_length(public_inputs.validation_requests.note_hash_read_requests), nullifier_read_requests: array_length(public_inputs.validation_requests.nullifier_read_requests), - key_validation_requests: array_length(public_inputs.validation_requests.key_validation_requests), + scoped_key_validation_requests_and_generators: array_length(public_inputs.validation_requests.scoped_key_validation_requests_and_generators), new_note_hashes: array_length(public_inputs.end.new_note_hashes), new_nullifiers: array_length(public_inputs.end.new_nullifiers), new_l2_to_l1_msgs: array_length(public_inputs.end.new_l2_to_l1_msgs), @@ -42,7 +42,7 @@ impl PrivateKernelCircuitPublicInputsArrayLengths { PrivateKernelCircuitPublicInputsArrayLengths { note_hash_read_requests: 0, nullifier_read_requests: 0, - key_validation_requests: 0, + scoped_key_validation_requests_and_generators: 0, new_note_hashes: 0, new_nullifiers: 0, new_l2_to_l1_msgs: 0, @@ -59,7 +59,7 @@ impl Eq for PrivateKernelCircuitPublicInputsArrayLengths { fn eq(self, other: Self) -> bool { (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) & - (self.key_validation_requests == other.key_validation_requests) & + (self.scoped_key_validation_requests_and_generators == other.scoped_key_validation_requests_and_generators) & (self.new_note_hashes == other.new_note_hashes) & (self.new_nullifiers == other.new_nullifiers) & (self.new_l2_to_l1_msgs == other.new_l2_to_l1_msgs) & diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr index 9d7d5646c4b..c212bd06385 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr @@ -1,5 +1,5 @@ use crate::{ - abis::side_effect::{Ordered, OrderedValue}, address::AztecAddress, + abis::side_effect::{Ordered, OrderedValue, Scoped}, address::AztecAddress, constants::{ LOG_HASH_LENGTH, NOTE_LOG_HASH_LENGTH, ENCRYPTED_LOG_HASH_LENGTH, SCOPED_LOG_HASH_LENGTH, SCOPED_ENCRYPTED_LOG_HASH_LENGTH @@ -73,6 +73,15 @@ struct ScopedLogHash { contract_address: AztecAddress, } +impl Scoped for ScopedLogHash { + fn inner(self) -> LogHash { + self.log_hash + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl Ordered for ScopedLogHash { fn counter(self) -> u32 { self.log_hash.counter @@ -192,6 +201,15 @@ struct ScopedEncryptedLogHash { contract_address: AztecAddress, } +impl Scoped for ScopedEncryptedLogHash { + fn inner(self) -> EncryptedLogHash { + self.log_hash + } + fn contract_address(self) -> AztecAddress { + self.contract_address + } +} + impl ScopedEncryptedLogHash { pub fn expose_to_public(self) -> LogHash { // Hide the secret randomness and counter when exposing to public diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index e4a14021fbc..193be2df5ac 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -201,7 +201,7 @@ impl FixtureBuilder { new_nullifiers: subarray(self.new_nullifiers.storage.map(|n: ScopedNullifier| n.nullifier)), private_call_requests: subarray(self.private_call_requests.storage.map(|r: ScopedPrivateCallRequest| r.call_request)), public_call_stack_hashes: subarray(self.public_call_requests.storage.map(|c: CallRequest| c.hash)), - public_teardown_function_hash: self.public_teardown_call_stack.get(0).hash, + public_teardown_function_hash: self.public_teardown_call_stack.storage[0].hash, new_l2_to_l1_msgs: subarray(self.new_l2_to_l1_msgs.storage.map(|r: ScopedL2ToL1Message| r.message)), start_side_effect_counter: self.counter_start, end_side_effect_counter: self.counter, @@ -225,7 +225,7 @@ impl FixtureBuilder { PrivateCallData { call_stack_item: self.to_private_call_stack_item(), public_call_stack: subarray(self.public_call_requests.storage), - public_teardown_call_request: self.public_teardown_call_stack.get(0), + public_teardown_call_request: self.public_teardown_call_stack.storage[0], proof: RecursiveProof::empty(), vk: self.vk, function_leaf_membership_witness: self.function_leaf_membership_witness, From 5a5bbd88f7c92b2f0998d050f2c0f958ca4956b7 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 24 May 2024 18:02:54 +0000 Subject: [PATCH 04/13] Update tests. --- ...private_kernel_circuit_output_validator.nr | 2 - ...e_kernel_circuit_public_inputs_composer.nr | 11 +- .../src/private_kernel_init.nr | 31 +--- .../src/private_kernel_inner.nr | 14 +- .../src/private_kernel_reset.nr | 18 +- .../src/private_kernel_tail.nr | 14 +- .../src/private_kernel_tail_to_public.nr | 8 +- ...alidate_propagated_from_previous_kernel.nr | 86 ++++----- .../validate_propagated_from_private_call.nr | 98 +++++----- ..._circuit_public_inputs_composer_builder.nr | 6 +- ..._from_previous_kernel_with_private_call.nr | 170 +++++++++++------- .../propagate_from_private_call.nr | 128 +++++++++---- .../src/public_kernel_app_logic.nr | 6 +- .../src/public_kernel_setup.nr | 4 +- .../src/public_kernel_tail.nr | 6 +- .../src/public_kernel_teardown.nr | 4 +- .../crates/types/src/tests.nr | 1 + .../crates/types/src/tests/fixture_builder.nr | 93 +++++++--- .../crates/types/src/tests/utils.nr | 20 +++ .../crates/types/src/utils/arrays.nr | 1 + 20 files changed, 433 insertions(+), 288 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/tests/utils.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index f364340f610..3affcb06b2c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -122,8 +122,6 @@ fn validate_note_hash_nullifier_counters( } } -fn validate_appended_public_call_requests() {} - struct PrivateKernelCircuitOutputValidator { output: PrivateKernelCircuitPublicInputs, } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr index db354e908d1..9657d55f051 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr @@ -202,6 +202,7 @@ impl PrivateKernelCircuitPublicInputsComposer { self.public_inputs.end.encrypted_logs_hashes.push(log.scope(source.storage_contract_address)); } } + let unencrypted_logs = source.private_call_public_inputs.unencrypted_logs_hashes; for i in 0..unencrypted_logs.len() { let log = unencrypted_logs[i]; @@ -211,15 +212,13 @@ impl PrivateKernelCircuitPublicInputsComposer { } let note_logs = source.private_call_public_inputs.note_encrypted_logs_hashes; + let new_note_hashes = self.public_inputs.end.new_note_hashes; for i in 0..note_logs.len() { if !is_empty(note_logs[i]) { let note_index = self.match_log_to_note(note_logs[i]); - assert( - note_index < MAX_NEW_NOTE_HASHES_PER_TX, "Could not find note hash linked to note log." - ); - assert( - note_logs[i].note_hash_counter - == self.public_inputs.end.new_note_hashes.get_unchecked(note_index).counter(), "Could not find note hash linked to note log." + assert(note_index < new_note_hashes.len(), "Could not find note hash linked to note log"); + assert_eq( + note_logs[i].note_hash_counter, new_note_hashes.get_unchecked(note_index).counter(), "Could not find note hash linked to note log" ); self.public_inputs.end.note_encrypted_logs_hashes.push(note_logs[i]); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 2641ddd34ff..c87724a8424 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -77,11 +77,11 @@ mod tests { use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - log_hash::{NoteLogHash, ScopedEncryptedLogHash, ScopedLogHash} + log_hash::{ScopedEncryptedLogHash, ScopedLogHash} }, constants::MAX_NEW_NOTE_HASHES_PER_CALL, - tests::private_call_data_builder::PrivateCallDataBuilder, transaction::tx_request::TxRequest, - utils::arrays::array_eq + tests::{private_call_data_builder::PrivateCallDataBuilder, utils::assert_array_eq}, + transaction::tx_request::TxRequest }; struct PrivateKernelInitInputsBuilder { @@ -145,26 +145,13 @@ mod tests { // Check the first nullifier is hash of the signed tx request let tx_hash = builder.tx_request.hash(); assert_eq(public_inputs.end.new_nullifiers[0].value(), tx_hash); - assert( - array_eq( - public_inputs.end.encrypted_logs_hashes.map(|l: ScopedEncryptedLogHash| l.log_hash), - expected_encrypted_logs - ) + assert_array_eq( + public_inputs.end.encrypted_logs_hashes.map(|l: ScopedEncryptedLogHash| l.log_hash), + expected_encrypted_logs ); - assert( - array_eq( - public_inputs.end.unencrypted_logs_hashes.map(|l: ScopedLogHash| l.log_hash), - expected_unencrypted_logs - ) + assert_array_eq( + public_inputs.end.unencrypted_logs_hashes.map(|l: ScopedLogHash| l.log_hash), + expected_unencrypted_logs ); } - - #[test(should_fail_with = "Could not find note hash linked to note log.")] - fn input_validation_note_log_not_linked() { - let mut builder = PrivateKernelInitInputsBuilder::new(); - - builder.private_call.public_inputs.note_encrypted_logs_hashes.extend_from_array([NoteLogHash { value: 9123, counter: 2, length: 2, note_hash_counter: 1 }]); - - builder.failed(); - } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index fdabe13d00c..92c731e6670 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -121,7 +121,7 @@ mod tests { builder.private_call.public_inputs.append_new_note_hashes(1); // Mock the previous new note hashes to be full, therefore no more note_hashes can be added. - builder.previous_kernel.append_new_note_hashes(MAX_NEW_NOTE_HASHES_PER_TX, false); + builder.previous_kernel.append_new_note_hashes(MAX_NEW_NOTE_HASHES_PER_TX); builder.failed(); } @@ -225,8 +225,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); @@ -254,14 +254,6 @@ mod tests { ); } - #[test(should_fail_with = "Could not find note hash linked to note log.")] - unconstrained fn input_validation_note_log_not_linked() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - - builder.private_call.public_inputs.note_encrypted_logs_hashes.push(NoteLogHash { value: 9123, counter: 2, length: 2, note_hash_counter: 1 }); - builder.failed(); - } - #[test] unconstrained fn propagate_fee_payer_init_succeeds() { let mut builder = PrivateKernelInnerInputsBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index 4fa9d86d323..2b135ac37b2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -213,7 +213,7 @@ mod tests { unconstrained fn two_pending_note_hash_read_request() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, false); + builder.previous_kernel.append_new_note_hashes(3); builder.add_pending_note_hash_read_request(1); builder.add_pending_note_hash_read_request(0); @@ -224,7 +224,7 @@ mod tests { unconstrained fn pending_note_hash_read_request_wrong_hint_fails() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, false); + builder.previous_kernel.append_new_note_hashes(3); builder.add_pending_note_hash_read_request(1); let mut hint = builder.note_hash_read_request_hints_builder.pending_read_hints.pop(); hint.pending_value_index = 2; @@ -286,7 +286,7 @@ mod tests { unconstrained fn propagates_unverified_requests() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, false); + builder.previous_kernel.append_new_note_hashes(3); builder.previous_kernel.append_new_nullifiers(3); builder.add_pending_note_hash_read_request(0); @@ -313,7 +313,7 @@ mod tests { #[test] unconstrained fn native_squash_one_of_one_transient_matches_works() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(1, true); + builder.previous_kernel.append_new_note_hashes_with_logs(1); builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_pending_note_hash(1, 0); @@ -335,7 +335,7 @@ mod tests { #[test] unconstrained fn native_squash_one_of_two_transient_matches_works() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, true); + builder.previous_kernel.append_new_note_hashes_with_logs(2); builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_pending_note_hash(1, 0); @@ -367,7 +367,7 @@ mod tests { #[test] unconstrained fn native_squash_two_of_two_transient_matches_works() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, true); + builder.previous_kernel.append_new_note_hashes_with_logs(2); builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_pending_note_hash(1, 1); @@ -387,7 +387,7 @@ mod tests { unconstrained fn squash_unordered_transient_notes_works() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, true); + builder.previous_kernel.append_new_note_hashes_with_logs(3); // Shuffle the note hashes so they will have to be re-ordered. let tmp = builder.previous_kernel.new_note_hashes.storage[0]; builder.previous_kernel.new_note_hashes.storage[0] = builder.previous_kernel.new_note_hashes.storage[1]; @@ -421,7 +421,7 @@ mod tests { #[test(should_fail_with="Value of the hinted transient note hash does not match")] unconstrained fn wrong_transient_nullifier_index_for_note_hash_fails() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(1, false); + builder.previous_kernel.append_new_note_hashes(1); builder.previous_kernel.append_new_nullifiers(1); // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_pending_note_hash(1, 0); @@ -433,7 +433,7 @@ mod tests { #[test(should_fail_with="Invalid transient nullifier index hint")] unconstrained fn wrong_transient_nullifier_index_hint_fails() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_pending_note_hash(1, 1); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 5ddf32c92f1..d7e0aeaf765 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -88,7 +88,7 @@ mod tests { silo_nullifier, silo_unencrypted_log, silo_encrypted_log }, tests::{fixture_builder::FixtureBuilder, sort::sort_get_sorted_hints}, - utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array}, + utils::{arrays::array_length}, traits::{Empty, is_empty, is_empty_array}, grumpkin_point::GrumpkinPoint }; @@ -219,15 +219,15 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); // Logs for the current call stack. let unencrypted_logs_hash = 26; let unencrypted_log_preimages_length = 50; - builder.previous_kernel.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash(unencrypted_logs_hash, unencrypted_log_preimages_length); let public_inputs = builder.execute(); @@ -273,7 +273,7 @@ mod tests { unconstrained fn ordering_of_note_hashes_and_nullifiers() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(10, false); + builder.previous_kernel.append_new_note_hashes(10); builder.previous_kernel.append_new_nullifiers(10); let sorted_note_hashes = builder.previous_kernel.new_note_hashes.storage; @@ -303,7 +303,7 @@ mod tests { #[test] unconstrained fn native_empty_nullified_note_hash_means_persistent_nullifier_0() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); builder.previous_kernel.append_new_nullifiers(2); let public_inputs = builder.execute(); assert_eq(array_length(public_inputs.end.new_note_hashes), 2); @@ -336,7 +336,7 @@ mod tests { #[test(should_fail_with="Non empty note hash read requests")] unconstrained fn non_empty_note_hash_read_requests() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, false); + builder.previous_kernel.append_new_note_hashes(3); let _void = builder.previous_kernel.add_read_request_for_pending_note_hash(1); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index 0b420579552..4d03dd6eb20 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -208,7 +208,7 @@ mod tests { unconstrained fn ordering_of_note_hashes_and_nullifiers() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(10, false); + builder.previous_kernel.append_new_note_hashes(10); builder.previous_kernel.append_new_nullifiers(10); let sorted_note_hashes = builder.previous_kernel.new_note_hashes.storage; @@ -298,11 +298,11 @@ mod tests { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); // expect 2 non-revertible note hashes - builder.previous_kernel.append_new_note_hashes(2, true); + builder.previous_kernel.append_new_note_hashes_with_logs(2); builder.previous_kernel.end_setup(); // expect 2 revertible note hashes - builder.previous_kernel.append_new_note_hashes(2, true); + builder.previous_kernel.append_new_note_hashes_with_logs(2); let new_note_hashes = builder.previous_kernel.new_note_hashes.storage; let new_note_logs = builder.previous_kernel.note_encrypted_logs_hashes.storage; @@ -360,7 +360,7 @@ mod tests { #[test(should_fail_with="Non empty note hash read requests")] unconstrained fn non_empty_note_hash_read_requests() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel.append_new_note_hashes(3, false); + builder.previous_kernel.append_new_note_hashes(3); let _void = builder.previous_kernel.add_read_request_for_pending_note_hash(1); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr index 164111a2fbc..5116c29bcdf 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr @@ -134,8 +134,8 @@ fn validate_propagated_from_previous_kernel_key_validation_requests_less_than_fa fn validate_propagated_from_previous_kernel_new_note_hashes_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); - builder.output.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); + builder.output.append_new_note_hashes(2); builder.validate_as_inner_call(); } @@ -144,9 +144,9 @@ fn validate_propagated_from_previous_kernel_new_note_hashes_succeeds() { fn validate_propagated_from_previous_kernel_new_note_hashes_less_than_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); // Propagate 1 less item to the output. - builder.output.append_new_note_hashes(1, false); + builder.output.append_new_note_hashes(1); builder.validate_as_inner_call(); } @@ -202,79 +202,79 @@ fn validate_propagated_from_previous_kernel_new_l2_to_l1_msgs_less_than_fails() } /** - * note_encrypted_logs_hashes + * note_encrypted_log_hashes */ #[test] -fn validate_propagated_from_previous_kernel_note_encrypted_logs_hashes_succeeds() { +fn validate_propagated_from_previous_kernel_note_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.previous_kernel.append_note_encrypted_logs_hashes(2); - builder.output.append_note_encrypted_logs_hashes(2); + builder.previous_kernel.append_note_encrypted_log_hashes(2); + builder.output.append_note_encrypted_log_hashes(2); builder.validate_as_inner_call(); } #[test(should_fail_with="source item does not prepend to dest")] -fn validate_propagated_from_previous_kernel_note_encrypted_logs_hashes_less_than_fails() { +fn validate_propagated_from_previous_kernel_note_encrypted_log_hashes_less_than_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.previous_kernel.append_note_encrypted_logs_hashes(2); + builder.previous_kernel.append_note_encrypted_log_hashes(2); // Propagate 1 less item to the output. - builder.output.append_note_encrypted_logs_hashes(1); + builder.output.append_note_encrypted_log_hashes(1); builder.validate_as_inner_call(); } /** - * encrypted_logs_hashes + * encrypted_log_hashes */ -// #[test] -// fn validate_propagated_from_previous_kernel_encrypted_logs_hashes_succeeds() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test] +fn validate_propagated_from_previous_kernel_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.previous_kernel.append_encrypted_logs_hashes(2); -// builder.output.append_encrypted_logs_hashes(2); + builder.previous_kernel.append_encrypted_log_hashes(2); + builder.output.append_encrypted_log_hashes(2); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} -// #[test(should_fail_with="source item does not prepend to dest")] -// fn validate_propagated_from_previous_kernel_encrypted_logs_hashes_less_than_fails() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_encrypted_log_hashes_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.previous_kernel.append_encrypted_logs_hashes(2); -// // Propagate 1 less item to the output. -// builder.output.append_encrypted_logs_hashes(1); + builder.previous_kernel.append_encrypted_log_hashes(2); + // Propagate 1 less item to the output. + builder.output.append_encrypted_log_hashes(1); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} /** - * unencrypted_logs_hashes + * unencrypted_log_hashes */ -// #[test] -// fn validate_propagated_from_previous_kernel_unencrypted_logs_hashes_succeeds() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test] +fn validate_propagated_from_previous_kernel_unencrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.previous_kernel.append_unencrypted_logs_hashes(2); -// builder.output.append_unencrypted_logs_hashes(2); + builder.previous_kernel.append_unencrypted_log_hashes(2); + builder.output.append_unencrypted_log_hashes(2); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} -// #[test(should_fail_with="source item does not prepend to dest")] -// fn validate_propagated_from_previous_kernel_unencrypted_logs_hashes_less_than_fails() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test(should_fail_with="source item does not prepend to dest")] +fn validate_propagated_from_previous_kernel_unencrypted_log_hashes_less_than_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.previous_kernel.append_unencrypted_logs_hashes(2); -// // Propagate 1 less item to the output. -// builder.output.append_unencrypted_logs_hashes(1); + builder.previous_kernel.append_unencrypted_log_hashes(2); + // Propagate 1 less item to the output. + builder.output.append_unencrypted_log_hashes(1); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} /** * private_call_requests diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr index 68b704dff49..156a29154c1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr @@ -225,8 +225,8 @@ fn validate_propagated_from_private_call_key_validation_requests_output_one_more fn validate_propagated_from_private_call_new_note_hashes_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); - builder.output.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); + builder.output.append_new_note_hashes(2); builder.validate_as_inner_call(); } @@ -235,9 +235,9 @@ fn validate_propagated_from_private_call_new_note_hashes_succeeds() { fn validate_propagated_from_private_call_new_note_hashes_output_one_more_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); // Propagate 1 more item to the output. - builder.output.append_new_note_hashes(3, false); + builder.output.append_new_note_hashes(3); builder.validate_as_inner_call(); } @@ -251,7 +251,7 @@ fn validate_propagated_from_private_call_new_note_hashes_output_one_more_fails() fn validate_propagated_from_private_call_new_note_hashes_non_zero_nullifier_counters_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; @@ -271,11 +271,11 @@ fn validate_propagated_from_private_call_new_note_hashes_non_zero_nullifier_coun fn validate_propagated_from_private_call_new_note_hashes_with_previous_non_zero_nullifier_counters_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); - builder.output.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); + builder.output.append_new_note_hashes(2); builder.offset_values(2); // Offset the first 2 note hashes. - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; @@ -295,7 +295,7 @@ fn validate_propagated_from_private_call_new_note_hashes_with_previous_non_zero_ fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_too_small_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; // Tweak the nullifier counter to be less than the counter of the note hash. @@ -316,7 +316,7 @@ fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_too_ fn validate_propagated_from_private_call_new_note_hashes_nullifier_counters_mismatch_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let note_hashes = [builder.private_call.new_note_hashes.storage[0], builder.private_call.new_note_hashes.storage[1]]; builder.note_hash_nullifier_counters[0] = note_hashes[0].counter() + 10; builder.note_hash_nullifier_counters[1] = note_hashes[1].counter() + 35; @@ -386,79 +386,79 @@ fn validate_propagated_from_private_call_new_l2_to_l1_msgs_output_one_more_fails } /** - * note_encrypted_logs_hashes + * note_encrypted_log_hashes */ #[test] -fn validate_propagated_from_private_call_note_encrypted_logs_hashes_succeeds() { +fn validate_propagated_from_private_call_note_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_note_encrypted_logs_hashes(2); - builder.output.append_note_encrypted_logs_hashes(2); + builder.private_call.append_note_encrypted_log_hashes(2); + builder.output.append_note_encrypted_log_hashes(2); builder.validate_as_inner_call(); } #[test(should_fail_with="output should be appended with empty items")] -fn validate_propagated_from_private_call_note_encrypted_logs_hashes_output_one_more_fails() { +fn validate_propagated_from_private_call_note_encrypted_log_hashes_output_one_more_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - builder.private_call.append_note_encrypted_logs_hashes(2); + builder.private_call.append_note_encrypted_log_hashes(2); // Propagate 1 more item to the output. - builder.output.append_note_encrypted_logs_hashes(3); + builder.output.append_note_encrypted_log_hashes(3); builder.validate_as_inner_call(); } /** - * encrypted_logs_hashes + * encrypted_log_hashes */ -// #[test] -// fn validate_propagated_from_private_call_encrypted_logs_hashes_succeeds() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test] +fn validate_propagated_from_private_call_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.private_call.append_encrypted_logs_hashes(2); -// builder.output.append_encrypted_logs_hashes(2); + builder.private_call.append_encrypted_log_hashes(2); + builder.output.append_encrypted_log_hashes(2); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} -// #[test(should_fail_with="output should be appended with empty items")] -// fn validate_propagated_from_private_call_encrypted_logs_hashes_output_one_more_fails() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_encrypted_log_hashes_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.private_call.append_encrypted_logs_hashes(2); -// // Propagate 1 more item to the output. -// builder.output.append_encrypted_logs_hashes(3); + builder.private_call.append_encrypted_log_hashes(2); + // Propagate 1 more item to the output. + builder.output.append_encrypted_log_hashes(3); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} /** - * unencrypted_logs_hashes + * unencrypted_log_hashes */ -// #[test] -// fn validate_propagated_from_private_call_unencrypted_logs_hashes_succeeds() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test] +fn validate_propagated_from_private_call_unencrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.private_call.append_unencrypted_logs_hashes(2); -// builder.output.append_unencrypted_logs_hashes(2); + builder.private_call.append_unencrypted_log_hashes(2); + builder.output.append_unencrypted_log_hashes(2); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} -// #[test(should_fail_with="output should be appended with empty items")] -// fn validate_propagated_from_private_call_unencrypted_logs_hashes_output_one_more_fails() { -// let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); +#[test(should_fail_with="output should be appended with empty items")] +fn validate_propagated_from_private_call_unencrypted_log_hashes_output_one_more_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); -// builder.private_call.append_unencrypted_logs_hashes(2); -// // Propagate 1 more item to the output. -// builder.output.append_unencrypted_logs_hashes(3); + builder.private_call.append_unencrypted_log_hashes(2); + // Propagate 1 more item to the output. + builder.output.append_unencrypted_log_hashes(3); -// builder.validate_as_inner_call(); -// } + builder.validate_as_inner_call(); +} /** * private_call_requests diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr index 68ee112fe8c..368ffb8fd2f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr @@ -22,13 +22,11 @@ struct PrivateKernelCircuitPublicInputsComposerBuilder { impl PrivateKernelCircuitPublicInputsComposerBuilder { pub fn new() -> Self { - let previous_kernel = FixtureBuilder::new(); + let previous_kernel = FixtureBuilder::new_from_counter(17); - let mut private_call = FixtureBuilder::new(); + let mut private_call = FixtureBuilder::new_from_counter(203); // Add an offset to the mock values so that the data in the private call won't be the same as those in the previous kernel. private_call.value_offset = 9999; - private_call.counter_start = 666; - private_call.counter = 777; let tx_request = private_call.build_tx_request(); let note_hash_nullifier_counters = [0; MAX_NEW_NOTE_HASHES_PER_CALL]; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index 20fd77b4bf7..d4dab26bce0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -1,7 +1,7 @@ use crate::{tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder}; use dep::types::{ abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, - utils::arrays::array_eq + tests::utils::assert_array_eq }; #[test] @@ -76,11 +76,9 @@ fn new_from_previous_kernel_with_private_call_note_hash_read_requests_succeeds() let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.validation_requests.note_hash_read_requests, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.validation_requests.note_hash_read_requests, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -95,11 +93,9 @@ fn new_from_previous_kernel_with_private_call_nullifier_read_requests_succeeds() let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.validation_requests.nullifier_read_requests, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.validation_requests.nullifier_read_requests, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -114,11 +110,9 @@ fn new_from_previous_kernel_with_private_call_key_validation_requests_succeeds() let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.validation_requests.scoped_key_validation_requests_and_generators, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.validation_requests.scoped_key_validation_requests_and_generators, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -126,18 +120,16 @@ fn new_from_previous_kernel_with_private_call_key_validation_requests_succeeds() fn new_from_previous_kernel_with_private_call_new_note_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); let prev = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let curr = builder.private_call.new_note_hashes.storage; let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.end.new_note_hashes, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -145,9 +137,9 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_succeeds() { fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); let prev = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let mut curr = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; @@ -156,11 +148,9 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_cou curr[0].nullifier_counter = curr[0].counter() + 10; curr[1].nullifier_counter = curr[1].counter() + 75; - assert( - array_eq( - output.end.new_note_hashes, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -168,9 +158,9 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_cou fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); let prev = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let mut curr = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; builder.note_hash_nullifier_counters[1] = curr[1].counter() + 75; @@ -181,11 +171,9 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_cou curr[0].nullifier_counter = curr[0].counter() + 10; curr[1].nullifier_counter = curr[1].counter() + 75; - assert( - array_eq( - output.end.new_note_hashes, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.end.new_note_hashes, + [prev[0], prev[1], curr[0], curr[1]] ); // The extra counter won't be propagated. assert_eq(output.end.new_note_hashes[4].nullifier_counter, 0); @@ -195,9 +183,9 @@ fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_cou fn new_from_previous_kernel_with_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.previous_kernel.append_new_note_hashes(2, false); + builder.previous_kernel.append_new_note_hashes(2); let _ = builder.previous_kernel.new_note_hashes.storage; - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let curr = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = curr[0].counter() + 10; // Tweak the nullifier counter to be less than the note hash counter. @@ -217,11 +205,9 @@ fn new_from_previous_kernel_with_private_call_new_nullifiers_succeeds() { let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.end.new_nullifiers, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.end.new_nullifiers, + [prev[0], prev[1], curr[0], curr[1]] ); } @@ -236,20 +222,82 @@ fn new_from_previous_kernel_with_private_call_new_l2_to_l1_msgs_succeeds() { let output = builder.compose_from_previous_kernel(); - assert(array_eq(output.end.new_l2_to_l1_msgs, [prev[0], curr[0]])); + assert_array_eq(output.end.new_l2_to_l1_msgs, [prev[0], curr[0]]); } -// #[test] -// fn new_from_previous_kernel_with_private_call_logs_succeeds() { -// let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); +#[test] +fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes_with_logs(2); + let prev = builder.previous_kernel.note_encrypted_logs_hashes.storage; + builder.private_call.append_new_note_hashes_with_logs(2); + let curr = builder.private_call.note_encrypted_logs_hashes.storage; + + let output = builder.compose_from_previous_kernel(); + + assert_array_eq( + output.end.note_encrypted_logs_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ); +} + +#[test(should_fail_with="Could not find note hash linked to note log")] +fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_zero_note_hash_counter_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); -// builder.private_call.append_logs(2); -// let res = builder.private_call.logs.storage; + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to be 0. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter = 0; -// let output = builder.compose_from_previous_kernel(); + let _ = builder.compose_from_previous_kernel(); +} + +#[test(should_fail_with="Could not find note hash linked to note log")] +fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_random_note_hash_counter_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_new_note_hashes_with_logs(2); + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to not match any note hash's counter. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter += 100; + + let _ = builder.compose_from_previous_kernel(); +} -// assert(array_eq(output.end.logs, [res[0], res[1]])); -// } +#[test] +fn new_from_previous_kernel_with_private_call_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_encrypted_log_hashes(2); + let prev = builder.previous_kernel.encrypted_logs_hashes.storage; + builder.private_call.append_encrypted_log_hashes(2); + let curr = builder.private_call.encrypted_logs_hashes.storage; + + let output = builder.compose_from_previous_kernel(); + + assert_array_eq( + output.end.encrypted_logs_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ); +} + +#[test] +fn new_from_previous_kernel_with_private_call_unencrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.append_unencrypted_log_hashes(2); + let prev = builder.previous_kernel.unencrypted_logs_hashes.storage; + builder.private_call.append_unencrypted_log_hashes(2); + let curr = builder.private_call.unencrypted_logs_hashes.storage; + + let output = builder.compose_from_previous_kernel(); + + assert_array_eq( + output.end.unencrypted_logs_hashes, + [prev[0], prev[1], curr[0], curr[1]] + ); +} #[test] fn new_from_previous_kernel_with_private_call_private_call_requests_succeeds() { @@ -263,11 +311,9 @@ fn new_from_previous_kernel_with_private_call_private_call_requests_succeeds() { let output = builder.compose_from_previous_kernel(); // Call requests from private call will be propagated in reversed order. - assert( - array_eq( - output.end.private_call_stack, - [prev[1], prev[0], curr[1], curr[0]] - ) + assert_array_eq( + output.end.private_call_stack, + [prev[1], prev[0], curr[1], curr[0]] ); } @@ -282,11 +328,9 @@ fn new_from_previous_kernel_with_private_call_public_call_requests_succeeds() { let output = builder.compose_from_previous_kernel(); - assert( - array_eq( - output.end.public_call_stack, - [prev[0], prev[1], curr[0], curr[1]] - ) + assert_array_eq( + output.end.public_call_stack, + [prev[0], prev[1], curr[0], curr[1]] ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index 486629ce07f..467356c8425 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -4,7 +4,7 @@ use crate::{ }; use dep::types::{ abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, - utils::arrays::array_eq + tests::utils::assert_array_eq }; #[test] @@ -48,11 +48,9 @@ fn propagate_from_private_call_note_hash_read_requests_succeeds() { let output = builder.compose_from_tx_request(); - assert( - array_eq( - output.validation_requests.note_hash_read_requests, - [res[0], res[1]] - ) + assert_array_eq( + output.validation_requests.note_hash_read_requests, + [res[0], res[1]] ); } @@ -65,11 +63,9 @@ fn propagate_from_private_call_nullifier_read_requests_succeeds() { let output = builder.compose_from_tx_request(); - assert( - array_eq( - output.validation_requests.nullifier_read_requests, - [res[0], res[1]] - ) + assert_array_eq( + output.validation_requests.nullifier_read_requests, + [res[0], res[1]] ); } @@ -82,11 +78,9 @@ fn propagate_from_private_call_key_validation_requests_succeeds() { let output = builder.compose_from_tx_request(); - assert( - array_eq( - output.validation_requests.scoped_key_validation_requests_and_generators, - [res[0], res[1]] - ) + assert_array_eq( + output.validation_requests.scoped_key_validation_requests_and_generators, + [res[0], res[1]] ); } @@ -94,19 +88,19 @@ fn propagate_from_private_call_key_validation_requests_succeeds() { fn propagate_from_private_call_new_note_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let res = builder.private_call.new_note_hashes.storage; let output = builder.compose_from_tx_request(); - assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); + assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); } #[test] fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let mut res = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; @@ -115,14 +109,14 @@ fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_succeeds( res[0].nullifier_counter = res[0].counter() + 10; res[1].nullifier_counter = res[1].counter() + 75; - assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); + assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); } #[test] fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_more_hints_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let mut res = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; builder.note_hash_nullifier_counters[1] = res[1].counter() + 75; @@ -133,7 +127,7 @@ fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_more_hint res[0].nullifier_counter = res[0].counter() + 10; res[1].nullifier_counter = res[1].counter() + 75; - assert(array_eq(output.end.new_note_hashes, [res[0], res[1]])); + assert_array_eq(output.end.new_note_hashes, [res[0], res[1]]); // The extra counter won't be propagated. assert_eq(output.end.new_note_hashes[2].nullifier_counter, 0); } @@ -142,7 +136,7 @@ fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_more_hint fn propagate_from_private_call_new_note_hashes_with_nullifier_counters_less_than_fails() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.private_call.append_new_note_hashes(2, false); + builder.private_call.append_new_note_hashes(2); let mut res = builder.private_call.new_note_hashes.storage; builder.note_hash_nullifier_counters[0] = res[0].counter() + 10; // Tweak the nullifier counter to be less than the note hash counter. @@ -163,7 +157,7 @@ fn propagate_from_private_call_new_nullifiers_succeeds() { let output = builder.compose_from_tx_request(); - assert(array_eq(output.end.new_nullifiers, [first_nullifier, res[0], res[1]])); + assert_array_eq(output.end.new_nullifiers, [first_nullifier, res[0], res[1]]); } #[test] @@ -175,20 +169,84 @@ fn propagate_from_private_call_new_l2_to_l1_msgs_succeeds() { let output = builder.compose_from_tx_request(); - assert(array_eq(output.end.new_l2_to_l1_msgs, [res[0], res[1]])); + assert_array_eq(output.end.new_l2_to_l1_msgs, [res[0], res[1]]); } -// #[test] -// fn propagate_from_private_call_logs_succeeds() { -// let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); +#[test] +fn propagate_from_private_call_note_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + let res = builder.private_call.note_encrypted_logs_hashes.storage; -// builder.private_call.append_logs(2); -// let res = builder.private_call.logs.storage; + let output = builder.compose_from_tx_request(); + + assert_array_eq(output.end.note_encrypted_logs_hashes, [res[0], res[1]]); +} -// let output = builder.compose_from_tx_request(); +#[test] +fn propagate_from_private_call_note_encrypted_log_hashes_extra_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + let note_hashes = builder.private_call.new_note_hashes.storage; + // Add an extra log hash for the note at index 1. + builder.private_call.add_note_encrypted_log_hash(123, 2, note_hashes[1].counter()); + let res = builder.private_call.note_encrypted_logs_hashes.storage; + + let output = builder.compose_from_tx_request(); -// assert(array_eq(output.end.logs, [res[0], res[1]])); -// } + assert_array_eq( + output.end.note_encrypted_logs_hashes, + [res[0], res[1], res[2]] + ); +} + +#[test(should_fail_with="Could not find note hash linked to note log")] +fn propagate_from_private_call_note_encrypted_log_hashes_zero_note_hash_counter_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to be 0. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter = 0; + + let _ = builder.compose_from_tx_request(); +} + +#[test(should_fail_with="Could not find note hash linked to note log")] +fn propagate_from_private_call_note_encrypted_log_hashes_random_note_hash_counter_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to not match any note hash's counter. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter += 100; + + let _ = builder.compose_from_tx_request(); +} + +#[test] +fn propagate_from_private_call_encrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_encrypted_log_hashes(2); + let res = builder.private_call.encrypted_logs_hashes.storage; + + let output = builder.compose_from_tx_request(); + + assert_array_eq(output.end.encrypted_logs_hashes, [res[0], res[1]]); +} + +#[test] +fn propagate_from_private_call_unencrypted_log_hashes_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.append_unencrypted_log_hashes(2); + let res = builder.private_call.unencrypted_logs_hashes.storage; + + let output = builder.compose_from_tx_request(); + + assert_array_eq(output.end.unencrypted_logs_hashes, [res[0], res[1]]); +} #[test] fn propagate_from_private_call_private_call_requests_succeeds() { @@ -200,7 +258,7 @@ fn propagate_from_private_call_private_call_requests_succeeds() { let output = builder.compose_from_tx_request(); // Call requests will be propagated in reversed order. - assert(array_eq(output.end.private_call_stack, [res[1], res[0]])); + assert_array_eq(output.end.private_call_stack, [res[1], res[0]]); } #[test] @@ -212,7 +270,7 @@ fn propagate_from_private_call_public_call_requests_succeeds() { let output = builder.compose_from_tx_request(); - assert(array_eq(output.end.public_call_stack, [res[0], res[1]])); + assert_array_eq(output.end.public_call_stack, [res[0], res[1]]); } #[test] diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr index e759f6d1fc1..bceaef1c5b5 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -210,7 +210,7 @@ mod tests { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); let contract_address = builder.public_call.contract_address; // Setup 2 new note hashes and logs on the previous kernel. - builder.previous_kernel.append_new_note_hashes(2, true); + builder.previous_kernel.append_new_note_hashes_with_logs(2); let previous = builder.previous_kernel.new_note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash); // Setup 2 new note hashes on the current public inputs. let current = [ @@ -337,8 +337,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr index 716b9710e90..a1dbe2d7e5c 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -443,8 +443,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index c37458ea749..f9858be4b94 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -328,15 +328,15 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_revertible.set_unencrypted_logs( + builder.previous_revertible.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_revertible.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); // Logs for the current call stack. let unencrypted_logs_hash = 26; let unencrypted_log_preimages_length = 50; - builder.previous_revertible.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + builder.previous_revertible.add_unencrypted_log_hash(unencrypted_logs_hash, unencrypted_log_preimages_length); let public_inputs = builder.execute(); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr index 951c70283ba..63be4f85b32 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr @@ -427,8 +427,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr index 4b5d7263f39..92712d66571 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr @@ -6,3 +6,4 @@ mod private_circuit_public_inputs_builder; mod public_call_data_builder; mod public_circuit_public_inputs_builder; mod sort; +mod utils; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 193be2df5ac..345356f723d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -135,6 +135,10 @@ struct FixtureBuilder { impl FixtureBuilder { pub fn new() -> Self { + FixtureBuilder::new_from_counter(0) + } + + pub fn new_from_counter(counter_start: u32) -> Self { let mut builder = FixtureBuilder::empty(); let contract_data = fixtures::contracts::default_contract; @@ -151,7 +155,8 @@ impl FixtureBuilder { builder.contract_class_artifact_hash = contract_data.artifact_hash; builder.contract_class_public_bytecode_commitment = contract_data.public_bytecode_commitment; builder.acir_hash = contract_function.acir_hash; - builder.counter = 1; + builder.counter_start = counter_start; + builder.counter = counter_start + 1; builder } @@ -381,19 +386,26 @@ impl FixtureBuilder { self.new_note_hashes.push( NoteHash { value, counter: self.next_counter() }.scope(nullifier_counter, self.storage_contract_address) ); - self.note_encrypted_log_preimages_length += 64; } - pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u64, broadcast: bool) { + pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u64) { let index_offset = self.new_note_hashes.len(); for i in 0..self.new_note_hashes.max_len() { if i < num_new_note_hashes { let value = self.mock_note_hash_value(index_offset + i); self.add_new_note_hash(value, 0); - if (broadcast) { - let log_hash = self.mock_note_encrypted_log_hash(index_offset + i); - self.add_note_encrypted_log_hash(log_hash, self.counter - 1); - } + } + } + } + + pub fn append_new_note_hashes_with_logs(&mut self, num_new_note_hashes: u64) { + let index_offset = self.new_note_hashes.len(); + for i in 0..self.new_note_hashes.max_len() { + if i < num_new_note_hashes { + let value = self.mock_note_hash_value(index_offset + i); + self.add_new_note_hash(value, 0); + let (log_hash, length) = self.mock_note_encrypted_log(index_offset + i); + self.add_note_encrypted_log_hash(log_hash, length, self.counter - 1); } } } @@ -541,31 +553,52 @@ impl FixtureBuilder { } } - pub fn add_note_encrypted_log_hash(&mut self, value: Field, note_hash_counter: u32) { - self.note_encrypted_logs_hashes.push(NoteLogHash { value, counter: self.next_counter(), length: 64, note_hash_counter }); - self.encrypted_log_preimages_length += 64; + pub fn add_note_encrypted_log_hash(&mut self, value: Field, length: Field, note_hash_counter: u32) { + let log_hash = NoteLogHash { value, counter: self.next_counter(), length, note_hash_counter }; + self.note_encrypted_logs_hashes.push(log_hash); + self.encrypted_log_preimages_length += length; } - pub fn append_note_encrypted_logs_hashes(&mut self, num: u64) { + pub fn append_note_encrypted_log_hashes(&mut self, num: u64) { let index_offset = self.note_encrypted_logs_hashes.len(); for i in 0..self.note_encrypted_logs_hashes.max_len() { if i < num { - let log_hash = self.mock_note_encrypted_log_hash(index_offset + i); - self.add_note_encrypted_log_hash(log_hash, 0); + let (log_hash, length) = self.mock_note_encrypted_log(index_offset + i); + self.add_note_encrypted_log_hash(log_hash, length, 0); } } } - pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { - let side_effect = EncryptedLogHash { value: hash, counter: self.next_counter(), length: preimages_length, randomness: 2 }; - self.encrypted_logs_hashes.push(side_effect.scope(self.storage_contract_address)); - self.encrypted_log_preimages_length += preimages_length; + pub fn add_encrypted_log_hash(&mut self, hash: Field, length: Field) { + let log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }; + self.encrypted_logs_hashes.push(log_hash.scope(self.storage_contract_address)); + self.encrypted_log_preimages_length += length; } - pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { - let side_effect = LogHash { value: hash, counter: self.next_counter(), length: preimages_length }; - self.unencrypted_logs_hashes.push(side_effect.scope(self.storage_contract_address)); - self.unencrypted_log_preimages_length += preimages_length; + pub fn append_encrypted_log_hashes(&mut self, num: u64) { + let index_offset = self.encrypted_logs_hashes.len(); + for i in 0..self.encrypted_logs_hashes.max_len() { + if i < num { + let (log_hash, length) = self.mock_encrypted_log(index_offset + i); + self.add_encrypted_log_hash(log_hash, length); + } + } + } + + pub fn add_unencrypted_log_hash(&mut self, hash: Field, length: Field) { + let log_hash = LogHash { value: hash, counter: self.next_counter(), length }; + self.unencrypted_logs_hashes.push(log_hash.scope(self.storage_contract_address)); + self.unencrypted_log_preimages_length += length; + } + + pub fn append_unencrypted_log_hashes(&mut self, num: u64) { + let index_offset = self.unencrypted_logs_hashes.len(); + for i in 0..self.unencrypted_logs_hashes.max_len() { + if i < num { + let (log_hash, length) = self.mock_unencrypted_log(index_offset + i); + self.add_unencrypted_log_hash(log_hash, length); + } + } } pub fn set_encrypted_logs_hash(&mut self, hash: Field, preimages_length: Field) { @@ -704,8 +737,22 @@ impl FixtureBuilder { (value_offset, EthAddress::from_field(1 + value_offset)) } - fn mock_note_encrypted_log_hash(self, index: u64) -> Field { - 282828 + self.value_offset + index as Field + fn mock_note_encrypted_log(self, index: u64) -> (Field, Field) { + let log_hash = 282828 + self.value_offset + index as Field; + let length = 5 + index as Field; + (log_hash, length) + } + + fn mock_encrypted_log(self, index: u64) -> (Field, Field) { + let log_hash = 50403 + self.value_offset + index as Field; + let length = 3 + index as Field; + (log_hash, length) + } + + fn mock_unencrypted_log(self, index: u64) -> (Field, Field) { + let log_hash = 199199 + self.value_offset + index as Field; + let length = 1 + index as Field; + (log_hash, length) } fn mock_private_call_request_hash(self, index: u64) -> Field { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/utils.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/utils.nr new file mode 100644 index 00000000000..8b4fc27bbd2 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/utils.nr @@ -0,0 +1,20 @@ +use dep::std::cmp::Eq; +use crate::traits::{Empty, is_empty}; + +fn count_non_empty_elements(array: [T; N]) -> u64 where T: Empty + Eq { + let mut length = 0; + for elem in array { + if !is_empty(elem) { + length += 1; + } + } + length +} + +pub fn assert_array_eq(array: [T; N], expected: [T; S]) where T: Empty + Eq { + assert_eq(count_non_empty_elements(expected), S, "cannot expect empty element in the result"); + assert_eq(count_non_empty_elements(array), S, "mismatch array lengths"); + for i in 0..S { + assert_eq(array[i], expected[i], "mismatch array elements"); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index 5ecb0d57578..4093d4ec220 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -81,6 +81,7 @@ pub fn array_length(array: [T; N]) -> u64 where T: Empty + Eq { length } +// Deprecated. Use tests/utils/assert_array_eq instead. pub fn array_eq(array: [T; N], expected: [T; S]) -> bool where T: Empty + Eq { let mut eq = array_length(array) == S; From 92c792f553d3d2eb2898706a67b81ee285ba78c7 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 24 May 2024 19:22:39 +0000 Subject: [PATCH 05/13] Move tests to folder. --- .../crates/private-kernel-lib/src/tests.nr | 11 +---------- .../src/tests/private_call_data_validator_builder.nr | 11 +++++++++++ .../validate_against_call_request.nr | 0 .../validate_against_previous_kernel.nr | 0 .../validate_against_tx_request.nr | 0 .../validate_arrays.nr | 0 .../validate_as_first_call.nr | 0 .../validate_call.nr | 0 .../validate_call_requests.nr | 0 .../validate_contract_address.nr | 0 .../validate_counters.nr | 0 .../validate_private_call_requests.nr | 0 12 files changed, 12 insertions(+), 10 deletions(-) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_against_call_request.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_against_previous_kernel.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_against_tx_request.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_arrays.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_as_first_call.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_call.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_call_requests.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_contract_address.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_counters.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/{ => private_call_data_validator_builder}/validate_private_call_requests.nr (100%) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr index d97b1175650..883a3581101 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr @@ -1,13 +1,4 @@ +mod kernel_circuit_public_inputs_composer_builder; mod private_call_data_validator_builder; mod private_kernel_circuit_output_validator_builder; mod private_kernel_circuit_public_inputs_composer_builder; -mod validate_against_call_request; -mod validate_against_previous_kernel; -mod validate_against_tx_request; -mod validate_arrays; -mod validate_as_first_call; -mod validate_call; -mod validate_call_requests; -mod validate_contract_address; -mod validate_counters; -mod validate_private_call_requests; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr index f014c86eb54..84db2d62f2d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr @@ -1,3 +1,14 @@ +mod validate_against_call_request; +mod validate_against_previous_kernel; +mod validate_against_tx_request; +mod validate_arrays; +mod validate_as_first_call; +mod validate_call; +mod validate_call_requests; +mod validate_contract_address; +mod validate_counters; +mod validate_private_call_requests; + use crate::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ abis::private_call_request::ScopedPrivateCallRequest, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_call_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_call_request.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_previous_kernel.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_tx_request.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_tx_request.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_arrays.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_arrays.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_as_first_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_as_first_call.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_call.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_call_requests.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_contract_address.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_counters.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_counters.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_private_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_private_call_requests.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr From 85f68c3a5fdca42b7f2c5217f702a196cc2571d6 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Sun, 26 May 2024 12:07:34 +0000 Subject: [PATCH 06/13] Use fixture builder for private call. --- .../src/main.nr | 2 +- .../crates/private-kernel-inner/src/main.nr | 2 +- .../src/private_call_data_validator.nr | 3 + .../src/private_kernel_init.nr | 62 ++-- .../src/private_kernel_inner.nr | 287 +++++------------- .../crates/private-kernel-lib/src/tests.nr | 1 - .../private_call_data_validator_builder.nr | 28 +- .../validate_against_call_request.nr | 24 +- .../validate_against_previous_kernel.nr | 2 +- .../validate_arrays.nr | 114 ++----- .../validate_as_first_call.nr | 20 +- .../validate_call.nr | 35 ++- .../validate_call_requests.nr | 85 +++--- .../validate_contract_address.nr | 2 +- .../validate_counters.nr | 91 +++--- .../validate_private_call_requests.nr | 57 ++-- .../crates/types/src/tests.nr | 2 - .../crates/types/src/tests/fixture_builder.nr | 85 +++++- .../src/tests/private_call_data_builder.nr | 151 --------- .../private_circuit_public_inputs_builder.nr | 282 ----------------- 20 files changed, 377 insertions(+), 958 deletions(-) delete mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr delete mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr index 0f58903b973..e8d723f2b0d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr @@ -2,5 +2,5 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.native_private_kernel_circuit_inner() + input.simulate() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr index 686cce6b595..e48714e175c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr @@ -3,5 +3,5 @@ use dep::types::PrivateKernelCircuitPublicInputs; #[recursive] fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.native_private_kernel_circuit_inner() + input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr index dece7c74d60..875ec4cfecc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr @@ -252,6 +252,9 @@ impl PrivateCallDataValidator { assert_eq( self.array_lengths.new_l2_to_l1_msgs, 0, "new_l2_to_l1_msgs must be empty for static calls" ); + assert_eq( + self.array_lengths.note_encrypted_logs_hashes, 0, "note_encrypted_logs_hashes must be empty for static calls" + ); assert_eq( self.array_lengths.encrypted_logs_hashes, 0, "encrypted_logs_hashes must be empty for static calls" ); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index c87724a8424..1c1ac50824b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -75,83 +75,55 @@ impl PrivateKernelInitCircuitPrivateInputs { mod tests { use crate::private_kernel_init::{PrivateKernelInitHints, PrivateKernelInitCircuitPrivateInputs}; use dep::types::{ - abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - log_hash::{ScopedEncryptedLogHash, ScopedLogHash} - }, + abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, constants::MAX_NEW_NOTE_HASHES_PER_CALL, - tests::{private_call_data_builder::PrivateCallDataBuilder, utils::assert_array_eq}, + tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, transaction::tx_request::TxRequest }; struct PrivateKernelInitInputsBuilder { tx_request: TxRequest, - private_call: PrivateCallDataBuilder, + private_call: FixtureBuilder, hints: PrivateKernelInitHints, } impl PrivateKernelInitInputsBuilder { pub fn new() -> Self { - let private_call = PrivateCallDataBuilder::new(); + let private_call = FixtureBuilder::new(); let tx_request = private_call.build_tx_request(); let hints = PrivateKernelInitHints { note_hash_nullifier_counters: [0; MAX_NEW_NOTE_HASHES_PER_CALL], first_revertible_private_call_request_index: 0 }; - PrivateKernelInitInputsBuilder { tx_request, private_call, hints } } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { - let kernel = PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call: self.private_call.finish(), hints: self.hints }; - - kernel.execute() - } - - pub fn failed(self) { - let _ = self.execute(); + let private_call = self.private_call.to_private_call_data(); + PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call, hints: self.hints }.execute() } } #[test] - fn deposit() { + fn private_kernel_init_output_as_expected() { let mut builder = PrivateKernelInitInputsBuilder::new(); - // Logs for the private call. - let encrypted_logs_hashes = [16, 36]; - let encrypted_log_preimages_length = [100, 75]; - let unencrypted_logs_hashes = [26, 46]; - let unencrypted_log_preimages_length = [50, 25]; - builder.private_call.public_inputs.add_encrypted_log(encrypted_logs_hashes[0], encrypted_log_preimages_length[0]); - builder.private_call.public_inputs.add_unencrypted_log( - unencrypted_logs_hashes[0], - unencrypted_log_preimages_length[0] - ); - builder.private_call.public_inputs.add_encrypted_log(encrypted_logs_hashes[1], encrypted_log_preimages_length[1]); - builder.private_call.public_inputs.add_unencrypted_log( - unencrypted_logs_hashes[1], - unencrypted_log_preimages_length[1] - ); + // note_hash_read_requests + builder.private_call.append_note_hash_read_requests(2); + let note_hash_read_requests = builder.private_call.note_hash_read_requests.storage; - let expected_unencrypted_logs = [ - builder.private_call.public_inputs.unencrypted_logs_hashes.storage[0], builder.private_call.public_inputs.unencrypted_logs_hashes.storage[1] - ]; - let expected_encrypted_logs = [ - builder.private_call.public_inputs.encrypted_logs_hashes.storage[0], builder.private_call.public_inputs.encrypted_logs_hashes.storage[1] - ]; + // encrypted_logs_hashes + builder.private_call.append_encrypted_log_hashes(1); + let encrypted_log_hashes = builder.private_call.encrypted_logs_hashes.storage; let public_inputs = builder.execute(); - - // Check the first nullifier is hash of the signed tx request - let tx_hash = builder.tx_request.hash(); - assert_eq(public_inputs.end.new_nullifiers[0].value(), tx_hash); assert_array_eq( - public_inputs.end.encrypted_logs_hashes.map(|l: ScopedEncryptedLogHash| l.log_hash), - expected_encrypted_logs + public_inputs.validation_requests.note_hash_read_requests, + [note_hash_read_requests[0], note_hash_read_requests[1]] ); assert_array_eq( - public_inputs.end.unencrypted_logs_hashes.map(|l: ScopedLogHash| l.log_hash), - expected_unencrypted_logs + public_inputs.end.encrypted_logs_hashes, + [encrypted_log_hashes[0]] ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 92c731e6670..76a34e08847 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -1,11 +1,12 @@ use crate::{ + components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, private_call_data_validator::PrivateCallDataValidator, private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer }; use dep::types::{ abis::{ - private_kernel_data::PrivateKernelData, private_kernel::private_call_data::PrivateCallData, - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs + kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, + private_kernel_data::PrivateKernelData, private_kernel::private_call_data::PrivateCallData }, constants::MAX_NEW_NOTE_HASHES_PER_CALL, utils::arrays::array_length }; @@ -21,58 +22,79 @@ struct PrivateKernelInnerCircuitPrivateInputs { } impl PrivateKernelInnerCircuitPrivateInputs { - pub fn native_private_kernel_circuit_inner(self) -> PrivateKernelCircuitPublicInputs { + unconstrained fn prepare_output( + self, + private_call_data_validator: PrivateCallDataValidator + ) -> PrivateKernelCircuitPublicInputs { + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( + self.private_call.call_stack_item.public_inputs, + private_call_data_validator.array_lengths, + self.private_call.call_stack_item.contract_address, + self.hints.note_hash_nullifier_counters, + self.private_call.public_call_stack, + self.private_call.public_teardown_call_request + ).finish() + } + + fn validate_inputs(self, private_call_stack_size: u64) -> PrivateCallDataValidator { + let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); + private_call_data_validator.validate(); + let call_request = self.previous_kernel.public_inputs.end.private_call_stack[private_call_stack_size - 1]; + private_call_data_validator.validate_against_call_request(call_request); + private_call_data_validator.validate_against_previous_kernel(self.previous_kernel.public_inputs); + private_call_data_validator + } + + pub fn simulate(self) -> PrivateKernelCircuitPublicInputs { + let private_call_stack_size = array_length(self.previous_kernel.public_inputs.end.private_call_stack); + let private_call_data_validator = self.validate_inputs(private_call_stack_size); + self.prepare_output(private_call_data_validator) + } + + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { // verify/aggregate the private call proof self.private_call.verify(); // verify/aggregate the previous kernel self.previous_kernel.verify(); - let privateCallDataValidator = PrivateCallDataValidator::new(self.private_call); - privateCallDataValidator.validate(); - - let private_call_stack = self.previous_kernel.public_inputs.end.private_call_stack; - // TODO: Should be a hint from private inputs. - let private_call_stack_size = array_length(private_call_stack); - let call_request = private_call_stack[private_call_stack_size - 1]; - privateCallDataValidator.validate_against_call_request(call_request); - privateCallDataValidator.validate_against_previous_kernel(self.previous_kernel.public_inputs); + let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); + let private_call_data_validator = self.validate_inputs(previous_kernel_array_lengths.private_call_stack); - PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( + let output = self.prepare_output(private_call_data_validator); + let output_validator = PrivateKernelCircuitOutputValidator::new(output); + output_validator.validate_as_inner_call( + self.previous_kernel.public_inputs, + previous_kernel_array_lengths, self.private_call.call_stack_item.public_inputs, - privateCallDataValidator.array_lengths, + private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, self.private_call.public_teardown_call_request - ).finish() + ); + output } } mod tests { use crate::private_kernel_inner::{PrivateKernelInnerCircuitPrivateInputs, PrivateKernelInnerHints}; - use dep::types::constants::MAX_NEW_NOTE_HASHES_PER_TX; use dep::types::{ - abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - max_block_number::MaxBlockNumber, note_hash::NoteHash, nullifier::Nullifier, - read_request::ReadRequest, log_hash::{LogHash, NoteLogHash, ScopedLogHash} - }, - address::{AztecAddress, EthAddress}, constants::MAX_NEW_NOTE_HASHES_PER_CALL, - messaging::l2_to_l1_message::L2ToL1Message, utils::arrays::{array_length, array_eq}, - tests::{private_call_data_builder::PrivateCallDataBuilder, fixture_builder::FixtureBuilder} + abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, + constants::MAX_NEW_NOTE_HASHES_PER_CALL, + tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq} }; struct PrivateKernelInnerInputsBuilder { previous_kernel: FixtureBuilder, - private_call: PrivateCallDataBuilder, + private_call: FixtureBuilder, hints: PrivateKernelInnerHints, } impl PrivateKernelInnerInputsBuilder { pub fn new() -> Self { - let mut previous_kernel = FixtureBuilder::new(); - let private_call = PrivateCallDataBuilder::new(); + let mut previous_kernel = FixtureBuilder::new_from_counter(15).as_parent_contract(); + let private_call = FixtureBuilder::new_from_counter(200); let hints = PrivateKernelInnerHints { note_hash_nullifier_counters: [0; MAX_NEW_NOTE_HASHES_PER_CALL] }; // 0th nullifier must be non-zero. @@ -81,18 +103,8 @@ mod tests { PrivateKernelInnerInputsBuilder { previous_kernel, private_call, hints } } - pub fn is_delegate_call(&mut self) -> Self { - let _ = self.private_call.is_delegate_call(); - *self - } - - pub fn is_static_call(&mut self) -> Self { - let _ = self.private_call.is_static_call(); - *self - } - pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); // Update the previous_kernel's private_call_stack with the current call_stack_item. let hash = private_call.call_stack_item.hash(); let is_delegate_call = private_call.call_stack_item.public_inputs.call_context.is_delegate_call; @@ -101,195 +113,36 @@ mod tests { let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call, hints: self.hints }; - kernel.native_private_kernel_circuit_inner() - } - - pub fn succeeded(&mut self) { - let _ = self.execute(); - } - - pub fn failed(&mut self) { - let _ = self.execute(); + kernel.execute() } } - #[test(should_fail_with = "push out of bounds")] - fn private_kernel_should_fail_if_aggregating_too_many_note_hashes() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - - // The current call stack has 1 note_hash; - builder.private_call.public_inputs.append_new_note_hashes(1); - - // Mock the previous new note hashes to be full, therefore no more note_hashes can be added. - builder.previous_kernel.append_new_note_hashes(MAX_NEW_NOTE_HASHES_PER_TX); - - builder.failed(); - } - #[test] - fn propagate_note_hashes_with_nullifier_counters() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(3); - builder.hints.note_hash_nullifier_counters[0] = 10; - builder.hints.note_hash_nullifier_counters[2] = 20; - - let public_inputs = builder.execute(); - - assert_eq(public_inputs.end.new_note_hashes[0].nullifier_counter, 10); - assert_eq(public_inputs.end.new_note_hashes[1].nullifier_counter, 0); - assert_eq(public_inputs.end.new_note_hashes[2].nullifier_counter, 20); - } - - #[test(should_fail_with="Invalid nullifier counter")] - fn propagate_note_hashes_with_incorrect_nullifier_counters_fails() { + fn private_kernel_inner_output_as_expected() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); - let note_hash_counter = builder.private_call.public_inputs.new_note_hashes.get(1).counter; - builder.hints.note_hash_nullifier_counters[1] = note_hash_counter - 1; - - builder.failed(); - } - #[test] - fn propagate_previous_kernel_max_block_number() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); - let public_inputs = builder.execute(); + // note_hash_read_requests + builder.previous_kernel.append_note_hash_read_requests(1); + let prev_note_hash_read_requests = builder.previous_kernel.note_hash_read_requests.storage; + builder.private_call.append_note_hash_read_requests(2); + let curr_note_hash_read_requests = builder.private_call.note_hash_read_requests.storage; - assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13); - } + // encrypted_logs_hashes + builder.previous_kernel.append_encrypted_log_hashes(2); + let prev_encrypted_log_hashes = builder.previous_kernel.encrypted_logs_hashes.storage; + builder.private_call.append_encrypted_log_hashes(1); + let curr_encrypted_log_hashes = builder.private_call.encrypted_logs_hashes.storage; - #[test] - fn propagate_max_block_number_request() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.private_call.public_inputs.set_tx_max_block_number(42); let public_inputs = builder.execute(); - - assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 42); - } - - #[test] - fn ignore_larger_max_block_number() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); - // A private call requesting a larger max_block_number should not change the current one as that constraint is - // already satisfied. - builder.private_call.public_inputs.set_tx_max_block_number(42); - let public_inputs = builder.execute(); - - assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13); - } - - #[test] - fn propagate_note_hash_read_requests() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - - builder.previous_kernel.append_note_hash_read_requests(2); - let prev_requests = builder.previous_kernel.note_hash_read_requests.storage; - - builder.private_call.public_inputs.append_note_hash_read_requests(2); - let cur_requests = builder.private_call.public_inputs.note_hash_read_requests.storage; - let cur_storage_contract_address = builder.private_call.public_inputs.call_context.storage_contract_address; - - let public_inputs = builder.execute(); - - let end_note_hash_read_requests = public_inputs.validation_requests.note_hash_read_requests; - assert_eq(array_length(end_note_hash_read_requests), 4); - - assert_eq(end_note_hash_read_requests[0], prev_requests[0]); - assert_eq(end_note_hash_read_requests[1], prev_requests[1]); - - let request = end_note_hash_read_requests[2]; - assert_eq(request.read_request, cur_requests[0]); - assert_eq(request.contract_address, cur_storage_contract_address); - - let request = end_note_hash_read_requests[3]; - assert_eq(request.read_request, cur_requests[1]); - assert_eq(request.contract_address, cur_storage_contract_address); - } - - #[test] - fn native_logs_are_set_as_expected() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - - // Logs for the current call stack. - let encrypted_logs_hash = 16; - let encrypted_log_preimages_length = 100; - let unencrypted_logs_hash = 26; - let unencrypted_log_preimages_length = 50; - builder.private_call.public_inputs.add_encrypted_log(encrypted_logs_hash, encrypted_log_preimages_length); - builder.private_call.public_inputs.add_unencrypted_log(unencrypted_logs_hash, unencrypted_log_preimages_length); - - // Logs for the previous call stack. - let prev_encrypted_logs_hash = 80; - let prev_encrypted_log_preimages_length = 13; - let prev_unencrypted_logs_hash = 956; - let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.add_unencrypted_log_hash( - prev_unencrypted_logs_hash, - prev_unencrypted_log_preimages_length + assert_array_eq( + public_inputs.validation_requests.note_hash_read_requests, + [ + prev_note_hash_read_requests[0], curr_note_hash_read_requests[0], curr_note_hash_read_requests[1] + ] ); - - let expected_unencrypted_logs = [ - builder.previous_kernel.unencrypted_logs_hashes.storage[0], builder.private_call.public_inputs.unencrypted_logs_hashes.storage[0].scope(builder.private_call.contract_address) - ]; - let expected_encrypted_logs = [ - builder.previous_kernel.encrypted_logs_hashes.storage[0], builder.private_call.public_inputs.encrypted_logs_hashes.storage[0].scope(builder.private_call.contract_address) - ]; - - let public_inputs = builder.execute(); - - assert( - array_eq( - public_inputs.end.encrypted_logs_hashes, - expected_encrypted_logs - ) - ); - assert( - array_eq( - public_inputs.end.unencrypted_logs_hashes, - expected_unencrypted_logs - ) + assert_array_eq( + public_inputs.end.encrypted_logs_hashes, + [prev_encrypted_log_hashes[0], prev_encrypted_log_hashes[1], curr_encrypted_log_hashes[0]] ); } - - #[test] - unconstrained fn propagate_fee_payer_init_succeeds() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - let fee_payer = builder.private_call.public_inputs.call_context.storage_contract_address; - builder.private_call.public_inputs.is_fee_payer = true; - let public_inputs = builder.execute(); - assert_eq(public_inputs.fee_payer, fee_payer); - } - - #[test] - unconstrained fn propagate_fee_payer_not_set_succeeds() { - // Check that the fee payer is not set if is_fee_payer is false - let mut builder = PrivateKernelInnerInputsBuilder::new(); - assert_eq(builder.private_call.public_inputs.is_fee_payer, false); - let public_inputs = builder.execute(); - assert_eq(public_inputs.fee_payer, AztecAddress::empty()); - } - - #[test] - unconstrained fn propagate_fee_payer_carry_forward_succeeds() { - // Check that we carry forward if the fee payer is already set - let mut builder = PrivateKernelInnerInputsBuilder::new(); - let fee_payer = AztecAddress::from_field(123); - builder.previous_kernel.fee_payer = fee_payer; - let public_inputs = builder.execute(); - assert_eq(public_inputs.fee_payer, fee_payer); - } - - #[test(should_fail_with="Cannot overwrite non-empty fee_payer")] - unconstrained fn does_not_overwrite_fee_payer() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - let original_fee_payer = AztecAddress::from_field(123); - - builder.private_call.public_inputs.is_fee_payer = true; - builder.previous_kernel.fee_payer = original_fee_payer; - - builder.failed(); - } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr index 883a3581101..c3468e0aa10 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests.nr @@ -1,4 +1,3 @@ -mod kernel_circuit_public_inputs_composer_builder; mod private_call_data_validator_builder; mod private_kernel_circuit_output_validator_builder; mod private_kernel_circuit_public_inputs_composer_builder; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr index 84db2d62f2d..da8a51355b3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr @@ -11,26 +11,30 @@ mod validate_private_call_requests; use crate::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ - abis::private_call_request::ScopedPrivateCallRequest, - tests::private_call_data_builder::PrivateCallDataBuilder, transaction::tx_request::TxRequest + abis::{private_kernel::private_call_data::PrivateCallData, private_call_request::ScopedPrivateCallRequest}, + tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest }; struct PrivateCallDataValidatorBuilder { - private_call: PrivateCallDataBuilder, + private_call: FixtureBuilder, first_revertible_private_call_request_index: u64, } impl PrivateCallDataValidatorBuilder { pub fn new() -> Self { let default_counter_start = 23; - PrivateCallDataValidatorBuilder::new_with_counter(default_counter_start) + PrivateCallDataValidatorBuilder::new_from_counter(default_counter_start) } - pub fn new_with_counter(counter: u32) -> Self { - let private_call = PrivateCallDataBuilder::new_with_counter(counter); + pub fn new_from_counter(counter: u32) -> Self { + let private_call = FixtureBuilder::new_from_counter(counter); PrivateCallDataValidatorBuilder { private_call, first_revertible_private_call_request_index: 0 } } + pub fn get_private_call_data(self) -> PrivateCallData { + self.private_call.to_private_call_data() + } + pub fn is_delegate_call(&mut self) -> Self { let _ = self.private_call.is_delegate_call(); *self @@ -42,22 +46,26 @@ impl PrivateCallDataValidatorBuilder { } pub fn validate(self) { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate(); } pub fn validate_as_first_call(self) { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate_as_first_call(self.first_revertible_private_call_request_index); } pub fn validate_against_tx_request(self, request: TxRequest) { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate_against_tx_request(request); } pub fn validate_against_call_request(self, request: ScopedPrivateCallRequest) { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate_against_call_request(request); } + + pub fn validate_with_private_call(private_call: PrivateCallData) { + PrivateCallDataValidator::new(private_call).validate(); + } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr index 900615e058f..e17350a5d4d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_call_request.nr @@ -5,7 +5,7 @@ use dep::types::abis::caller_context::CallerContext; fn validate_against_call_request_succeeds() { let builder = PrivateCallDataValidatorBuilder::new(); - let request = builder.private_call.build_call_request(); + let request = builder.private_call.build_private_call_request(); builder.validate_against_call_request(request); } @@ -14,7 +14,7 @@ fn validate_against_call_request_succeeds() { fn validate_against_call_request_delegate_call_succeeds() { let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - let request = builder.private_call.build_call_request(); + let request = builder.private_call.build_private_call_request(); builder.validate_against_call_request(request); } @@ -23,7 +23,7 @@ fn validate_against_call_request_delegate_call_succeeds() { fn validate_against_call_request_static_call_succeeds() { let builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - let request = builder.private_call.build_call_request(); + let request = builder.private_call.build_private_call_request(); builder.validate_against_call_request(request); } @@ -32,7 +32,7 @@ fn validate_against_call_request_static_call_succeeds() { fn validate_against_call_request_mismatch_hash_fails() { let builder = PrivateCallDataValidatorBuilder::new(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the hash to be a different value. request.call_request.hash += 1; @@ -43,7 +43,7 @@ fn validate_against_call_request_mismatch_hash_fails() { fn validate_against_call_request_empty_caller_context_for_delegate_calls_fails() { let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); request.call_request.caller_context = CallerContext::empty(); builder.validate_against_call_request(request); @@ -53,7 +53,7 @@ fn validate_against_call_request_empty_caller_context_for_delegate_calls_fails() fn validate_against_call_request_incorrect_msg_sender_for_delegate_call_fails() { let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the msg_sender to be a different value. request.call_request.caller_context.msg_sender.inner += 1; @@ -64,7 +64,7 @@ fn validate_against_call_request_incorrect_msg_sender_for_delegate_call_fails() fn validate_against_call_request_incorrect_storage_contract_address_for_delegate_call_fails() { let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the storage contract address to be a different value. request.call_request.caller_context.storage_contract_address.inner += 1; @@ -75,7 +75,7 @@ fn validate_against_call_request_incorrect_storage_contract_address_for_delegate fn validate_against_call_request_incorrect_msg_sender_for_regular_call_fails() { let builder = PrivateCallDataValidatorBuilder::new(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the caller's contract address to be a different value. request.contract_address.inner += 1; @@ -86,7 +86,7 @@ fn validate_against_call_request_incorrect_msg_sender_for_regular_call_fails() { fn validate_against_call_request_non_empty_caller_for_regular_call_fails() { let builder = PrivateCallDataValidatorBuilder::new(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the caller's msg_sender to be non-empty. request.call_request.caller_context.msg_sender.inner = 1234; @@ -97,7 +97,7 @@ fn validate_against_call_request_non_empty_caller_for_regular_call_fails() { fn validate_against_call_request_non_empty_caller_for_static_call_fails() { let builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the caller's msg_sender to be non-empty. request.call_request.caller_context.msg_sender.inner = 1234; @@ -108,7 +108,7 @@ fn validate_against_call_request_non_empty_caller_for_static_call_fails() { fn validate_against_call_request_static_call_regular_call_fails() { let builder = PrivateCallDataValidatorBuilder::new(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the caller to be making a static call. request.call_request.caller_context.is_static_call = true; @@ -119,7 +119,7 @@ fn validate_against_call_request_static_call_regular_call_fails() { fn validate_against_call_request_static_call_delegate_call_fails() { let builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - let mut request = builder.private_call.build_call_request(); + let mut request = builder.private_call.build_private_call_request(); // Tweak the caller to be making a static call. request.call_request.caller_context.is_static_call = true; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr index 837661b0b00..b40f7408b38 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr @@ -9,7 +9,7 @@ use dep::types::{ impl PrivateCallDataValidatorBuilder { pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { - let private_call = self.private_call.finish(); + let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate_against_previous_kernel(previous_kernel); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr index bd07cc65013..01796cafa0c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr @@ -1,25 +1,19 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; -use dep::types::{ - abis::{ - validation_requests::{KeyValidationRequest, KeyValidationRequestAndGenerator}, - caller_context::CallerContext, note_hash::NoteHash, nullifier::Nullifier, - private_call_request::PrivateCallRequest, read_request::ReadRequest, - log_hash::{LogHash, NoteLogHash, EncryptedLogHash} -}, - address::EthAddress, constants::GENERATOR_INDEX__IVSK_M, grumpkin_point::GrumpkinPoint, - messaging::l2_to_l1_message::L2ToL1Message -}; + +fn unshift_empty_item(vec: &mut BoundedVec) { + let len = vec.len(); + let empty_item = vec.storage[len]; + let first_item = vec.get(0); + vec.push(first_item); + vec.storage[0] = empty_item; +} #[test(should_fail_with="invalid array")] fn validate_arrays_malformed_note_hash_read_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.note_hash_read_requests.extend_from_array( - [ - ReadRequest::empty(), - ReadRequest { value: 9123, counter: 1 } - ] - ); + builder.private_call.append_note_hash_read_requests(1); + unshift_empty_item(&mut builder.private_call.note_hash_read_requests); builder.validate(); } @@ -28,12 +22,8 @@ fn validate_arrays_malformed_note_hash_read_requests_fails() { fn validate_arrays_malformed_nullifier_read_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.nullifier_read_requests.extend_from_array( - [ - ReadRequest::empty(), - ReadRequest { value: 9123, counter: 1 } - ] - ); + builder.private_call.append_nullifier_read_requests(1); + unshift_empty_item(&mut builder.private_call.nullifier_read_requests); builder.validate(); } @@ -42,15 +32,8 @@ fn validate_arrays_malformed_nullifier_read_requests_fails() { fn validate_arrays_malformed_key_validation_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.key_validation_requests_and_generators.extend_from_array( - [ - KeyValidationRequestAndGenerator::empty(), - KeyValidationRequestAndGenerator { - request: KeyValidationRequest { pk_m: GrumpkinPoint { x: 12, y: 34 }, sk_app: 5 }, - sk_app_generator: GENERATOR_INDEX__IVSK_M - } - ] - ); + builder.private_call.append_key_validation_requests(1); + unshift_empty_item(&mut builder.private_call.scoped_key_validation_requests_and_generators); builder.validate(); } @@ -59,12 +42,8 @@ fn validate_arrays_malformed_key_validation_requests_fails() { fn validate_arrays_malformed_note_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.new_note_hashes.extend_from_array( - [ - NoteHash::empty(), - NoteHash { value: 9123, counter: 1 } - ] - ); + builder.private_call.append_new_note_hashes(1); + unshift_empty_item(&mut builder.private_call.new_note_hashes); builder.validate(); } @@ -73,12 +52,8 @@ fn validate_arrays_malformed_note_hashes_fails() { fn validate_arrays_malformed_nullifiers_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.new_nullifiers.extend_from_array( - [ - Nullifier::empty(), - Nullifier { value: 9123, note_hash: 0, counter: 1 } - ] - ); + builder.private_call.append_new_nullifiers(1); + unshift_empty_item(&mut builder.private_call.new_nullifiers); builder.validate(); } @@ -87,12 +62,8 @@ fn validate_arrays_malformed_nullifiers_fails() { fn validate_arrays_malformed_l2_to_l1_msgs_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.new_l2_to_l1_msgs.extend_from_array( - [ - L2ToL1Message::empty(), - L2ToL1Message { recipient: EthAddress::from_field(6), content: 9123, counter: 0 } - ] - ); + builder.private_call.append_new_l2_to_l1_msgs(1); + unshift_empty_item(&mut builder.private_call.new_l2_to_l1_msgs); builder.validate(); } @@ -101,16 +72,8 @@ fn validate_arrays_malformed_l2_to_l1_msgs_fails() { fn validate_arrays_malformed_private_call_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.private_call_requests.extend_from_array( - [ - PrivateCallRequest::empty(), PrivateCallRequest { - hash: 9123, - start_side_effect_counter: 1, - end_side_effect_counter: 2, - caller_context: CallerContext::empty() - } - ] - ); + builder.private_call.append_private_call_requests(1); + unshift_empty_item(&mut builder.private_call.private_call_requests); builder.validate(); } @@ -119,49 +82,38 @@ fn validate_arrays_malformed_private_call_requests_fails() { fn validate_arrays_malformed_public_call_stack_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.public_call_stack_hashes.extend_from_array([0, 9123]); + builder.private_call.append_public_call_requests(1); + unshift_empty_item(&mut builder.private_call.public_call_requests); builder.validate(); } #[test(should_fail_with="invalid array")] -fn validate_arrays_malformed_encrypted_logs_hashes_fails() { +fn validate_arrays_malformed_note_encrypted_logs_hashes() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.encrypted_logs_hashes.extend_from_array( - [ - EncryptedLogHash { value: 0, counter: 0, length: 0, randomness: 0 }, - EncryptedLogHash { value: 9123, counter: 1, length: 2, randomness: 4 } - ] - ); + builder.private_call.append_note_encrypted_log_hashes(1); + unshift_empty_item(&mut builder.private_call.note_encrypted_logs_hashes); builder.validate(); } #[test(should_fail_with="invalid array")] -fn validate_arrays_malformed_unencrypted_logs_hashes_fails() { +fn validate_arrays_malformed_encrypted_logs_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.unencrypted_logs_hashes.extend_from_array( - [ - LogHash { value: 0, counter: 0, length: 0 }, - LogHash { value: 9123, counter: 1, length: 2 } - ] - ); + builder.private_call.append_encrypted_log_hashes(1); + unshift_empty_item(&mut builder.private_call.encrypted_logs_hashes); builder.validate(); } #[test(should_fail_with="invalid array")] -fn validate_arrays_malformed_note_encrypted_logs_hashes() { +fn validate_arrays_malformed_unencrypted_logs_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.note_encrypted_logs_hashes.extend_from_array( - [ - NoteLogHash { value: 0, counter: 0, length: 0, note_hash_counter: 0 }, - NoteLogHash { value: 9123, counter: 2, length: 2, note_hash_counter: 1 } - ] - ); + builder.private_call.append_unencrypted_log_hashes(1); + unshift_empty_item(&mut builder.private_call.unencrypted_logs_hashes); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr index 59bdc8a6f8f..122661c9047 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_as_first_call.nr @@ -3,20 +3,20 @@ use dep::types::constants::MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL; impl PrivateCallDataValidatorBuilder { pub fn new_first_call() -> Self { - PrivateCallDataValidatorBuilder::new_with_counter(0) + PrivateCallDataValidatorBuilder::new_from_counter(0) } pub fn split_calls(&mut self, counter: u32) { - self.private_call.public_inputs.min_revertible_side_effect_counter = counter; - self.first_revertible_private_call_request_index = self.private_call.public_inputs.private_call_requests.len(); + self.private_call.min_revertible_side_effect_counter = counter; + self.first_revertible_private_call_request_index = self.private_call.private_call_requests.len(); } pub fn add_private_call_request(&mut self, counter_start: u32, counter_end: u32) { - let index = self.private_call.public_inputs.private_call_requests.len(); - self.private_call.public_inputs.append_private_call_requests(1, false); - self.private_call.public_inputs.private_call_requests.storage[index].start_side_effect_counter = counter_start; - self.private_call.public_inputs.private_call_requests.storage[index].end_side_effect_counter = counter_end; - self.private_call.public_inputs.counter_end = counter_end + 1; + let index = self.private_call.private_call_requests.len(); + self.private_call.append_private_call_requests(1); + self.private_call.private_call_requests.storage[index].call_request.start_side_effect_counter = counter_start; + self.private_call.private_call_requests.storage[index].call_request.end_side_effect_counter = counter_end; + self.private_call.counter = counter_end + 1; } } @@ -80,8 +80,8 @@ fn validate_as_first_call_split_private_empty_non_revertible_succeeds() { fn validate_as_first_call_split_private_full_non_revertible_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); - builder.private_call.public_inputs.append_private_call_requests(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, false); - builder.split_calls(builder.private_call.public_inputs.counter_end); + builder.private_call.append_private_call_requests(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL); + builder.split_calls(builder.private_call.counter); builder.validate_as_first_call(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr index 3146174d775..a17eeef9d53 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call.nr @@ -1,8 +1,4 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; -use dep::types::{ - abis::{note_hash::NoteHash, nullifier::Nullifier, log_hash::{LogHash, EncryptedLogHash}}, - address::EthAddress, messaging::l2_to_l1_message::L2ToL1Message -}; #[test] fn validate_call_is_regular_succeeds() { @@ -15,7 +11,7 @@ fn validate_call_is_regular_mismatch_storage_contract_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); // Change the storage contract address to be a different value. - builder.private_call.public_inputs.call_context.storage_contract_address.inner += 1; + builder.private_call.storage_contract_address.inner += 1; builder.validate(); } @@ -26,12 +22,18 @@ fn validate_call_is_delegate_succeeds() { builder.validate(); } +#[test] +fn validate_call_is_delegate_static_succeeds() { + let mut builder = PrivateCallDataValidatorBuilder::new().is_delegate_call().is_static_call(); + builder.validate(); +} + #[test(should_fail_with="current contract address must not match storage contract address for delegate calls")] fn validate_call_is_delegate_call_from_same_contract_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); // Change the caller's storage contract address to be the same as the contract address. - builder.private_call.public_inputs.call_context.storage_contract_address = builder.private_call.contract_address; + builder.private_call.storage_contract_address = builder.private_call.contract_address; builder.validate(); } @@ -47,7 +49,7 @@ fn validate_call_is_static_mismatch_storage_contract_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); // Change the storage contract address to be a different value. - builder.private_call.public_inputs.call_context.storage_contract_address.inner += 1; + builder.private_call.storage_contract_address.inner += 1; builder.validate(); } @@ -56,7 +58,7 @@ fn validate_call_is_static_mismatch_storage_contract_fails() { fn validate_call_is_static_creating_note_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.new_note_hashes.push(NoteHash { value: 1, counter: 0 }); + builder.private_call.append_new_note_hashes(1); builder.validate(); } @@ -65,7 +67,7 @@ fn validate_call_is_static_creating_note_hashes_fails() { fn validate_call_is_static_creating_nullifiers_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.new_nullifiers.push(Nullifier { value: 1, counter: 0, note_hash: 0 }); + builder.private_call.append_new_nullifiers(1); builder.validate(); } @@ -74,7 +76,16 @@ fn validate_call_is_static_creating_nullifiers_fails() { fn validate_call_is_static_creating_l2_to_l1_msgs_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.new_l2_to_l1_msgs.push(L2ToL1Message { recipient: EthAddress::from_field(6), content: 9123, counter: 0 }); + builder.private_call.append_new_l2_to_l1_msgs(1); + + builder.validate(); +} + +#[test(should_fail_with="note_encrypted_logs_hashes must be empty for static calls")] +fn validate_call_is_static_creating_note_encrypted_logs_hashes_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); + + builder.private_call.append_note_encrypted_log_hashes(1); builder.validate(); } @@ -83,7 +94,7 @@ fn validate_call_is_static_creating_l2_to_l1_msgs_fails() { fn validate_call_is_static_creating_encrypted_logs_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.encrypted_logs_hashes.push(EncryptedLogHash { value: 9123, counter: 1, length: 2, randomness: 4 }); + builder.private_call.append_encrypted_log_hashes(1); builder.validate(); } @@ -92,7 +103,7 @@ fn validate_call_is_static_creating_encrypted_logs_hashes_fails() { fn validate_call_is_static_creating_unencrypted_logs_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.unencrypted_logs_hashes.push(LogHash { value: 9123, counter: 1, length: 2 }); + builder.private_call.append_unencrypted_log_hashes(1); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr index 4534d291e7c..b9a8b2fd386 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr @@ -1,5 +1,4 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; -use dep::types::abis::call_request::CallRequest; /** * validate_public_call_requests @@ -9,7 +8,7 @@ use dep::types::abis::call_request::CallRequest; fn validate_public_call_requests_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(2, false); + builder.private_call.append_public_call_requests(2); builder.validate(); } @@ -18,7 +17,7 @@ fn validate_public_call_requests_succeeds() { fn validate_public_call_requests_delegate_calls_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(2, true); + builder.private_call.append_public_call_requests_delegate(2); builder.validate(); } @@ -27,24 +26,23 @@ fn validate_public_call_requests_delegate_calls_succeeds() { fn validate_public_call_requests_incorrect_hash_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(2, false); - let mut call_request = builder.private_call.public_call_stack.pop(); + builder.private_call.append_public_call_requests(2); + let mut private_call = builder.get_private_call_data(); // Change the hash to be a different value. - call_request.hash += 1; - builder.private_call.public_call_stack.push(call_request); + private_call.call_stack_item.public_inputs.public_call_stack_hashes[0] += 1; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } #[test(should_fail_with="invalid caller contract address")] fn validate_public_call_requests_incorrect_caller_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(1, false); - let mut call_request = builder.private_call.public_call_stack.pop(); + builder.private_call.append_public_call_requests(1); + let mut call_request = builder.private_call.public_call_requests.pop(); // Change the caller contract address to be a different value. call_request.caller_contract_address.inner += 1; - builder.private_call.public_call_stack.push(call_request); + builder.private_call.public_call_requests.push(call_request); builder.validate(); } @@ -53,11 +51,11 @@ fn validate_public_call_requests_incorrect_caller_address_fails() { fn validate_public_call_requests_incorrect_caller_storage_contract_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(1, true); - let mut call_request = builder.private_call.public_call_stack.pop(); + builder.private_call.append_public_call_requests_delegate(1); + let mut call_request = builder.private_call.public_call_requests.pop(); // Change the storage contract to be a different value. call_request.caller_context.storage_contract_address.inner += 1; - builder.private_call.public_call_stack.push(call_request); + builder.private_call.public_call_requests.push(call_request); builder.validate(); } @@ -66,11 +64,11 @@ fn validate_public_call_requests_incorrect_caller_storage_contract_address_fails fn validate_public_call_requests_incorrect_caller_msg_sender_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(1, true); - let mut call_request = builder.private_call.public_call_stack.pop(); + builder.private_call.append_public_call_requests_delegate(1); + let mut call_request = builder.private_call.public_call_requests.pop(); // Change the msg_sender to be a different value. call_request.caller_context.msg_sender.inner += 1; - builder.private_call.public_call_stack.push(call_request); + builder.private_call.public_call_requests.push(call_request); builder.validate(); } @@ -79,22 +77,24 @@ fn validate_public_call_requests_incorrect_caller_msg_sender_fails() { fn validate_public_call_requests_fewer_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(2, false); + builder.private_call.append_public_call_requests(2); + let mut private_call = builder.get_private_call_data(); // Remove one call stack item hash. - let _ = builder.private_call.public_inputs.public_call_stack_hashes.pop(); + private_call.call_stack_item.public_inputs.public_call_stack_hashes[1] = 0; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } #[test(should_fail_with="call stack hash does not match call request hash")] fn validate_public_call_requests_more_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.append_public_call_requests(2, false); + builder.private_call.append_public_call_requests(2); + let mut private_call = builder.get_private_call_data(); // Add one random call stack item hash. - builder.private_call.public_inputs.public_call_stack_hashes.push(9123); + private_call.call_stack_item.public_inputs.public_call_stack_hashes[2] = 123; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } /** @@ -105,7 +105,7 @@ fn validate_public_call_requests_more_hashes_fails() { fn validate_teardown_call_request_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(false); + builder.private_call.append_public_teardown_call_request(); builder.validate(); } @@ -114,7 +114,7 @@ fn validate_teardown_call_request_succeeds() { fn validate_teardown_call_request_delegate_calls_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); builder.validate(); } @@ -123,20 +123,21 @@ fn validate_teardown_call_request_delegate_calls_succeeds() { fn validate_teardown_call_request_incorrect_hash_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); + let mut private_call = builder.get_private_call_data(); // Change the hash to be a different value. - builder.private_call.public_teardown_call_request.hash += 1; + private_call.call_stack_item.public_inputs.public_teardown_function_hash += 1; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } #[test(should_fail_with="invalid caller contract address")] fn validate_teardown_call_request_incorrect_caller_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); // Change the caller contract address to be a different value. - builder.private_call.public_teardown_call_request.caller_contract_address.inner += 1; + builder.private_call.public_teardown_call_stack.storage[0].caller_contract_address.inner += 1; builder.validate(); } @@ -145,9 +146,9 @@ fn validate_teardown_call_request_incorrect_caller_address_fails() { fn validate_teardown_call_request_incorrect_caller_storage_contract_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); // Change the storage contract to be a different value. - builder.private_call.public_teardown_call_request.caller_context.storage_contract_address.inner += 1; + builder.private_call.public_teardown_call_stack.storage[0].caller_context.storage_contract_address.inner += 1; builder.validate(); } @@ -156,9 +157,9 @@ fn validate_teardown_call_request_incorrect_caller_storage_contract_address_fail fn validate_teardown_call_request_incorrect_caller_msg_sender_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); // Change the msg_sender to be a different value. - builder.private_call.public_teardown_call_request.caller_context.msg_sender.inner += 1; + builder.private_call.public_teardown_call_stack.storage[0].caller_context.msg_sender.inner += 1; builder.validate(); } @@ -167,20 +168,22 @@ fn validate_teardown_call_request_incorrect_caller_msg_sender_fails() { fn validate_teardown_call_request_fewer_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); + builder.private_call.append_public_teardown_call_request_delegate(); + let mut private_call = builder.get_private_call_data(); // Remove the call stack item hash. - builder.private_call.public_inputs.public_teardown_function_hash = 0; + private_call.call_stack_item.public_inputs.public_teardown_function_hash = 0; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } #[test(should_fail_with="call stack hash does not match call request hash")] fn validate_teardown_call_request_more_hashes_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.add_teardown_call_request(true); - // Remove the call request. - builder.private_call.public_teardown_call_request = CallRequest::empty(); + builder.private_call.append_public_teardown_call_request_delegate(); + let mut private_call = builder.get_private_call_data(); + // Add a random call stack item hash. + private_call.call_stack_item.public_inputs.public_teardown_function_hash = 123; - builder.validate(); + PrivateCallDataValidatorBuilder::validate_with_private_call(private_call); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr index 9e9228c6c21..b14ab5cef71 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr @@ -7,7 +7,7 @@ fn validate_contract_address_zero_storage_contract_address_fails() { // Set (storage) contract_address to 0 builder.private_call.contract_address = AztecAddress::zero(); - builder.private_call.public_inputs.call_context.storage_contract_address = AztecAddress::zero(); + builder.private_call.storage_contract_address = AztecAddress::zero(); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr index 044441e5382..2f85c7df52f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr @@ -6,13 +6,13 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorB #[test] fn validate_counters_private_call_succeeds() { - let builder = PrivateCallDataValidatorBuilder::new_with_counter(23); + let builder = PrivateCallDataValidatorBuilder::new_from_counter(23); builder.validate(); } #[test] fn validate_counters_private_call_from_0_counter_succeeds() { - let builder = PrivateCallDataValidatorBuilder::new_with_counter(0); + let builder = PrivateCallDataValidatorBuilder::new_from_counter(0); builder.validate(); } @@ -20,7 +20,7 @@ fn validate_counters_private_call_from_0_counter_succeeds() { fn validate_counters_private_call_no_counter_range_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.counter_end = builder.private_call.public_inputs.counter_start; + builder.private_call.counter = builder.private_call.counter_start; builder.validate(); } @@ -29,7 +29,7 @@ fn validate_counters_private_call_no_counter_range_fails() { fn validate_counters_private_call_negative_call_counter_range_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.counter_end = builder.private_call.public_inputs.counter_start - 1; + builder.private_call.counter = builder.private_call.counter_start - 1; builder.validate(); } @@ -42,7 +42,7 @@ fn validate_counters_private_call_negative_call_counter_range_fails() { fn validate_counters_note_hashes_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); + builder.private_call.append_new_note_hashes(2); builder.validate(); } @@ -51,9 +51,9 @@ fn validate_counters_note_hashes_succeeds() { fn validate_counters_note_hash_counter_same_as_call_counter_start_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(1); + builder.private_call.append_new_note_hashes(1); // Tweak the counter of the first note hash to EQUAL the start counter of the call. - builder.private_call.public_inputs.new_note_hashes.storage[0].counter = builder.private_call.public_inputs.counter_start; + builder.private_call.new_note_hashes.storage[0].note_hash.counter = builder.private_call.counter_start; builder.validate(); } @@ -62,9 +62,9 @@ fn validate_counters_note_hash_counter_same_as_call_counter_start_fails() { fn validate_counters_note_hash_counter_smaller_than_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(1); + builder.private_call.append_new_note_hashes(1); // Tweak the counter of the first note hash to be LESS than the start counter of the call. - builder.private_call.public_inputs.new_note_hashes.storage[0].counter = builder.private_call.public_inputs.counter_start - 1; + builder.private_call.new_note_hashes.storage[0].note_hash.counter = builder.private_call.counter_start - 1; builder.validate(); } @@ -73,11 +73,11 @@ fn validate_counters_note_hash_counter_smaller_than_call_fails() { fn validate_counters_note_hash_identical_counters_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); - let counter_start = builder.private_call.public_inputs.counter_start; + builder.private_call.append_new_note_hashes(2); + let counter_start = builder.private_call.counter_start; // Tweak the counter of the second note hash to EQUAL the counter of the first note hash. - builder.private_call.public_inputs.new_note_hashes.storage[0].counter = counter_start + 1; - builder.private_call.public_inputs.new_note_hashes.storage[1].counter = counter_start + 1; + builder.private_call.new_note_hashes.storage[0].note_hash.counter = counter_start + 1; + builder.private_call.new_note_hashes.storage[1].note_hash.counter = counter_start + 1; builder.validate(); } @@ -86,11 +86,11 @@ fn validate_counters_note_hash_identical_counters_fails() { fn validate_counters_note_hash_unordered_counters_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); - let counter_start = builder.private_call.public_inputs.counter_start; + builder.private_call.append_new_note_hashes(2); + let counter_start = builder.private_call.counter_start; // Tweak the counter of the second note hash to be LESS than the counter of the first note hash. - builder.private_call.public_inputs.new_note_hashes.storage[0].counter = counter_start + 2; - builder.private_call.public_inputs.new_note_hashes.storage[1].counter = counter_start + 1; + builder.private_call.new_note_hashes.storage[0].note_hash.counter = counter_start + 2; + builder.private_call.new_note_hashes.storage[1].note_hash.counter = counter_start + 1; builder.validate(); } @@ -99,9 +99,9 @@ fn validate_counters_note_hash_unordered_counters_fails() { fn validate_counters_note_hash_counter_larger_than_call_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); + builder.private_call.append_new_note_hashes(2); // Tweak the counter of the second note hash to be GREATER than the end counter of the call. - builder.private_call.public_inputs.new_note_hashes.storage[1].counter = builder.private_call.public_inputs.counter_end + 1; + builder.private_call.new_note_hashes.storage[1].note_hash.counter = builder.private_call.counter + 1; builder.validate(); } @@ -110,9 +110,9 @@ fn validate_counters_note_hash_counter_larger_than_call_fails() { fn validate_counters_note_hash_counter_same_as_call_counter_end_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_new_note_hashes(2); + builder.private_call.append_new_note_hashes(2); // Tweak the counter of the second note hash to EQUAL the end counter of the call. - builder.private_call.public_inputs.new_note_hashes.storage[1].counter = builder.private_call.public_inputs.counter_end; + builder.private_call.new_note_hashes.storage[1].note_hash.counter = builder.private_call.counter; builder.validate(); } @@ -125,7 +125,7 @@ fn validate_counters_note_hash_counter_same_as_call_counter_end_fails() { fn validate_counters_private_call_requests_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(2, false); + builder.private_call.append_private_call_requests(2); builder.validate(); } @@ -134,10 +134,10 @@ fn validate_counters_private_call_requests_succeeds() { fn validate_counters_private_call_requests_less_than_call_start_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the start counter of the first nested call to be LESS than the start counter of the call. - let counter_start = builder.private_call.public_inputs.counter_start; - builder.private_call.public_inputs.private_call_requests.storage[0].start_side_effect_counter = counter_start - 1; + let counter_start = builder.private_call.counter_start; + builder.private_call.private_call_requests.storage[0].call_request.start_side_effect_counter = counter_start - 1; builder.validate(); } @@ -146,10 +146,10 @@ fn validate_counters_private_call_requests_less_than_call_start_fails() { fn validate_counters_private_call_requests_equal_call_start_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the start counter of the call to EQUAL the start counter of the first nested call. - let counter_start = builder.private_call.public_inputs.counter_start; - builder.private_call.public_inputs.private_call_requests.storage[0].start_side_effect_counter = counter_start; + let counter_start = builder.private_call.counter_start; + builder.private_call.private_call_requests.storage[0].call_request.start_side_effect_counter = counter_start; builder.validate(); } @@ -158,10 +158,10 @@ fn validate_counters_private_call_requests_equal_call_start_fails() { fn validate_counters_private_call_requests_less_than_previous_end_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(2, false); + builder.private_call.append_private_call_requests(2); // Tweak the start counter of the second nested call to be LESS than the end counter of the first nested call. - let counter_end = builder.private_call.public_inputs.private_call_requests.get(0).end_side_effect_counter; - builder.private_call.public_inputs.private_call_requests.storage[1].start_side_effect_counter = counter_end - 1; + let counter_end = builder.private_call.private_call_requests.get(0).call_request.end_side_effect_counter; + builder.private_call.private_call_requests.storage[1].call_request.start_side_effect_counter = counter_end - 1; builder.validate(); } @@ -170,10 +170,10 @@ fn validate_counters_private_call_requests_less_than_previous_end_fails() { fn validate_counters_private_call_requests_same_as_previous_end_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(2, false); + builder.private_call.append_private_call_requests(2); // Tweak the start counter of the second nested call to EQUAL the end counter of the first nested call. - let counter_end = builder.private_call.public_inputs.private_call_requests.get(0).end_side_effect_counter; - builder.private_call.public_inputs.private_call_requests.storage[1].start_side_effect_counter = counter_end; + let counter_end = builder.private_call.private_call_requests.get(0).call_request.end_side_effect_counter; + builder.private_call.private_call_requests.storage[1].call_request.start_side_effect_counter = counter_end; builder.validate(); } @@ -182,10 +182,10 @@ fn validate_counters_private_call_requests_same_as_previous_end_fails() { fn validate_counters_private_call_requests_end_less_than_start_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the end counter of the first nested call to be LESS than its start counter. - let counter_start = builder.private_call.public_inputs.private_call_requests.get(0).start_side_effect_counter; - builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_start - 1; + let counter_start = builder.private_call.private_call_requests.get(0).call_request.start_side_effect_counter; + builder.private_call.private_call_requests.storage[0].call_request.end_side_effect_counter = counter_start - 1; builder.validate(); } @@ -194,10 +194,10 @@ fn validate_counters_private_call_requests_end_less_than_start_fails() { fn validate_counters_private_call_requests_end_equal_start_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the end counter of the first nested call to EQUAL its start counter. - let counter_start = builder.private_call.public_inputs.private_call_requests.get(0).start_side_effect_counter; - builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_start; + let counter_start = builder.private_call.private_call_requests.get(0).call_request.start_side_effect_counter; + builder.private_call.private_call_requests.storage[0].call_request.end_side_effect_counter = counter_start; builder.validate(); } @@ -206,10 +206,10 @@ fn validate_counters_private_call_requests_end_equal_start_fails() { fn validate_counters_private_call_requests_greater_than_call_end_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the end counter of the nested call to be GREATER than the end counter of the call. - let counter_end = builder.private_call.public_inputs.counter_end; - builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_end + 1; + let counter_end = builder.private_call.counter; + builder.private_call.private_call_requests.storage[0].call_request.end_side_effect_counter = counter_end + 1; builder.validate(); } @@ -218,10 +218,9 @@ fn validate_counters_private_call_requests_greater_than_call_end_fails() { fn validate_counters_private_call_requests_equal_call_end_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); + builder.private_call.append_private_call_requests(1); // Tweak the end counter of the nested call to EQUAL the end counter of the call. - let counter_end = builder.private_call.public_inputs.counter_end; - builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_end; + builder.private_call.private_call_requests.storage[0].call_request.end_side_effect_counter = builder.private_call.counter; builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr index 89f730cc504..1a6a047d0b4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr @@ -4,9 +4,9 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorB fn validate_private_call_requests_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, true); - builder.private_call.public_inputs.append_private_call_requests(1, false); - builder.private_call.public_inputs.append_private_call_requests(1, true); + builder.private_call.append_private_call_requests(1); + builder.private_call.append_private_call_requests_delegate(1); + builder.private_call.append_private_call_requests(1); builder.validate(); } @@ -15,9 +15,9 @@ fn validate_private_call_requests_succeeds() { fn validate_private_call_requests_from_delegate_call_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_delegate_call(); - builder.private_call.public_inputs.append_private_call_requests(1, true); - builder.private_call.public_inputs.append_private_call_requests(1, false); - builder.private_call.public_inputs.append_private_call_requests(1, true); + builder.private_call.append_private_call_requests(1); + builder.private_call.append_private_call_requests_delegate(1); + builder.private_call.append_private_call_requests(1); builder.validate(); } @@ -26,16 +26,9 @@ fn validate_private_call_requests_from_delegate_call_succeeds() { fn validate_private_call_requests_from_static_call_succeeds() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.append_private_call_requests(2, false); - - builder.validate(); -} - -#[test] -fn validate_private_call_requests_delegate_calls_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.public_inputs.append_private_call_requests(2, true); + builder.private_call.append_private_call_requests(1); + builder.private_call.append_private_call_requests_delegate(1); + builder.private_call.append_private_call_requests(1); builder.validate(); } @@ -44,11 +37,11 @@ fn validate_private_call_requests_delegate_calls_succeeds() { fn validate_private_call_requests_incorrect_caller_storage_contract_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, true); - let mut call_request = builder.private_call.public_inputs.private_call_requests.pop(); + builder.private_call.append_private_call_requests_delegate(1); + let mut call_request = builder.private_call.private_call_requests.pop(); // Tweak the storage contract to be a different value. - call_request.caller_context.storage_contract_address.inner += 1; - builder.private_call.public_inputs.private_call_requests.push(call_request); + call_request.call_request.caller_context.storage_contract_address.inner += 1; + builder.private_call.private_call_requests.push(call_request); builder.validate(); } @@ -57,11 +50,11 @@ fn validate_private_call_requests_incorrect_caller_storage_contract_address_fail fn validate_private_call_requests_incorrect_caller_msg_sender_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, true); - let mut call_request = builder.private_call.public_inputs.private_call_requests.pop(); + builder.private_call.append_private_call_requests_delegate(1); + let mut call_request = builder.private_call.private_call_requests.pop(); // Tweak the msg_sender to be a different value. - call_request.caller_context.msg_sender.inner += 1; - builder.private_call.public_inputs.private_call_requests.push(call_request); + call_request.call_request.caller_context.msg_sender.inner += 1; + builder.private_call.private_call_requests.push(call_request); builder.validate(); } @@ -70,11 +63,11 @@ fn validate_private_call_requests_incorrect_caller_msg_sender_fails() { fn validate_private_call_requests_regular_call_is_static_true_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.append_private_call_requests(1, false); - let mut call_request = builder.private_call.public_inputs.private_call_requests.pop(); + builder.private_call.append_private_call_requests(1); + let mut call_request = builder.private_call.private_call_requests.pop(); // Tweak the is_static_call flag to be true. - call_request.caller_context.is_static_call = true; - builder.private_call.public_inputs.private_call_requests.push(call_request); + call_request.call_request.caller_context.is_static_call = true; + builder.private_call.private_call_requests.push(call_request); builder.validate(); } @@ -83,11 +76,11 @@ fn validate_private_call_requests_regular_call_is_static_true_fails() { fn validate_private_call_requests_static_call_is_static_false_fails() { let mut builder = PrivateCallDataValidatorBuilder::new().is_static_call(); - builder.private_call.public_inputs.append_private_call_requests(1, false); - let mut call_request = builder.private_call.public_inputs.private_call_requests.pop(); + builder.private_call.append_private_call_requests(1); + let mut call_request = builder.private_call.private_call_requests.pop(); // Tweak the is_static_call flag to be false. - call_request.caller_context.is_static_call = false; - builder.private_call.public_inputs.private_call_requests.push(call_request); + call_request.call_request.caller_context.is_static_call = false; + builder.private_call.private_call_requests.push(call_request); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr index 92712d66571..7d57afca711 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr @@ -1,8 +1,6 @@ mod fixture_builder; mod fixtures; mod merkle_tree_utils; -mod private_call_data_builder; -mod private_circuit_public_inputs_builder; mod public_call_data_builder; mod public_circuit_public_inputs_builder; mod sort; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 345356f723d..75949ad7a6f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -143,11 +143,12 @@ impl FixtureBuilder { let contract_data = fixtures::contracts::default_contract; let contract_function = fixtures::contract_functions::default_private_function; + let contract_address = contract_data.address; builder.tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; - builder.contract_address = fixtures::contracts::parent_contract.address; - builder.storage_contract_address = fixtures::contracts::parent_contract.address; - builder.msg_sender = fixtures::MSG_SENDER; + builder.contract_address = contract_address; + builder.storage_contract_address = contract_address; + builder.msg_sender = fixtures::contracts::parent_contract.address; builder.function_data = contract_function.data; builder.function_leaf_membership_witness = contract_function.membership_witness; builder.salted_initialization_hash = contract_data.salted_initialization_hash; @@ -161,6 +162,25 @@ impl FixtureBuilder { builder } + pub fn as_parent_contract(&mut self) -> Self { + self.contract_address = fixtures::contracts::parent_contract.address; + self.storage_contract_address = fixtures::contracts::parent_contract.address; + self.msg_sender = fixtures::MSG_SENDER; + *self + } + + pub fn is_delegate_call(&mut self) -> Self { + self.is_delegate_call = true; + self.storage_contract_address = fixtures::contracts::parent_contract.address; + self.msg_sender = fixtures::MSG_SENDER; + *self + } + + pub fn is_static_call(&mut self) -> Self { + self.is_static_call = true; + *self + } + pub fn to_constant_data(self) -> CombinedConstantData { CombinedConstantData { historical_header: self.historical_header, @@ -189,6 +209,23 @@ impl FixtureBuilder { } } + pub fn build_private_call_request(self) -> ScopedPrivateCallRequest { + let hash = self.to_private_call_stack_item().hash(); + let is_delegate_call = self.is_delegate_call; + let mut caller_context = CallerContext::empty(); + caller_context.is_static_call = self.is_static_call; + if is_delegate_call { + caller_context.msg_sender = self.msg_sender; + caller_context.storage_contract_address = self.storage_contract_address; + }; + PrivateCallRequest { + hash, + caller_context, + start_side_effect_counter: self.counter_start, + end_side_effect_counter: self.counter + }.scope(self.msg_sender) + } + pub fn to_private_circuit_public_inputs(self) -> PrivateCircuitPublicInputs { PrivateCircuitPublicInputs { call_context: self.build_call_context(), @@ -613,19 +650,30 @@ impl FixtureBuilder { pub fn add_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { let mut caller_context = CallerContext::empty(); + caller_context.is_static_call = self.is_static_call; if is_delegate_call { - caller_context.msg_sender = fixtures::MSG_SENDER; - caller_context.storage_contract_address = self.contract_address; + caller_context.msg_sender = self.msg_sender; + caller_context.storage_contract_address = self.storage_contract_address; } let start_counter = self.next_counter(); let end_counter = start_counter + 10; - self.counter = end_counter; + self.counter = end_counter + 1; self.private_call_requests.push( PrivateCallRequest { hash, caller_context, start_side_effect_counter: start_counter, end_side_effect_counter: end_counter }.scope(self.contract_address) ); } pub fn append_private_call_requests(&mut self, num: u64) { + let index_offset = self.private_call_requests.len(); + for i in 0..self.private_call_requests.max_len() { + if i < num { + let hash = self.mock_private_call_request_hash(index_offset + i); + self.add_private_call_request(hash, false); + } + } + } + + pub fn append_private_call_requests_delegate(&mut self, num: u64) { let index_offset = self.private_call_requests.len(); for i in 0..self.private_call_requests.max_len() { if i < num { @@ -636,11 +684,21 @@ impl FixtureBuilder { } pub fn push_public_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_request = self.generate_call_request(hash, is_delegate_call); + let call_request = self.generate_public_call_request(hash, is_delegate_call); self.public_call_requests.push(call_request); } pub fn append_public_call_requests(&mut self, num: u64) { + let index_offset = self.public_call_requests.len(); + for i in 0..self.public_call_requests.max_len() { + if i < num { + let hash = self.mock_public_call_request_hash(index_offset + i); + self.push_public_call_request(hash, false); + } + } + } + + pub fn append_public_call_requests_delegate(&mut self, num: u64) { let index_offset = self.public_call_requests.len(); for i in 0..self.public_call_requests.max_len() { if i < num { @@ -661,11 +719,16 @@ impl FixtureBuilder { } pub fn push_public_teardown_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); + let call_stack_item = self.generate_public_call_request(hash, is_delegate_call); self.public_teardown_call_stack.push(call_stack_item); } pub fn append_public_teardown_call_request(&mut self) { + let hash = self.mock_public_teardown_call_request_hash(0); + self.push_public_teardown_call_request(hash, false); + } + + pub fn append_public_teardown_call_request_delegate(&mut self) { let hash = self.mock_public_teardown_call_request_hash(0); self.push_public_teardown_call_request(hash, true); } @@ -678,21 +741,19 @@ impl FixtureBuilder { self.max_block_number = MaxBlockNumber::new(max_block_number); } - fn generate_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { + fn generate_public_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { let mut caller_context = CallerContext::empty(); if is_delegate_call { caller_context.msg_sender = self.msg_sender; caller_context.storage_contract_address = self.contract_address; } let start_counter = self.next_counter(); - let end_counter = start_counter + 10; - self.counter = end_counter; CallRequest { hash, caller_contract_address: self.contract_address, caller_context, start_side_effect_counter: start_counter, - end_side_effect_counter: end_counter + end_side_effect_counter: 0 } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr deleted file mode 100644 index afbf7f07b7d..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr +++ /dev/null @@ -1,151 +0,0 @@ -use crate::{ - abis::{ - gas_settings::GasSettings, call_request::{CallerContext, CallRequest}, - private_call_stack_item::PrivateCallStackItem, function_data::FunctionData, - max_block_number::MaxBlockNumber, - private_call_request::{PrivateCallRequest, ScopedPrivateCallRequest}, - private_circuit_public_inputs::PrivateCircuitPublicInputs, - private_kernel::private_call_data::PrivateCallData, log_hash::LogHash -}, - merkle_tree::membership::MembershipWitness, - address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, - recursion::{proof::RecursiveProof, verification_key::VerificationKey}, - tests::{fixtures, private_circuit_public_inputs_builder::PrivateCircuitPublicInputsBuilder}, - transaction::{tx_request::TxRequest, tx_context::TxContext} -}; -use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, FUNCTION_TREE_HEIGHT}; - -struct PrivateCallDataBuilder { - // Values of PrivateCallStackItem. - contract_address: AztecAddress, - public_inputs: PrivateCircuitPublicInputsBuilder, - is_execution_request: bool, - function_data: FunctionData, - // The rest of the values of PrivateCallData. - public_call_stack: BoundedVec, - public_teardown_call_request: CallRequest, - proof: RecursiveProof, - vk: VerificationKey, - salted_initialization_hash: SaltedInitializationHash, - public_keys_hash: PublicKeysHash, - contract_class_artifact_hash: Field, - contract_class_public_bytecode_commitment: Field, - function_leaf_membership_witness: MembershipWitness, - acir_hash: Field, - gas_settings: GasSettings, -} - -impl PrivateCallDataBuilder { - pub fn new() -> Self { - PrivateCallDataBuilder::new_with_counter(0) - } - - pub fn new_with_counter(counter: u32) -> Self { - let public_inputs = PrivateCircuitPublicInputsBuilder::new_with_counter(counter); - - let contract_data = fixtures::contracts::default_contract; - let contract_function = fixtures::contract_functions::default_private_function; - let function_data = contract_function.data; - - PrivateCallDataBuilder { - contract_address: public_inputs.call_context.storage_contract_address, - public_inputs, - is_execution_request: false, - function_data, - public_call_stack: BoundedVec::new(), - public_teardown_call_request: CallRequest::empty(), - proof: RecursiveProof::empty(), - vk: VerificationKey::empty(), - function_leaf_membership_witness: contract_function.membership_witness, - salted_initialization_hash: contract_data.salted_initialization_hash, - public_keys_hash: contract_data.public_keys_hash, - contract_class_artifact_hash: contract_data.artifact_hash, - contract_class_public_bytecode_commitment: contract_data.public_bytecode_commitment, - acir_hash: contract_function.acir_hash, - gas_settings: public_inputs.gas_settings - } - } - - pub fn is_delegate_call(&mut self) -> Self { - let _ = self.public_inputs.is_delegate_call(); - *self - } - - pub fn is_static_call(&mut self) -> Self { - let _ = self.public_inputs.is_static_call(); - *self - } - - pub fn build_tx_request(self) -> TxRequest { - let tx_context = self.public_inputs.build_tx_context(); - TxRequest { - origin: self.contract_address, - args_hash: self.public_inputs.args_hash, - tx_context, - function_data: self.function_data - } - } - - pub fn build_call_request(self) -> ScopedPrivateCallRequest { - let hash = self.build_call_stack_item().hash(); - let is_delegate_call = self.public_inputs.call_context.is_delegate_call; - let mut caller_context = CallerContext::empty(); - caller_context.is_static_call = self.public_inputs.call_context.is_static_call; - if is_delegate_call { - caller_context.msg_sender = fixtures::MSG_SENDER; - caller_context.storage_contract_address = self.public_inputs.call_context.storage_contract_address; - }; - PrivateCallRequest { - hash, - caller_context, - start_side_effect_counter: self.public_inputs.counter_start, - end_side_effect_counter: self.public_inputs.counter_end - }.scope(self.public_inputs.call_context.msg_sender) - } - - pub fn append_public_call_requests(&mut self, num_requests: u64, is_delegate_call: bool) { - let hash_offset = 7070 + self.public_call_stack.len() as Field; - for i in 0..self.public_call_stack.max_len() { - if i < num_requests { - let hash = hash_offset + i as Field; - let request = self.public_inputs.generate_call_request(hash, is_delegate_call); - self.public_call_stack.push(request); - self.public_inputs.add_public_call_request(hash); - } - } - } - - pub fn add_teardown_call_request(&mut self, is_delegate_call: bool) { - let hash = 909090; - self.public_teardown_call_request = self.public_inputs.generate_call_request(hash, is_delegate_call); - self.public_inputs.add_teardown_call_request(hash); - } - - fn build_call_stack_item(self) -> PrivateCallStackItem { - PrivateCallStackItem { - contract_address: self.contract_address, - function_data: self.function_data, - public_inputs: self.public_inputs.finish() - } - } - - pub fn get_call_stack_item_hash(self) -> Field { - self.build_call_stack_item().hash() - } - - pub fn finish(self) -> PrivateCallData { - PrivateCallData { - call_stack_item: self.build_call_stack_item(), - public_call_stack: self.public_call_stack.storage, - public_teardown_call_request: self.public_teardown_call_request, - proof: self.proof, - vk: self.vk, - function_leaf_membership_witness: self.function_leaf_membership_witness, - salted_initialization_hash: self.salted_initialization_hash, - public_keys_hash: self.public_keys_hash, - contract_class_artifact_hash: self.contract_class_artifact_hash, - contract_class_public_bytecode_commitment: self.contract_class_public_bytecode_commitment, - acir_hash: self.acir_hash - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr deleted file mode 100644 index 0089f82df85..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ /dev/null @@ -1,282 +0,0 @@ -use crate::{ - abis::{ - call_context::CallContext, call_request::CallRequest, caller_context::CallerContext, - gas_settings::GasSettings, gas::Gas, max_block_number::MaxBlockNumber, note_hash::NoteHash, - nullifier::Nullifier, - validation_requests::key_validation_request_and_generator::KeyValidationRequestAndGenerator, - private_call_request::PrivateCallRequest, private_circuit_public_inputs::PrivateCircuitPublicInputs, - read_request::ReadRequest, log_hash::{LogHash, NoteLogHash, EncryptedLogHash} -}, - address::{AztecAddress, compute_initialization_hash}, header::Header, - messaging::l2_to_l1_message::L2ToL1Message, tests::fixtures, transaction::tx_context::TxContext -}; -use crate::{ - constants::{ - MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, - MAX_KEY_VALIDATION_REQUESTS_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, MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL, - MAX_NOTE_ENCRYPTED_LOGS_PER_CALL -}, - traits::Empty -}; - -struct PrivateCircuitPublicInputsBuilder { - contract_address: AztecAddress, - call_context: CallContext, - - args_hash: Field, - returns_hash: Field, - - min_revertible_side_effect_counter: u32, - is_fee_payer: bool, - - max_block_number: MaxBlockNumber, - - note_hash_read_requests: BoundedVec, - nullifier_read_requests: BoundedVec, - key_validation_requests_and_generators: BoundedVec, - - new_note_hashes: BoundedVec, - new_nullifiers: BoundedVec, - - private_call_requests: BoundedVec, - public_call_stack_hashes: BoundedVec, - public_teardown_function_hash: Field, - new_l2_to_l1_msgs: BoundedVec, - - note_encrypted_logs_hashes: BoundedVec, - encrypted_logs_hashes: BoundedVec, - unencrypted_logs_hashes: BoundedVec, - - historical_header: Header, - - chain_id: Field, - version: Field, - - gas_settings: GasSettings, - - counter_start: u32, - counter_end: u32, -} - -impl PrivateCircuitPublicInputsBuilder { - pub fn new() -> Self { - PrivateCircuitPublicInputsBuilder::new_with_counter(0) - } - - pub fn new_with_counter(counter: u32) -> Self { - let mut public_inputs = PrivateCircuitPublicInputsBuilder::empty(); - - let contract_data = fixtures::contracts::default_contract; - let contract_function = fixtures::contract_functions::default_private_function; - let function_data = contract_function.data; - let contract_address = contract_data.address; - - public_inputs.contract_address = contract_address; - - public_inputs.call_context = CallContext { - msg_sender: fixtures::contracts::parent_contract.address, - storage_contract_address: contract_address, - function_selector: function_data.selector, - is_delegate_call: false, - is_static_call: false, - side_effect_counter: counter - }; - - public_inputs.chain_id = fixtures::CHAIN_ID; - public_inputs.version = fixtures::VERSION; - public_inputs.gas_settings = GasSettings::empty(); - public_inputs.counter_start = counter; - public_inputs.counter_end = counter + 1; - - public_inputs - } - - pub fn is_delegate_call(&mut self) -> Self { - self.call_context.is_delegate_call = true; - self.call_context.storage_contract_address = fixtures::contracts::parent_contract.address; - self.call_context.msg_sender = fixtures::MSG_SENDER; - *self - } - - pub fn is_static_call(&mut self) -> Self { - self.call_context.is_static_call = true; - *self - } - - pub fn build_tx_context(self) -> TxContext { - TxContext::new(self.chain_id, self.version, self.gas_settings) - } - - pub fn end_setup(&mut self) { - self.min_revertible_side_effect_counter = self.counter_end; - } - - pub fn set_tx_max_block_number(&mut self, max_block_number: u32) { - self.max_block_number = MaxBlockNumber::new(max_block_number); - } - - pub fn append_note_hash_read_requests(&mut self, num_reads: u64) { - let value_offset = self.note_hash_read_requests.len(); - for i in 0..self.note_hash_read_requests.max_len() { - if i < num_reads { - let read_request = ReadRequest { value: (value_offset + i + 987) as Field, counter: self.next_counter() }; - self.note_hash_read_requests.push(read_request); - } - } - } - - pub fn append_nullifier_read_requests(&mut self, num_reads: u64) { - let value_offset = self.nullifier_read_requests.len(); - for i in 0..self.nullifier_read_requests.max_len() { - if i < num_reads { - let read_request = ReadRequest { value: (value_offset + i + 3344) as Field, counter: self.next_counter() }; - self.nullifier_read_requests.push(read_request); - } - } - } - - pub fn add_new_note_hash(&mut self, value: Field) { - self.new_note_hashes.push(NoteHash { value, counter: self.next_counter() }); - } - - pub fn append_new_note_hashes(&mut self, count: u64) { - let value_offset = self.new_note_hashes.len(); - for i in 0..self.new_note_hashes.max_len() { - if i < count { - let mocked_value = 123123 + value_offset as Field; - self.add_new_note_hash(mocked_value); - } - } - } - - pub fn add_encrypted_log(&mut self, hash: Field, preimages_length: Field) { - let side_effect = EncryptedLogHash { value: hash, counter: self.next_counter(), length: preimages_length, randomness: 2 }; - self.encrypted_logs_hashes.push(side_effect); - } - - pub fn add_unencrypted_log(&mut self, hash: Field, preimages_length: Field) { - let side_effect = LogHash { value: hash, counter: self.next_counter(), length: preimages_length }; - self.unencrypted_logs_hashes.push(side_effect); - } - - pub fn generate_call_request(self, hash: Field, is_delegate_call: bool) -> CallRequest { - let mut caller_context = CallerContext::empty(); - if is_delegate_call { - caller_context.msg_sender = self.call_context.msg_sender; - caller_context.storage_contract_address = self.call_context.storage_contract_address; - } - CallRequest { - hash, - caller_contract_address: self.contract_address, - caller_context, - start_side_effect_counter: self.counter_end, - end_side_effect_counter: self.counter_end + 1 - } - } - - pub fn add_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let mut caller_context = CallerContext::empty(); - caller_context.is_static_call = self.call_context.is_static_call; - if is_delegate_call { - caller_context.msg_sender = self.call_context.msg_sender; - caller_context.storage_contract_address = self.call_context.storage_contract_address; - } - self.private_call_requests.push( - PrivateCallRequest { - hash, - caller_context, - start_side_effect_counter: self.next_counter(), - end_side_effect_counter: self.next_counter() - } - ); - } - - pub fn append_private_call_requests(&mut self, num_requests: u64, is_delegate_call: bool) { - let hash_offset = 7070 + self.private_call_requests.len(); - for i in 0..self.private_call_requests.max_len() { - if i < num_requests { - let hash = (hash_offset + i) as Field; - self.add_private_call_request(hash, is_delegate_call); - } - } - } - - pub fn add_public_call_request(&mut self, hash: Field) { - let _ = self.next_counter(); // Increment for creating the call - self.public_call_stack_hashes.push(hash); - let _ = self.next_counter(); // Increment for ending the call. - } - - pub fn add_teardown_call_request(&mut self, hash: Field) { - let _ = self.next_counter(); // Increment for creating the call - self.public_teardown_function_hash = hash; - let _ = self.next_counter(); // Increment for ending the call. - } - - pub fn finish(self) -> PrivateCircuitPublicInputs { - PrivateCircuitPublicInputs { - call_context: self.call_context, - args_hash: self.args_hash, - returns_hash: self.returns_hash, - min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, - is_fee_payer: self.is_fee_payer, - max_block_number: self.max_block_number, - note_hash_read_requests: self.note_hash_read_requests.storage, - nullifier_read_requests: self.nullifier_read_requests.storage, - key_validation_requests_and_generators: self.key_validation_requests_and_generators.storage, - new_note_hashes: self.new_note_hashes.storage, - new_nullifiers: self.new_nullifiers.storage, - private_call_requests: self.private_call_requests.storage, - public_call_stack_hashes: self.public_call_stack_hashes.storage, - public_teardown_function_hash: self.public_teardown_function_hash, - new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - start_side_effect_counter: self.counter_start, - end_side_effect_counter: self.counter_end, - note_encrypted_logs_hashes: self.note_encrypted_logs_hashes.storage, - encrypted_logs_hashes: self.encrypted_logs_hashes.storage, - unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, - historical_header: self.historical_header, - tx_context: self.build_tx_context() - } - } - - fn next_counter(&mut self) -> u32 { - let counter = self.counter_end; - self.counter_end += 1; - counter - } -} - -impl Empty for PrivateCircuitPublicInputsBuilder { - fn empty() -> Self { - PrivateCircuitPublicInputsBuilder { - contract_address: AztecAddress::empty(), - call_context: CallContext::empty(), - args_hash: 0, - returns_hash: 0, - min_revertible_side_effect_counter: 0 as u32, - is_fee_payer: false, - max_block_number: MaxBlockNumber::empty(), - note_hash_read_requests: BoundedVec::new(), - nullifier_read_requests: BoundedVec::new(), - key_validation_requests_and_generators: BoundedVec::new(), - new_note_hashes: BoundedVec::new(), - new_nullifiers: BoundedVec::new(), - private_call_requests: BoundedVec::new(), - public_call_stack_hashes: BoundedVec::new(), - public_teardown_function_hash: 0, - new_l2_to_l1_msgs: BoundedVec::new(), - note_encrypted_logs_hashes: BoundedVec::new(), - encrypted_logs_hashes: BoundedVec::new(), - unencrypted_logs_hashes: BoundedVec::new(), - historical_header: Header::empty(), - chain_id: 0, - version: 0, - gas_settings: GasSettings::empty(), - counter_start: 0, - counter_end: 0 - } - } -} From 7b9504e91aec63b55b22accd48c8a01622bec929 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Mon, 27 May 2024 10:46:32 +0000 Subject: [PATCH 07/13] Fix after merge. --- .../crates/private-kernel-lib/src/private_kernel_tail.nr | 4 ++-- .../private-kernel-lib/src/private_kernel_tail_to_public.nr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 0c1c37dfbfb..bf734e59c61 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -275,14 +275,14 @@ mod tests { // Logs for the previous call stack. let prev_encrypted_logs_hash = 80; let prev_encrypted_log_preimages_length = 13; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); // Set the randomness to 0 to signal not masking the address to silo with builder.previous_kernel.encrypted_logs_hashes.storage[0].log_hash.randomness = 0; let new_encrypted_logs_hash = 26; let new_encrypted_log_preimages_length = 50; - builder.previous_kernel.set_encrypted_logs(new_encrypted_logs_hash, new_encrypted_log_preimages_length); + builder.previous_kernel.add_encrypted_log_hash(new_encrypted_logs_hash, new_encrypted_log_preimages_length); let public_inputs = builder.execute(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index 1ccb7897703..49a01ad3541 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -186,7 +186,7 @@ mod tests { let sorted_unencrypted_log_hashes_indexes = sorted.sorted_index_hints; let sorted = sort_get_sorted_hints( - self.previous_kernel.public_call_stack.storage, + self.previous_kernel.public_call_requests.storage, |a: CallRequest, b: CallRequest| a.counter() > b.counter() ); let sorted_call_requests = sorted.sorted_array; From 026f359cce03ad7e287bc07909b429c31b8ffbf4 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Mon, 27 May 2024 19:30:34 +0000 Subject: [PATCH 08/13] Update tests. --- ...private_kernel_circuit_output_validator.nr | 21 ++++- ...e_kernel_circuit_public_inputs_composer.nr | 10 +-- .../validate_aggregated_values.nr | 82 +++++++++++++++++++ ...alidate_propagated_from_previous_kernel.nr | 14 ---- .../validate_propagated_from_private_call.nr | 78 ++++++++++++++---- ..._from_previous_kernel_with_private_call.nr | 32 ++++++++ .../new_from_tx_request.nr | 6 +- .../propagate_from_private_call.nr | 13 +++ 8 files changed, 214 insertions(+), 42 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 3affcb06b2c..5e583f6e6c2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -29,7 +29,8 @@ fn validate_array_appended( let mut should_check = false; let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; - for i in 0..dest.len() { + assert(items_propagated <= N, "number of total items exceeds limit"); + for i in 0..dest.len() { // Loop through dest instead of source because we also need to check that dest is appended with empty items. should_check |= i == num_prepended_items; // Prepended items have been checked in validate_array_prepended() and can be skipped here. if should_check { is_non_empty_item &= i != items_propagated; @@ -53,6 +54,7 @@ fn validate_array_appended_scoped( let mut should_check = false; let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; + assert(items_propagated <= N, "number of total items exceeds limit"); for i in 0..dest.len() { should_check |= i == num_prepended_items; if should_check { @@ -82,6 +84,7 @@ fn validate_array_appended_reversed_scoped( let mut should_check = false; let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; + assert(items_propagated <= N, "number of total items exceeds limit"); for i in 0..dest.len() { should_check |= i == num_prepended_items; if should_check { @@ -222,6 +225,19 @@ impl PrivateKernelCircuitOutputValidator { private_call: PrivateCircuitPublicInputs, public_teardown_call_request: CallRequest ) { + // min_revertible_side_effect_counter + let propagated_min_revertible_counter = if previous_kernel.min_revertible_side_effect_counter != 0 { + assert( + private_call.min_revertible_side_effect_counter == 0, "cannot overwrite min_revertible_side_effect_counter" + ); + previous_kernel.min_revertible_side_effect_counter + } else { + private_call.min_revertible_side_effect_counter + }; + assert_eq( + self.output.min_revertible_side_effect_counter, propagated_min_revertible_counter, "incorrect output min_revertible_side_effect_counter" + ); + // max_block_number let max_block_number = MaxBlockNumber::min( previous_kernel.validation_requests.for_rollup.max_block_number, @@ -260,9 +276,6 @@ impl PrivateKernelCircuitOutputValidator { array_lengths: PrivateKernelCircuitPublicInputsArrayLengths ) { assert_eq(self.output.constants, previous_kernel.constants, "mismatch constants"); - assert_eq( - self.output.min_revertible_side_effect_counter, previous_kernel.min_revertible_side_effect_counter, "mismatch min_revertible_side_effect_counter" - ); validate_array_prepended( self.output.validation_requests.note_hash_read_requests, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr index a6fbcb8c6db..a1e094ec4ec 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr @@ -42,8 +42,6 @@ impl PrivateKernelCircuitPublicInputsComposer { tx_request.tx_context, ); - public_inputs.min_revertible_side_effect_counter = private_call_public_inputs.min_revertible_side_effect_counter; - // Since it's the first iteration, we need to push the tx hash nullifier into the `new_nullifiers` array public_inputs.end.new_nullifiers.push(create_first_nullifier(tx_request)); // Note that we do not need to nullify the transaction request nonce anymore. @@ -127,10 +125,12 @@ impl PrivateKernelCircuitPublicInputsComposer { } fn propagate_min_revertible_side_effect_counter(&mut self, source: DataSource) { - self.public_inputs.min_revertible_side_effect_counter = if self.public_inputs.min_revertible_side_effect_counter > 0 { - self.public_inputs.min_revertible_side_effect_counter + if self.public_inputs.min_revertible_side_effect_counter != 0 { + assert( + source.private_call_public_inputs.min_revertible_side_effect_counter == 0, "cannot overwrite non-zero min_revertible_side_effect_counter" + ); } else { - source.private_call_public_inputs.min_revertible_side_effect_counter + self.public_inputs.min_revertible_side_effect_counter = source.private_call_public_inputs.min_revertible_side_effect_counter; }; } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr index 025b987257f..8e25e7fd781 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_aggregated_values.nr @@ -6,6 +6,70 @@ fn validate_aggregated_values_empty_data_succeeds() { builder.validate_as_inner_call(); } +/** + * min_revertible_side_effect_counter + */ + +#[test] +fn validate_aggregated_values_min_revertible_side_effect_counter_from_previous_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 123; + builder.output.min_revertible_side_effect_counter = 123; + + builder.validate_as_inner_call(); +} + +#[test] +fn validate_aggregated_values_min_revertible_side_effect_counter_from_private_call_succeeds() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 123; + builder.output.min_revertible_side_effect_counter = 123; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="cannot overwrite min_revertible_side_effect_counter")] +fn validate_aggregated_values_min_revertible_side_effect_counter_overwrite_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 123; + builder.private_call.min_revertible_side_effect_counter = 4567; + builder.output.min_revertible_side_effect_counter = 123; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output min_revertible_side_effect_counter")] +fn validate_aggregated_values_min_revertible_side_effect_counter_from_previous_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 123; + builder.output.min_revertible_side_effect_counter = 4567; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output min_revertible_side_effect_counter")] +fn validate_aggregated_values_min_revertible_side_effect_counter_from_private_call_mismatch_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 123; + builder.output.min_revertible_side_effect_counter = 4567; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="incorrect output min_revertible_side_effect_counter")] +fn validate_aggregated_values_min_revertible_side_effect_counter_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.min_revertible_side_effect_counter = 123; + + builder.validate_as_inner_call(); +} + /** * max_block_number */ @@ -142,6 +206,15 @@ fn validate_aggregated_values_public_teardown_call_request_from_private_call_mis builder.validate_as_inner_call(); } +#[test(should_fail_with="incorrect output public_teardown_call_request")] +fn validate_aggregated_values_public_teardown_call_request_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.append_public_teardown_call_request(); + + builder.validate_as_inner_call(); +} + /** * fee_payer */ @@ -200,3 +273,12 @@ fn validate_aggregated_values_fee_payer_from_private_call_mismatch_fails() { builder.validate_as_inner_call(); } + +#[test(should_fail_with="incorrect output fee_payer")] +fn validate_aggregated_values_fee_payer_random_output_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + builder.output.set_fee_payer(builder.private_call.storage_contract_address); + + builder.validate_as_inner_call(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr index 5116c29bcdf..de27661df47 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_previous_kernel.nr @@ -37,20 +37,6 @@ fn validate_propagated_from_previous_kernel_constants_non_empty_global_variables builder.validate_as_inner_call(); } -/** -* min_revertible_side_effect_counter -*/ - -#[test(should_fail_with="mismatch min_revertible_side_effect_counter")] -fn validate_propagated_from_previous_kernel_min_revertible_side_effect_counter_mismatch_fails() { - let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - - builder.previous_kernel.min_revertible_side_effect_counter = 8989; - builder.output.min_revertible_side_effect_counter = 50; - - builder.validate_as_inner_call(); -} - /** * note_hash_read_requests */ diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr index 156a29154c1..71df944d90f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr @@ -1,5 +1,4 @@ use crate::tests::private_kernel_circuit_output_validator_builder::PrivateKernelCircuitOutputValidatorBuilder; -use dep::types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL; #[test] fn validate_propagated_from_private_call_empty_data_succeeds() { @@ -74,8 +73,9 @@ fn validate_propagated_from_private_call_note_hash_read_requests_output_extra_no builder.private_call.append_note_hash_read_requests(2); builder.output.append_note_hash_read_requests(2); - // Add a non-empty item to the output. - builder.output.note_hash_read_requests.storage[MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = builder.output.note_hash_read_requests.storage[0]; + // Add a non-empty item to the end of the output. + let len = builder.output.note_hash_read_requests.storage.len(); + builder.output.note_hash_read_requests.storage[len - 1] = builder.output.note_hash_read_requests.storage[0]; builder.validate_as_inner_call(); } @@ -85,17 +85,20 @@ fn validate_propagated_from_private_call_note_hash_read_requests_output_extra_no * With previous kernel. */ -fn append_note_hash_read_requests_to_previous_kernel(builder: &mut PrivateKernelCircuitOutputValidatorBuilder) { - builder.previous_kernel.append_note_hash_read_requests(3); - builder.output.append_note_hash_read_requests(3); - builder.offset_values(3); +fn append_note_hash_read_requests_to_previous_kernel( + builder: &mut PrivateKernelCircuitOutputValidatorBuilder, + num_requests: u64 +) { + builder.previous_kernel.append_note_hash_read_requests(num_requests); + builder.output.append_note_hash_read_requests(num_requests); + builder.offset_values(num_requests as Field); } #[test] fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); builder.output.append_note_hash_read_requests(2); @@ -106,7 +109,7 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_s fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_mismatch_value_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); builder.output.append_note_hash_read_requests(2); // Tweak the value in the output. @@ -119,7 +122,7 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_m fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_mismatch_contract_address_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); builder.output.append_note_hash_read_requests(2); // Tweak the contract address in the output. @@ -132,7 +135,7 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_m fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_one_less_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); // Propagate 1 less item to the output. builder.output.append_note_hash_read_requests(1); @@ -144,7 +147,7 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_o fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_one_more_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); // Propagate 1 more item to the output. builder.output.append_note_hash_read_requests(3); @@ -156,11 +159,25 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_o fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_extra_non_empty_fails() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); - append_note_hash_read_requests_to_previous_kernel(&mut builder); + append_note_hash_read_requests_to_previous_kernel(&mut builder, 3); builder.private_call.append_note_hash_read_requests(2); builder.output.append_note_hash_read_requests(2); - // Add a non-empty item to the output. - builder.output.note_hash_read_requests.storage[MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = builder.output.note_hash_read_requests.storage[0]; + // Add a non-empty item to the end of the output. + let len = builder.output.note_hash_read_requests.storage.len(); + builder.output.note_hash_read_requests.storage[len - 1] = builder.output.note_hash_read_requests.storage[0]; + + builder.validate_as_inner_call(); +} + +#[test(should_fail_with="number of total items exceeds limit")] +fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_output_exceeds_max_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + // Make the previous array to be full, therefore no more items can be added. + let max_len = builder.output.note_hash_read_requests.max_len(); + append_note_hash_read_requests_to_previous_kernel(&mut builder, max_len); + // Add 1 item to the current call. + builder.private_call.append_note_hash_read_requests(1); builder.validate_as_inner_call(); } @@ -410,6 +427,20 @@ fn validate_propagated_from_private_call_note_encrypted_log_hashes_output_one_mo builder.validate_as_inner_call(); } +#[test(should_fail_with="number of total items exceeds limit")] +fn validate_propagated_from_private_call_note_encrypted_log_hashes_with_previous_output_exceeds_max_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + // Make the previous array to be full, therefore no more items can be added. + let max_len = builder.previous_kernel.note_encrypted_logs_hashes.max_len(); + builder.previous_kernel.append_note_encrypted_log_hashes(max_len); + builder.output.append_note_encrypted_log_hashes(max_len); + // Add 1 item to the current call. + builder.private_call.append_note_encrypted_log_hashes(1); + + builder.validate_as_inner_call(); +} + /** * encrypted_log_hashes */ @@ -489,7 +520,7 @@ fn validate_propagated_from_private_call_private_call_requests_not_reversed_fail } #[test] -fn validate_propagated_from_private_call_private_call_requests_with_private_call_succeeds() { +fn validate_propagated_from_private_call_private_call_requests_with_previous_output_succeeds() { let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); builder.output.append_private_call_requests(5); @@ -508,6 +539,21 @@ fn validate_propagated_from_private_call_private_call_requests_with_private_call builder.validate_as_inner_call(); } +#[test(should_fail_with="number of total items exceeds limit")] +fn validate_propagated_from_private_call_private_call_requests_with_previous_output_exceeds_max_fails() { + let mut builder = PrivateKernelCircuitOutputValidatorBuilder::new(); + + // Make the previous array to be full, therefore no more items can be added. + // Minus one because an extra request for the current call will be added in validate_as_inner_call(). + let max_len = builder.previous_kernel.private_call_requests.max_len() - 1; + builder.previous_kernel.append_private_call_requests(max_len); + builder.output.append_private_call_requests(max_len); + // Add 2 item to the current call. + builder.private_call.append_private_call_requests(2); + + builder.validate_as_inner_call(); +} + /** * public_call_requests */ diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index d4dab26bce0..d57f789993d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -19,6 +19,38 @@ fn new_from_previous_kernel_with_private_call_empty_data_succeeds() { assert(is_empty(output.fee_payer)); } +#[test] +fn new_from_previous_kernel_with_private_call_min_revertible_side_effect_counter_prev_empty_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 123; + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.min_revertible_side_effect_counter, 123); +} + +#[test] +fn new_from_previous_kernel_with_private_call_min_revertible_side_effect_counter_curr_empty_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 123; + + let output = builder.compose_from_previous_kernel(); + + assert_eq(output.min_revertible_side_effect_counter, 123); +} + +#[test(should_fail_with="cannot overwrite non-zero min_revertible_side_effect_counter")] +fn new_from_previous_kernel_with_private_call_min_revertible_side_effect_counter_overwrite_fails() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.previous_kernel.min_revertible_side_effect_counter = 123; + builder.private_call.min_revertible_side_effect_counter = 123; + + let _ = builder.compose_from_previous_kernel(); +} + #[test] fn new_from_previous_kernel_with_private_call_max_block_number_prev_empty_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr index 458f22d1984..9333d1b101e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr @@ -16,7 +16,6 @@ fn new_from_tx_request_succeeds() { builder.private_call.historical_header.total_fees = 979797; builder.private_call.historical_header.content_commitment.out_hash = 122122; let historical_header = builder.private_call.historical_header; - builder.private_call.min_revertible_side_effect_counter = 37; let output = builder.new_from_tx_request().public_inputs.finish(); @@ -25,8 +24,7 @@ fn new_from_tx_request_succeeds() { assert_eq(output.constants.historical_header, historical_header); assert(is_empty(output.constants.global_variables)); - // Check output requests and accumulated data. - assert_eq(output.min_revertible_side_effect_counter, 37); + // Check first nullifier is set. assert_eq(output.end.new_nullifiers[0], first_nullifier); let array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(output); @@ -35,6 +33,8 @@ fn new_from_tx_request_succeeds() { assert_eq(array_lengths, expected_array_lengths); // Check values default to empty. + assert_eq(output.min_revertible_side_effect_counter, 0); + assert(is_empty(output.validation_requests)); assert(output.validation_requests.for_rollup.max_block_number.is_none()); assert(is_empty(output.public_teardown_call_request)); assert(is_empty(output.fee_payer)); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index 467356c8425..b104192ad26 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -23,11 +23,24 @@ fn propagate_from_private_call_empty_data_succeeds() { expected_array_lengths.new_nullifiers = 1; assert_eq(array_lengths, expected_array_lengths); + assert_eq(output.min_revertible_side_effect_counter, 0); + assert(is_empty(output.validation_requests)); assert(output.validation_requests.for_rollup.max_block_number.is_none()); assert(is_empty(output.public_teardown_call_request)); assert(is_empty(output.fee_payer)); } +#[test] +fn propagate_from_private_call_min_revertible_side_effect_counter_succeeds() { + let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); + + builder.private_call.min_revertible_side_effect_counter = 123; + + let output = builder.compose_from_tx_request(); + + assert_eq(output.min_revertible_side_effect_counter, 123); +} + #[test] fn propagate_from_private_call_max_block_number_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); From 7b4584b06215b409599b08bbd864e45c66a7f703 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Tue, 28 May 2024 08:10:27 +0000 Subject: [PATCH 09/13] Fix fixtures. --- .../crates/public-kernel-lib/src/public_kernel_app_logic.nr | 2 +- .../crates/public-kernel-lib/src/public_kernel_setup.nr | 2 +- .../crates/public-kernel-lib/src/public_kernel_teardown.nr | 2 +- .../crates/types/src/tests/fixture_builder.nr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr index bceaef1c5b5..bf40391ba37 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -121,7 +121,7 @@ mod tests { impl PublicKernelAppLogicCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = FixtureBuilder::new(); + let previous_kernel = FixtureBuilder::new().as_parent_contract(); let public_call = PublicCallDataBuilder::new(); PublicKernelAppLogicCircuitPrivateInputsBuilder { previous_kernel, public_call } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr index a1dbe2d7e5c..b42b8e8c7f2 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -107,7 +107,7 @@ mod tests { impl PublicKernelSetupCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = FixtureBuilder::new(); + let previous_kernel = FixtureBuilder::new().as_parent_contract(); let previous_revertible = FixtureBuilder::new(); let public_call = PublicCallDataBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr index 63be4f85b32..e0d8298b8d4 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr @@ -171,7 +171,7 @@ mod tests { impl PublicKernelTeardownCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = FixtureBuilder::new(); + let previous_kernel = FixtureBuilder::new().as_parent_contract(); let previous_revertible = FixtureBuilder::new(); let public_call = PublicCallDataBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 75949ad7a6f..680eec11116 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -745,7 +745,7 @@ impl FixtureBuilder { let mut caller_context = CallerContext::empty(); if is_delegate_call { caller_context.msg_sender = self.msg_sender; - caller_context.storage_contract_address = self.contract_address; + caller_context.storage_contract_address = self.storage_contract_address; } let start_counter = self.next_counter(); CallRequest { From 3dfd361091a68127ea3242de7437b9a18e567586 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Tue, 28 May 2024 10:06:20 +0000 Subject: [PATCH 10/13] Move components to folder. --- .../crates/private-kernel-lib/src/components.nr | 3 +++ .../kernel_circuit_public_inputs_composer.nr | 0 .../src/{ => components}/private_call_data_validator.nr | 0 .../private_kernel_circuit_output_validator.nr | 2 +- .../private_kernel_circuit_public_inputs_composer.nr | 0 .../crates/private-kernel-lib/src/lib.nr | 5 +---- .../crates/private-kernel-lib/src/private_kernel_init.nr | 9 ++++----- .../private-kernel-lib/src/private_kernel_inner.nr | 9 ++++----- .../private-kernel-lib/src/private_kernel_reset.nr | 1 - .../crates/private-kernel-lib/src/private_kernel_tail.nr | 2 +- .../src/private_kernel_tail_to_public.nr | 2 +- .../src/tests/private_call_data_validator_builder.nr | 2 +- .../validate_against_previous_kernel.nr | 2 +- .../private_kernel_circuit_output_validator_builder.nr | 4 +++- ...vate_kernel_circuit_public_inputs_composer_builder.nr | 2 +- .../new_from_tx_request.nr | 2 +- .../propagate_from_private_call.nr | 2 +- 17 files changed, 23 insertions(+), 24 deletions(-) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/{ => components}/kernel_circuit_public_inputs_composer.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/{ => components}/private_call_data_validator.nr (100%) rename noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/{ => components}/private_kernel_circuit_public_inputs_composer.nr (100%) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr index 39a4d96f650..8d23a10f943 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components.nr @@ -1 +1,4 @@ +mod kernel_circuit_public_inputs_composer; +mod private_call_data_validator; mod private_kernel_circuit_output_validator; +mod private_kernel_circuit_public_inputs_composer; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/kernel_circuit_public_inputs_composer.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_call_data_validator.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 5e583f6e6c2..88c4a89b7ac 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -1,4 +1,4 @@ -use crate::private_kernel_circuit_public_inputs_composer::create_first_nullifier; +use crate::components::private_kernel_circuit_public_inputs_composer::create_first_nullifier; use dep::types::{ abis::{ call_request::CallRequest, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_circuit_public_inputs_composer.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr index a5d91a004c9..4bf3805a70b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr @@ -1,13 +1,10 @@ mod components; -mod kernel_circuit_public_inputs_composer; -mod private_call_data_validator; -mod private_kernel_circuit_public_inputs_composer; mod private_kernel_init; mod private_kernel_inner; mod private_kernel_tail; mod private_kernel_tail_to_public; -mod tests; mod private_kernel_reset; +mod tests; use private_kernel_init::PrivateKernelInitCircuitPrivateInputs; use private_kernel_inner::PrivateKernelInnerCircuitPrivateInputs; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 1c1ac50824b..008818fb3e3 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -1,7 +1,9 @@ use crate::{ - components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, + components::{ private_call_data_validator::PrivateCallDataValidator, + private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer +} }; use dep::types::{ abis::{ @@ -24,10 +26,7 @@ struct PrivateKernelInitCircuitPrivateInputs { } impl PrivateKernelInitCircuitPrivateInputs { - unconstrained fn prepare_output( - self, - private_call_data_validator: PrivateCallDataValidator - ) -> PrivateKernelCircuitPublicInputs { + unconstrained fn prepare_output(self, private_call_data_validator: PrivateCallDataValidator) -> PrivateKernelCircuitPublicInputs { let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call_public_inputs).compose( private_call_public_inputs, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 76a34e08847..8a5a8a6a30a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -1,7 +1,9 @@ use crate::{ - components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, + components::{ private_call_data_validator::PrivateCallDataValidator, + private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer +} }; use dep::types::{ abis::{ @@ -22,10 +24,7 @@ struct PrivateKernelInnerCircuitPrivateInputs { } impl PrivateKernelInnerCircuitPrivateInputs { - unconstrained fn prepare_output( - self, - private_call_data_validator: PrivateCallDataValidator - ) -> PrivateKernelCircuitPublicInputs { + unconstrained fn prepare_output(self, private_call_data_validator: PrivateCallDataValidator) -> PrivateKernelCircuitPublicInputs { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( self.private_call.call_stack_item.public_inputs, private_call_data_validator.array_lengths, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index 2b135ac37b2..7991d9ffeac 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -1,4 +1,3 @@ -use crate::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; use dep::reset_kernel_lib::{ NoteHashReadRequestHints, NullifierReadRequestHints, PrivateValidationRequestProcessor, verify_squashed_transient_note_hashes_and_nullifiers, reset::key_validation_hint::KeyValidationHint diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index bf734e59c61..0c7d3f1c39c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -1,4 +1,4 @@ -use crate::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; +use crate::components::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; use dep::types::{ abis::{ private_kernel_data::PrivateKernelData, kernel_circuit_public_inputs::KernelCircuitPublicInputs, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index 49a01ad3541..be6771e4c7b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -1,4 +1,4 @@ -use crate::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; +use crate::components::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; use dep::types::{ abis::{ private_kernel_data::PrivateKernelData, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr index da8a51355b3..d63961a157d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr @@ -9,7 +9,7 @@ mod validate_contract_address; mod validate_counters; mod validate_private_call_requests; -use crate::private_call_data_validator::PrivateCallDataValidator; +use crate::components::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ abis::{private_kernel::private_call_data::PrivateCallData, private_call_request::ScopedPrivateCallRequest}, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr index b40f7408b38..20eebb7c838 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr @@ -1,5 +1,5 @@ use crate::{ - private_call_data_validator::PrivateCallDataValidator, + components::private_call_data_validator::PrivateCallDataValidator, tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder }; use dep::types::{ diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr index 12ea9825282..d52c6cf82b1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder.nr @@ -4,8 +4,10 @@ mod validate_propagated_from_previous_kernel; mod validate_propagated_from_private_call; use crate::{ - components::private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, + components::{ + private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, private_kernel_circuit_public_inputs_composer::create_first_nullifier +} }; use dep::types::{ abis::{ diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr index 368ffb8fd2f..232e002b947 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr @@ -2,7 +2,7 @@ mod new_from_previous_kernel_with_private_call; mod new_from_tx_request; mod propagate_from_private_call; -use crate::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; +use crate::components::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr index 9333d1b101e..b29457dee8a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr @@ -1,5 +1,5 @@ use crate::{ - private_kernel_circuit_public_inputs_composer::create_first_nullifier, + components::private_kernel_circuit_public_inputs_composer::create_first_nullifier, tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder }; use dep::types::{abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty}; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index b104192ad26..de1de963e91 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -1,5 +1,5 @@ use crate::{ - private_kernel_circuit_public_inputs_composer::create_first_nullifier, + components::private_kernel_circuit_public_inputs_composer::create_first_nullifier, tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder }; use dep::types::{ From 7d06e86301c8b6fa926d8b80d3a671cb1d1c097a Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Tue, 28 May 2024 16:46:18 +0000 Subject: [PATCH 11/13] Address feedback. --- .../private-kernel-init-simulated/src/main.nr | 2 +- .../src/main.nr | 2 +- ...private_kernel_circuit_output_validator.nr | 18 +++--- .../src/private_kernel_init.nr | 41 ++++++-------- .../src/private_kernel_inner.nr | 55 ++++++++----------- 5 files changed, 53 insertions(+), 65 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr index 4f78ecb91b8..af1a989750b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr @@ -2,5 +2,5 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.simulate() + input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr index e8d723f2b0d..75d54f4f319 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr @@ -2,5 +2,5 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { - input.simulate() + input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 88c4a89b7ac..1a241a3fddf 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -26,14 +26,14 @@ fn validate_array_appended( num_source_items: u64, num_prepended_items: u64 ) where T: Empty + Eq { - let mut should_check = false; - let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); + let mut should_check = false; + let mut is_non_empty_item = true; for i in 0..dest.len() { // Loop through dest instead of source because we also need to check that dest is appended with empty items. should_check |= i == num_prepended_items; // Prepended items have been checked in validate_array_prepended() and can be skipped here. + is_non_empty_item &= i != items_propagated; if should_check { - is_non_empty_item &= i != items_propagated; if is_non_empty_item { assert_eq(dest[i], source[i - num_prepended_items], "source item does not append to dest"); } else { @@ -51,14 +51,14 @@ fn validate_array_appended_scoped( num_prepended_items: u64, contract_address: AztecAddress ) where ST: Scoped + Empty + Eq, T: Eq { - let mut should_check = false; - let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); + let mut should_check = false; + let mut is_non_empty_item = true; for i in 0..dest.len() { should_check |= i == num_prepended_items; + is_non_empty_item &= i != items_propagated; if should_check { - is_non_empty_item &= i != items_propagated; if is_non_empty_item { assert_eq( dest[i].inner(), source[i - num_prepended_items], "source item does not append to dest" @@ -81,14 +81,14 @@ fn validate_array_appended_reversed_scoped( num_prepended_items: u64, contract_address: AztecAddress ) where ST: Scoped + Empty + Eq, T: Eq { - let mut should_check = false; - let mut is_non_empty_item = true; let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); + let mut should_check = false; + let mut is_non_empty_item = true; for i in 0..dest.len() { should_check |= i == num_prepended_items; + is_non_empty_item &= i != items_propagated; if should_check { - is_non_empty_item &= i != items_propagated; if is_non_empty_item { assert_eq( dest[i].inner(), source[items_propagated - i - 1], "source item does not reversed append to dest" diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 008818fb3e3..49a54c27842 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -38,35 +38,30 @@ impl PrivateKernelInitCircuitPrivateInputs { ).finish() } - fn validate_inputs(self) -> PrivateCallDataValidator { + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + // Validate inputs. let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); private_call_data_validator.validate(); private_call_data_validator.validate_as_first_call(self.hints.first_revertible_private_call_request_index); private_call_data_validator.validate_against_tx_request(self.tx_request); - private_call_data_validator - } - - pub fn simulate(self) -> PrivateKernelCircuitPublicInputs { - let private_call_data_validator = self.validate_inputs(); - self.prepare_output(private_call_data_validator) - } - - pub fn execute(self) -> PrivateKernelCircuitPublicInputs { - // verify/aggregate the private call proof - self.private_call.verify(); - let private_call_data_validator = self.validate_inputs(); + if !dep::std::runtime::is_unconstrained() { + // verify/aggregate the private call proof + self.private_call.verify(); + } + // Validate output. let output = self.prepare_output(private_call_data_validator); - let output_validator = PrivateKernelCircuitOutputValidator::new(output); - output_validator.validate_as_first_call( - self.tx_request, - self.private_call.call_stack_item.public_inputs, - private_call_data_validator.array_lengths, - self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, - self.private_call.public_call_stack, - self.private_call.public_teardown_call_request - ); + if !dep::std::runtime::is_unconstrained() { + PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( + self.tx_request, + self.private_call.call_stack_item.public_inputs, + private_call_data_validator.array_lengths, + self.private_call.call_stack_item.contract_address, + self.hints.note_hash_nullifier_counters, + self.private_call.public_call_stack, + self.private_call.public_teardown_call_request + ); + } output } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 8a5a8a6a30a..9f386578379 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -10,7 +10,7 @@ use dep::types::{ kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, private_kernel_data::PrivateKernelData, private_kernel::private_call_data::PrivateCallData }, - constants::MAX_NEW_NOTE_HASHES_PER_CALL, utils::arrays::array_length + constants::MAX_NEW_NOTE_HASHES_PER_CALL }; struct PrivateKernelInnerHints { @@ -35,43 +35,36 @@ impl PrivateKernelInnerCircuitPrivateInputs { ).finish() } - fn validate_inputs(self, private_call_stack_size: u64) -> PrivateCallDataValidator { + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + // Validate inputs. + let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); private_call_data_validator.validate(); + let private_call_stack_size = previous_kernel_array_lengths.private_call_stack; let call_request = self.previous_kernel.public_inputs.end.private_call_stack[private_call_stack_size - 1]; private_call_data_validator.validate_against_call_request(call_request); private_call_data_validator.validate_against_previous_kernel(self.previous_kernel.public_inputs); - private_call_data_validator - } - - pub fn simulate(self) -> PrivateKernelCircuitPublicInputs { - let private_call_stack_size = array_length(self.previous_kernel.public_inputs.end.private_call_stack); - let private_call_data_validator = self.validate_inputs(private_call_stack_size); - self.prepare_output(private_call_data_validator) - } - - pub fn execute(self) -> PrivateKernelCircuitPublicInputs { - // verify/aggregate the private call proof - self.private_call.verify(); - - // verify/aggregate the previous kernel - self.previous_kernel.verify(); - - let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); - let private_call_data_validator = self.validate_inputs(previous_kernel_array_lengths.private_call_stack); + if !dep::std::runtime::is_unconstrained() { + // verify/aggregate the private call proof + self.private_call.verify(); + // verify/aggregate the previous kernel + self.previous_kernel.verify(); + } + // Validate output. let output = self.prepare_output(private_call_data_validator); - let output_validator = PrivateKernelCircuitOutputValidator::new(output); - output_validator.validate_as_inner_call( - self.previous_kernel.public_inputs, - previous_kernel_array_lengths, - self.private_call.call_stack_item.public_inputs, - private_call_data_validator.array_lengths, - self.private_call.call_stack_item.contract_address, - self.hints.note_hash_nullifier_counters, - self.private_call.public_call_stack, - self.private_call.public_teardown_call_request - ); + if !dep::std::runtime::is_unconstrained() { + PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( + self.previous_kernel.public_inputs, + previous_kernel_array_lengths, + self.private_call.call_stack_item.public_inputs, + private_call_data_validator.array_lengths, + self.private_call.call_stack_item.contract_address, + self.hints.note_hash_nullifier_counters, + self.private_call.public_call_stack, + self.private_call.public_teardown_call_request + ); + } output } } From b97e523ccb2616298bc0b3710b720e1adeb5f456 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Tue, 28 May 2024 23:12:28 +0000 Subject: [PATCH 12/13] Check note logs in private call data validator. --- .../components/private_call_data_validator.nr | 41 +++++++++++++--- ...e_kernel_circuit_public_inputs_composer.nr | 23 ++------- .../src/private_kernel_init.nr | 13 ++--- .../src/private_kernel_inner.nr | 11 +++-- .../private_call_data_validator_builder.nr | 19 ++++---- .../validate_call_requests.nr | 16 ++++++- .../validate_note_logs.nr | 48 +++++++++++++++++++ ..._circuit_public_inputs_composer_builder.nr | 7 +-- ..._from_previous_kernel_with_private_call.nr | 27 +---------- .../propagate_from_private_call.nr | 42 +--------------- 10 files changed, 126 insertions(+), 121 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr index 875ec4cfecc..5fbb2037846 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr @@ -1,16 +1,24 @@ use dep::types::{ abis::{ call_context::CallContext, call_request::CallRequest, caller_context::CallerContext, - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - private_call_request::ScopedPrivateCallRequest, private_call_stack_item::PrivateCallStackItem, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::NoteLogHash, + note_hash::ScopedNoteHash, private_call_request::ScopedPrivateCallRequest, + private_call_stack_item::PrivateCallStackItem, private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths, private_kernel::private_call_data::PrivateCallData, side_effect::{Ordered, RangeOrdered} }, address::{AztecAddress, PartialAddress}, contract_class_id::ContractClassId, hash::{private_functions_root_from_siblings, stdlib_recursion_verification_key_compress_native_vk}, - traits::is_empty, transaction::tx_request::TxRequest + traits::is_empty, transaction::tx_request::TxRequest, utils::arrays::find_index }; +unconstrained fn match_log_to_note(note_log: NoteLogHash, accumulated_note_hashes: [ScopedNoteHash; N]) -> u64 { + find_index( + accumulated_note_hashes, + |n: ScopedNoteHash| n.counter() == note_log.note_hash_counter + ) +} + fn validate_caller_context(caller_context: CallerContext, this_context: CallContext) { let matching_caller_context = caller_context.msg_sender.eq(this_context.msg_sender) & caller_context.storage_contract_address.eq(this_context.storage_contract_address); @@ -107,13 +115,14 @@ impl PrivateCallDataValidator { PrivateCallDataValidator { data, array_lengths } } - pub fn validate(self) { + pub fn validate(self, accumulated_note_hashes: [ScopedNoteHash; N]) { self.validate_contract_address(); self.validate_call(); self.validate_private_call_requests(); self.validate_public_call_requests(); self.validate_teardown_call_request(); self.validate_counters(); + self.validate_note_logs(accumulated_note_hashes); } pub fn validate_as_first_call(self, first_revertible_private_call_request_index: u64) { @@ -188,8 +197,7 @@ impl PrivateCallDataValidator { let public_inputs = self.data.call_stack_item.public_inputs; assert_eq(public_inputs.historical_header, constants.historical_header, "mismatch historical header"); assert_eq(public_inputs.tx_context, constants.tx_context, "mismatch tx context"); - // constants.global_variables refers to the states shared among all txs in a block. - // It should be empty when executing private functions (initialized in PrivateKernelCircuitPublicInputsComposer.new_from_tx_request()). + // constants.global_variables is not relevant to private functions and is ensured to be empty in PrivateKernelCircuitOutputValidator. } fn validate_contract_address(self) { @@ -371,4 +379,25 @@ impl PrivateCallDataValidator { teardown_call_request_count ); } + + fn validate_note_logs(self, accumulated_note_hashes: [ScopedNoteHash; N]) { + let note_logs = self.data.call_stack_item.public_inputs.note_encrypted_logs_hashes; + let num_logs = self.array_lengths.note_encrypted_logs_hashes; + let storage_contract_address = self.data.call_stack_item.public_inputs.call_context.storage_contract_address; + let mut should_check = true; + for i in 0..note_logs.len() { + should_check &= i != num_logs; + if should_check { + let note_index = match_log_to_note(note_logs[i], accumulated_note_hashes); + assert(note_index != N, "could not find note hash linked to note log"); + assert_eq( + note_logs[i].note_hash_counter, accumulated_note_hashes[note_index].counter(), "could not find note hash linked to note log" + ); + // If the note_index points to an empty note hash, the following check will fail. + assert_eq( + accumulated_note_hashes[note_index].contract_address, storage_contract_address, "could not link a note log to a note hash in another contract" + ); + } + } + } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr index a1e094ec4ec..b11bf4e76fc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr @@ -3,8 +3,7 @@ use dep::types::{ call_request::CallRequest, combined_constant_data::CombinedConstantData, kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, max_block_number::MaxBlockNumber, nullifier::{Nullifier, ScopedNullifier}, - note_hash::ScopedNoteHash, log_hash::NoteLogHash, - private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths} + private_circuit_public_inputs::PrivateCircuitPublicInputs }, address::AztecAddress, constants::{ @@ -12,12 +11,11 @@ use dep::types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL }, traits::is_empty, transaction::tx_request::TxRequest, - utils::arrays::{array_to_bounded_vec, find_index} + utils::arrays::{array_length, array_to_bounded_vec} }; struct DataSource { private_call_public_inputs: PrivateCircuitPublicInputs, - array_lengths: PrivateCircuitPublicInputsArrayLengths, contract_address: AztecAddress, storage_contract_address: AztecAddress, note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], @@ -83,7 +81,6 @@ impl PrivateKernelCircuitPublicInputsComposer { pub fn compose( &mut self, private_call_public_inputs: PrivateCircuitPublicInputs, - array_lengths: PrivateCircuitPublicInputsArrayLengths, contract_address: AztecAddress, note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], public_call_requests: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], @@ -92,7 +89,6 @@ impl PrivateKernelCircuitPublicInputsComposer { let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; let source = DataSource { private_call_public_inputs, - array_lengths, contract_address, storage_contract_address, note_hash_nullifier_counters, @@ -221,29 +217,16 @@ impl PrivateKernelCircuitPublicInputsComposer { } let note_logs = source.private_call_public_inputs.note_encrypted_logs_hashes; - let new_note_hashes = self.public_inputs.end.new_note_hashes; for i in 0..note_logs.len() { if !is_empty(note_logs[i]) { - let note_index = self.match_log_to_note(note_logs[i]); - assert(note_index < new_note_hashes.len(), "Could not find note hash linked to note log"); - assert_eq( - note_logs[i].note_hash_counter, new_note_hashes.get_unchecked(note_index).counter(), "Could not find note hash linked to note log" - ); self.public_inputs.end.note_encrypted_logs_hashes.push(note_logs[i]); } } } - unconstrained fn match_log_to_note(self, note_log: NoteLogHash) -> u64 { - find_index( - self.public_inputs.end.new_note_hashes.storage, - |n: ScopedNoteHash| n.counter() == note_log.note_hash_counter - ) - } - fn propagate_private_call_requests(&mut self, source: DataSource) { let call_requests = source.private_call_public_inputs.private_call_requests; - let num_requests = source.array_lengths.private_call_requests; + let num_requests = array_length(call_requests); let mut proceed = true; for i in 0..call_requests.len() { proceed &= i != num_requests; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 49a54c27842..b15a9a124b7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -7,8 +7,8 @@ use crate::{ }; use dep::types::{ abis::{ - private_kernel::private_call_data::PrivateCallData, - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_kernel::private_call_data::PrivateCallData }, constants::MAX_NEW_NOTE_HASHES_PER_CALL, transaction::tx_request::TxRequest }; @@ -26,11 +26,10 @@ struct PrivateKernelInitCircuitPrivateInputs { } impl PrivateKernelInitCircuitPrivateInputs { - unconstrained fn prepare_output(self, private_call_data_validator: PrivateCallDataValidator) -> PrivateKernelCircuitPublicInputs { + unconstrained fn generate_output(self) -> PrivateKernelCircuitPublicInputs { let private_call_public_inputs = self.private_call.call_stack_item.public_inputs; PrivateKernelCircuitPublicInputsComposer::new_from_tx_request(self.tx_request, private_call_public_inputs).compose( private_call_public_inputs, - private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, @@ -39,18 +38,20 @@ impl PrivateKernelInitCircuitPrivateInputs { } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + // Generate output. + let output = self.generate_output(); + // Validate inputs. let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); - private_call_data_validator.validate(); private_call_data_validator.validate_as_first_call(self.hints.first_revertible_private_call_request_index); private_call_data_validator.validate_against_tx_request(self.tx_request); + private_call_data_validator.validate(output.end.new_note_hashes); if !dep::std::runtime::is_unconstrained() { // verify/aggregate the private call proof self.private_call.verify(); } // Validate output. - let output = self.prepare_output(private_call_data_validator); if !dep::std::runtime::is_unconstrained() { PrivateKernelCircuitOutputValidator::new(output).validate_as_first_call( self.tx_request, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 9f386578379..1270c6d4f39 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -24,10 +24,9 @@ struct PrivateKernelInnerCircuitPrivateInputs { } impl PrivateKernelInnerCircuitPrivateInputs { - unconstrained fn prepare_output(self, private_call_data_validator: PrivateCallDataValidator) -> PrivateKernelCircuitPublicInputs { + unconstrained fn generate_output(self) -> PrivateKernelCircuitPublicInputs { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( self.private_call.call_stack_item.public_inputs, - private_call_data_validator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, @@ -36,14 +35,17 @@ impl PrivateKernelInnerCircuitPrivateInputs { } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { + // Generate output. + let output = self.generate_output(); + // Validate inputs. - let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); - private_call_data_validator.validate(); + let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); let private_call_stack_size = previous_kernel_array_lengths.private_call_stack; let call_request = self.previous_kernel.public_inputs.end.private_call_stack[private_call_stack_size - 1]; private_call_data_validator.validate_against_call_request(call_request); private_call_data_validator.validate_against_previous_kernel(self.previous_kernel.public_inputs); + private_call_data_validator.validate(output.end.new_note_hashes); if !dep::std::runtime::is_unconstrained() { // verify/aggregate the private call proof self.private_call.verify(); @@ -52,7 +54,6 @@ impl PrivateKernelInnerCircuitPrivateInputs { } // Validate output. - let output = self.prepare_output(private_call_data_validator); if !dep::std::runtime::is_unconstrained() { PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( self.previous_kernel.public_inputs, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr index d63961a157d..79df86fddee 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder.nr @@ -7,17 +7,19 @@ mod validate_call; mod validate_call_requests; mod validate_contract_address; mod validate_counters; +mod validate_note_logs; mod validate_private_call_requests; use crate::components::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ - abis::{private_kernel::private_call_data::PrivateCallData, private_call_request::ScopedPrivateCallRequest}, + abis::{note_hash::ScopedNoteHash, private_call_request::ScopedPrivateCallRequest}, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest }; struct PrivateCallDataValidatorBuilder { private_call: FixtureBuilder, first_revertible_private_call_request_index: u64, + previous_note_hashes: BoundedVec, } impl PrivateCallDataValidatorBuilder { @@ -28,11 +30,8 @@ impl PrivateCallDataValidatorBuilder { pub fn new_from_counter(counter: u32) -> Self { let private_call = FixtureBuilder::new_from_counter(counter); - PrivateCallDataValidatorBuilder { private_call, first_revertible_private_call_request_index: 0 } - } - - pub fn get_private_call_data(self) -> PrivateCallData { - self.private_call.to_private_call_data() + let previous_note_hashes = BoundedVec::new(); + PrivateCallDataValidatorBuilder { private_call, first_revertible_private_call_request_index: 0, previous_note_hashes } } pub fn is_delegate_call(&mut self) -> Self { @@ -47,7 +46,9 @@ impl PrivateCallDataValidatorBuilder { pub fn validate(self) { let private_call = self.private_call.to_private_call_data(); - PrivateCallDataValidator::new(private_call).validate(); + let mut accumulated_note_hashes = self.previous_note_hashes; + accumulated_note_hashes.extend_from_bounded_vec(self.private_call.new_note_hashes); + PrivateCallDataValidator::new(private_call).validate(accumulated_note_hashes.storage); } pub fn validate_as_first_call(self) { @@ -64,8 +65,4 @@ impl PrivateCallDataValidatorBuilder { let private_call = self.private_call.to_private_call_data(); PrivateCallDataValidator::new(private_call).validate_against_call_request(request); } - - pub fn validate_with_private_call(private_call: PrivateCallData) { - PrivateCallDataValidator::new(private_call).validate(); - } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr index b9a8b2fd386..b8f6be6902d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr @@ -1,4 +1,18 @@ -use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; +use crate::{ + components::private_call_data_validator::PrivateCallDataValidator, + tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder +}; +use dep::types::abis::private_kernel::private_call_data::PrivateCallData; + +impl PrivateCallDataValidatorBuilder { + pub fn get_private_call_data(self) -> PrivateCallData { + self.private_call.to_private_call_data() + } + + pub fn validate_with_private_call(private_call: PrivateCallData) { + PrivateCallDataValidator::new(private_call).validate([]); + } +} /** * validate_public_call_requests diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr new file mode 100644 index 00000000000..958157529fd --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_note_logs.nr @@ -0,0 +1,48 @@ +use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; +use dep::types::{abis::note_hash::NoteHash, address::AztecAddress}; + +#[test] +fn validate_note_logs_succeeds() { + let mut builder = PrivateCallDataValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + + builder.validate(); +} + +#[test(should_fail_with="could not find note hash linked to note log")] +fn validate_note_logs_random_note_hash_counter_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to not match any note hash's counter. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter += 100; + + builder.validate(); +} + +#[test(should_fail_with="could not link a note log to a note hash in another contract")] +fn validate_note_logs_zero_note_hash_counter_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new(); + + builder.private_call.append_new_note_hashes_with_logs(2); + // Tweak the note_hash_counter to be 0. + builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter = 0; + + builder.validate(); +} + +#[test(should_fail_with="could not link a note log to a note hash in another contract")] +fn validate_note_logs_mismatch_contract_address_fails() { + let mut builder = PrivateCallDataValidatorBuilder::new_from_counter(50); + + // Create a note hash emitted from a different contract. + let another_contract_address = AztecAddress::from_field(9999); + let previous_note_hash = NoteHash { value: 1, counter: 17 }.scope(0, another_contract_address); + builder.previous_note_hashes.push(previous_note_hash); + + // Add a not log linked to the previous note hash. + builder.private_call.add_note_encrypted_log_hash(123, 2, previous_note_hash.counter()); + + builder.validate(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr index 232e002b947..3720c01ce06 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder.nr @@ -6,8 +6,7 @@ use crate::components::private_kernel_circuit_public_inputs_composer::PrivateKer use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - private_call_request::ScopedPrivateCallRequest, - private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths + private_call_request::ScopedPrivateCallRequest }, constants::MAX_NEW_NOTE_HASHES_PER_CALL, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest @@ -49,10 +48,8 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { pub fn compose_from_tx_request(self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.to_private_call_data(); - let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); self.new_from_tx_request().compose( private_call.call_stack_item.public_inputs, - array_lengths, private_call.call_stack_item.contract_address, self.note_hash_nullifier_counters, private_call.public_call_stack, @@ -62,10 +59,8 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { pub fn compose_from_previous_kernel(self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.to_private_call_data(); - let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.call_stack_item.public_inputs); self.new_from_previous_kernel().compose( private_call.call_stack_item.public_inputs, - array_lengths, private_call.call_stack_item.contract_address, self.note_hash_nullifier_counters, private_call.public_call_stack, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index d57f789993d..eb2421ac767 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -261,9 +261,9 @@ fn new_from_previous_kernel_with_private_call_new_l2_to_l1_msgs_succeeds() { fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.previous_kernel.append_new_note_hashes_with_logs(2); + builder.previous_kernel.append_note_encrypted_log_hashes(2); let prev = builder.previous_kernel.note_encrypted_logs_hashes.storage; - builder.private_call.append_new_note_hashes_with_logs(2); + builder.private_call.append_note_encrypted_log_hashes(2); let curr = builder.private_call.note_encrypted_logs_hashes.storage; let output = builder.compose_from_previous_kernel(); @@ -274,29 +274,6 @@ fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_succeeds ); } -#[test(should_fail_with="Could not find note hash linked to note log")] -fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_zero_note_hash_counter_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes_with_logs(2); - // Tweak the note_hash_counter to be 0. - builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter = 0; - - let _ = builder.compose_from_previous_kernel(); -} - -#[test(should_fail_with="Could not find note hash linked to note log")] -fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_random_note_hash_counter_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.previous_kernel.append_new_note_hashes_with_logs(2); - builder.private_call.append_new_note_hashes_with_logs(2); - // Tweak the note_hash_counter to not match any note hash's counter. - builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter += 100; - - let _ = builder.compose_from_previous_kernel(); -} - #[test] fn new_from_previous_kernel_with_private_call_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index de1de963e91..613cd104cf1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -189,7 +189,7 @@ fn propagate_from_private_call_new_l2_to_l1_msgs_succeeds() { fn propagate_from_private_call_note_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - builder.private_call.append_new_note_hashes_with_logs(2); + builder.private_call.append_note_encrypted_log_hashes(2); let res = builder.private_call.note_encrypted_logs_hashes.storage; let output = builder.compose_from_tx_request(); @@ -197,46 +197,6 @@ fn propagate_from_private_call_note_encrypted_log_hashes_succeeds() { assert_array_eq(output.end.note_encrypted_logs_hashes, [res[0], res[1]]); } -#[test] -fn propagate_from_private_call_note_encrypted_log_hashes_extra_log_hashes_succeeds() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes_with_logs(2); - let note_hashes = builder.private_call.new_note_hashes.storage; - // Add an extra log hash for the note at index 1. - builder.private_call.add_note_encrypted_log_hash(123, 2, note_hashes[1].counter()); - let res = builder.private_call.note_encrypted_logs_hashes.storage; - - let output = builder.compose_from_tx_request(); - - assert_array_eq( - output.end.note_encrypted_logs_hashes, - [res[0], res[1], res[2]] - ); -} - -#[test(should_fail_with="Could not find note hash linked to note log")] -fn propagate_from_private_call_note_encrypted_log_hashes_zero_note_hash_counter_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes_with_logs(2); - // Tweak the note_hash_counter to be 0. - builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter = 0; - - let _ = builder.compose_from_tx_request(); -} - -#[test(should_fail_with="Could not find note hash linked to note log")] -fn propagate_from_private_call_note_encrypted_log_hashes_random_note_hash_counter_fails() { - let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); - - builder.private_call.append_new_note_hashes_with_logs(2); - // Tweak the note_hash_counter to not match any note hash's counter. - builder.private_call.note_encrypted_logs_hashes.storage[1].note_hash_counter += 100; - - let _ = builder.compose_from_tx_request(); -} - #[test] fn propagate_from_private_call_encrypted_log_hashes_succeeds() { let mut builder = PrivateKernelCircuitPublicInputsComposerBuilder::new(); From 02fd639790fa40673b3c022832f4e20aace679df Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 29 May 2024 09:57:21 +0000 Subject: [PATCH 13/13] Fix. --- .../crates/types/src/tests/fixture_builder.nr | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 4b75cac5d7b..3537863357d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -503,8 +503,8 @@ impl FixtureBuilder { let index_offset = self.public_data_update_requests.len(); for i in 0..self.public_data_update_requests.max_len() { if i < num_updates { - let write = self.mock_public_data_write(index_offset + i); - self.add_public_data_update_request(write.leaf_slot, write.new_value); + let (leaf_slot, value) = self.mock_public_data_write(index_offset + i); + self.add_public_data_update_request(leaf_slot, value); } } } @@ -776,9 +776,11 @@ impl FixtureBuilder { PublicDataRead { leaf_slot: value_offset, value: 1 + value_offset } } - fn mock_public_data_write(self, index: u64) -> PublicDataUpdateRequest { + fn mock_public_data_write(self, index: u64) -> (Field, Field) { let value_offset = 7788 + self.value_offset + index as Field; - PublicDataUpdateRequest { leaf_slot: value_offset, new_value: 1 + value_offset } + let leaf_slot = value_offset; + let value = 1 + value_offset; + (leaf_slot, value) } fn mock_note_hash_value(self, index: u64) -> Field {