diff --git a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr index f86292dff7ac..a7cfe65f6d7b 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr @@ -1,7 +1,12 @@ use crate::macros::{ - calls_generation::internal_functions::generate_call_internal_struct, + calls_generation::{ + external_functions::{ + generate_external_function_calls, generate_external_function_self_calls_structs, + }, + internal_functions::generate_call_internal_struct, + }, dispatch::generate_public_dispatch, - functions::{self_call_registry, stub_registry, utils::check_each_fn_macroified}, + functions::utils::check_each_fn_macroified, internals_functions_generation::{create_fn_abi_exports, process_functions}, notes::NOTES, storage::STORAGE_LAYOUT_NAME, @@ -19,8 +24,9 @@ pub comptime fn aztec(m: Module) -> Quoted { // with `static_assert(false, ...)` to prevent them from being called directly from within the contract. let functions = process_functions(m); + // We generate structs and their implementations necessary for convenient functions calls. let interface = generate_contract_interface(m); - let self_call_structs = generate_self_call_structs(m); + let self_call_structs = generate_external_function_self_calls_structs(m); let call_internal_struct = generate_call_internal_struct(m); // We generate ABI exports for all the external functions in the contract. @@ -67,13 +73,9 @@ pub comptime fn aztec(m: Module) -> Quoted { } comptime fn generate_contract_interface(m: Module) -> Quoted { + let calls = generate_external_function_calls(m); + let module_name = m.name(); - let contract_stubs = stub_registry::get(m); - let fn_stubs_quote = if contract_stubs.is_some() { - contract_stubs.unwrap().join(quote {}) - } else { - quote {} - }; let has_storage_layout = module_has_storage(m) & STORAGE_LAYOUT_NAME.get(m).is_some(); let storage_layout_getter = if has_storage_layout { @@ -102,7 +104,7 @@ comptime fn generate_contract_interface(m: Module) -> Quoted { } impl $module_name { - $fn_stubs_quote + $calls pub fn at( addr: aztec::protocol_types::address::AztecAddress @@ -313,71 +315,3 @@ comptime fn generate_process_message() -> Quoted { } } } - -/// Generates helper structs for convenient self-invocation of contract functions: -/// -/// - `CallSelf`: Call your own private or public functions, e.g.: -/// `self.call_self.some_private_function(args)` -/// - `CallSelfStatic`: Call your own view (static) functions, e.g.: -/// `self.call_self_static.some_view_function(args)` -/// - `EnqueueSelf`: Enqueue your own (non-view) public functions for deferred execution, e.g.: -/// `self.enqueue_self.some_public_function(args)` -/// - `EnqueueSelfStatic`: Enqueue your own view public functions, e.g.: -/// `self.enqueue_self_static.some_view_function(args)` -comptime fn generate_self_call_structs(m: Module) -> Quoted { - let stubs = self_call_registry::get_all_self_call_stubs(m); - - // We need to destructure the stubs here because accessing struct fields in a quote block is not supported. - let call_self_private_methods = stubs.call_self_private_methods; - let call_self_public_methods = stubs.call_self_public_methods; - let enqueue_self_methods = stubs.enqueue_self_methods; - let call_self_private_static_methods = stubs.call_self_private_static_methods; - let call_self_public_static_methods = stubs.call_self_public_static_methods; - let enqueue_self_static_methods = stubs.enqueue_self_static_methods; - - quote { - pub struct CallSelf { - pub address: dep::aztec::protocol_types::address::AztecAddress, - pub context: Context, - } - - impl CallSelf<&mut dep::aztec::context::private_context::PrivateContext> { - $call_self_private_methods - } - - impl CallSelf { - $call_self_public_methods - } - - pub struct CallSelfStatic { - pub address: dep::aztec::protocol_types::address::AztecAddress, - pub context: Context, - } - - impl CallSelfStatic<&mut dep::aztec::context::private_context::PrivateContext> { - $call_self_private_static_methods - } - - impl CallSelfStatic { - $call_self_public_static_methods - } - - pub struct EnqueueSelf { - pub address: dep::aztec::protocol_types::address::AztecAddress, - pub context: Context, - } - - impl EnqueueSelf<&mut dep::aztec::context::private_context::PrivateContext> { - $enqueue_self_methods - } - - pub struct EnqueueSelfStatic { - pub address: dep::aztec::protocol_types::address::AztecAddress, - pub context: Context, - } - - impl EnqueueSelfStatic<&mut dep::aztec::context::private_context::PrivateContext> { - $enqueue_self_static_methods - } - } -} diff --git a/noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions.nr b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions.nr new file mode 100644 index 000000000000..dcefe4d2f65a --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions.nr @@ -0,0 +1,170 @@ +use crate::macros::{ + calls_generation::external_functions_stubs::{ + create_private_self_call_stub, create_private_static_stub, create_private_stub, + create_public_self_call_static_stub, create_public_self_call_stub, + create_public_self_enqueue_static_stub, create_public_self_enqueue_stub, + create_public_static_stub, create_public_stub, create_utility_stub, + }, + internals_functions_generation::external_functions_registry, + utils::is_fn_view, +}; + +/// Generates external function calls that are to be injected into the contract interface. +/// +/// The contract interface enables you to form calls such as `Token::at(address).some_function(args)`. +/// This function generates the implementation of `some_function` within the interface. +pub(crate) comptime fn generate_external_function_calls(m: Module) -> Quoted { + let private_functions = external_functions_registry::get_private_functions(m); + let public_functions = external_functions_registry::get_public_functions(m); + let utility_functions = external_functions_registry::get_utility_functions(m); + + let private_contract_methods = private_functions + .map(|function| { + if is_fn_view(function) { + create_private_static_stub(function) + } else { + create_private_stub(function) + } + }) + .join(quote {}); + + let public_contract_methods = public_functions + .map(|function| { + if is_fn_view(function) { + create_public_static_stub(function) + } else { + create_public_stub(function) + } + }) + .join(quote {}); + + let utility_contract_methods = + utility_functions.map(|function| create_utility_stub(function)).join(quote {}); + + quote { + $private_contract_methods + $public_contract_methods + $utility_contract_methods + } +} + +/// Generates helper structs for convenient self-invocation of contract functions: +/// +/// - `CallSelf`: Call your own private or public functions, e.g.: +/// `self.call_self.some_private_function(args)` +/// - `CallSelfStatic`: Call your own view (static) functions, e.g.: +/// `self.call_self_static.some_view_function(args)` +/// - `EnqueueSelf`: Enqueue your own (non-view) public functions for deferred execution, e.g.: +/// `self.enqueue_self.some_public_function(args)` +/// - `EnqueueSelfStatic`: Enqueue your own view public functions, e.g.: +/// `self.enqueue_self_static.some_view_function(args)` +pub(crate) comptime fn generate_external_function_self_calls_structs(m: Module) -> Quoted { + let private_functions = external_functions_registry::get_private_functions(m); + let public_functions = external_functions_registry::get_public_functions(m); + + let call_self_private_methods = private_functions + .map(|function| { + if is_fn_view(function) { + quote {} + } else { + create_private_self_call_stub(function, false) + } + }) + .join(quote {}); + + let call_self_private_static_methods = private_functions + .map(|function| { + if is_fn_view(function) { + create_private_self_call_stub(function, true) + } else { + quote {} + } + }) + .join(quote {}); + + let call_self_public_methods = public_functions + .map(|function| { + if is_fn_view(function) { + quote {} + } else { + create_public_self_call_stub(function) + } + }) + .join(quote {}); + + let call_self_public_static_methods = public_functions + .map(|function| { + if is_fn_view(function) { + create_public_self_call_static_stub(function) + } else { + quote {} + } + }) + .join(quote {}); + + let enqueue_self_methods = public_functions + .map(|function| { + if is_fn_view(function) { + quote {} + } else { + create_public_self_enqueue_stub(function) + } + }) + .join(quote {}); + + let enqueue_self_static_methods = public_functions + .map(|function| { + if is_fn_view(function) { + create_public_self_enqueue_static_stub(function) + } else { + quote {} + } + }) + .join(quote {}); + + quote { + pub struct CallSelf { + pub address: dep::aztec::protocol_types::address::AztecAddress, + pub context: Context, + } + + impl CallSelf<&mut dep::aztec::context::private_context::PrivateContext> { + $call_self_private_methods + } + + impl CallSelf { + $call_self_public_methods + } + + pub struct CallSelfStatic { + pub address: dep::aztec::protocol_types::address::AztecAddress, + pub context: Context, + } + + impl CallSelfStatic<&mut dep::aztec::context::private_context::PrivateContext> { + $call_self_private_static_methods + } + + impl CallSelfStatic { + $call_self_public_static_methods + } + + pub struct EnqueueSelf { + pub address: dep::aztec::protocol_types::address::AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut dep::aztec::context::private_context::PrivateContext> { + $enqueue_self_methods + } + + pub struct EnqueueSelfStatic { + pub address: dep::aztec::protocol_types::address::AztecAddress, + pub context: Context, + } + + impl EnqueueSelfStatic<&mut dep::aztec::context::private_context::PrivateContext> { + $enqueue_self_static_methods + } + } +} diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/call_interface_stubs.nr b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions_stubs.nr similarity index 85% rename from noir-projects/aztec-nr/aztec/src/macros/functions/call_interface_stubs.nr rename to noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions_stubs.nr index a000e6b6389d..ccec188016b2 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/call_interface_stubs.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions_stubs.nr @@ -4,10 +4,7 @@ //! //! ExternalContract.at(address).some_method(arg1, arg2).enqueue() -use crate::macros::{ - functions::{self_call_registry, stub_registry as call_registry}, - utils::{AsStrQuote, compute_fn_selector, is_fn_view}, -}; +use crate::macros::utils::{AsStrQuote, compute_fn_selector}; use protocol_types::meta::utils::derive_serialization_quotes; use std::meta::unquote; @@ -21,47 +18,6 @@ comptime global FROM_FIELD: TypedExpr = { .as_typed_expr() }; -// Call registry is used to register calls to the contract from other contracts. -// Self-call registry is used to register calls to the contract from itself. - -pub comptime fn register_private_fn_stubs(f: FunctionDefinition) { - if is_fn_view(f) { - call_registry::register(f.module(), create_private_static_stub(f)); - self_call_registry::register_call_self_private_static( - f.module(), - create_private_self_call_stub(f, true), - ); - } else { - call_registry::register(f.module(), create_private_stub(f)); - self_call_registry::register_call_self_private( - f.module(), - create_private_self_call_stub(f, false), - ); - }; -} - -pub comptime fn register_public_fn_stubs(f: FunctionDefinition) { - if is_fn_view(f) { - call_registry::register(f.module(), create_public_static_stub(f)); - self_call_registry::register_call_self_public_static( - f.module(), - create_public_self_call_static_stub(f), - ); - self_call_registry::register_enqueue_self_static( - f.module(), - create_public_self_enqueue_static_stub(f), - ); - } else { - call_registry::register(f.module(), create_public_stub(f)); - self_call_registry::register_call_self_public(f.module(), create_public_self_call_stub(f)); - self_call_registry::register_enqueue_self(f.module(), create_public_self_enqueue_stub(f)); - }; -} - -pub comptime fn register_utility_fn_stub(f: FunctionDefinition) { - call_registry::register(f.module(), create_utility_stub(f)); -} - /// Utility function creating stubs used by all the stub functions in this file. comptime fn create_stub_base( f: FunctionDefinition, @@ -100,7 +56,7 @@ comptime fn create_stub_base( ) } -comptime fn create_private_stub(f: FunctionDefinition) -> Quoted { +pub(crate) comptime fn create_private_stub(f: FunctionDefinition) -> Quoted { let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, fn_name_str, fn_name_len, fn_selector) = create_stub_base(f); let fn_return_type = f.return_type(); @@ -120,7 +76,7 @@ comptime fn create_private_stub(f: FunctionDefinition) -> Quoted { } } -comptime fn create_private_static_stub(f: FunctionDefinition) -> Quoted { +pub(crate) comptime fn create_private_static_stub(f: FunctionDefinition) -> Quoted { let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, fn_name_str, fn_name_len, fn_selector) = create_stub_base(f); let fn_return_type = f.return_type(); @@ -139,7 +95,7 @@ comptime fn create_private_static_stub(f: FunctionDefinition) -> Quoted { } } -comptime fn create_public_stub(f: FunctionDefinition) -> Quoted { +pub(crate) comptime fn create_public_stub(f: FunctionDefinition) -> Quoted { let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, fn_name_str, fn_name_len, fn_selector) = create_stub_base(f); let fn_return_type = f.return_type(); @@ -159,7 +115,7 @@ comptime fn create_public_stub(f: FunctionDefinition) -> Quoted { } } -comptime fn create_public_static_stub(f: FunctionDefinition) -> Quoted { +pub(crate) comptime fn create_public_static_stub(f: FunctionDefinition) -> Quoted { let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, fn_name_str, fn_name_len, fn_selector) = create_stub_base(f); let fn_return_type = f.return_type(); @@ -178,7 +134,7 @@ comptime fn create_public_static_stub(f: FunctionDefinition) -> Quoted { } } -comptime fn create_utility_stub(f: FunctionDefinition) -> Quoted { +pub(crate) comptime fn create_utility_stub(f: FunctionDefinition) -> Quoted { let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, fn_name_str, fn_name_len, fn_selector) = create_stub_base(f); let fn_return_type = f.return_type(); diff --git a/noir-projects/aztec-nr/aztec/src/macros/calls_generation/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/mod.nr index 5474e067624a..175107cc1f31 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/calls_generation/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/calls_generation/mod.nr @@ -1 +1,3 @@ +pub(crate) mod external_functions_stubs; +pub(crate) mod external_functions; pub(crate) mod internal_functions; diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr index 97aa21cf8420..1583fa7b8ddd 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr @@ -1,9 +1,6 @@ -pub(crate) mod call_interface_stubs; // TODO: Move initialization_utils out of this crate // See https://github.com/AztecProtocol/aztec-packages/pull/15856#discussion_r2229134689 for more details pub mod initialization_utils; -pub(crate) mod stub_registry; -pub(crate) mod self_call_registry; pub(crate) mod auth_registry; pub(crate) mod utils; diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/self_call_registry.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/self_call_registry.nr deleted file mode 100644 index d006ff49bec4..000000000000 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/self_call_registry.nr +++ /dev/null @@ -1,91 +0,0 @@ -// TODO(F-131): Drop all this and instead just iterate over the functions directly in the `#[aztec]` macro. This -// approach was already implemented for `#[internal(...)]` functions. - -//! Registry of self-call function stubs (CallSelf, CallSelfStatic, EnqueueSelf and EnqueueSelfStatic) that allow for -//! the following API: -//! self.call_self.some_private_function(args) -//! self.call_self_static.some_view_function(args) -//! self.enqueue_self.some_public_function(args) -//! self.enqueue_self_static.some_view_function(args) - -use poseidon::poseidon2::Poseidon2Hasher; -use std::{collections::umap::UHashMap, hash::BuildHasherDefault}; - -// Each of the maps contains a quote of concatenated function stubs for a given contract module. - -comptime mut global CALL_SELF_PRIVATE_STUBS: UHashMap> = - UHashMap::default(); - -comptime mut global CALL_SELF_PUBLIC_STUBS: UHashMap> = - UHashMap::default(); - -comptime mut global ENQUEUE_SELF_STUBS: UHashMap> = - UHashMap::default(); - -comptime mut global CALL_SELF_PRIVATE_STATIC_STUBS: UHashMap> = - UHashMap::default(); - -comptime mut global CALL_SELF_PUBLIC_STATIC_STUBS: UHashMap> = - UHashMap::default(); - -comptime mut global ENQUEUE_SELF_STATIC_STUBS: UHashMap> = - UHashMap::default(); - -comptime fn concat_to_stubs( - map: &mut UHashMap>, - m: Module, - stub: Quoted, -) { - let maybe_current_stubs = map.get(m); - let stubs_to_insert = if maybe_current_stubs.is_some() { - let current_stubs = maybe_current_stubs.unwrap(); - quote { $current_stubs $stub } - } else { - stub - }; - map.insert(m, stubs_to_insert); -} - -pub(crate) comptime fn register_call_self_private(m: Module, stub: Quoted) { - concat_to_stubs(&mut CALL_SELF_PRIVATE_STUBS, m, stub); -} - -pub(crate) comptime fn register_call_self_public(m: Module, stub: Quoted) { - concat_to_stubs(&mut CALL_SELF_PUBLIC_STUBS, m, stub); -} - -pub(crate) comptime fn register_enqueue_self(m: Module, stub: Quoted) { - concat_to_stubs(&mut ENQUEUE_SELF_STUBS, m, stub); -} - -pub(crate) comptime fn register_call_self_private_static(m: Module, stub: Quoted) { - concat_to_stubs(&mut CALL_SELF_PRIVATE_STATIC_STUBS, m, stub); -} - -pub(crate) comptime fn register_call_self_public_static(m: Module, stub: Quoted) { - concat_to_stubs(&mut CALL_SELF_PUBLIC_STATIC_STUBS, m, stub); -} - -pub(crate) comptime fn register_enqueue_self_static(m: Module, stub: Quoted) { - concat_to_stubs(&mut ENQUEUE_SELF_STATIC_STUBS, m, stub); -} - -pub struct SelfCallStubs { - pub call_self_private_methods: Quoted, - pub call_self_public_methods: Quoted, - pub enqueue_self_methods: Quoted, - pub call_self_private_static_methods: Quoted, - pub call_self_public_static_methods: Quoted, - pub enqueue_self_static_methods: Quoted, -} - -pub comptime fn get_all_self_call_stubs(m: Module) -> SelfCallStubs { - SelfCallStubs { - call_self_private_methods: CALL_SELF_PRIVATE_STUBS.get(m).unwrap_or(quote {}), - call_self_public_methods: CALL_SELF_PUBLIC_STUBS.get(m).unwrap_or(quote {}), - enqueue_self_methods: ENQUEUE_SELF_STUBS.get(m).unwrap_or(quote {}), - call_self_private_static_methods: CALL_SELF_PRIVATE_STATIC_STUBS.get(m).unwrap_or(quote {}), - call_self_public_static_methods: CALL_SELF_PUBLIC_STATIC_STUBS.get(m).unwrap_or(quote {}), - enqueue_self_static_methods: ENQUEUE_SELF_STATIC_STUBS.get(m).unwrap_or(quote {}), - } -} diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/stub_registry.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/stub_registry.nr deleted file mode 100644 index c31235c5bd70..000000000000 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/stub_registry.nr +++ /dev/null @@ -1,27 +0,0 @@ -// TODO(F-131): Rename to call_registry to have consistent naming with self_call_registry - -// This file provides a registry for storing and retrieving function stubs generated by macros. -// It maintains a global hashmap that maps modules to their generated stub functions, -// allowing the macro system to collect and organize contract interface stubs. -// See the call_interface_stubs module for more details on what stubs are and how they are generated. - -use poseidon::poseidon2::Poseidon2Hasher; -use std::{collections::umap::UHashMap, hash::BuildHasherDefault}; - -comptime mut global STUBS: UHashMap> = - UHashMap::default(); - -/// Registers a function stub created via `stub_fn` as part of a module, -pub(crate) comptime fn register(m: Module, stub: Quoted) { - let current_stubs = STUBS.get(m); - let stubs_to_insert = if current_stubs.is_some() { - current_stubs.unwrap().push_back(stub) - } else { - &[stub] - }; - STUBS.insert(m, stubs_to_insert); -} - -pub comptime fn get(m: Module) -> Option<[Quoted]> { - STUBS.get(m) -} diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr index 5f35e253736f..6820f60aa9a5 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr @@ -1,12 +1,7 @@ // TODO(benesjan): Move this whole file to `noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation`. // Not done yet in order to not murder the PR diff. use crate::macros::{ - functions::{ - auth_registry::AUTHORIZE_ONCE_REGISTRY, - call_interface_stubs::{ - register_private_fn_stubs, register_public_fn_stubs, register_utility_fn_stub, - }, - }, + functions::auth_registry::AUTHORIZE_ONCE_REGISTRY, notes::NOTES, utils::{ fn_has_authorize_once, fn_has_noinitcheck, is_fn_contract_library_method, is_fn_external, @@ -39,10 +34,6 @@ comptime fn get_abi_relevant_attributes(f: FunctionDefinition) -> Quoted { } pub(crate) comptime fn transform_private(f: FunctionDefinition) -> Quoted { - // TODO(benesjan): This function should only generate the new function's quote. Move the following to a different - // place. - register_private_fn_stubs(f); - let module_has_initializer = module_has_initializer(f.module()); let module_has_storage = module_has_storage(f.module()); @@ -227,10 +218,6 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) -> Quoted { } pub(crate) comptime fn transform_public(f: FunctionDefinition) -> Quoted { - // TODO(benesjan): This function should only generate the new function's quote. Move the following to a different - // place. - register_public_fn_stubs(f); - let module_has_initializer = module_has_initializer(f.module()); let module_has_storage = module_has_storage(f.module()); @@ -365,10 +352,6 @@ pub(crate) comptime fn transform_public(f: FunctionDefinition) -> Quoted { } pub(crate) comptime fn transform_utility(f: FunctionDefinition) -> Quoted { - // TODO(benesjan): This function should only generate the new function's quote. Move the following to a different - // place. - register_utility_fn_stub(f); - // Initialize Storage if module has storage let storage_init = if module_has_storage(f.module()) { quote {