diff --git a/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr b/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr index 9e4efde8cd5a..35be7114e025 100644 --- a/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr @@ -1,5 +1,6 @@ use crate::oracle::ephemeral; use crate::protocol::traits::{Deserialize, Serialize}; +use crate::protocol::utils::{reader::Reader, writer::Writer}; /// A dynamically sized array that exists only during a single contract call frame. /// @@ -101,6 +102,34 @@ impl EphemeralArray { } } +/// Serializes an `EphemeralArray` as its slot identifier, allowing oracle function signatures to use +/// `EphemeralArray` instead of opaque `Field` slots. +impl Serialize for EphemeralArray { + let N: u32 = 1; + + fn serialize(self) -> [Field; Self::N] { + [self.slot] + } + + fn stream_serialize(self, writer: &mut Writer) { + writer.write(self.slot); + } +} + +/// Deserializes a single Field into an `EphemeralArray` handle, treating the field value as the slot identifier. +/// This is the inverse of [`Serialize`]. +impl Deserialize for EphemeralArray { + let N: u32 = 1; + + fn deserialize(fields: [Field; Self::N]) -> Self { + Self { slot: fields[0] } + } + + fn stream_deserialize(reader: &mut Reader) -> Self { + Self { slot: reader.read() } + } +} + mod test { use crate::test::helpers::test_environment::TestEnvironment; use crate::test::mocks::MockStruct; diff --git a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr index a793fe5df64f..df716e43ccbe 100644 --- a/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr @@ -137,8 +137,8 @@ pub unconstrained fn enqueue_event_for_validation( /// API (PXE::getPrivateEvents). pub unconstrained fn validate_and_store_enqueued_notes_and_events(scope: AztecAddress) { message_processing::validate_and_store_enqueued_notes_and_events( - NOTE_VALIDATION_REQUESTS_ARRAY_BASE_SLOT, - EVENT_VALIDATION_REQUESTS_ARRAY_BASE_SLOT, + EphemeralArray::at(NOTE_VALIDATION_REQUESTS_ARRAY_BASE_SLOT), + EphemeralArray::at(EVENT_VALIDATION_REQUESTS_ARRAY_BASE_SLOT), MAX_NOTE_PACKED_LEN as Field, MAX_EVENT_SERIALIZED_LEN as Field, scope, diff --git a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr index 7a2f2f5a666d..876f55dd9e96 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr @@ -1,7 +1,8 @@ use crate::ephemeral::EphemeralArray; use crate::messages::processing::{ + event_validation_request::EventValidationRequest, log_retrieval_request::LogRetrievalRequest, log_retrieval_response::LogRetrievalResponse, MessageContext, - pending_tagged_log::PendingTaggedLog, + NoteValidationRequest, pending_tagged_log::PendingTaggedLog, }; use crate::protocol::address::AztecAddress; use crate::protocol::blob_data::TxEffect; @@ -9,24 +10,23 @@ use crate::protocol::blob_data::TxEffect; /// Finds new private logs that may have been sent to all registered accounts in PXE in the current contract and /// returns them in an ephemeral array with an oracle-allocated base slot. pub(crate) unconstrained fn get_pending_tagged_logs(scope: AztecAddress) -> EphemeralArray { - let result_slot = get_pending_tagged_logs_oracle(scope); - EphemeralArray::at(result_slot) + get_pending_tagged_logs_oracle(scope) } #[oracle(aztec_utl_getPendingTaggedLogs)] -unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> Field {} +unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> EphemeralArray {} /// Validates note/event requests stored in ephemeral arrays. pub(crate) unconstrained fn validate_and_store_enqueued_notes_and_events( - note_validation_requests_array_slot: Field, - event_validation_requests_array_slot: Field, + note_validation_requests: EphemeralArray, + event_validation_requests: EphemeralArray, max_note_packed_len: Field, max_event_serialized_len: Field, scope: AztecAddress, ) { validate_and_store_enqueued_notes_and_events_oracle( - note_validation_requests_array_slot, - event_validation_requests_array_slot, + note_validation_requests, + event_validation_requests, max_note_packed_len, max_event_serialized_len, scope, @@ -35,8 +35,8 @@ pub(crate) unconstrained fn validate_and_store_enqueued_notes_and_events( #[oracle(aztec_utl_validateAndStoreEnqueuedNotesAndEvents)] unconstrained fn validate_and_store_enqueued_notes_and_events_oracle( - note_validation_requests_array_slot: Field, - event_validation_requests_array_slot: Field, + note_validation_requests: EphemeralArray, + event_validation_requests: EphemeralArray, max_note_packed_len: Field, max_event_serialized_len: Field, scope: AztecAddress, @@ -46,23 +46,25 @@ unconstrained fn validate_and_store_enqueued_notes_and_events_oracle( pub(crate) unconstrained fn get_logs_by_tag( requests: EphemeralArray, ) -> EphemeralArray> { - let response_slot = get_logs_by_tag_oracle(requests.slot); - EphemeralArray::at(response_slot) + get_logs_by_tag_oracle(requests) } #[oracle(aztec_utl_getLogsByTag)] -unconstrained fn get_logs_by_tag_oracle(request_array_slot: Field) -> Field {} +unconstrained fn get_logs_by_tag_oracle( + requests: EphemeralArray, +) -> EphemeralArray> {} /// Resolves message contexts for tx hashes in an ephemeral request array and returns a response ephemeral array. pub(crate) unconstrained fn get_message_contexts_by_tx_hash( requests: EphemeralArray, ) -> EphemeralArray> { - let response_slot = get_message_contexts_by_tx_hash_oracle(requests.slot); - EphemeralArray::at(response_slot) + get_message_contexts_by_tx_hash_oracle(requests) } #[oracle(aztec_utl_getMessageContextsByTxHash)] -unconstrained fn get_message_contexts_by_tx_hash_oracle(request_array_slot: Field) -> Field {} +unconstrained fn get_message_contexts_by_tx_hash_oracle( + requests: EphemeralArray, +) -> EphemeralArray> {} /// Fetches all effects of a settled transaction by its hash. pub unconstrained fn get_tx_effect(tx_hash: Field) -> Option { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr index 4785328f9d71..cbcd9390d71a 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr @@ -7,9 +7,9 @@ global GET_SHARED_SECRETS_REQUEST_SLOT: Field = #[oracle(aztec_utl_getSharedSecrets)] unconstrained fn get_shared_secrets_oracle( address: AztecAddress, - eph_pks_slot: Field, + eph_pks: EphemeralArray, contract_address: AztecAddress, -) -> Field {} +) -> EphemeralArray {} /// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key. pub unconstrained fn get_shared_secret( @@ -48,8 +48,7 @@ pub unconstrained fn get_shared_secrets( EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear(); eph_pks.for_each(|pk| request_array.push(pk)); - let response_slot = get_shared_secrets_oracle(address, request_array.slot, contract_address); - let response_array: EphemeralArray = EphemeralArray::at(response_slot); + let response_array = get_shared_secrets_oracle(address, request_array, contract_address); assert( response_array.len() == eph_pks.len(), "get_shared_secrets: response length does not match request length",