Skip to content
Closed
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
25 changes: 21 additions & 4 deletions noir-projects/aztec-nr/aztec/src/event/event_interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub fn emit_event_in_private<Event>(
delivery_mode: u8,
)
where
Event: EventInterface + Serialize,
Event: EventInterface,
{
// This function relies on `delivery_mode` being a constant in order to reduce circuit constraints when unconstrained
// usage is requested. If `delivery_mode` were a runtime value then performance would suffer.
Expand All @@ -127,7 +127,20 @@ where
// - nullifiers require no nonce, and events, being non-spendable, don't need the guarantee that a "spending"
// nullifier can be computed.
// TODO(#11571): with decryption happening in Noir we can now use the Packable trait instead.
let serialized_event_with_randomness = [randomness].concat(event.serialize());

// TODO: NUKE THIS NOIR BUG WORKAROUND
// ####### WORKAROUND START #######
let serialized_event: [Field; <Event as Serialize>::N] = event.serialize();
let mut serialized_event_with_randomness: [Field; <Event as Serialize>::N + 1] =
std::mem::zeroed();
serialized_event_with_randomness[0] = randomness;
for i in 0..<Event as Serialize>::N {
serialized_event_with_randomness[i] = serialized_event[i];
}
// ####### WORKAROUND END #######

// let serialized_event_with_randomness = [randomness].concat(serialized_event);

let event_commitment = poseidon2_hash_with_separator(
serialized_event_with_randomness,
GENERATOR_INDEX__EVENT_COMMITMENT,
Expand All @@ -147,7 +160,7 @@ where

pub fn emit_event_in_public<Event>(event: Event, context: &mut PublicContext)
where
Event: EventInterface + Serialize,
Event: EventInterface,
{
let mut log_content = [0; <Event as Serialize>::N + 1];

Expand All @@ -162,6 +175,10 @@ where
context.emit_public_log(log_content);
}

pub trait EventInterface {
pub trait EventInterface: Serialize {
fn get_event_type_id() -> EventSelector;

fn emit_private(self, context: &mut PrivateContext, recipient: AztecAddress, delivery_mode: u8);

fn emit_public(self, context: &mut PublicContext);
}
14 changes: 11 additions & 3 deletions noir-projects/aztec-nr/aztec/src/macros/events.nr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ comptime fn generate_event_interface_and_get_selector(s: TypeDefinition) -> (Quo
fn get_event_type_id() -> aztec::event::event_selector::EventSelector {
$from_field($event_selector)
}

fn emit_private(self, context: &mut aztec::context::PrivateContext, recipient: aztec::protocol_types::address::AztecAddress, delivery_mode: u8) {
aztec::event::event_interface::emit_event_in_private(self, context, recipient, delivery_mode);
}

fn emit_public(self, context: &mut aztec::context::PublicContext) {
aztec::event::event_interface::emit_event_in_public(self, context);
}
}
},
event_selector,
Expand All @@ -46,15 +54,15 @@ comptime fn register_event_selector(event_selector: Field, event_name: Quoted) {
}

pub comptime fn event(s: TypeDefinition) -> Quoted {

@benesjan benesjan Sep 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Did the change in this function as now it feels more logical given that we have the super trait and EventInterface is kinda like dependent on Serilize.

let serialize_impl = derive_serialize_if_not_implemented(s);

let (event_interface_impl, event_selector) = generate_event_interface_and_get_selector(s);
register_event_selector(event_selector, s.name());

let serialize_impl = derive_serialize_if_not_implemented(s);

s.add_attribute("abi(events)");

quote {
$event_interface_impl
$serialize_impl
$event_interface_impl
}
}
16 changes: 14 additions & 2 deletions noir-projects/aztec-nr/aztec/src/messages/logs/event.nr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn to_encrypted_private_event_message<Event>(
recipient: AztecAddress,
) -> ([Field; PRIVATE_LOG_CIPHERTEXT_LEN], Field)
where
Event: EventInterface + Serialize,
Event: EventInterface,
{
// In private events, we automatically inject randomness to prevent event commitment preimage attacks and event
// commitment collisions (the commitments are included in the nullifier tree and duplicate nullifiers are by
Expand All @@ -32,7 +32,19 @@ where
let randomness = unsafe { random() };

// TODO(#11571): with decryption happening in Noir we can now use the Packable trait instead.
let serialized_event_with_randomness = [randomness].concat(event.serialize());

// TODO: NUKE THIS NOIR BUG WORKAROUND
// ####### WORKAROUND START #######
let serialized_event: [Field; <Event as Serialize>::N] = event.serialize();
let mut serialized_event_with_randomness: [Field; <Event as Serialize>::N + 1] =
std::mem::zeroed();
serialized_event_with_randomness[0] = randomness;
for i in 0..<Event as Serialize>::N {
serialized_event_with_randomness[i] = serialized_event[i];
}
// ####### WORKAROUND END #######

// let serialized_event_with_randomness = [randomness].concat(event.serialize());

// Private events are encoded by placing the event type id (which is expected to fit in 32 bits) in the metadata.
let plaintext = encode_message(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub contract Token {

use dep::aztec::{
context::{PrivateCallInterface, PrivateContext, PublicContext},
event::event_interface::{emit_event_in_private, MessageDelivery},
event::event_interface::{EventInterface, MessageDelivery},
macros::{
events::event,
functions::{authorize_once, initializer, internal, private, public, utility, view},
Expand Down Expand Up @@ -301,8 +301,7 @@ pub contract Token {
// another person where the payment is considered to be successful when the other party successfully decrypts a
// note).
// docs:start:encrypted_unconstrained
emit_event_in_private(
Transfer { from, to, amount },
Transfer { from, to, amount }.emit_private(
&mut context,
to,
MessageDelivery.UNCONSTRAINED_ONCHAIN,
Expand Down
Loading