diff --git a/docs/netlify.toml b/docs/netlify.toml index e658fa4fdb4c..24996e99586c 100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@ -774,8 +774,13 @@ from = "/errors/3" to = "/aztec-nr-api/nightly/noir_aztec/messages/msg_type/index.html" -# Example (uncomment and modify when adding error codes): -# [[redirects]] -# from = "/errors/4" -# to = "/developers/docs/aztec-nr/framework-description/functions/how_to_define_functions" +[[redirects]] + # Aztec-nr: note packed length exceeds MAX_NOTE_PACKED_LEN + from = "/errors/4" + to = "/aztec-nr-api/nightly/noir_aztec/macros/notes/fn.note.html" + +[[redirects]] + # Aztec-nr: event serialized length exceeds MAX_EVENT_SERIALIZED_LEN + from = "/errors/5" + to = "/aztec-nr-api/nightly/noir_aztec/macros/events/fn.event.html" diff --git a/noir-projects/aztec-nr/aztec/src/macros/events.nr b/noir-projects/aztec-nr/aztec/src/macros/events.nr index b7a5ccd96ea6..62c71634d32c 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/events.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/events.nr @@ -10,6 +10,9 @@ pub comptime mut global EVENT_SELECTORS: CHashMap = CHashMap::new comptime fn generate_event_interface_and_get_selector(s: TypeDefinition) -> (Quoted, Field) { let name = s.name(); + let typ = s.as_type(); + let event_type_name: str<_> = f"{name}".as_quoted_str!(); + let max_event_serialized_len = crate::messages::logs::event::MAX_EVENT_SERIALIZED_LEN; let event_selector = compute_struct_selector(s, quote { crate::event::EventSelector::from_signature }); @@ -23,6 +26,18 @@ comptime fn generate_event_interface_and_get_selector(s: TypeDefinition) -> (Quo quote { impl aztec::event::event_interface::EventInterface for $name { fn get_event_type_id() -> aztec::event::EventSelector { + // This static assertion ensures the event's serialized length doesn't exceed the maximum + // allowed size. While this check would ideally live in the Serialize trait implementation, we + // place it here since this function is always generated by our macros and the Serialize trait + // implementation is not. + // + // Note: We set the event type name and max serialized length as local variables because + // injecting them directly into the error message doesn't work. + let event_type_name = $event_type_name; + let max_event_serialized_len: u32 = $max_event_serialized_len; + let event_serialized_len = <$typ as aztec::protocol::traits::Serialize>::N; + std::static_assert(event_serialized_len <= $max_event_serialized_len, f"{event_type_name} has a serialized length of {event_serialized_len} fields, which exceeds the maximum allowed length of {max_event_serialized_len} fields. See https://docs.aztec.network/errors/5"); + $from_field($event_selector) } } @@ -42,6 +57,14 @@ comptime fn register_event_selector(event_selector: Field, event_name: Quoted) { EVENT_SELECTORS.insert(event_selector, event_name); } +/// Generates the core event functionality for a struct, including the +/// [`EventInterface`](crate::event::event_interface::EventInterface) implementation (which provides the event type +/// id) and a [`Serialize`](crate::protocol::traits::Serialize) implementation if one is not already provided. +/// +/// ## Requirements +/// +/// The event struct must not exceed +/// [`MAX_EVENT_SERIALIZED_LEN`](crate::messages::logs::event::MAX_EVENT_SERIALIZED_LEN) when serialized. pub comptime fn event(s: TypeDefinition) -> Quoted { let (event_interface_impl, event_selector) = generate_event_interface_and_get_selector(s); register_event_selector(event_selector, s.name()); diff --git a/noir-projects/aztec-nr/aztec/src/macros/notes.nr b/noir-projects/aztec-nr/aztec/src/macros/notes.nr index 9943804900e7..b2895f9fc3c9 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/notes.nr @@ -48,8 +48,8 @@ comptime fn generate_note_type_impl(s: TypeDefinition, note_type_id: Field) -> Q // directly into the error message doesn't work. let note_type_name = $note_type_name; let max_note_packed_len: u32 = $max_note_packed_len; // Casting to u32 to avoid the value to be printed in hex. - let note_packed_len = <$typ as Packable>::N; - std::static_assert(note_packed_len <= $max_note_packed_len, f"{note_type_name} has a packed length of {note_packed_len} fields, which exceeds the maximum allowed length of {max_note_packed_len} fields"); + let note_packed_len = <$typ as aztec::protocol::traits::Packable>::N; + std::static_assert(note_packed_len <= $max_note_packed_len, f"{note_type_name} has a packed length of {note_packed_len} fields, which exceeds the maximum allowed length of {max_note_packed_len} fields. See https://docs.aztec.network/errors/4"); $note_type_id } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml new file mode 100644 index 000000000000..fd5c446ab345 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "invalid_event" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error new file mode 100644 index 000000000000..4f092dbf4803 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error @@ -0,0 +1 @@ +InvalidEvent has a serialized length of 11 fields, which exceeds the maximum allowed length of 10 fields. See https://docs.aztec.network/errors/5 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/invalid_event.nr b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/invalid_event.nr new file mode 100644 index 000000000000..a38ba6855727 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/invalid_event.nr @@ -0,0 +1,18 @@ +use aztec::{ + macros::events::event, + messages::logs::event::MAX_EVENT_SERIALIZED_LEN, + protocol::{traits::Serialize, utils::writer::Writer}, +}; + +#[event] +pub struct InvalidEvent {} + +impl Serialize for InvalidEvent { + let N: u32 = MAX_EVENT_SERIALIZED_LEN + 1; + + fn serialize(self) -> [Field; Self::N] { + std::mem::zeroed() + } + + fn stream_serialize(self, _writer: &mut Writer) {} +} diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/main.nr b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/main.nr new file mode 100644 index 000000000000..03fdfb49b062 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/main.nr @@ -0,0 +1,15 @@ +use aztec::macros::aztec; + +mod invalid_event; + +#[aztec] +pub contract InvalidEventContract { + use crate::invalid_event::InvalidEvent; + use aztec::{event::event_interface::EventInterface, macros::functions::external}; + + // We have here this function in order for the static_assert in `get_event_type_id` to get triggered. + #[external("private")] + fn trigger_event_check() { + let _ = InvalidEvent::get_event_type_id(); + } +} diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error index ee90fdf8adb9..02c046ffd7ab 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error +++ b/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error @@ -1 +1 @@ -InvalidNote has a packed length of 9 fields, which exceeds the maximum allowed length of 8 fields +InvalidNote has a packed length of 9 fields, which exceeds the maximum allowed length of 8 fields. See https://docs.aztec.network/errors/4