From 61c861bce349faf4e412db9a46e00a588f565331 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 15 May 2024 15:57:04 +0000 Subject: [PATCH 1/9] Validate constants. --- .../src/private_call_data_validator.nr | 15 +++++- .../src/private_kernel_inner.nr | 1 + .../crates/private-kernel-lib/src/tests.nr | 1 + .../tests/validate_against_previous_kernel.nr | 49 +++++++++++++++++++ .../crates/types/src/tests/fixture_builder.nr | 2 +- .../crates/types/src/tests/fixtures.nr | 4 ++ .../private_circuit_public_inputs_builder.nr | 4 +- 7 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_previous_kernel.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/private_call_data_validator.nr index 0a43701e29a..9f361c1488c 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 @@ -1,7 +1,9 @@ use dep::types::{ abis::{ - call_context::CallContext, call_request::CallRequest, private_call_stack_item::PrivateCallStackItem, - private_kernel::private_call_data::PrivateCallData, side_effect::Ordered + call_context::CallContext, call_request::CallRequest, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_call_stack_item::PrivateCallStackItem, private_kernel::private_call_data::PrivateCallData, + side_effect::Ordered }, address::{AztecAddress, PartialAddress}, contract_class_id::ContractClassId, hash::{private_functions_root_from_siblings, stdlib_recursion_verification_key_compress_native_vk}, @@ -241,6 +243,15 @@ impl PrivateCallDataValidator { } } + pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { + let constants = previous_kernel.constants; + 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()). + } + fn validate_contract_address(self) { let contract_address = self.data.call_stack_item.contract_address; 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 b4d4090f5b5..d4eaf3b4749 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 @@ -37,6 +37,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { 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); PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( self.private_call.call_stack_item.public_inputs, 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 e2af8ade73b..b05b9057f88 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 validate_against_call_request; +mod validate_against_previous_kernel; mod validate_against_tx_request; mod validate_arrays; mod validate_as_first_call; 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/validate_against_previous_kernel.nr new file mode 100644 index 00000000000..837661b0b00 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_against_previous_kernel.nr @@ -0,0 +1,49 @@ +use crate::{ + private_call_data_validator::PrivateCallDataValidator, + tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder +}; +use dep::types::{ + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + tests::fixture_builder::FixtureBuilder +}; + +impl PrivateCallDataValidatorBuilder { + pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { + let private_call = self.private_call.finish(); + PrivateCallDataValidator::new(private_call).validate_against_previous_kernel(previous_kernel); + } +} + +fn make_previous_kernel() -> PrivateKernelCircuitPublicInputs { + let builder = FixtureBuilder::new(); + builder.to_private_kernel_circuit_public_inputs() +} + +#[test] +fn validate_against_previous_kernel_succeeds() { + let builder = PrivateCallDataValidatorBuilder::new(); + + let previous_kernel = make_previous_kernel(); + + builder.validate_against_previous_kernel(previous_kernel); +} + +#[test(should_fail_with="mismatch historical header")] +fn validate_against_previous_kernel_mismatch_header_version_fails() { + let builder = PrivateCallDataValidatorBuilder::new(); + + let mut previous_kernel = make_previous_kernel(); + previous_kernel.constants.historical_header.global_variables.version += 1; + + builder.validate_against_previous_kernel(previous_kernel); +} + +#[test(should_fail_with="mismatch tx context")] +fn validate_against_previous_kernel_mismatch_chain_id_fails() { + let builder = PrivateCallDataValidatorBuilder::new(); + + let mut previous_kernel = make_previous_kernel(); + previous_kernel.constants.tx_context.chain_id += 1; + + builder.validate_against_previous_kernel(previous_kernel); +} 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 a1d2159d279..10ba38b664d 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 @@ -81,7 +81,7 @@ struct FixtureBuilder { impl FixtureBuilder { pub fn new() -> Self { - let tx_context = TxContext { chain_id: 1, version: 0, gas_settings: GasSettings::empty() }; + let tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::default() }; FixtureBuilder { contract_address: fixtures::contracts::parent_contract.address, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures.nr index e4e95339cda..d30e18d7056 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures.nr @@ -6,3 +6,7 @@ use crate::{address::AztecAddress, grumpkin_point::GrumpkinPoint}; global MSG_SENDER = AztecAddress { inner: 27 }; global PUBLIC_KEY = GrumpkinPoint { x: 123456789, y: 123456789 }; + +global CHAIN_ID = 1; + +global VERSION = 3; 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 index 20dd2efc32e..e98089acc21 100644 --- 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 @@ -85,8 +85,8 @@ impl PrivateCircuitPublicInputsBuilder { side_effect_counter: counter }; - public_inputs.chain_id = 0; - public_inputs.version = 1; + public_inputs.chain_id = fixtures::CHAIN_ID; + public_inputs.version = fixtures::VERSION; public_inputs.gas_settings = GasSettings::default(); public_inputs.counter_start = counter; public_inputs.counter_end = counter + 1; From a58626acfee5f9ae5dfc90d90ad3e0ea8406922f Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Thu, 16 May 2024 22:45:48 +0000 Subject: [PATCH 2/9] Emit private call requests from private function circuits. --- .../aztec/src/context/private_context.nr | 38 +++-- .../src/private_call_data_validator.nr | 140 +++++++--------- ...e_kernel_circuit_public_inputs_composer.nr | 10 +- .../src/private_kernel_init.nr | 11 +- .../src/private_kernel_inner.nr | 2 +- .../crates/private-kernel-lib/src/tests.nr | 1 + .../private_call_data_validator_builder.nr | 18 +-- .../tests/validate_against_call_request.nr | 56 ++++++- .../src/tests/validate_arrays.nr | 21 ++- .../src/tests/validate_as_first_call.nr | 84 ++-------- .../src/tests/validate_call_requests.nr | 108 +------------ .../src/tests/validate_counters.nr | 42 ++--- .../tests/validate_private_call_requests.nr | 93 +++++++++++ .../crates/types/src/abis.nr | 1 + .../private_accumulated_data.nr | 8 +- .../private_accumulated_data_builder.nr | 39 ++--- .../crates/types/src/abis/caller_context.nr | 17 +- .../types/src/abis/private_call_request.nr | 152 ++++++++++++++++++ .../src/abis/private_circuit_public_inputs.nr | 15 +- .../abis/private_kernel/private_call_data.nr | 3 +- .../crates/types/src/abis/side_effect.nr | 5 + .../crates/types/src/constants.nr | 8 +- .../crates/types/src/tests/fixture_builder.nr | 22 ++- .../src/tests/private_call_data_builder.nr | 42 ++--- .../private_circuit_public_inputs_builder.nr | 39 +++-- .../crates/types/src/utils/reader.nr | 4 + 26 files changed, 570 insertions(+), 409 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_private_call_requests.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 43dd101a97c..6bc392209f5 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -15,9 +15,9 @@ use crate::{ }; use dep::protocol_types::{ abis::{ - function_selector::FunctionSelector, max_block_number::MaxBlockNumber, - nullifier_key_validation_request::NullifierKeyValidationRequest, - private_circuit_public_inputs::PrivateCircuitPublicInputs, + caller_context::CallerContext, function_selector::FunctionSelector, + max_block_number::MaxBlockNumber, nullifier_key_validation_request::NullifierKeyValidationRequest, + private_call_request::PrivateCallRequest, private_circuit_public_inputs::PrivateCircuitPublicInputs, public_call_stack_item::PublicCallStackItem, read_request::ReadRequest, note_hash::NoteHash, nullifier::Nullifier, log_hash::{LogHash, NoteLogHash} }, @@ -56,7 +56,7 @@ struct PrivateContext { new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, - private_call_stack_hashes : BoundedVec, + private_call_requests : BoundedVec, public_call_stack_hashes : BoundedVec, public_teardown_function_hash: Field, new_l2_to_l1_msgs : BoundedVec, @@ -124,7 +124,7 @@ impl PrivateContext { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), historical_header: inputs.historical_header, - private_call_stack_hashes: 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(), @@ -167,7 +167,7 @@ impl PrivateContext { nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, - private_call_stack_hashes: self.private_call_stack_hashes.storage, + 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, @@ -422,18 +422,20 @@ impl PrivateContext { is_delegate_call: bool ) -> PackedReturns { let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call; + let start_side_effect_counter = self.side_effect_counter; let item = call_private_function_internal( contract_address, function_selector, args_hash, - self.side_effect_counter, + start_side_effect_counter, is_static_call, is_delegate_call ); - assert_eq(item.public_inputs.call_context.side_effect_counter, self.side_effect_counter); - assert_eq(item.public_inputs.start_side_effect_counter, self.side_effect_counter); - self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1; + assert_eq(item.public_inputs.call_context.side_effect_counter, start_side_effect_counter); + assert_eq(item.public_inputs.start_side_effect_counter, start_side_effect_counter); + let end_side_effect_counter = item.public_inputs.end_side_effect_counter; + self.side_effect_counter = end_side_effect_counter + 1; // TODO (fees) figure out why this crashes the prover and enable it // we need this in order to pay fees inside child call contexts @@ -471,7 +473,15 @@ impl PrivateContext { ); } - self.private_call_stack_hashes.push(item.hash()); + let mut caller_context = CallerContext::empty(); + caller_context.is_static_call = self.inputs.call_context.is_static_call; + if is_delegate_call { + caller_context.msg_sender = self.inputs.call_context.msg_sender; + caller_context.storage_contract_address = self.inputs.call_context.storage_contract_address; + } + self.private_call_requests.push( + PrivateCallRequest { hash: item.hash(), start_side_effect_counter, end_side_effect_counter, caller_context } + ); PackedReturns::new(item.public_inputs.returns_hash) } @@ -665,10 +675,10 @@ impl Empty for PrivateContext { nullifier_key_validation_requests: BoundedVec::new(), new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), - private_call_stack_hashes : BoundedVec::new(), - public_call_stack_hashes : 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(), + new_l2_to_l1_msgs: BoundedVec::new(), historical_header: Header::empty(), note_encrypted_logs_hashes: BoundedVec::new(), encrypted_logs_hashes: BoundedVec::new(), 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 e229f67c11b..d1aeb2624f0 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 @@ -1,9 +1,9 @@ use dep::types::{ abis::{ - call_context::CallContext, call_request::CallRequest, + call_context::CallContext, call_request::CallRequest, caller_context::CallerContext, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - private_call_stack_item::PrivateCallStackItem, private_kernel::private_call_data::PrivateCallData, - side_effect::Ordered + private_call_request::ScopedPrivateCallRequest, private_call_stack_item::PrivateCallStackItem, + 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}, @@ -22,7 +22,7 @@ fn validate_arrays(data: PrivateCallData) -> ArrayLengths { new_note_hashes: validate_array(public_inputs.new_note_hashes), new_nullifiers: validate_array(public_inputs.new_nullifiers), new_l2_to_l1_msgs: validate_array(public_inputs.new_l2_to_l1_msgs), - private_call_stack_hashes: validate_array(public_inputs.private_call_stack_hashes), + private_call_requests: validate_array(public_inputs.private_call_requests), public_call_stack_hashes: validate_array(public_inputs.public_call_stack_hashes), note_encrypted_logs_hashes: validate_array(public_inputs.note_encrypted_logs_hashes), encrypted_logs_hashes: validate_array(public_inputs.encrypted_logs_hashes), @@ -30,24 +30,20 @@ fn validate_arrays(data: PrivateCallData) -> ArrayLengths { } } -fn is_valid_caller(request: CallRequest, caller_address: AztecAddress, caller_context: CallContext) -> bool { - let valid_caller_context = request.caller_context.msg_sender.eq(caller_context.msg_sender) - & request.caller_context.storage_contract_address.eq(caller_context.storage_contract_address); +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); + let hidden_caller_context = caller_context.is_hidden(); + assert(matching_caller_context | hidden_caller_context, "invalid caller context"); - request.caller_contract_address.eq(caller_address) - & (request.caller_context.is_empty() | valid_caller_context) + assert_eq(caller_context.is_static_call, this_context.is_static_call, "mismatch is_static_call flag"); } fn validate_call_request(request: CallRequest, hash: Field, caller: PrivateCallStackItem) { if hash != 0 { assert_eq(request.hash, hash, "call stack hash does not match call request hash"); - assert( - is_valid_caller( - request, - caller.contract_address, - caller.public_inputs.call_context - ), "invalid caller" - ); + assert_eq(request.caller_contract_address, caller.contract_address, "invalid caller contract address"); + validate_caller_context(request.caller_context, caller.public_inputs.call_context) } else { assert(is_empty(request), "call requests length does not match the expected length"); } @@ -74,12 +70,12 @@ fn validate_incrementing_counters_within_range( assert(prev_counter < counter_end, "counter must be smaller than the end counter of the call"); } -fn validate_incrementing_counter_ranges_within_range( +fn validate_incrementing_counter_ranges_within_range( counter_start: u32, counter_end: u32, - items: [CallRequest; N], + items: [T; N], num_items: u64 -) { +) where T: RangeOrdered { let mut prev_counter = counter_start; let mut should_check = true; for i in 0..N { @@ -87,12 +83,10 @@ fn validate_incrementing_counter_ranges_within_range( if should_check { let item = items[i]; assert( - item.start_side_effect_counter > prev_counter, "start counter must be larger than the end counter of the previous call" + item.counter_start() > prev_counter, "start counter must be larger than the end counter of the previous call" ); - assert( - item.end_side_effect_counter > item.start_side_effect_counter, "nested call has incorrect counter range" - ); - prev_counter = item.end_side_effect_counter; + assert(item.counter_end() > item.counter_start(), "nested call has incorrect counter range"); + prev_counter = item.counter_end(); } } assert( @@ -100,44 +94,23 @@ fn validate_incrementing_counter_ranges_within_range( ); } -fn validate_split_private_call_requests( +fn validate_clean_split_ranges( min_revertible_side_effect_counter: u32, - first_revertible_call_request_index: u64, - call_requests: [CallRequest; N], - num_call_requests: u64 -) { - if first_revertible_call_request_index != 0 { - let last_non_revertible_call_request_index = first_revertible_call_request_index - 1; - let call_request = call_requests[last_non_revertible_call_request_index]; - assert( - min_revertible_side_effect_counter > call_request.end_side_effect_counter, "min_revertible_side_effect_counter must be greater than the end counter of the last non revertible call" - ); - } - if first_revertible_call_request_index != num_call_requests { - let call_request = call_requests[first_revertible_call_request_index]; - assert( - min_revertible_side_effect_counter <= call_request.start_side_effect_counter, "min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible call" - ); - } -} - -fn validate_split_public_call_requests( - min_revertible_side_effect_counter: u32, - first_revertible_call_request_index: u64, - call_requests: [CallRequest; N], - num_call_requests: u64 -) { - if first_revertible_call_request_index != 0 { - let last_non_revertible_call_request_index = first_revertible_call_request_index - 1; - let call_request = call_requests[last_non_revertible_call_request_index]; + first_revertible_item_index: u64, + items: [T; N], + num_items: u64 +) where T: RangeOrdered { + if first_revertible_item_index != 0 { + let last_non_revertible_item_index = first_revertible_item_index - 1; + let item = items[last_non_revertible_item_index]; assert( - min_revertible_side_effect_counter > call_request.counter(), "min_revertible_side_effect_counter must be greater than the counter of the last non revertible call" + min_revertible_side_effect_counter > item.counter_end(), "min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item" ); } - if first_revertible_call_request_index != num_call_requests { - let call_request = call_requests[first_revertible_call_request_index]; + if first_revertible_item_index != num_items { + let item = items[first_revertible_item_index]; assert( - min_revertible_side_effect_counter <= call_request.counter(), "min_revertible_side_effect_counter must be less than or equal to the counter of the first revertible call" + min_revertible_side_effect_counter <= item.counter_start(), "min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible item" ); } } @@ -149,7 +122,7 @@ struct ArrayLengths { new_note_hashes: u64, new_nullifiers: u64, new_l2_to_l1_msgs: u64, - private_call_stack_hashes: u64, + private_call_requests: u64, public_call_stack_hashes: u64, note_encrypted_logs_hashes: u64, encrypted_logs_hashes: u64, @@ -176,11 +149,7 @@ impl PrivateCallDataValidator { self.validate_counters(); } - pub fn validate_as_first_call( - self, - first_revertible_private_call_request_index: u64, - first_revertible_public_call_request_index: u64 - ) { + pub fn validate_as_first_call(self, first_revertible_private_call_request_index: u64) { let public_inputs = self.data.call_stack_item.public_inputs; let call_context = public_inputs.call_context; assert(call_context.is_delegate_call == false, "Users cannot make a delegatecall"); @@ -189,17 +158,11 @@ impl PrivateCallDataValidator { let min_revertible_side_effect_counter = public_inputs.min_revertible_side_effect_counter; // No need to check that the min_revertible_side_effect_counter falls in the counter range of the private call. // It is valid as long as it does not fall in the middle of any nested call. - validate_split_private_call_requests( + validate_clean_split_ranges( min_revertible_side_effect_counter, first_revertible_private_call_request_index, - self.data.private_call_stack, - self.array_lengths.private_call_stack_hashes - ); - validate_split_public_call_requests( - min_revertible_side_effect_counter, - first_revertible_public_call_request_index, - self.data.public_call_stack, - self.array_lengths.public_call_stack_hashes + public_inputs.private_call_requests, + self.array_lengths.private_call_requests ); } @@ -220,18 +183,21 @@ impl PrivateCallDataValidator { ); } - pub fn validate_against_call_request(self, request: CallRequest) { + pub fn validate_against_call_request(self, scoped_call_request: ScopedPrivateCallRequest) { let call_stack_item = self.data.call_stack_item; + let caller_contract_address = scoped_call_request.contract_address; + let request = scoped_call_request.call_request; assert_eq( request.hash, call_stack_item.hash(), "calculated private_call_hash does not match provided private_call_hash at the top of the call stack" ); let call_context = call_stack_item.public_inputs.call_context; + let caller_context = request.caller_context; + let is_caller_hidden = caller_context.is_hidden(); if call_context.is_delegate_call { - let caller_context = request.caller_context; - assert(!caller_context.is_empty(), "caller context cannot be empty for delegate calls"); + assert(!is_caller_hidden, "caller context cannot be hidden for delegate calls"); assert_eq( call_context.msg_sender, caller_context.msg_sender, "call stack msg_sender does not match expected msg_sender for delegate calls" ); @@ -239,10 +205,15 @@ impl PrivateCallDataValidator { call_context.storage_contract_address, caller_context.storage_contract_address, "call stack storage address does not match expected contract address for delegate calls" ); } else { + assert(is_caller_hidden, "caller context must be hidden for non-delegate calls"); assert_eq( - call_context.msg_sender, request.caller_contract_address, "call stack msg_sender does not match caller contract address" + call_context.msg_sender, caller_contract_address, "call stack msg_sender does not match caller contract address" ); } + + if !call_context.is_static_call { + assert(caller_context.is_static_call == false, "static call cannot make non-static calls"); + } } pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { @@ -324,10 +295,17 @@ impl PrivateCallDataValidator { } fn validate_private_call_requests(self) { - let call_requests = self.data.private_call_stack; - let hashes = self.data.call_stack_item.public_inputs.private_call_stack_hashes; + let call_requests = self.data.call_stack_item.public_inputs.private_call_requests; + let num_requests = self.array_lengths.private_call_requests; + let mut should_check = true; for i in 0..call_requests.len() { - validate_call_request(call_requests[i], hashes[i], self.data.call_stack_item); + should_check &= i != num_requests; + if should_check { + validate_caller_context( + call_requests[i].caller_context, + self.data.call_stack_item.public_inputs.call_context + ); + } } } @@ -399,8 +377,8 @@ impl PrivateCallDataValidator { validate_incrementing_counter_ranges_within_range( counter_start, counter_end, - self.data.private_call_stack, - self.array_lengths.private_call_stack_hashes + public_inputs.private_call_requests, + self.array_lengths.private_call_requests ); // Validate the public call requests by checking their start counters only, as their end counters are unknown. 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 32e9219529e..fe884af87b3 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 @@ -16,9 +16,9 @@ use dep::types::{ struct DataSource { private_call_public_inputs: PrivateCircuitPublicInputs, + contract_address: AztecAddress, storage_contract_address: AztecAddress, note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], - private_call_requests: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_requests: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_call_request: CallRequest, } @@ -81,17 +81,17 @@ impl PrivateKernelCircuitPublicInputsComposer { pub fn compose( &mut self, private_call_public_inputs: PrivateCircuitPublicInputs, + contract_address: AztecAddress, note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], - private_call_requests: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_requests: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_call_request: CallRequest ) -> Self { let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; let source = DataSource { + contract_address, storage_contract_address, private_call_public_inputs, note_hash_nullifier_counters, - private_call_requests, public_call_requests, public_teardown_call_request }; @@ -216,11 +216,11 @@ impl PrivateKernelCircuitPublicInputsComposer { } fn propagate_private_call_requests(&mut self, source: DataSource) { - let call_requests = source.private_call_requests; + let call_requests = source.private_call_public_inputs.private_call_requests; for i in 0..call_requests.len() { let call_request = call_requests[i]; if !is_empty(call_request) { - self.public_inputs.end.private_call_stack.push(call_request); + self.public_inputs.end.private_call_stack.push(call_request.scope(source.contract_address)); } } } 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 c6ae0c8d193..2622a1b53c8 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 @@ -14,7 +14,6 @@ use dep::types::{ struct PrivateKernelInitHints { note_hash_nullifier_counters: [u32; MAX_NEW_NOTE_HASHES_PER_CALL], first_revertible_private_call_request_index: u64, - first_revertible_public_call_request_index: u64 } // Initialization struct for private inputs to the private kernel @@ -31,17 +30,14 @@ impl PrivateKernelInitCircuitPrivateInputs { let privateCallDataValidator = PrivateCallDataValidator::new(self.private_call); privateCallDataValidator.validate(); - privateCallDataValidator.validate_as_first_call( - self.hints.first_revertible_private_call_request_index, - self.hints.first_revertible_public_call_request_index - ); + privateCallDataValidator.validate_as_first_call(self.hints.first_revertible_private_call_request_index); privateCallDataValidator.validate_against_tx_request(self.tx_request); 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, + self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, - self.private_call.private_call_stack, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ).finish() @@ -75,8 +71,7 @@ mod tests { 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, - first_revertible_public_call_request_index: 0 + first_revertible_private_call_request_index: 0 }; PrivateKernelInitInputsBuilder { tx_request, private_call, hints } 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 c4ce76fd8a2..33991494e52 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 @@ -41,8 +41,8 @@ impl PrivateKernelInnerCircuitPrivateInputs { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( self.private_call.call_stack_item.public_inputs, + self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, - self.private_call.private_call_stack, self.private_call.public_call_stack, self.private_call.public_teardown_call_request ).finish() 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 b05b9057f88..2a9c7d34cf3 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 @@ -8,3 +8,4 @@ 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 c76216a9635..f014c86eb54 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,13 +1,12 @@ use crate::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ - abis::call_request::CallRequest, tests::private_call_data_builder::PrivateCallDataBuilder, - transaction::tx_request::TxRequest + abis::private_call_request::ScopedPrivateCallRequest, + tests::private_call_data_builder::PrivateCallDataBuilder, transaction::tx_request::TxRequest }; struct PrivateCallDataValidatorBuilder { private_call: PrivateCallDataBuilder, first_revertible_private_call_request_index: u64, - first_revertible_public_call_request_index: u64 } impl PrivateCallDataValidatorBuilder { @@ -18,11 +17,7 @@ impl PrivateCallDataValidatorBuilder { pub fn new_with_counter(counter: u32) -> Self { let private_call = PrivateCallDataBuilder::new_with_counter(counter); - PrivateCallDataValidatorBuilder { - private_call, - first_revertible_private_call_request_index: 0, - first_revertible_public_call_request_index: 0 - } + PrivateCallDataValidatorBuilder { private_call, first_revertible_private_call_request_index: 0 } } pub fn is_delegate_call(&mut self) -> Self { @@ -42,10 +37,7 @@ impl PrivateCallDataValidatorBuilder { pub fn validate_as_first_call(self) { let private_call = self.private_call.finish(); - PrivateCallDataValidator::new(private_call).validate_as_first_call( - self.first_revertible_private_call_request_index, - self.first_revertible_public_call_request_index - ); + PrivateCallDataValidator::new(private_call).validate_as_first_call(self.first_revertible_private_call_request_index); } pub fn validate_against_tx_request(self, request: TxRequest) { @@ -53,7 +45,7 @@ impl PrivateCallDataValidatorBuilder { PrivateCallDataValidator::new(private_call).validate_against_tx_request(request); } - pub fn validate_against_call_request(self, request: CallRequest) { + pub fn validate_against_call_request(self, request: ScopedPrivateCallRequest) { let private_call = self.private_call.finish(); PrivateCallDataValidator::new(private_call).validate_against_call_request(request); } 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/validate_against_call_request.nr index 87dd96f84ed..900615e058f 100644 --- 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/validate_against_call_request.nr @@ -34,17 +34,17 @@ fn validate_against_call_request_mismatch_hash_fails() { let mut request = builder.private_call.build_call_request(); // Tweak the hash to be a different value. - request.hash += 1; + request.call_request.hash += 1; builder.validate_against_call_request(request); } -#[test(should_fail_with="caller context cannot be empty for delegate calls")] +#[test(should_fail_with="caller context cannot be hidden for delegate calls")] 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(); - request.caller_context = CallerContext::empty(); + request.call_request.caller_context = CallerContext::empty(); builder.validate_against_call_request(request); } @@ -55,7 +55,7 @@ fn validate_against_call_request_incorrect_msg_sender_for_delegate_call_fails() let mut request = builder.private_call.build_call_request(); // Tweak the msg_sender to be a different value. - request.caller_context.msg_sender.inner += 1; + request.call_request.caller_context.msg_sender.inner += 1; builder.validate_against_call_request(request); } @@ -66,7 +66,7 @@ fn validate_against_call_request_incorrect_storage_contract_address_for_delegate let mut request = builder.private_call.build_call_request(); // Tweak the storage contract address to be a different value. - request.caller_context.storage_contract_address.inner += 1; + request.call_request.caller_context.storage_contract_address.inner += 1; builder.validate_against_call_request(request); } @@ -77,7 +77,51 @@ fn validate_against_call_request_incorrect_msg_sender_for_regular_call_fails() { let mut request = builder.private_call.build_call_request(); // Tweak the caller's contract address to be a different value. - request.caller_contract_address.inner += 1; + request.contract_address.inner += 1; + + builder.validate_against_call_request(request); +} + +#[test(should_fail_with="caller context must be hidden for non-delegate calls")] +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(); + // Tweak the caller's msg_sender to be non-empty. + request.call_request.caller_context.msg_sender.inner = 1234; + + builder.validate_against_call_request(request); +} + +#[test(should_fail_with="caller context must be hidden for non-delegate calls")] +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(); + // Tweak the caller's msg_sender to be non-empty. + request.call_request.caller_context.msg_sender.inner = 1234; + + builder.validate_against_call_request(request); +} + +#[test(should_fail_with="static call cannot make non-static calls")] +fn validate_against_call_request_static_call_regular_call_fails() { + let builder = PrivateCallDataValidatorBuilder::new(); + + let mut request = builder.private_call.build_call_request(); + // Tweak the caller to be making a static call. + request.call_request.caller_context.is_static_call = true; + + builder.validate_against_call_request(request); +} + +#[test(should_fail_with="static call cannot make non-static calls")] +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(); + // Tweak the caller to be making a static call. + request.call_request.caller_context.is_static_call = true; builder.validate_against_call_request(request); } 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/validate_arrays.nr index a8c1b2f6efd..dbc5f629877 100644 --- 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/validate_arrays.nr @@ -1,6 +1,10 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; use dep::types::{ - abis::{note_hash::NoteHash, nullifier::Nullifier, read_request::ReadRequest, log_hash::{LogHash, NoteLogHash}}, + abis::{ + caller_context::CallerContext, note_hash::NoteHash, nullifier::Nullifier, + private_call_request::PrivateCallRequest, read_request::ReadRequest, + log_hash::{LogHash, NoteLogHash} +}, address::EthAddress, grumpkin_point::GrumpkinPoint, messaging::l2_to_l1_message::L2ToL1Message }; @@ -90,10 +94,19 @@ fn validate_arrays_malformed_l2_to_l1_msgs_fails() { } #[test(should_fail_with="invalid array")] -fn validate_arrays_malformed_private_call_stack_fails() { +fn validate_arrays_malformed_private_call_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); - builder.private_call.public_inputs.private_call_stack_hashes.extend_from_array([0, 9123]); + 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.validate(); } @@ -136,7 +149,7 @@ fn validate_arrays_malformed_unencrypted_logs_hashes_fails() { } #[test(should_fail_with="invalid array")] -fn input_validation_malformed_arrays_note_logs() { +fn validate_arrays_malformed_note_encrypted_logs_hashes() { let mut builder = PrivateCallDataValidatorBuilder::new(); builder.private_call.public_inputs.note_encrypted_logs_hashes.extend_from_array( 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/validate_as_first_call.nr index 852de8b834b..59bdc8a6f8f 100644 --- 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/validate_as_first_call.nr @@ -1,6 +1,5 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; use dep::types::constants::MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL; -use dep::types::abis::call_request::CallRequest; impl PrivateCallDataValidatorBuilder { pub fn new_first_call() -> Self { @@ -9,25 +8,16 @@ impl PrivateCallDataValidatorBuilder { 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.private_call_stack.len(); - self.first_revertible_public_call_request_index = self.private_call.public_call_stack.len(); + self.first_revertible_private_call_request_index = self.private_call.public_inputs.private_call_requests.len(); } pub fn add_private_call_request(&mut self, counter_start: u32, counter_end: u32) { - let index = self.private_call.private_call_stack.len(); - self.private_call.append_private_call_requests(1, false); - self.private_call.private_call_stack.storage[index].start_side_effect_counter = counter_start; - self.private_call.private_call_stack.storage[index].end_side_effect_counter = counter_end; + 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; } - - pub fn add_public_call_request(&mut self, counter_start: u32) { - let index = self.private_call.public_call_stack.len(); - self.private_call.append_public_call_requests(1, false); - self.private_call.public_call_stack.storage[index].start_side_effect_counter = counter_start; - self.private_call.public_call_stack.storage[index].end_side_effect_counter = 0; - self.private_call.public_inputs.counter_end = counter_start + 1; - } } #[test] @@ -90,7 +80,7 @@ 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.append_private_call_requests(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, false); + 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.validate_as_first_call(); @@ -109,7 +99,7 @@ fn validate_as_first_call_split_private_calls_less_than_first_revertible_success builder.validate_as_first_call(); } -#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible call")] +#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item")] fn validate_as_first_call_split_private_calls_less_than_last_non_revertible_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); @@ -122,7 +112,7 @@ fn validate_as_first_call_split_private_calls_less_than_last_non_revertible_fail builder.validate_as_first_call(); } -#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible call")] +#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item")] fn validate_as_first_call_split_private_calls_equal_last_non_revertible_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); @@ -134,7 +124,7 @@ fn validate_as_first_call_split_private_calls_equal_last_non_revertible_fails() builder.validate_as_first_call(); } -#[test(should_fail_with="min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible call")] +#[test(should_fail_with="min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible item")] fn validate_as_first_call_split_private_calls_greater_than_first_revertible_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); @@ -159,7 +149,7 @@ fn validate_as_first_call_split_private_calls_0_succeeds() { builder.validate_as_first_call(); } -#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible call")] +#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item")] fn validate_as_first_call_split_private_calls_0_wrong_hint_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); @@ -172,7 +162,7 @@ fn validate_as_first_call_split_private_calls_0_wrong_hint_fails() { builder.validate_as_first_call(); } -#[test(should_fail_with="min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible call")] +#[test(should_fail_with="min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible item")] fn validate_as_first_call_split_private_calls_index_hint_greater_than_len_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); @@ -184,55 +174,3 @@ fn validate_as_first_call_split_private_calls_index_hint_greater_than_len_fails( builder.validate_as_first_call(); } - -#[test] -fn validate_as_first_call_split_public_calls_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); - - builder.add_public_call_request(20); - builder.add_public_call_request(30); - builder.split_calls(40); - builder.add_public_call_request(40); - - builder.validate_as_first_call(); -} - -#[test(should_fail_with="min_revertible_side_effect_counter must be greater than the counter of the last non revertible call")] -fn validate_as_first_call_split_public_calls_less_than_last_non_revertible_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); - - builder.add_public_call_request(20); - builder.add_public_call_request(30); - // Tweak the counter to be less than the end counter of the last non-revertible call. - builder.split_calls(29); - builder.add_public_call_request(40); - - builder.validate_as_first_call(); -} - -#[test] -fn validate_as_first_call_split_private_public_mix_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); - - builder.add_private_call_request(20, 30); - builder.add_public_call_request(40); - builder.split_calls(50); - builder.add_public_call_request(50); - builder.add_private_call_request(60, 70); - - builder.validate_as_first_call(); -} - -#[test(should_fail_with="min_revertible_side_effect_counter must be less than or equal to the counter of the first revertible call")] -fn validate_as_first_call_split_private_public_mix_falls_in_revertible_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new_first_call(); - - builder.add_private_call_request(20, 30); - builder.add_public_call_request(40); - // Tweak the counter to be greater than the start counter of the next call. - builder.split_calls(51); - builder.add_public_call_request(50); - builder.add_private_call_request(60, 70); - - builder.validate_as_first_call(); -} 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/validate_call_requests.nr index 58fede8fb72..4534d291e7c 100644 --- 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/validate_call_requests.nr @@ -1,102 +1,6 @@ use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; use dep::types::abis::call_request::CallRequest; -/** - * validate_private_call_requests - */ - -#[test] -fn validate_private_call_requests_succeeds() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.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.append_private_call_requests(2, true); - - builder.validate(); -} - -#[test(should_fail_with="call stack hash does not match call request hash")] -fn validate_private_call_requests_incorrect_hash_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(2, false); - let mut call_request = builder.private_call.private_call_stack.pop(); - // Change the hash to be a different value. - call_request.hash += 1; - builder.private_call.private_call_stack.push(call_request); - - builder.validate(); -} - -#[test(should_fail_with="invalid caller")] -fn validate_private_call_requests_incorrect_caller_address_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(1, false); - let mut call_request = builder.private_call.private_call_stack.pop(); - // Change the caller contract address to be a different value. - call_request.caller_contract_address.inner += 1; - builder.private_call.private_call_stack.push(call_request); - - builder.validate(); -} - -#[test(should_fail_with="invalid caller")] -fn validate_private_call_requests_incorrect_caller_storage_contract_address_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(1, true); - let mut call_request = builder.private_call.private_call_stack.pop(); - // Change the storage contract to be a different value. - call_request.caller_context.storage_contract_address.inner += 1; - builder.private_call.private_call_stack.push(call_request); - - builder.validate(); -} - -#[test(should_fail_with="invalid caller")] -fn validate_private_call_requests_incorrect_caller_msg_sender_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(1, true); - let mut call_request = builder.private_call.private_call_stack.pop(); - // Change the msg_sender to be a different value. - call_request.caller_context.msg_sender.inner += 1; - builder.private_call.private_call_stack.push(call_request); - - builder.validate(); -} - -#[test(should_fail_with="call requests length does not match the expected length")] -fn validate_private_call_requests_fewer_hashes_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(2, false); - // Remove one call stack item hash. - let _ = builder.private_call.public_inputs.private_call_stack_hashes.pop(); - - builder.validate(); -} - -#[test(should_fail_with="call stack hash does not match call request hash")] -fn validate_private_call_requests_more_hashes_fails() { - let mut builder = PrivateCallDataValidatorBuilder::new(); - - builder.private_call.append_private_call_requests(2, false); - // Add one random call stack item hash. - builder.private_call.public_inputs.private_call_stack_hashes.push(9123); - - builder.validate(); -} - /** * validate_public_call_requests */ @@ -132,7 +36,7 @@ fn validate_public_call_requests_incorrect_hash_fails() { builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller contract address")] fn validate_public_call_requests_incorrect_caller_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -145,7 +49,7 @@ fn validate_public_call_requests_incorrect_caller_address_fails() { builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller context")] fn validate_public_call_requests_incorrect_caller_storage_contract_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -158,7 +62,7 @@ fn validate_public_call_requests_incorrect_caller_storage_contract_address_fails builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller context")] fn validate_public_call_requests_incorrect_caller_msg_sender_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -226,7 +130,7 @@ fn validate_teardown_call_request_incorrect_hash_fails() { builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller contract address")] fn validate_teardown_call_request_incorrect_caller_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -237,7 +141,7 @@ fn validate_teardown_call_request_incorrect_caller_address_fails() { builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller context")] fn validate_teardown_call_request_incorrect_caller_storage_contract_address_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); @@ -248,7 +152,7 @@ fn validate_teardown_call_request_incorrect_caller_storage_contract_address_fail builder.validate(); } -#[test(should_fail_with="invalid caller")] +#[test(should_fail_with="invalid caller context")] fn validate_teardown_call_request_incorrect_caller_msg_sender_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); 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/validate_counters.nr index d18493899b7..044441e5382 100644 --- 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/validate_counters.nr @@ -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.append_private_call_requests(2, false); + builder.private_call.public_inputs.append_private_call_requests(2, false); 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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // 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.private_call_stack.storage[0].start_side_effect_counter = counter_start - 1; + builder.private_call.public_inputs.private_call_requests.storage[0].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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // 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.private_call_stack.storage[0].start_side_effect_counter = counter_start; + builder.private_call.public_inputs.private_call_requests.storage[0].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.append_private_call_requests(2, false); + builder.private_call.public_inputs.append_private_call_requests(2, false); // 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.private_call_stack.get(0).end_side_effect_counter; - builder.private_call.private_call_stack.storage[1].start_side_effect_counter = counter_end - 1; + 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; 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.append_private_call_requests(2, false); + builder.private_call.public_inputs.append_private_call_requests(2, false); // 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.private_call_stack.get(0).end_side_effect_counter; - builder.private_call.private_call_stack.storage[1].start_side_effect_counter = counter_end; + 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; 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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // Tweak the end counter of the first nested call to be LESS than its start counter. - let counter_start = builder.private_call.private_call_stack.get(0).start_side_effect_counter; - builder.private_call.private_call_stack.storage[0].end_side_effect_counter = counter_start - 1; + 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; 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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // Tweak the end counter of the first nested call to EQUAL its start counter. - let counter_start = builder.private_call.private_call_stack.get(0).start_side_effect_counter; - builder.private_call.private_call_stack.storage[0].end_side_effect_counter = counter_start; + 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; 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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // 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.private_call_stack.storage[0].end_side_effect_counter = counter_end + 1; + builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_end + 1; builder.validate(); } @@ -218,10 +218,10 @@ 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.append_private_call_requests(1, false); + builder.private_call.public_inputs.append_private_call_requests(1, false); // 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.private_call_stack.storage[0].end_side_effect_counter = counter_end; + builder.private_call.public_inputs.private_call_requests.storage[0].end_side_effect_counter = counter_end; builder.validate(); } 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/validate_private_call_requests.nr new file mode 100644 index 00000000000..89f730cc504 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/validate_private_call_requests.nr @@ -0,0 +1,93 @@ +use crate::tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder; + +#[test] +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.validate(); +} + +#[test] +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.validate(); +} + +#[test] +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.validate(); +} + +#[test(should_fail_with="invalid caller context")] +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(); + // 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); + + builder.validate(); +} + +#[test(should_fail_with="invalid caller context")] +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(); + // 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); + + builder.validate(); +} + +#[test(should_fail_with="mismatch is_static_call flag")] +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(); + // 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); + + builder.validate(); +} + +#[test(should_fail_with="mismatch is_static_call flag")] +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(); + // 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); + + builder.validate(); +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr index 8c12f9caeb1..dca4e80ae20 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr @@ -32,6 +32,7 @@ mod private_kernel_data; mod public_kernel_data; mod call_request; +mod private_call_request; mod private_call_stack_item; mod public_call_stack_item; mod call_context; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr index 8d225670ec8..a0022b4b271 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr @@ -1,7 +1,7 @@ use crate::{ abis::{ call_request::CallRequest, gas::Gas, note_hash::ScopedNoteHash, nullifier::ScopedNullifier, - log_hash::{LogHash, NoteLogHash} + private_call_request::ScopedPrivateCallRequest, log_hash::{LogHash, NoteLogHash} }, traits::{Serialize, Deserialize, Eq, Empty}, messaging::l2_to_l1_message::ScopedL2ToL1Message, utils::reader::Reader @@ -26,7 +26,7 @@ struct PrivateAccumulatedData { encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, - private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], + private_call_stack: [ScopedPrivateCallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], } @@ -88,7 +88,7 @@ impl Deserialize for PrivateAccumulatedData { unencrypted_logs_hashes: reader.read_struct_array(LogHash::deserialize, [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX]), encrypted_log_preimages_length: reader.read(), unencrypted_log_preimages_length: reader.read(), - private_call_stack: reader.read_struct_array(CallRequest::deserialize, [CallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX]), + private_call_stack: reader.read_struct_array(ScopedPrivateCallRequest::deserialize, [ScopedPrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX]), public_call_stack: reader.read_struct_array(CallRequest::deserialize, [CallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX]), }; reader.finish(); @@ -122,7 +122,7 @@ impl Empty for PrivateAccumulatedData { unencrypted_logs_hashes: [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, - private_call_stack: [CallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], + private_call_stack: [ScopedPrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], public_call_stack: [CallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr index ecf583f00e9..a6194604397 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr @@ -8,7 +8,8 @@ use crate::{ public_accumulated_data_builder::PublicAccumulatedDataBuilder }, call_request::CallRequest, note_hash::{NoteHash, ScopedNoteHash}, nullifier::ScopedNullifier, - public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, NoteLogHash} + private_call_request::ScopedPrivateCallRequest, public_data_update_request::PublicDataUpdateRequest, + log_hash::{LogHash, NoteLogHash} }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, @@ -37,7 +38,7 @@ struct PrivateAccumulatedDataBuilder { encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, - private_call_stack: BoundedVec, + private_call_stack: BoundedVec, public_call_stack: BoundedVec, } @@ -233,6 +234,23 @@ impl PrivateAccumulatedDataBuilder { } } +impl Empty for PrivateAccumulatedDataBuilder { + fn empty() -> Self { + PrivateAccumulatedDataBuilder { + 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(), + encrypted_log_preimages_length: 0, + unencrypted_log_preimages_length: 0, + private_call_stack: BoundedVec::new(), + public_call_stack: BoundedVec::new(), + } + } +} + mod tests { use crate::{ abis::{ @@ -459,20 +477,3 @@ mod tests { ); } } - -impl Empty for PrivateAccumulatedDataBuilder { - fn empty() -> Self { - PrivateAccumulatedDataBuilder { - 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(), - encrypted_log_preimages_length: 0, - unencrypted_log_preimages_length: 0, - private_call_stack: BoundedVec::new(), - public_call_stack: BoundedVec::new(), - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/caller_context.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/caller_context.nr index e9c7b283947..0594718a73f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/caller_context.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/caller_context.nr @@ -7,12 +7,14 @@ use crate::utils::reader::Reader; struct CallerContext { msg_sender: AztecAddress, storage_contract_address: AztecAddress, + is_static_call: bool, } impl Eq for CallerContext { - fn eq(self, caller_context: CallerContext) -> bool { - caller_context.msg_sender.eq(self.msg_sender) - & caller_context.storage_contract_address.eq(self.storage_contract_address) + fn eq(self, other: CallerContext) -> bool { + other.msg_sender.eq(self.msg_sender) + & other.storage_contract_address.eq(self.storage_contract_address) + & other.is_static_call == self.is_static_call } } @@ -21,12 +23,19 @@ impl Empty for CallerContext { CallerContext { msg_sender: AztecAddress::zero(), storage_contract_address: AztecAddress::zero(), + is_static_call: false, } } } impl CallerContext { pub fn is_empty(self) -> bool { + self.msg_sender.is_zero() & self.storage_contract_address.is_zero() & !self.is_static_call + } + + // Different to an empty context, a hidden context won't reveal the caller's msg_sender and storage_contract_address, + // but will still propagate the is_static_call flag. + pub fn is_hidden(self) -> bool { self.msg_sender.is_zero() & self.storage_contract_address.is_zero() } } @@ -37,6 +46,7 @@ impl Serialize for CallerContext { fields.extend_from_array(self.msg_sender.serialize()); fields.extend_from_array(self.storage_contract_address.serialize()); + fields.push(self.is_static_call as Field); assert_eq(fields.len(), CALLER_CONTEXT_LENGTH); @@ -51,6 +61,7 @@ impl Deserialize for CallerContext { let item = CallerContext { msg_sender: reader.read_struct(AztecAddress::deserialize), storage_contract_address: reader.read_struct(AztecAddress::deserialize), + is_static_call: reader.read_bool(), }; reader.finish(); item 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 new file mode 100644 index 00000000000..167595b2d4d --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr @@ -0,0 +1,152 @@ +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}, + traits::{Empty, Serialize, Deserialize}, utils::reader::Reader +}; + +struct PrivateCallRequest { + hash: Field, + start_side_effect_counter: u32, + end_side_effect_counter: u32, + caller_context: CallerContext, +} + +impl Ordered for PrivateCallRequest { + fn counter(self) -> u32 { + self.start_side_effect_counter + } +} + +impl RangeOrdered for PrivateCallRequest { + fn counter_start(self) -> u32 { + self.start_side_effect_counter + } + fn counter_end(self) -> u32 { + self.end_side_effect_counter + } +} + +impl Eq for PrivateCallRequest { + fn eq(self, other: PrivateCallRequest) -> bool { + (self.hash == other.hash) + & (self.start_side_effect_counter == other.start_side_effect_counter) + & (self.end_side_effect_counter == other.end_side_effect_counter) + & (self.caller_context == other.caller_context) + } +} + +impl Empty for PrivateCallRequest { + fn empty() -> Self { + PrivateCallRequest { + hash: 0, + start_side_effect_counter: 0, + end_side_effect_counter: 0, + caller_context: CallerContext::empty(), + } + } +} + +impl Serialize for PrivateCallRequest { + fn serialize(self) -> [Field; PRIVATE_CALL_REQUEST_LENGTH] { + let mut fields: BoundedVec = BoundedVec::new(); + + fields.push(self.hash); + fields.push(self.start_side_effect_counter as Field); + fields.push(self.end_side_effect_counter as Field); + fields.extend_from_array(self.caller_context.serialize()); + + assert_eq(fields.len(), PRIVATE_CALL_REQUEST_LENGTH); + + fields.storage + } +} + +impl Deserialize for PrivateCallRequest { + fn deserialize(fields: [Field; PRIVATE_CALL_REQUEST_LENGTH]) -> PrivateCallRequest { + let mut reader = Reader::new(fields); + let item = PrivateCallRequest { + hash: reader.read(), + start_side_effect_counter: reader.read_u32(), + end_side_effect_counter: reader.read_u32(), + caller_context: reader.read_struct(CallerContext::deserialize), + }; + reader.finish(); + item + } +} + +impl PrivateCallRequest { + pub fn scope(self, contract_address: AztecAddress) -> ScopedPrivateCallRequest { + ScopedPrivateCallRequest { call_request: self, contract_address } + } +} + +struct ScopedPrivateCallRequest { + call_request: PrivateCallRequest, + contract_address: AztecAddress, +} + +impl Ordered for ScopedPrivateCallRequest { + fn counter(self) -> u32 { + self.call_request.counter_start() + } +} + +impl RangeOrdered for ScopedPrivateCallRequest { + fn counter_start(self) -> u32 { + self.call_request.counter_start() + } + fn counter_end(self) -> u32 { + self.call_request.counter_end() + } +} + +impl Eq for ScopedPrivateCallRequest { + fn eq(self, other: ScopedPrivateCallRequest) -> bool { + (self.call_request == other.call_request) + & (self.contract_address == other.contract_address) + } +} + +impl Empty for ScopedPrivateCallRequest { + fn empty() -> Self { + ScopedPrivateCallRequest { + call_request: PrivateCallRequest::empty(), + contract_address: AztecAddress::zero(), + } + } +} + +impl Serialize for ScopedPrivateCallRequest { + fn serialize(self) -> [Field; SCOPED_PRIVATE_CALL_REQUEST_LENGTH] { + let mut fields: BoundedVec = BoundedVec::new(); + + fields.extend_from_array(self.call_request.serialize()); + fields.extend_from_array(self.contract_address.serialize()); + + assert_eq(fields.len(), SCOPED_PRIVATE_CALL_REQUEST_LENGTH); + + fields.storage + } +} + +impl Deserialize for ScopedPrivateCallRequest { + fn deserialize(fields: [Field; SCOPED_PRIVATE_CALL_REQUEST_LENGTH]) -> ScopedPrivateCallRequest { + let mut reader = Reader::new(fields); + let item = ScopedPrivateCallRequest { + call_request: reader.read_struct(PrivateCallRequest::deserialize), + contract_address: reader.read_struct(AztecAddress::deserialize), + }; + reader.finish(); + item + } +} + +#[test] +fn serialization_of_empty() { + let item = ScopedPrivateCallRequest::empty(); + let serialized = item.serialize(); + let deserialized = ScopedPrivateCallRequest::deserialize(serialized); + assert(item.eq(deserialized)); +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr index 849e0c82b47..e1f26101cb0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr @@ -2,7 +2,8 @@ use crate::{ abis::{ call_context::CallContext, max_block_number::MaxBlockNumber, gas_settings::GasSettings, nullifier_key_validation_request::NullifierKeyValidationRequest, note_hash::NoteHash, - nullifier::Nullifier, read_request::ReadRequest, log_hash::{LogHash, NoteLogHash} + nullifier::Nullifier, private_call_request::PrivateCallRequest, read_request::ReadRequest, + log_hash::{LogHash, NoteLogHash} }, constants::{ MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, @@ -34,7 +35,7 @@ struct PrivateCircuitPublicInputs { new_note_hashes: [NoteHash; MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [Nullifier; MAX_NEW_NULLIFIERS_PER_CALL], - private_call_stack_hashes: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], + private_call_requests: [PrivateCallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_function_hash: Field, new_l2_to_l1_msgs: [L2ToL1Message; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], @@ -72,7 +73,7 @@ impl Eq for PrivateCircuitPublicInputs { (self.nullifier_key_validation_requests == other.nullifier_key_validation_requests) & (self.new_note_hashes == other.new_note_hashes) & (self.new_nullifiers == other.new_nullifiers) & - (self.private_call_stack_hashes == other.private_call_stack_hashes) & + (self.private_call_requests == other.private_call_requests) & (self.public_call_stack_hashes == other.public_call_stack_hashes) & (self.new_l2_to_l1_msgs == other.new_l2_to_l1_msgs) & (self.start_side_effect_counter == other.start_side_effect_counter) & @@ -114,7 +115,9 @@ impl Serialize for PrivateCircuitPublicInp for i in 0..self.new_nullifiers.len() { fields.extend_from_array(self.new_nullifiers[i].serialize()); } - fields.extend_from_array(self.private_call_stack_hashes); + for i in 0..self.private_call_requests.len() { + fields.extend_from_array(self.private_call_requests[i].serialize()); + } fields.extend_from_array(self.public_call_stack_hashes); fields.push(self.public_teardown_function_hash); for i in 0..self.new_l2_to_l1_msgs.len() { @@ -158,7 +161,7 @@ impl Deserialize for PrivateCircuitPublicI nullifier_key_validation_requests: reader.read_struct_array(NullifierKeyValidationRequest::deserialize, [NullifierKeyValidationRequest::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL]), new_note_hashes: reader.read_struct_array(NoteHash::deserialize, [NoteHash::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]), new_nullifiers: reader.read_struct_array(Nullifier::deserialize, [Nullifier::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), - private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), + private_call_requests: reader.read_struct_array(PrivateCallRequest::deserialize, [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), public_teardown_function_hash: reader.read(), new_l2_to_l1_msgs: reader.read_struct_array(L2ToL1Message::deserialize, [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), @@ -198,7 +201,7 @@ impl Empty for PrivateCircuitPublicInputs { nullifier_key_validation_requests: [NullifierKeyValidationRequest::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL], new_note_hashes: [NoteHash::empty(); MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [Nullifier::empty(); MAX_NEW_NULLIFIERS_PER_CALL], - private_call_stack_hashes: [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], + private_call_requests: [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_function_hash: 0, new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 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 56224018099..db120790ac0 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 @@ -5,13 +5,12 @@ use crate::abis::{ call_request::CallRequest, private_call_stack_item::PrivateCallStackItem, private_circuit_public_inputs::PrivateCircuitPublicInputs }; -use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, FUNCTION_TREE_HEIGHT}; +use crate::constants::{MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, FUNCTION_TREE_HEIGHT}; use crate::merkle_tree::membership::MembershipWitness; struct PrivateCallData { call_stack_item: PrivateCallStackItem, - private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], public_teardown_call_request: CallRequest, 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 1f402b623b4..b4e9a8b5947 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 @@ -9,6 +9,11 @@ trait Ordered { fn counter(self) -> u32; } +trait RangeOrdered { + fn counter_start(self) -> u32; + fn counter_end(self) -> u32; +} + trait OrderedValue where T: Eq { fn value(self) -> T; fn counter(self) -> u32; 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 a39b851d223..1b3657cd331 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -170,13 +170,16 @@ global NOTE_HASH_LENGTH = 2; global SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2; global NULLIFIER_LENGTH = 3; 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; global TX_REQUEST_LENGTH: u64 = 2 + TX_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH; global HEADER_LENGTH: u64 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH; -global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 2 + HEADER_LENGTH + TX_CONTEXT_LENGTH; +global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 2 + HEADER_LENGTH + TX_CONTEXT_LENGTH; global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + 2 + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 1 + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + AZTEC_ADDRESS_LENGTH + /* revert_code */ 1 + 2 * GAS_LENGTH + /* transaction_fee */ 1; global PRIVATE_CALL_STACK_ITEM_LENGTH: u64 = AZTEC_ADDRESS_LENGTH + FUNCTION_DATA_LENGTH + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH; global PUBLIC_CONTEXT_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + GAS_LENGTH + 2; @@ -189,9 +192,8 @@ global PUBLIC_DATA_UPDATE_REQUEST_LENGTH = 2; global COMBINED_ACCUMULATED_DATA_LENGTH = MAX_NEW_NOTE_HASHES_PER_TX + MAX_NEW_NULLIFIERS_PER_TX + MAX_NEW_L2_TO_L1_MSGS_PER_TX + 5 + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + GAS_LENGTH; global COMBINED_CONSTANT_DATA_LENGTH = HEADER_LENGTH + TX_CONTEXT_LENGTH + GLOBAL_VARIABLES_LENGTH; -global CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH; global CALL_REQUEST_LENGTH = 1 + AZTEC_ADDRESS_LENGTH + CALLER_CONTEXT_LENGTH + 2; -global PRIVATE_ACCUMULATED_DATA_LENGTH = (SCOPED_NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_TX) + (SCOPED_NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_TX) + (MAX_NEW_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + 2 + (CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + (CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); +global PRIVATE_ACCUMULATED_DATA_LENGTH = (SCOPED_NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_TX) + (SCOPED_NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_TX) + (MAX_NEW_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + 2 + (SCOPED_PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + (CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); global PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1 + VALIDATION_REQUESTS_LENGTH + PRIVATE_ACCUMULATED_DATA_LENGTH + COMBINED_CONSTANT_DATA_LENGTH + CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; global PUBLIC_ACCUMULATED_DATA_LENGTH = (MAX_NEW_NOTE_HASHES_PER_TX * NOTE_HASH_LENGTH) + (MAX_NEW_NULLIFIERS_PER_TX * NULLIFIER_LENGTH) + (MAX_NEW_L2_TO_L1_MSGS_PER_TX * 1) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (MAX_ENCRYPTED_LOGS_PER_TX * LOG_HASH_LENGTH) + (MAX_UNENCRYPTED_LOGS_PER_TX * LOG_HASH_LENGTH) + 2 + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + (MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX * CALL_REQUEST_LENGTH) + GAS_LENGTH; 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 e1bd2ef6863..844fbcf364d 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 @@ -9,6 +9,7 @@ use crate::{ private_kernel_data::PrivateKernelData, note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, nullifier_key_validation_request::{ScopedNullifierKeyValidationRequest, NullifierKeyValidationRequest}, + private_call_request::{PrivateCallRequest, ScopedPrivateCallRequest}, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, read_request::{ReadRequest, ScopedReadRequest}, log_hash::{LogHash, NoteLogHash}, validation_requests::{ValidationRequests, ValidationRequestsBuilder} @@ -54,7 +55,7 @@ struct FixtureBuilder { encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, public_data_update_requests: BoundedVec, - private_call_stack: BoundedVec, + private_call_requests: BoundedVec, public_call_stack: BoundedVec, gas_used: Gas, non_revertible_gas_used: Gas, @@ -104,7 +105,7 @@ impl FixtureBuilder { encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, public_data_update_requests: BoundedVec::new(), - private_call_stack: BoundedVec::new(), + private_call_requests: BoundedVec::new(), public_call_stack: BoundedVec::new(), max_block_number: MaxBlockNumber::empty(), note_hash_read_requests: BoundedVec::new(), @@ -145,7 +146,7 @@ impl FixtureBuilder { unencrypted_logs_hashes: self.unencrypted_logs_hashes, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, - private_call_stack: self.private_call_stack, + private_call_stack: self.private_call_requests, public_call_stack: self.public_call_stack }; public_inputs.finish() @@ -450,8 +451,17 @@ impl FixtureBuilder { } pub fn push_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); - self.private_call_stack.push(call_stack_item); + let mut caller_context = CallerContext::empty(); + if is_delegate_call { + caller_context.msg_sender = fixtures::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; + 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 push_public_call_request(&mut self, hash: Field, is_delegate_call: bool) { @@ -536,7 +546,7 @@ impl Empty for FixtureBuilder { encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, public_data_update_requests: BoundedVec::new(), - private_call_stack: BoundedVec::new(), + private_call_requests: BoundedVec::new(), public_call_stack: BoundedVec::new(), max_block_number: MaxBlockNumber::empty(), note_hash_read_requests: BoundedVec::new(), 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 index c3d29483cca..c41d7e8a65a 100644 --- 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 @@ -2,7 +2,9 @@ use crate::{ abis::{ gas_settings::GasSettings, call_request::{CallerContext, CallRequest}, private_call_stack_item::PrivateCallStackItem, function_data::FunctionData, - max_block_number::MaxBlockNumber, private_circuit_public_inputs::PrivateCircuitPublicInputs, + 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, @@ -20,7 +22,6 @@ struct PrivateCallDataBuilder { is_execution_request: bool, function_data: FunctionData, // The rest of the values of PrivateCallData. - private_call_stack: BoundedVec, public_call_stack: BoundedVec, public_teardown_call_request: CallRequest, proof: RecursiveProof, @@ -51,7 +52,6 @@ impl PrivateCallDataBuilder { public_inputs, is_execution_request: false, function_data, - private_call_stack: BoundedVec::new(), public_call_stack: BoundedVec::new(), public_teardown_call_request: CallRequest::empty(), proof: RecursiveProof::empty(), @@ -86,36 +86,21 @@ impl PrivateCallDataBuilder { } } - pub fn build_call_request(self) -> CallRequest { + 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 caller_context = if is_delegate_call { - CallerContext { - msg_sender: fixtures::MSG_SENDER, - storage_contract_address: self.public_inputs.call_context.storage_contract_address - } - } else { - CallerContext::empty() + 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; }; - CallRequest { + PrivateCallRequest { hash, - caller_contract_address: self.public_inputs.call_context.msg_sender, - caller_context, start_side_effect_counter: self.public_inputs.counter_start, - end_side_effect_counter: self.public_inputs.counter_end - } - } - - pub fn append_private_call_requests(&mut self, num_requests: u64, is_delegate_call: bool) { - let hash_offset = 7070 + self.private_call_stack.len(); - for i in 0..self.private_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.private_call_stack.push(request); - self.public_inputs.add_private_call_request(hash); - } - } + end_side_effect_counter: self.public_inputs.counter_end, + caller_context + }.scope(self.public_inputs.call_context.msg_sender) } pub fn append_public_call_requests(&mut self, num_requests: u64, is_delegate_call: bool) { @@ -151,7 +136,6 @@ impl PrivateCallDataBuilder { pub fn finish(self) -> PrivateCallData { PrivateCallData { call_stack_item: self.build_call_stack_item(), - private_call_stack: self.private_call_stack.storage, public_call_stack: self.public_call_stack.storage, public_teardown_call_request: self.public_teardown_call_request, proof: self.proof, 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 index 9df7ea282bc..88da1d0d33f 100644 --- 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 @@ -3,8 +3,8 @@ use crate::{ call_context::CallContext, call_request::CallRequest, caller_context::CallerContext, gas_settings::GasSettings, gas::Gas, max_block_number::MaxBlockNumber, note_hash::NoteHash, nullifier::Nullifier, nullifier_key_validation_request::NullifierKeyValidationRequest, - private_circuit_public_inputs::PrivateCircuitPublicInputs, read_request::ReadRequest, - log_hash::{LogHash, NoteLogHash} + private_call_request::PrivateCallRequest, private_circuit_public_inputs::PrivateCircuitPublicInputs, + read_request::ReadRequest, log_hash::{LogHash, NoteLogHash} }, address::{AztecAddress, compute_initialization_hash}, header::Header, messaging::l2_to_l1_message::L2ToL1Message, tests::fixtures, transaction::tx_context::TxContext @@ -39,7 +39,7 @@ struct PrivateCircuitPublicInputsBuilder { new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, - private_call_stack_hashes: BoundedVec, + private_call_requests: BoundedVec, public_call_stack_hashes: BoundedVec, public_teardown_function_hash: Field, new_l2_to_l1_msgs: BoundedVec, @@ -180,10 +180,31 @@ impl PrivateCircuitPublicInputsBuilder { } } - pub fn add_private_call_request(&mut self, hash: Field) { - let _ = self.next_counter(); // Increment for creating the call. - self.private_call_stack_hashes.push(hash); - let _ = self.next_counter(); // Increment for ending the call. + 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, + start_side_effect_counter: self.next_counter(), + end_side_effect_counter: self.next_counter(), + caller_context + } + ); + } + + 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) { @@ -211,7 +232,7 @@ impl PrivateCircuitPublicInputsBuilder { nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, - private_call_stack_hashes: self.private_call_stack_hashes.storage, + 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, @@ -249,7 +270,7 @@ impl Empty for PrivateCircuitPublicInputsBuilder { nullifier_key_validation_requests: BoundedVec::new(), new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), - private_call_stack_hashes: 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(), diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr index 4f1b5ab95a1..7320e430475 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr @@ -18,6 +18,10 @@ impl Reader { self.read() as u32 } + pub fn read_bool(&mut self) -> bool { + self.read() as bool + } + pub fn read_array(&mut self, mut result: [Field; K]) -> [Field; K] { for i in 0..K { result[i] = self.data[self.offset + i]; From 2cf825fb866514408f080fa523c5b69e181ba715 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Thu, 16 May 2024 23:26:17 +0000 Subject: [PATCH 3/9] Fix tests. --- .../crates/rollup-lib/src/base/base_rollup_inputs.nr | 10 +++++----- .../crates/types/src/abis/private_call_stack_item.nr | 2 +- .../types/src/abis/private_circuit_public_inputs.nr | 2 +- .../crates/types/src/tests/fixture_builder.nr | 2 +- .../src/tests/private_circuit_public_inputs_builder.nr | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) 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 704b1ac6e65..c4d9c5ad826 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 @@ -385,8 +385,8 @@ mod tests { public_data_tree_leaf::PublicDataTreeLeaf, public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, tests::{ - fixture_builder::FixtureBuilder, merkle_tree_utils::{NonEmptyMerkleTree, compute_zero_hashes}, - sort::sort_high_to_low + fixtures, fixture_builder::FixtureBuilder, + merkle_tree_utils::{NonEmptyMerkleTree, compute_zero_hashes}, sort::sort_high_to_low }, utils::{field::{full_field_less_than, field_from_bytes_32_trunc, field_from_bytes}, uint256::U256}, traits::Empty @@ -500,8 +500,8 @@ mod tests { fn new() -> Self { let mut inputs = BaseRollupInputsBuilder::empty(); inputs.kernel_data = FixtureBuilder::new(); - inputs.constants.global_variables.chain_id = 1; - inputs.constants.global_variables.version = 0; + inputs.constants.global_variables.chain_id = fixtures::CHAIN_ID; + inputs.constants.global_variables.version = fixtures::VERSION; inputs.pre_existing_blocks[0] = inputs.kernel_data.historical_header.hash(); @@ -983,7 +983,7 @@ mod tests { #[test(should_fail_with = "kernel version does not match the rollup version")] unconstrained fn constants_dont_match_kernels_version() { let mut builder = BaseRollupInputsBuilder::new(); - builder.constants.global_variables.version = 3; + builder.constants.global_variables.version += 1; builder.fails(); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr index a34738bc2d8..89de213d6c9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr @@ -85,6 +85,6 @@ fn empty_hash() { let hash = item.hash(); // Value from private_call_stack_item.test.ts "computes empty item hash" test - let test_data_empty_hash = 0x23e9b31fb9659181d8e6d941e95cc88a6d4d43c6b6ee316351528db772f419c0; + let test_data_empty_hash = 0x6b31356bc5ba7ebd1037e561196c32756978fb4b079692cb742133afab2711; assert_eq(hash, test_data_empty_hash); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr index e1f26101cb0..a1cb6dffe69 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr @@ -231,6 +231,6 @@ fn empty_hash() { let inputs = PrivateCircuitPublicInputs::empty(); let hash = inputs.hash(); // Value from private_circuit_public_inputs.test.ts "computes empty item hash" test - let test_data_empty_hash = 0x04f513d6a85e9d0c994d3c3764732e4486264190b3bf285257f41180f09a0b58; + let test_data_empty_hash = 0xb6f2c00b491fb2a5f27952a3221dc9124093a36a7dd729a79fd427a93a370e; assert_eq(hash, test_data_empty_hash); } 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 844fbcf364d..9c913adf608 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 @@ -85,7 +85,7 @@ struct FixtureBuilder { impl FixtureBuilder { pub fn new() -> Self { - let tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::default() }; + let tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; FixtureBuilder { contract_address: fixtures::contracts::parent_contract.address, 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 index 88da1d0d33f..8f84e8dda83 100644 --- 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 @@ -88,7 +88,7 @@ impl PrivateCircuitPublicInputsBuilder { public_inputs.chain_id = fixtures::CHAIN_ID; public_inputs.version = fixtures::VERSION; - public_inputs.gas_settings = GasSettings::default(); + public_inputs.gas_settings = GasSettings::empty(); public_inputs.counter_start = counter; public_inputs.counter_end = counter + 1; From 05a879fe4768a1ad180ddc0f67e31576d57724ae Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 17 May 2024 15:19:15 +0000 Subject: [PATCH 4/9] Update ts side. --- .../aztec/src/context/private_context.nr | 2 +- .../types/src/abis/private_call_request.nr | 10 +- .../src/tests/private_call_data_builder.nr | 4 +- .../private_circuit_public_inputs_builder.nr | 4 +- .../circuits.js/src/structs/call_request.ts | 65 +---------- .../circuits.js/src/structs/caller_context.ts | 80 +++++++++++++ yarn-project/circuits.js/src/structs/index.ts | 2 + .../kernel/private_accumulated_data.ts | 8 +- .../src/structs/kernel/private_call_data.ts | 7 -- ...vate_kernel_init_circuit_private_inputs.ts | 7 +- .../src/structs/private_call_request.ts | 109 ++++++++++++++++++ .../src/structs/private_call_stack_item.ts | 26 +---- .../structs/private_circuit_public_inputs.ts | 15 +-- .../src/structs/public_call_request.ts | 9 +- .../src/structs/public_call_stack_item.ts | 9 +- .../circuits.js/src/tests/factories.ts | 33 ++---- .../src/type_conversion.ts | 37 +++++- .../pxe/src/kernel_prover/kernel_prover.ts | 16 +-- .../build_private_kernel_init_hints.ts | 19 +-- .../src/client/private_execution.test.ts | 2 +- 20 files changed, 276 insertions(+), 188 deletions(-) create mode 100644 yarn-project/circuits.js/src/structs/caller_context.ts create mode 100644 yarn-project/circuits.js/src/structs/private_call_request.ts diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 6bc392209f5..09fe6367c6e 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -480,7 +480,7 @@ impl PrivateContext { caller_context.storage_contract_address = self.inputs.call_context.storage_contract_address; } self.private_call_requests.push( - PrivateCallRequest { hash: item.hash(), start_side_effect_counter, end_side_effect_counter, caller_context } + PrivateCallRequest { hash: item.hash(), caller_context, start_side_effect_counter, end_side_effect_counter } ); PackedReturns::new(item.public_inputs.returns_hash) 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 167595b2d4d..8638a124253 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 @@ -7,9 +7,9 @@ use crate::{ struct PrivateCallRequest { hash: Field, + caller_context: CallerContext, start_side_effect_counter: u32, end_side_effect_counter: u32, - caller_context: CallerContext, } impl Ordered for PrivateCallRequest { @@ -30,9 +30,9 @@ impl RangeOrdered for PrivateCallRequest { impl Eq for PrivateCallRequest { fn eq(self, other: PrivateCallRequest) -> bool { (self.hash == other.hash) + & (self.caller_context == other.caller_context) & (self.start_side_effect_counter == other.start_side_effect_counter) & (self.end_side_effect_counter == other.end_side_effect_counter) - & (self.caller_context == other.caller_context) } } @@ -40,9 +40,9 @@ impl Empty for PrivateCallRequest { fn empty() -> Self { PrivateCallRequest { hash: 0, + caller_context: CallerContext::empty(), start_side_effect_counter: 0, end_side_effect_counter: 0, - caller_context: CallerContext::empty(), } } } @@ -52,9 +52,9 @@ impl Serialize for PrivateCallRequest { let mut fields: BoundedVec = BoundedVec::new(); fields.push(self.hash); + fields.extend_from_array(self.caller_context.serialize()); fields.push(self.start_side_effect_counter as Field); fields.push(self.end_side_effect_counter as Field); - fields.extend_from_array(self.caller_context.serialize()); assert_eq(fields.len(), PRIVATE_CALL_REQUEST_LENGTH); @@ -67,9 +67,9 @@ impl Deserialize for PrivateCallRequest { let mut reader = Reader::new(fields); let item = PrivateCallRequest { hash: reader.read(), + caller_context: reader.read_struct(CallerContext::deserialize), start_side_effect_counter: reader.read_u32(), end_side_effect_counter: reader.read_u32(), - caller_context: reader.read_struct(CallerContext::deserialize), }; reader.finish(); item 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 index c41d7e8a65a..afbf7f07b7d 100644 --- 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 @@ -97,9 +97,9 @@ impl PrivateCallDataBuilder { }; PrivateCallRequest { hash, + caller_context, start_side_effect_counter: self.public_inputs.counter_start, - end_side_effect_counter: self.public_inputs.counter_end, - caller_context + end_side_effect_counter: self.public_inputs.counter_end }.scope(self.public_inputs.call_context.msg_sender) } 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 index 8f84e8dda83..02cdad6cf97 100644 --- 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 @@ -190,9 +190,9 @@ impl PrivateCircuitPublicInputsBuilder { self.private_call_requests.push( PrivateCallRequest { hash, + caller_context, start_side_effect_counter: self.next_counter(), - end_side_effect_counter: self.next_counter(), - caller_context + end_side_effect_counter: self.next_counter() } ); } diff --git a/yarn-project/circuits.js/src/structs/call_request.ts b/yarn-project/circuits.js/src/structs/call_request.ts index 89fef28fcb7..518b846cc58 100644 --- a/yarn-project/circuits.js/src/structs/call_request.ts +++ b/yarn-project/circuits.js/src/structs/call_request.ts @@ -1,72 +1,9 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type FieldsOf } from '@aztec/foundation/types'; -/** - * Caller context. - */ -export class CallerContext { - constructor( - /** - * Address of the caller contract. - */ - public msgSender: AztecAddress, - /** - * Storage contract address of the caller contract. - */ - public storageContractAddress: AztecAddress, - ) {} - - /** - * Returns a new instance of CallerContext with zero values. - * @returns A new instance of CallerContext with zero values. - */ - public static empty(): CallerContext { - return new CallerContext(AztecAddress.ZERO, AztecAddress.ZERO); - } - - isEmpty() { - return this.msgSender.isZero() && this.storageContractAddress.isZero(); - } - - static from(fields: FieldsOf): CallerContext { - return new CallerContext(...CallerContext.getFields(fields)); - } - - static getFields(fields: FieldsOf) { - return [fields.msgSender, fields.storageContractAddress] as const; - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(...CallerContext.getFields(this)); - } - - /** - * Deserialize this from a buffer. - * @param buffer - The bufferable type from which to deserialize. - * @returns The deserialized instance of PublicCallRequest. - */ - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new CallerContext(new AztecAddress(reader.readBytes(32)), new AztecAddress(reader.readBytes(32))); - } - - equals(callerContext: CallerContext) { - return ( - callerContext.msgSender.equals(this.msgSender) && - callerContext.storageContractAddress.equals(this.storageContractAddress) - ); - } -} +import { CallerContext } from './caller_context.js'; -/** - * Call request. - */ export class CallRequest { constructor( /** diff --git a/yarn-project/circuits.js/src/structs/caller_context.ts b/yarn-project/circuits.js/src/structs/caller_context.ts new file mode 100644 index 00000000000..bce17c1d313 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/caller_context.ts @@ -0,0 +1,80 @@ +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { type Fr } from '@aztec/foundation/fields'; +import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import { type FieldsOf } from '@aztec/foundation/types'; + +export class CallerContext { + constructor( + /** + * Address of the caller contract. + */ + public msgSender: AztecAddress, + /** + * Storage contract address of the caller contract. + */ + public storageContractAddress: AztecAddress, + /** + * Whether the caller was modifying state. + */ + public isStaticCall: boolean, + ) {} + + toFields(): Fr[] { + return serializeToFields([this.msgSender, this.storageContractAddress, this.isStaticCall]); + } + + static fromFields(fields: Fr[] | FieldReader) { + const reader = FieldReader.asReader(fields); + return new CallerContext(reader.readObject(AztecAddress), reader.readObject(AztecAddress), reader.readBoolean()); + } + + /** + * Returns a new instance of CallerContext with zero values. + * @returns A new instance of CallerContext with zero values. + */ + public static empty(): CallerContext { + return new CallerContext(AztecAddress.ZERO, AztecAddress.ZERO, false); + } + + isEmpty() { + return this.msgSender.isZero() && this.storageContractAddress.isZero() && !this.isStaticCall; + } + + static from(fields: FieldsOf): CallerContext { + return new CallerContext(...CallerContext.getFields(fields)); + } + + static getFields(fields: FieldsOf) { + return [fields.msgSender, fields.storageContractAddress, fields.isStaticCall] as const; + } + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(...CallerContext.getFields(this)); + } + + /** + * Deserialize this from a buffer. + * @param buffer - The bufferable type from which to deserialize. + * @returns The deserialized instance of PublicCallRequest. + */ + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new CallerContext( + new AztecAddress(reader.readBytes(32)), + new AztecAddress(reader.readBytes(32)), + reader.readBoolean(), + ); + } + + equals(callerContext: CallerContext) { + return ( + callerContext.msgSender.equals(this.msgSender) && + callerContext.storageContractAddress.equals(this.storageContractAddress) && + callerContext.isStaticCall === this.isStaticCall + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index 8be49f1d142..e4e2b2b4194 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -2,6 +2,7 @@ export * from '@aztec/foundation/eth-address'; export * from './aggregation_object.js'; export * from './call_context.js'; export * from './call_request.js'; +export * from './caller_context.js'; export * from './complete_address.js'; export * from './content_commitment.js'; export * from './context/private_context_inputs.js'; @@ -46,6 +47,7 @@ export * from './parity/parity_public_inputs.js'; export * from './parity/root_parity_input.js'; export * from './parity/root_parity_inputs.js'; export * from './partial_state_reference.js'; +export * from './private_call_request.js'; export * from './private_call_stack_item.js'; export * from './private_circuit_public_inputs.js'; export * from './proof.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts index 0c83610688a..9390eeef9fc 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts @@ -17,6 +17,7 @@ import { ScopedL2ToL1Message } from '../l2_to_l1_message.js'; import { LogHash, NoteLogHash } from '../log_hash.js'; import { ScopedNoteHash } from '../note_hash.js'; import { ScopedNullifier } from '../nullifier.js'; +import { ScopedPrivateCallRequest } from '../private_call_request.js'; /** * Specific accumulated data structure for the final ordering private kernel circuit. It is included @@ -61,9 +62,8 @@ export class PrivateAccumulatedData { public unencryptedLogPreimagesLength: Fr, /** * Current private call stack. - * TODO(#3417): Given this field must empty, should we just remove it? */ - public privateCallStack: Tuple, + public privateCallStack: Tuple, /** * Current public call stack. */ @@ -105,7 +105,7 @@ export class PrivateAccumulatedData { reader.readArray(MAX_UNENCRYPTED_LOGS_PER_TX, LogHash), Fr.fromBuffer(reader), Fr.fromBuffer(reader), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), + reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, ScopedPrivateCallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), ); } @@ -129,7 +129,7 @@ export class PrivateAccumulatedData { makeTuple(MAX_UNENCRYPTED_LOGS_PER_TX, LogHash.empty), Fr.zero(), Fr.zero(), - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), + makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, ScopedPrivateCallRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), ); } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts index 0500563e16d..c00d927fb5b 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_call_data.ts @@ -4,7 +4,6 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { FUNCTION_TREE_HEIGHT, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, RECURSIVE_PROOF_LENGTH, } from '../../constants.gen.js'; @@ -23,10 +22,6 @@ export class PrivateCallData { * The call stack item currently being processed. */ public callStackItem: PrivateCallStackItem, - /** - * Other private call stack items to be processed. - */ - public privateCallStack: Tuple, /** * Other public call stack items to be processed. */ @@ -77,7 +72,6 @@ export class PrivateCallData { static getFields(fields: FieldsOf) { return [ fields.callStackItem, - fields.privateCallStack, fields.publicCallStack, fields.publicTeardownCallRequest, fields.proof, @@ -112,7 +106,6 @@ export class PrivateCallData { const reader = BufferReader.asReader(buffer); return new PrivateCallData( reader.readObject(PrivateCallStackItem), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, CallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, CallRequest), reader.readObject(CallRequest), RecursiveProof.fromBuffer(reader, RECURSIVE_PROOF_LENGTH), diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts index 7262cc7b1b5..b2b83ece100 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_init_circuit_private_inputs.ts @@ -8,7 +8,6 @@ export class PrivateKernelInitHints { constructor( public noteHashNullifierCounters: Tuple, public firstRevertiblePrivateCallRequestIndex: number, - public firstRevertiblePublicCallRequestIndex: number, ) {} toBuffer() { @@ -17,11 +16,7 @@ export class PrivateKernelInitHints { static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new PrivateKernelInitHints( - reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_CALL), - reader.readNumber(), - reader.readNumber(), - ); + return new PrivateKernelInitHints(reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_CALL), reader.readNumber()); } } diff --git a/yarn-project/circuits.js/src/structs/private_call_request.ts b/yarn-project/circuits.js/src/structs/private_call_request.ts new file mode 100644 index 00000000000..2363165925c --- /dev/null +++ b/yarn-project/circuits.js/src/structs/private_call_request.ts @@ -0,0 +1,109 @@ +import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; + +import { CallerContext } from './caller_context.js'; + +export class PrivateCallRequest { + constructor( + /** + * The call stack item hash of the call. + */ + public hash: Fr, + /** + * The call context of the contract making the call. + */ + public callerContext: CallerContext, + /** + * The start counter of the call. + */ + public startSideEffectCounter: number, + /** + * The end counter of the call. + */ + public endSideEffectCounter: number, + ) {} + + toFields(): Fr[] { + return serializeToFields([this.hash, this.callerContext, this.startSideEffectCounter, this.endSideEffectCounter]); + } + + static fromFields(fields: Fr[] | FieldReader) { + const reader = FieldReader.asReader(fields); + return new PrivateCallRequest( + reader.readField(), + reader.readObject(CallerContext), + reader.readU32(), + reader.readU32(), + ); + } + + toBuffer() { + return serializeToBuffer(this.hash, this.callerContext, this.startSideEffectCounter, this.endSideEffectCounter); + } + + public static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new PrivateCallRequest( + Fr.fromBuffer(reader), + reader.readObject(CallerContext), + reader.readNumber(), + reader.readNumber(), + ); + } + + isEmpty() { + return ( + this.hash.isZero() && + this.callerContext.isEmpty() && + this.startSideEffectCounter === 0 && + this.endSideEffectCounter === 0 + ); + } + + public static empty() { + return new PrivateCallRequest(Fr.ZERO, CallerContext.empty(), 0, 0); + } + + equals(callRequest: PrivateCallRequest) { + return ( + callRequest.hash.equals(this.hash) && + callRequest.callerContext.equals(this.callerContext) && + callRequest.startSideEffectCounter === this.startSideEffectCounter && + callRequest.endSideEffectCounter === this.endSideEffectCounter + ); + } + + toString() { + return `PrivateCallRequest(hash: ${this.hash}, callerContext: ${this.callerContext}, startSideEffectCounter: ${this.startSideEffectCounter}, endSideEffectCounter: ${this.endSideEffectCounter})`; + } +} + +export class ScopedPrivateCallRequest { + constructor(public callRequest: PrivateCallRequest, public contractAddress: AztecAddress) {} + + toBuffer() { + return serializeToBuffer(this.callRequest, this.contractAddress); + } + + public static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new ScopedPrivateCallRequest(reader.readObject(PrivateCallRequest), reader.readObject(AztecAddress)); + } + + isEmpty() { + return this.callRequest.isEmpty() && this.contractAddress.isZero(); + } + + public static empty() { + return new ScopedPrivateCallRequest(PrivateCallRequest.empty(), AztecAddress.ZERO); + } + + equals(callRequest: ScopedPrivateCallRequest) { + return callRequest.callRequest.equals(this.callRequest) && callRequest.contractAddress.equals(this.contractAddress); + } + + toString() { + return `ScopedPrivateCallRequest(callRequest: ${this.callRequest}, contractAddress: ${this.contractAddress})`; + } +} diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts index 23f9060c372..bfce7897770 100644 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts @@ -1,12 +1,10 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { pedersenHash } from '@aztec/foundation/crypto'; -import { Fr } from '@aztec/foundation/fields'; +import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, PRIVATE_CALL_STACK_ITEM_LENGTH } from '../constants.gen.js'; -import { type CallContext } from './call_context.js'; -import { CallRequest, CallerContext } from './call_request.js'; import { FunctionData } from './function_data.js'; import { PrivateCircuitPublicInputs } from './private_circuit_public_inputs.js'; @@ -93,26 +91,4 @@ export class PrivateCallStackItem { public hash(): Fr { return pedersenHash(this.toFields(), GeneratorIndex.CALL_STACK_ITEM); } - - /** - * Creates a new CallRequest with values of the calling contract. - * @returns A CallRequest instance with the contract address, caller context, and the hash of the call stack item. - */ - public toCallRequest(parentCallContext: CallContext) { - if (this.isEmpty()) { - return CallRequest.empty(); - } - - const currentCallContext = this.publicInputs.callContext; - const callerContext = currentCallContext.isDelegateCall - ? new CallerContext(parentCallContext.msgSender, parentCallContext.storageContractAddress) - : CallerContext.empty(); - return new CallRequest( - this.hash(), - parentCallContext.storageContractAddress, - callerContext, - new Fr(this.publicInputs.callContext.sideEffectCounter), - this.publicInputs.endSideEffectCounter, - ); - } } diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 7eae5eedb78..6ff1402ad58 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -35,6 +35,7 @@ import { MaxBlockNumber } from './max_block_number.js'; import { NoteHash } from './note_hash.js'; import { Nullifier } from './nullifier.js'; import { NullifierKeyValidationRequest } from './nullifier_key_validation_request.js'; +import { PrivateCallRequest } from './private_call_request.js'; import { ReadRequest } from './read_request.js'; import { TxContext } from './tx_context.js'; @@ -91,9 +92,9 @@ export class PrivateCircuitPublicInputs { */ public newNullifiers: Tuple, /** - * Private call stack at the current kernel iteration. + * Private call requests made within the current kernel iteration. */ - public privateCallStackHashes: Tuple, + public privateCallRequests: Tuple, /** * Public call stack at the current kernel iteration. */ @@ -181,7 +182,7 @@ export class PrivateCircuitPublicInputs { reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, NoteHash), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, Nullifier), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr), + reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, PrivateCallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr), reader.readObject(Fr), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), @@ -211,7 +212,7 @@ export class PrivateCircuitPublicInputs { reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, NoteHash), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, Nullifier), - reader.readFieldArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL), + reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, PrivateCallRequest), reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL), reader.readField(), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), @@ -244,7 +245,7 @@ export class PrivateCircuitPublicInputs { makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest.empty), makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, NoteHash.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, Nullifier.empty), - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr.zero), + makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, PrivateCallRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr.zero), Fr.ZERO, makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message.empty), @@ -274,7 +275,7 @@ export class PrivateCircuitPublicInputs { isEmptyArray(this.nullifierKeyValidationRequests) && isEmptyArray(this.newNoteHashes) && isEmptyArray(this.newNullifiers) && - isZeroArray(this.privateCallStackHashes) && + isEmptyArray(this.privateCallRequests) && isZeroArray(this.publicCallStackHashes) && this.publicTeardownFunctionHash.isZero() && isEmptyArray(this.newL2ToL1Msgs) && @@ -306,7 +307,7 @@ export class PrivateCircuitPublicInputs { fields.nullifierKeyValidationRequests, fields.newNoteHashes, fields.newNullifiers, - fields.privateCallStackHashes, + fields.privateCallRequests, fields.publicCallStackHashes, fields.publicTeardownFunctionHash, fields.newL2ToL1Msgs, diff --git a/yarn-project/circuits.js/src/structs/public_call_request.ts b/yarn-project/circuits.js/src/structs/public_call_request.ts index f371a91b1d2..752adfc7672 100644 --- a/yarn-project/circuits.js/src/structs/public_call_request.ts +++ b/yarn-project/circuits.js/src/structs/public_call_request.ts @@ -7,7 +7,8 @@ import { inspect } from 'util'; import { computeVarArgsHash } from '../hash/hash.js'; import { CallContext } from './call_context.js'; -import { CallRequest, CallerContext } from './call_request.js'; +import { CallRequest } from './call_request.js'; +import { CallerContext } from './caller_context.js'; import { FunctionData } from './function_data.js'; import { PublicCallStackItem } from './public_call_stack_item.js'; import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; @@ -116,7 +117,11 @@ export class PublicCallRequest { toCallRequest() { const item = this.toPublicCallStackItem(); const callerContext = this.callContext.isDelegateCall - ? new CallerContext(this.parentCallContext.msgSender, this.parentCallContext.storageContractAddress) + ? new CallerContext( + this.parentCallContext.msgSender, + this.parentCallContext.storageContractAddress, + this.parentCallContext.isStaticCall, + ) : CallerContext.empty(); return new CallRequest( item.hash(), diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.ts index 0d53df6b95c..3223909d287 100644 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/public_call_stack_item.ts @@ -6,7 +6,8 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex } from '../constants.gen.js'; import { type CallContext } from './call_context.js'; -import { CallRequest, CallerContext } from './call_request.js'; +import { CallRequest } from './call_request.js'; +import { CallerContext } from './caller_context.js'; import { FunctionData } from './function_data.js'; import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; @@ -113,7 +114,11 @@ export class PublicCallStackItem { const currentCallContext = this.publicInputs.callContext; const callerContext = currentCallContext.isDelegateCall - ? new CallerContext(parentCallContext.msgSender, parentCallContext.storageContractAddress) + ? new CallerContext( + parentCallContext.msgSender, + parentCallContext.storageContractAddress, + parentCallContext.isStaticCall, + ) : CallerContext.empty(); // todo: populate side effect counters correctly return new CallRequest(this.hash(), parentCallContext.storageContractAddress, callerContext, Fr.ZERO, Fr.ZERO); diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 49ccb6738b4..ff67b7ab32f 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -27,7 +27,6 @@ import { ConstantRollupData, ContractStorageRead, ContractStorageUpdateRequest, - FUNCTION_TREE_HEIGHT, Fq, Fr, FunctionData, @@ -91,7 +90,7 @@ import { PartialStateReference, Point, PreviousRollupData, - PrivateCallData, + PrivateCallRequest, PrivateCallStackItem, PrivateCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, @@ -619,7 +618,7 @@ export function makeProof(seed = 1) { * @returns A call stack item. */ export function makeCallerContext(seed = 1): CallerContext { - return new CallerContext(makeAztecAddress(seed), makeAztecAddress(seed + 0x1)); + return new CallerContext(makeAztecAddress(seed), makeAztecAddress(seed + 0x1), false); } /** @@ -631,6 +630,10 @@ export function makeCallRequest(seed = 1): CallRequest { return new CallRequest(fr(seed), makeAztecAddress(seed + 0x1), makeCallerContext(seed + 0x2), fr(0), fr(0)); } +function makePrivateCallRequest(seed = 1): PrivateCallRequest { + return new PrivateCallRequest(fr(seed), makeCallerContext(seed + 0x2), seed + 0x10, seed + 0x11); +} + /** * Makes arbitrary public call stack item. * @param seed - The seed to use for generating the public call stack item. @@ -732,28 +735,6 @@ export function makeTxRequest(seed = 1): TxRequest { }); } -/** - * Makes arbitrary private call data. - * @param seed - The seed to use for generating the private call data. - * @returns A private call data. - */ -export function makePrivateCallData(seed = 1): PrivateCallData { - return PrivateCallData.from({ - callStackItem: makePrivateCallStackItem(seed), - privateCallStack: makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, makeCallRequest, seed + 0x10), - publicCallStack: makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, makeCallRequest, seed + 0x20), - publicTeardownCallRequest: makeCallRequest(seed + 0x30), - proof: makeRecursiveProof(RECURSIVE_PROOF_LENGTH, seed + 0x50), - vk: makeVerificationKeyAsFields(), - contractClassArtifactHash: fr(seed + 0x70), - contractClassPublicBytecodeCommitment: fr(seed + 0x71), - publicKeysHash: fr(seed + 0x72), - saltedInitializationHash: fr(seed + 0x73), - functionLeafMembershipWitness: makeMembershipWitness(FUNCTION_TREE_HEIGHT, seed + 0x30), - acirHash: fr(seed + 0x60), - }); -} - /** * Makes arbitrary private call stack item. * @param seed - The seed to use for generating the private call stack item. @@ -788,7 +769,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn ), newNoteHashes: makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, makeNoteHash, seed + 0x400), newNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, makeNullifier, seed + 0x500), - privateCallStackHashes: makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), + privateCallRequests: makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, makePrivateCallRequest, seed + 0x600), publicCallStackHashes: makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x700), publicTeardownFunctionHash: fr(seed + 0x800), newL2ToL1Msgs: makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x800), diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 750d1909db5..f2c276da523 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -70,6 +70,7 @@ import { type PreviousRollupData, PrivateAccumulatedData, type PrivateCallData, + PrivateCallRequest, type PrivateCallStackItem, type PrivateCircuitPublicInputs, PrivateKernelCircuitPublicInputs, @@ -112,6 +113,7 @@ import { ScopedNoteHash, ScopedNullifier, ScopedNullifierKeyValidationRequest, + ScopedPrivateCallRequest, ScopedReadRequest, type SettledReadHint, type StateDiffHints, @@ -177,6 +179,7 @@ import type { PreviousRollupData as PreviousRollupDataNoir, PrivateAccumulatedData as PrivateAccumulatedDataNoir, PrivateCallData as PrivateCallDataNoir, + PrivateCallRequest as PrivateCallRequestNoir, PrivateCallStackItem as PrivateCallStackItemNoir, PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, @@ -216,6 +219,7 @@ import type { ScopedNoteHash as ScopedNoteHashNoir, ScopedNullifierKeyValidationRequest as ScopedNullifierKeyValidationRequestNoir, ScopedNullifier as ScopedNullifierNoir, + ScopedPrivateCallRequest as ScopedPrivateCallRequestNoir, ScopedReadRequest as ScopedReadRequestNoir, StateDiffHints as StateDiffHintsNoir, StateReference as StateReferenceNoir, @@ -491,6 +495,7 @@ export function mapCallerContextFromNoir(callerContext: CallerContextNoir): Call return new CallerContext( mapAztecAddressFromNoir(callerContext.msg_sender), mapAztecAddressFromNoir(callerContext.storage_contract_address), + callerContext.is_static_call, ); } @@ -503,9 +508,35 @@ export function mapCallerContextToNoir(callerContext: CallerContext): CallerCont return { msg_sender: mapAztecAddressToNoir(callerContext.msgSender), storage_contract_address: mapAztecAddressToNoir(callerContext.storageContractAddress), + is_static_call: callerContext.isStaticCall, }; } +function mapPrivateCallRequestToNoir(callRequest: PrivateCallRequest): PrivateCallRequestNoir { + return { + hash: mapFieldToNoir(callRequest.hash), + caller_context: mapCallerContextToNoir(callRequest.callerContext), + start_side_effect_counter: mapNumberToNoir(callRequest.startSideEffectCounter), + end_side_effect_counter: mapNumberToNoir(callRequest.endSideEffectCounter), + }; +} + +function mapPrivateCallRequestFromNoir(callRequest: PrivateCallRequestNoir) { + return new PrivateCallRequest( + mapFieldFromNoir(callRequest.hash), + mapCallerContextFromNoir(callRequest.caller_context), + mapNumberFromNoir(callRequest.start_side_effect_counter), + mapNumberFromNoir(callRequest.end_side_effect_counter), + ); +} + +function mapScopedPrivateCallRequestFromNoir(callRequest: ScopedPrivateCallRequestNoir) { + return new ScopedPrivateCallRequest( + mapPrivateCallRequestFromNoir(callRequest.call_request), + mapAztecAddressFromNoir(callRequest.contract_address), + ); +} + /** * Maps a noir call request to a call request. * @param callRequest - The noir call request. @@ -789,7 +820,7 @@ export function mapPrivateCircuitPublicInputsToNoir( ), new_note_hashes: mapTuple(privateCircuitPublicInputs.newNoteHashes, mapNoteHashToNoir), new_nullifiers: mapTuple(privateCircuitPublicInputs.newNullifiers, mapNullifierToNoir), - private_call_stack_hashes: mapTuple(privateCircuitPublicInputs.privateCallStackHashes, mapFieldToNoir), + private_call_requests: mapTuple(privateCircuitPublicInputs.privateCallRequests, mapPrivateCallRequestToNoir), public_call_stack_hashes: mapTuple(privateCircuitPublicInputs.publicCallStackHashes, mapFieldToNoir), public_teardown_function_hash: mapFieldToNoir(privateCircuitPublicInputs.publicTeardownFunctionHash), new_l2_to_l1_msgs: mapTuple(privateCircuitPublicInputs.newL2ToL1Msgs, mapL2ToL1MessageToNoir), @@ -828,7 +859,6 @@ export function mapPrivateCallStackItemToNoir(privateCallStackItem: PrivateCallS export function mapPrivateCallDataToNoir(privateCallData: PrivateCallData): PrivateCallDataNoir { return { call_stack_item: mapPrivateCallStackItemToNoir(privateCallData.callStackItem), - private_call_stack: mapTuple(privateCallData.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(privateCallData.publicCallStack, mapCallRequestToNoir), public_teardown_call_request: mapCallRequestToNoir(privateCallData.publicTeardownCallRequest), proof: mapRecursiveProofToNoir(privateCallData.proof), @@ -1097,7 +1127,7 @@ export function mapPrivateAccumulatedDataFromNoir( mapTupleFromNoir( privateAccumulatedData.private_call_stack, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, + mapScopedPrivateCallRequestFromNoir, ), mapTupleFromNoir( privateAccumulatedData.public_call_stack, @@ -1436,7 +1466,6 @@ function mapPrivateKernelInitHintsToNoir(inputs: PrivateKernelInitHints): Privat return { note_hash_nullifier_counters: mapTuple(inputs.noteHashNullifierCounters, mapNumberToNoir), first_revertible_private_call_request_index: mapNumberToNoir(inputs.firstRevertiblePrivateCallRequestIndex), - first_revertible_public_call_request_index: mapNumberToNoir(inputs.firstRevertiblePublicCallRequestIndex), }; } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 6c9f033c274..c9b3a5e1d6a 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -2,7 +2,6 @@ import { type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types' import { CallRequest, Fr, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, NESTED_RECURSIVE_PROOF_LENGTH, PrivateCallData, @@ -76,9 +75,6 @@ export class KernelProver { const currentExecution = executionStack.pop()!; executionStack.push(...currentExecution.nestedExecutions); - const privateCallRequests = currentExecution.nestedExecutions.map(result => - result.callStackItem.toCallRequest(currentExecution.callStackItem.publicInputs.callContext), - ); const publicCallRequests = currentExecution.enqueuedPublicFunctionCalls.map(result => result.toCallRequest()); const publicTeardownCallRequest = currentExecution.publicTeardownFunctionCall.isEmpty() ? CallRequest.empty() @@ -91,7 +87,6 @@ export class KernelProver { const privateCallData = await this.createPrivateCallData( currentExecution, - privateCallRequests, publicCallRequests, publicTeardownCallRequest, proofOutput.proof, @@ -102,8 +97,7 @@ export class KernelProver { const hints = buildPrivateKernelInitHints( currentExecution.callStackItem.publicInputs, noteHashNullifierCounterMap, - privateCallRequests, - publicCallRequests, + currentExecution.callStackItem.publicInputs.privateCallRequests, ); const proofInput = new PrivateKernelInitCircuitPrivateInputs(txRequest, privateCallData, hints); pushTestData('private-kernel-inputs-init', proofInput); @@ -174,7 +168,6 @@ export class KernelProver { private async createPrivateCallData( { callStackItem }: ExecutionResult, - privateCallRequests: CallRequest[], publicCallRequests: CallRequest[], publicTeardownCallRequest: CallRequest, proof: RecursiveProof, @@ -182,12 +175,6 @@ export class KernelProver { ) { const { contractAddress, functionData } = callStackItem; - // Pad with empty items to reach max/const length expected by circuit. - const privateCallStack = padArrayEnd( - privateCallRequests, - CallRequest.empty(), - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, - ); const publicCallStack = padArrayEnd(publicCallRequests, CallRequest.empty(), MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL); const functionLeafMembershipWitness = await this.oracle.getFunctionMembershipWitness( @@ -206,7 +193,6 @@ export class KernelProver { return PrivateCallData.from({ callStackItem, - privateCallStack, publicCallStack, publicTeardownCallRequest, proof, diff --git a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts index fb6a95f5fd9..b81c952d023 100644 --- a/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts +++ b/yarn-project/pxe/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts @@ -1,6 +1,6 @@ import { - type CallRequest, type MAX_NEW_NOTE_HASHES_PER_CALL, + type PrivateCallRequest, type PrivateCircuitPublicInputs, PrivateKernelInitHints, countAccumulatedItems, @@ -10,30 +10,19 @@ import { type Tuple } from '@aztec/foundation/serialize'; export function buildPrivateKernelInitHints( publicInputs: PrivateCircuitPublicInputs, noteHashNullifierCounterMap: Map, - privateCallRequests: CallRequest[], - publicCallRequests: CallRequest[], + privateCallRequests: PrivateCallRequest[], ) { const nullifierCounters = publicInputs.newNoteHashes.map( n => noteHashNullifierCounterMap.get(n.counter) ?? 0, ) as Tuple; - const minRevertibleCounter = publicInputs.minRevertibleSideEffectCounter; + const minRevertibleCounter = publicInputs.minRevertibleSideEffectCounter.toNumber(); let firstRevertiblePrivateCallRequestIndex = privateCallRequests.findIndex( r => r.startSideEffectCounter >= minRevertibleCounter, ); if (firstRevertiblePrivateCallRequestIndex === -1) { firstRevertiblePrivateCallRequestIndex = countAccumulatedItems(privateCallRequests); } - let firstRevertiblePublicCallRequestIndex = publicCallRequests.findIndex( - r => r.startSideEffectCounter >= minRevertibleCounter, - ); - if (firstRevertiblePublicCallRequestIndex === -1) { - firstRevertiblePublicCallRequestIndex = countAccumulatedItems(publicCallRequests); - } - return new PrivateKernelInitHints( - nullifierCounters, - firstRevertiblePrivateCallRequestIndex, - firstRevertiblePublicCallRequestIndex, - ); + return new PrivateKernelInitHints(nullifierCounters, firstRevertiblePrivateCallRequestIndex); } diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 7750808fd5d..fefa26bc243 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -527,7 +527,7 @@ describe('Private Execution test suite', () => { // check that Aztec.nr calculated the call stack item hash like cpp does const expectedCallStackItemHash = result.nestedExecutions[0].callStackItem.hash(); - expect(result.callStackItem.publicInputs.privateCallStackHashes[0]).toEqual(expectedCallStackItemHash); + expect(result.callStackItem.publicInputs.privateCallRequests[0].hash).toEqual(expectedCallStackItemHash); }); }); From 8c0afe5de0bdf058061e0c01201c204036ccba5d Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 17 May 2024 15:28:00 +0000 Subject: [PATCH 5/9] Update constants and snapshots. --- .../src/barretenberg/vm/avm_trace/aztec_constants.hpp | 9 ++++++--- l1-contracts/src/core/libraries/ConstantsGen.sol | 10 +++++++--- yarn-project/circuits.js/src/constants.gen.ts | 8 +++++--- .../__snapshots__/private_call_stack_item.test.ts.snap | 4 ++-- .../private_circuit_public_inputs.test.ts.snap | 4 ++-- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/aztec_constants.hpp index caa72df3834..32b7e2c53c8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/aztec_constants.hpp @@ -101,6 +101,9 @@ const size_t NOTE_HASH_LENGTH = 2; const size_t SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2; const size_t NULLIFIER_LENGTH = 3; const size_t SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1; +const size_t CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1; +const size_t PRIVATE_CALL_REQUEST_LENGTH = 3 + CALLER_CONTEXT_LENGTH; +const size_t SCOPED_PRIVATE_CALL_REQUEST_LENGTH = PRIVATE_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; const size_t SIDE_EFFECT_LENGTH = 2; const size_t ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH; const size_t STATE_REFERENCE_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; @@ -113,7 +116,7 @@ const size_t PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + HEADER_LENGTH + TX_CONTEXT_LENGTH; @@ -143,13 +146,13 @@ const size_t COMBINED_ACCUMULATED_DATA_LENGTH = MAX_NEW_NOTE_HASHES_PER_TX + MAX_NEW_NULLIFIERS_PER_TX + MAX_NEW_L2_TO_L1_MSGS_PER_TX + 5 + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + GAS_LENGTH; const size_t COMBINED_CONSTANT_DATA_LENGTH = HEADER_LENGTH + TX_CONTEXT_LENGTH + GLOBAL_VARIABLES_LENGTH; -const size_t CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH; const size_t CALL_REQUEST_LENGTH = 1 + AZTEC_ADDRESS_LENGTH + CALLER_CONTEXT_LENGTH + 2; const size_t PRIVATE_ACCUMULATED_DATA_LENGTH = (SCOPED_NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_TX) + (SCOPED_NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_TX) + (MAX_NEW_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + - (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + (CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + + (SCOPED_PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + (CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); const size_t PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1 + VALIDATION_REQUESTS_LENGTH + PRIVATE_ACCUMULATED_DATA_LENGTH + COMBINED_CONSTANT_DATA_LENGTH + diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index cb991f7b17d..3fc11522d55 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -130,6 +130,10 @@ library Constants { uint256 internal constant SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2; uint256 internal constant NULLIFIER_LENGTH = 3; uint256 internal constant SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1; + uint256 internal constant CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1; + uint256 internal constant PRIVATE_CALL_REQUEST_LENGTH = 3 + CALLER_CONTEXT_LENGTH; + uint256 internal constant SCOPED_PRIVATE_CALL_REQUEST_LENGTH = + PRIVATE_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; uint256 internal constant SIDE_EFFECT_LENGTH = 2; uint256 internal constant ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH; uint256 internal constant STATE_REFERENCE_LENGTH = @@ -143,7 +147,8 @@ library Constants { + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) - + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + + (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) @@ -177,7 +182,6 @@ library Constants { + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + GAS_LENGTH; uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = HEADER_LENGTH + TX_CONTEXT_LENGTH + GLOBAL_VARIABLES_LENGTH; - uint256 internal constant CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH; uint256 internal constant CALL_REQUEST_LENGTH = 1 + AZTEC_ADDRESS_LENGTH + CALLER_CONTEXT_LENGTH + 2; uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = ( @@ -186,7 +190,7 @@ library Constants { + (MAX_NEW_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) - + (CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + + (SCOPED_PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + (CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1 + VALIDATION_REQUESTS_LENGTH + PRIVATE_ACCUMULATED_DATA_LENGTH + COMBINED_CONSTANT_DATA_LENGTH diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 3be95e96e9a..b31cd34afb5 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -112,6 +112,9 @@ export const NOTE_HASH_LENGTH = 2; export const SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2; export const NULLIFIER_LENGTH = 3; export const SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1; +export const CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH + 1; +export const PRIVATE_CALL_REQUEST_LENGTH = 3 + CALLER_CONTEXT_LENGTH; +export const SCOPED_PRIVATE_CALL_REQUEST_LENGTH = PRIVATE_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; export const SIDE_EFFECT_LENGTH = 2; export const ROLLUP_VALIDATION_REQUESTS_LENGTH = MAX_BLOCK_NUMBER_LENGTH; export const STATE_REFERENCE_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; @@ -128,7 +131,7 @@ export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL + NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL + NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL + - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + + PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1 + L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL + @@ -179,7 +182,6 @@ export const COMBINED_ACCUMULATED_DATA_LENGTH = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH + GAS_LENGTH; export const COMBINED_CONSTANT_DATA_LENGTH = HEADER_LENGTH + TX_CONTEXT_LENGTH + GLOBAL_VARIABLES_LENGTH; -export const CALLER_CONTEXT_LENGTH = 2 * AZTEC_ADDRESS_LENGTH; export const CALL_REQUEST_LENGTH = 1 + AZTEC_ADDRESS_LENGTH + CALLER_CONTEXT_LENGTH + 2; export const PRIVATE_ACCUMULATED_DATA_LENGTH = SCOPED_NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_TX + @@ -188,7 +190,7 @@ export const PRIVATE_ACCUMULATED_DATA_LENGTH = NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX + LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX + LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX + - CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX + + SCOPED_PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX + CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX; export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1 + diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap index be2f85234d3..8b469583dee 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x1eaa8a277851ba8de6f7630ec75a2324e03a00a6ee99f24dd834faa422bdee4f>`; +exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x140e6a3702395dfaa918b0946c80bd0e0db9131a177b44f201651208479306ba>`; -exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x0cb30e5fa0e822ff93dc0bc3752c4b277e4629dfd8c31651aca53541873a5505>`; +exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x06187d416696eca3a85d0462b30db1e229271a00d17bc91e39b3dcb7e75bd3f9>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap index dbe26205c72..1193874ffdc 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x0e8b75e4ecf8bed8e361ff2702a1c200d1f4d4394c8f06dc9003eee571982c6c>`; +exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x24ea8c67b7902c1bdc827592303786ea3df7ada25a95e8682ed26b9b36fe2f9e>`; -exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x16aaaeeda5082bca41b5488bb064a3384f43c61b6f4f6f14d6ad3c3e1eb71fcc>`; +exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0a365dc5815493927b46c010f3388958a3a5373f6098fbaafa70aa61d6a92ca2>`; From 8aff9dc5513201cf5d4683f879157836d370f14e Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 17 May 2024 17:17:45 +0000 Subject: [PATCH 6/9] Fix type. --- .../src/type_conversion.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 80a3b5f6fec..44ea21dd924 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -512,15 +512,6 @@ export function mapCallerContextToNoir(callerContext: CallerContext): CallerCont }; } -function mapPrivateCallRequestToNoir(callRequest: PrivateCallRequest): PrivateCallRequestNoir { - return { - hash: mapFieldToNoir(callRequest.hash), - caller_context: mapCallerContextToNoir(callRequest.callerContext), - start_side_effect_counter: mapNumberToNoir(callRequest.startSideEffectCounter), - end_side_effect_counter: mapNumberToNoir(callRequest.endSideEffectCounter), - }; -} - function mapPrivateCallRequestFromNoir(callRequest: PrivateCallRequestNoir) { return new PrivateCallRequest( mapFieldFromNoir(callRequest.hash), @@ -530,6 +521,15 @@ function mapPrivateCallRequestFromNoir(callRequest: PrivateCallRequestNoir) { ); } +function mapPrivateCallRequestToNoir(callRequest: PrivateCallRequest): PrivateCallRequestNoir { + return { + hash: mapFieldToNoir(callRequest.hash), + caller_context: mapCallerContextToNoir(callRequest.callerContext), + start_side_effect_counter: mapNumberToNoir(callRequest.startSideEffectCounter), + end_side_effect_counter: mapNumberToNoir(callRequest.endSideEffectCounter), + }; +} + function mapScopedPrivateCallRequestFromNoir(callRequest: ScopedPrivateCallRequestNoir) { return new ScopedPrivateCallRequest( mapPrivateCallRequestFromNoir(callRequest.call_request), @@ -537,6 +537,13 @@ function mapScopedPrivateCallRequestFromNoir(callRequest: ScopedPrivateCallReque ); } +function mapScopedPrivateCallRequestToNoir(callRequest: ScopedPrivateCallRequest): ScopedPrivateCallRequestNoir { + return { + call_request: mapPrivateCallRequestToNoir(callRequest.callRequest), + contract_address: mapAztecAddressToNoir(callRequest.contractAddress), + }; +} + /** * Maps a noir call request to a call request. * @param callRequest - The noir call request. @@ -1141,7 +1148,7 @@ export function mapPrivateAccumulatedDataToNoir(data: PrivateAccumulatedData): P note_encrypted_logs_hashes: mapTuple(data.noteEncryptedLogsHashes, mapNoteLogHashToNoir), encrypted_logs_hashes: mapTuple(data.encryptedLogsHashes, mapLogHashToNoir), unencrypted_logs_hashes: mapTuple(data.unencryptedLogsHashes, mapLogHashToNoir), - private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), + private_call_stack: mapTuple(data.privateCallStack, mapScopedPrivateCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), }; } From e4eeb1a4157f8a4e61f2723ab5cf21ab565789cb Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 17 May 2024 19:36:10 +0000 Subject: [PATCH 7/9] Push private call requests to the stack in reverse order. --- .../src/private_call_data_validator.nr | 41 ++----------------- ...e_kernel_circuit_public_inputs_composer.nr | 16 ++++++-- .../src/private_kernel_init.nr | 1 + .../src/private_kernel_inner.nr | 1 + .../src/abis/private_circuit_public_inputs.nr | 34 ++++++++++++++- .../src/kernel_prover/kernel_prover.test.ts | 4 +- .../pxe/src/kernel_prover/kernel_prover.ts | 2 +- 7 files changed, 54 insertions(+), 45 deletions(-) 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 d1aeb2624f0..dece7c74d60 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 @@ -3,33 +3,14 @@ use dep::types::{ call_context::CallContext, call_request::CallRequest, caller_context::CallerContext, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, 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, is_empty_array}, transaction::tx_request::TxRequest, - utils::arrays::{array_length, validate_array} + traits::is_empty, transaction::tx_request::TxRequest }; -fn validate_arrays(data: PrivateCallData) -> ArrayLengths { - let public_inputs = data.call_stack_item.public_inputs; - - // Each of the following arrays is expected to be zero-padded. - ArrayLengths { - note_hash_read_requests: validate_array(public_inputs.note_hash_read_requests), - nullifier_read_requests: validate_array(public_inputs.nullifier_read_requests), - nullifier_key_validation_requests: validate_array(public_inputs.nullifier_key_validation_requests), - new_note_hashes: validate_array(public_inputs.new_note_hashes), - new_nullifiers: validate_array(public_inputs.new_nullifiers), - new_l2_to_l1_msgs: validate_array(public_inputs.new_l2_to_l1_msgs), - private_call_requests: validate_array(public_inputs.private_call_requests), - public_call_stack_hashes: validate_array(public_inputs.public_call_stack_hashes), - note_encrypted_logs_hashes: validate_array(public_inputs.note_encrypted_logs_hashes), - encrypted_logs_hashes: validate_array(public_inputs.encrypted_logs_hashes), - unencrypted_logs_hashes: validate_array(public_inputs.unencrypted_logs_hashes) - } -} - 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); @@ -115,28 +96,14 @@ fn validate_clean_split_ranges( } } -struct ArrayLengths { - note_hash_read_requests: u64, - nullifier_read_requests: u64, - nullifier_key_validation_requests: u64, - new_note_hashes: u64, - new_nullifiers: u64, - new_l2_to_l1_msgs: u64, - private_call_requests: u64, - public_call_stack_hashes: u64, - note_encrypted_logs_hashes: u64, - encrypted_logs_hashes: u64, - unencrypted_logs_hashes: u64, -} - struct PrivateCallDataValidator { data: PrivateCallData, - array_lengths: ArrayLengths, + array_lengths: PrivateCircuitPublicInputsArrayLengths, } impl PrivateCallDataValidator { pub fn new(data: PrivateCallData) -> Self { - let array_lengths = validate_arrays(data); + let array_lengths = PrivateCircuitPublicInputsArrayLengths::new(data.call_stack_item.public_inputs); PrivateCallDataValidator { data, array_lengths } } 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 3f372a9cf22..e0dfcb2e78f 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 @@ -3,7 +3,8 @@ use dep::types::{ 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, private_circuit_public_inputs::PrivateCircuitPublicInputs + log_hash::NoteLogHash, + private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths} }, address::AztecAddress, constants::{ @@ -16,6 +17,7 @@ use dep::types::{ 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], @@ -79,6 +81,7 @@ 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], @@ -86,9 +89,10 @@ impl PrivateKernelCircuitPublicInputsComposer { ) -> Self { 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, - private_call_public_inputs, note_hash_nullifier_counters, public_call_requests, public_teardown_call_request @@ -211,9 +215,13 @@ impl PrivateKernelCircuitPublicInputsComposer { 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 mut proceed = true; for i in 0..call_requests.len() { - let call_request = call_requests[i]; - if !is_empty(call_request) { + proceed &= i != num_requests; + if proceed { + // Push the call requests to the stack in reverse order. + let call_request = call_requests[num_requests - i - 1]; self.public_inputs.end.private_call_stack.push(call_request.scope(source.contract_address)); } } 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 5a21bb7b350..61ed5046436 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 @@ -36,6 +36,7 @@ impl PrivateKernelInitCircuitPrivateInputs { 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, + privateCallDataValidator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, 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 0e48ac1f822..e9c8e2b6071 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 @@ -41,6 +41,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).compose( self.private_call.call_stack_item.public_inputs, + privateCallDataValidator.array_lengths, self.private_call.call_stack_item.contract_address, self.hints.note_hash_nullifier_counters, self.private_call.public_call_stack, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr index e5a0e55037c..cca11e36c4a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr @@ -15,9 +15,41 @@ use crate::{ }, header::Header, hash::pedersen_hash, messaging::l2_to_l1_message::L2ToL1Message, traits::{Deserialize, Hash, Serialize, Empty}, utils::reader::Reader, - transaction::tx_context::TxContext + transaction::tx_context::TxContext, utils::arrays::validate_array }; +struct PrivateCircuitPublicInputsArrayLengths { + note_hash_read_requests: u64, + nullifier_read_requests: u64, + nullifier_key_validation_requests: u64, + new_note_hashes: u64, + new_nullifiers: u64, + new_l2_to_l1_msgs: u64, + private_call_requests: u64, + public_call_stack_hashes: u64, + note_encrypted_logs_hashes: u64, + encrypted_logs_hashes: u64, + unencrypted_logs_hashes: u64, +} + +impl PrivateCircuitPublicInputsArrayLengths { + pub fn new(public_inputs: PrivateCircuitPublicInputs) -> Self { + PrivateCircuitPublicInputsArrayLengths { + note_hash_read_requests: validate_array(public_inputs.note_hash_read_requests), + nullifier_read_requests: validate_array(public_inputs.nullifier_read_requests), + nullifier_key_validation_requests: validate_array(public_inputs.nullifier_key_validation_requests), + new_note_hashes: validate_array(public_inputs.new_note_hashes), + new_nullifiers: validate_array(public_inputs.new_nullifiers), + new_l2_to_l1_msgs: validate_array(public_inputs.new_l2_to_l1_msgs), + private_call_requests: validate_array(public_inputs.private_call_requests), + public_call_stack_hashes: validate_array(public_inputs.public_call_stack_hashes), + note_encrypted_logs_hashes: validate_array(public_inputs.note_encrypted_logs_hashes), + encrypted_logs_hashes: validate_array(public_inputs.encrypted_logs_hashes), + unencrypted_logs_hashes: validate_array(public_inputs.unencrypted_logs_hashes) + } + } +} + struct PrivateCircuitPublicInputs { call_context: CallContext, diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index efbfafffe61..e96547fbbd7 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -186,7 +186,7 @@ describe('Kernel Prover', () => { }; const executionResult = createExecutionResult('a'); await prove(executionResult); - expectExecution(['a', 'd', 'b', 'c']); + expectExecution(['a', 'b', 'c', 'd']); } { @@ -197,7 +197,7 @@ describe('Kernel Prover', () => { }; const executionResult = createExecutionResult('k'); await prove(executionResult); - expectExecution(['k', 'o', 'r', 'p', 'n', 'm', 'q']); + expectExecution(['k', 'm', 'q', 'o', 'n', 'p', 'r']); } }); }); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 07044521e43..6a88d0a2791 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -73,7 +73,7 @@ export class KernelProver { while (executionStack.length) { const currentExecution = executionStack.pop()!; - executionStack.push(...currentExecution.nestedExecutions); + executionStack.push(...[...currentExecution.nestedExecutions].reverse()); const publicCallRequests = currentExecution.enqueuedPublicFunctionCalls.map(result => result.toCallRequest()); const publicTeardownCallRequest = currentExecution.publicTeardownFunctionCall.isEmpty() From 7470926a202b36fbef913ae815819b685c060f00 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Fri, 17 May 2024 21:29:13 +0000 Subject: [PATCH 8/9] Fix test. --- yarn-project/end-to-end/src/e2e_outbox.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_outbox.test.ts b/yarn-project/end-to-end/src/e2e_outbox.test.ts index 4a8d8ede821..1438588f500 100644 --- a/yarn-project/end-to-end/src/e2e_outbox.test.ts +++ b/yarn-project/end-to-end/src/e2e_outbox.test.ts @@ -58,7 +58,7 @@ describe('E2E Outbox Tests', () => { const l2ToL1Messages = block?.body.txEffects.flatMap(txEffect => txEffect.l2ToL1Msgs); expect(l2ToL1Messages?.map(l2ToL1Message => l2ToL1Message.toString())).toStrictEqual( - [makeL2ToL1Message(recipient2, content2), makeL2ToL1Message(recipient1, content1)].map(expectedL2ToL1Message => + [makeL2ToL1Message(recipient1, content1), makeL2ToL1Message(recipient2, content2)].map(expectedL2ToL1Message => expectedL2ToL1Message.toString(), ), ); From 84abe7c8c76f9cb5a72de8ec9c595afb0b25d862 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Mon, 20 May 2024 12:25:28 +0000 Subject: [PATCH 9/9] Update comment. --- yarn-project/circuits.js/src/structs/caller_context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/circuits.js/src/structs/caller_context.ts b/yarn-project/circuits.js/src/structs/caller_context.ts index bce17c1d313..7edceebc5a2 100644 --- a/yarn-project/circuits.js/src/structs/caller_context.ts +++ b/yarn-project/circuits.js/src/structs/caller_context.ts @@ -6,7 +6,7 @@ import { type FieldsOf } from '@aztec/foundation/types'; export class CallerContext { constructor( /** - * Address of the caller contract. + * Message sender of the caller contract. */ public msgSender: AztecAddress, /**