Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr
Original file line number Diff line number Diff line change
@@ -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.
///
Expand Down Expand Up @@ -101,6 +102,34 @@ impl<T> EphemeralArray<T> {
}
}

/// Serializes an `EphemeralArray` as its slot identifier, allowing oracle function signatures to use
/// `EphemeralArray<T>` instead of opaque `Field` slots.
impl<T> Serialize for EphemeralArray<T> {
let N: u32 = 1;

fn serialize(self) -> [Field; Self::N] {
[self.slot]
}

fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {
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<T> Deserialize for EphemeralArray<T> {
let N: u32 = 1;

fn deserialize(fields: [Field; Self::N]) -> Self {
Self { slot: fields[0] }
}

fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {
Self { slot: reader.read() }
}
}

mod test {
use crate::test::helpers::test_environment::TestEnvironment;
use crate::test::mocks::MockStruct;
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/messages/processing/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
34 changes: 18 additions & 16 deletions noir-projects/aztec-nr/aztec/src/oracle/message_processing.nr
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
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;

/// 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<PendingTaggedLog> {
let result_slot = get_pending_tagged_logs_oracle(scope);
EphemeralArray::at(result_slot)
get_pending_tagged_logs_oracle(scope)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lovely!

}

#[oracle(aztec_utl_getPendingTaggedLogs)]
unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> Field {}
unconstrained fn get_pending_tagged_logs_oracle(scope: AztecAddress) -> EphemeralArray<PendingTaggedLog> {}

/// 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<NoteValidationRequest>,
event_validation_requests: EphemeralArray<EventValidationRequest>,
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,
Expand All @@ -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<NoteValidationRequest>,
event_validation_requests: EphemeralArray<EventValidationRequest>,
max_note_packed_len: Field,
max_event_serialized_len: Field,
scope: AztecAddress,
Expand All @@ -46,23 +46,25 @@ unconstrained fn validate_and_store_enqueued_notes_and_events_oracle(
pub(crate) unconstrained fn get_logs_by_tag(
requests: EphemeralArray<LogRetrievalRequest>,
) -> EphemeralArray<Option<LogRetrievalResponse>> {
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<LogRetrievalRequest>,
) -> EphemeralArray<Option<LogRetrievalResponse>> {}

/// 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<Field>,
) -> EphemeralArray<Option<MessageContext>> {
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<Field>,
) -> EphemeralArray<Option<MessageContext>> {}

/// Fetches all effects of a settled transaction by its hash.
pub unconstrained fn get_tx_effect(tx_hash: Field) -> Option<TxEffect> {
Expand Down
7 changes: 3 additions & 4 deletions noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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<Point>,
contract_address: AztecAddress,
) -> Field {}
) -> EphemeralArray<Field> {}

/// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key.
pub unconstrained fn get_shared_secret(
Expand Down Expand Up @@ -48,8 +48,7 @@ pub unconstrained fn get_shared_secrets<let N: u32>(
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<Field> = 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",
Expand Down
Loading