Skip to content

Commit 8df6f44

Browse files
committed
make helper constructors for internal/utility in public
1 parent 0101820 commit 8df6f44

10 files changed

Lines changed: 76 additions & 61 deletions

File tree

noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ use crate::macros::{
1818
/// helper keeps that AVM-bytecode-heavy preamble from being duplicated into every public function body.
1919
pub(crate) comptime fn generate_public_self_builder_from_context(m: Module) -> Quoted {
2020
let (storage_type, storage_init) = if module_has_storage(m) {
21-
(
22-
quote { Storage<aztec::context::PublicContext> },
23-
quote { let storage = Storage::init(context); },
24-
)
21+
(quote { Storage<aztec::context::PublicContext> }, quote { let storage = Storage::init(context); })
2522
} else {
2623
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfPublic requires
2724
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and

noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/utility.nr

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,43 @@
11
use crate::macros::utils::{fn_has_noinitcheck, module_has_initializer, module_has_storage};
22

3-
pub(crate) comptime fn generate_utility_external(f: FunctionDefinition) -> Quoted {
4-
let module_has_initializer = module_has_initializer(f.module());
5-
6-
// Initialize Storage if module has storage
7-
let storage_init = if module_has_storage(f.module()) {
8-
quote {
9-
let storage = Storage::init(context);
10-
}
3+
/// Emits a per-contract helper that builds the `self` value used by every utility external function.
4+
///
5+
/// Each utility external function calls this helper instead of inlining the construction, so the
6+
/// `UtilityContext::new`/`Storage::init`/`CallSelfUtility`/`ContractSelfUtility::new` chain does not appear duplicated
7+
/// in every utility function body. We let Noir's inliner decide whether to inline the helper at each call site rather
8+
/// than forcing it via macro expansion.
9+
///
10+
/// Unlike the public counterpart, this helper takes no arguments because `UtilityContext::new` does not need calldata.
11+
pub(crate) comptime fn generate_utility_self_creator(m: Module) -> Quoted {
12+
let (storage_type, storage_init) = if module_has_storage(m) {
13+
(quote { Storage<aztec::context::UtilityContext> }, quote { let storage = Storage::init(context); })
1114
} else {
12-
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfUtility
13-
// requires a
14-
// storage struct in its constructor. Using an Option type would lead to worse developer experience and higher
15+
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfUtility requires
16+
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and higher
1517
// constraint counts so we use the unit type `()` instead.
16-
quote {
17-
let storage = ();
18-
}
18+
(quote { () }, quote { let storage = (); })
1919
};
2020

21-
// Create utility context
22-
let contract_self_creation = quote {
23-
#[allow(unused_variables)]
24-
let mut self = {
21+
quote {
22+
#[contract_library_method]
23+
unconstrained fn __aztec_nr_internals__create_utility_self() -> aztec::contract_self::ContractSelfUtility<$storage_type, CallSelfUtility> {
2524
let context = aztec::context::UtilityContext::new();
2625
$storage_init
2726
let self_address = context.this_address();
2827
let call_self = CallSelfUtility { address: self_address };
2928
aztec::contract_self::ContractSelfUtility::new(context, storage, call_self)
30-
};
29+
}
30+
}
31+
}
32+
33+
pub(crate) comptime fn generate_utility_external(f: FunctionDefinition) -> Quoted {
34+
let module_has_initializer = module_has_initializer(f.module());
35+
36+
// Construct `self` via the per-contract `__aztec_nr_internals__create_utility_self` helper rather than inlining the
37+
// preamble in every utility function. See `generate_utility_self_creator` for the helper definition.
38+
let contract_self_creation = quote {
39+
#[allow(unused_variables)]
40+
let mut self = __aztec_nr_internals__create_utility_self();
3141
};
3242

3343
// Initialization checks are not included in contracts that don't have initializers.

noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/internal.nr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub(crate) comptime fn generate_private_internal(f: FunctionDefinition) -> Quote
5757
/// this module.
5858
///
5959
/// The `self` value is constructed by delegating to the per-contract
60+
///
6061
/// [`__aztec_nr_internals__build_public_self_from_context`](super::external::public::generate_public_self_builder_from_context)
6162
/// helper rather than inlining the preamble in every internal body.
6263
pub(crate) comptime fn generate_public_internal(f: FunctionDefinition) -> Quoted {

noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ pub(crate) mod internal;
1313
use abi_export::create_fn_abi_export;
1414
use external::{
1515
private::generate_private_external,
16-
public::{
17-
generate_public_external, generate_public_self_builder_from_context,
18-
generate_public_self_creator,
19-
},
20-
utility::generate_utility_external,
16+
public::{generate_public_external, generate_public_self_builder_from_context, generate_public_self_creator},
17+
utility::{generate_utility_external, generate_utility_self_creator},
2118
};
2219
use internal::{generate_private_internal, generate_public_internal};
2320

@@ -72,6 +69,15 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
7269
quote {}
7370
};
7471

72+
// Same idea for utility functions: emit a per-contract helper that builds the `self` value, so the construction is
73+
// not duplicated into every utility body. UtilityContext takes no calldata, so a single helper is enough; there is
74+
// no internal/external split to share with.
75+
let utility_self_creator = if utility_functions.len() > 0 {
76+
generate_utility_self_creator(m)
77+
} else {
78+
quote {}
79+
};
80+
7581
// Now that we have generated quotes of the new functions based on the original function definitions, we replace
7682
// the original functions' bodies with `static_assert(false, ...)` to prevent them from being called directly from
7783
// within the contract. We also need to set the return type to `()` to avoid compilation errors.
@@ -107,6 +113,7 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
107113
quote {
108114
$public_self_builder_from_context
109115
$public_self_creator
116+
$utility_self_creator
110117
$transformed_private_functions
111118
$transformed_public_functions
112119
$transformed_utility_functions

noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: Argument from in function foo must be of type AztecAddress, but is of typ
1414
2: aztec
1515
at <repo>/noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21
1616
3: process_functions
17-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:9
17+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9
1818
4: [T]::map
1919
at std/vector.nr:67:33
2020
5: process_functions
21-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:41
21+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
2222
6: generate_public_external
23-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:139:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:136:9
2424
7: create_authorize_once_check
2525
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:72:9
2626

noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: Function foo does not have a from parameter. Please specify which one to
1414
2: aztec
1515
at <repo>/noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21
1616
3: process_functions
17-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:9
17+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9
1818
4: [T]::map
1919
at std/vector.nr:67:33
2020
5: process_functions
21-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:41
21+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
2222
6: generate_public_external
23-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:139:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:136:9
2424
7: create_authorize_once_check
2525
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:67:9
2626

noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: Function foo does not have a authwit_nonce. Please specify which one to u
1414
2: aztec
1515
at <repo>/noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21
1616
3: process_functions
17-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:9
17+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9
1818
4: [T]::map
1919
at std/vector.nr:67:33
2020
5: process_functions
21-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:41
21+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
2222
6: generate_public_external
23-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:139:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:136:9
2424
7: create_authorize_once_check
2525
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:81:9
2626

noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: Argument authwit_nonce in function foo must be of type Field, but is of t
1414
2: aztec
1515
at <repo>/noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21
1616
3: process_functions
17-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:9
17+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:9
1818
4: [T]::map
1919
at std/vector.nr:67:33
2020
5: process_functions
21-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:51:41
21+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
2222
6: generate_public_external
23-
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:139:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:136:9
2424
7: create_authorize_once_check
2525
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:86:9
2626

noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,15 +2546,18 @@ pub contract AMM {
25462546
aztec::macros::functions::initialization_utils::mark_as_initialized_from_public_initializer(self.context);
25472547
}
25482548

2549+
#[contract_library_method]
2550+
unconstrained fn __aztec_nr_internals__create_utility_self() -> aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> {
2551+
let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new();
2552+
let storage: Storage<aztec::context::UtilityContext> = Storage::<aztec::context::UtilityContext>::init(context);
2553+
let self_address: AztecAddress = context.this_address();
2554+
let call_self: CallSelfUtility = CallSelfUtility { address: self_address};
2555+
aztec::contract_self::contract_self_utility::ContractSelfUtility::<Storage<aztec::context::UtilityContext>, CallSelfUtility>::new(context, storage, call_self)
2556+
}
2557+
25492558
unconstrained fn __aztec_nr_internals__get_amount_in_for_exact_out(balance_in: u128, balance_out: u128, amount_out: u128) -> pub u128 {
25502559
aztec::oracle::version::assert_compatible_oracle_version();
2551-
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = {
2552-
let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new();
2553-
let storage: Storage<aztec::context::UtilityContext> = Storage::<aztec::context::UtilityContext>::init(context);
2554-
let self_address: AztecAddress = context.this_address();
2555-
let call_self: CallSelfUtility = CallSelfUtility { address: self_address};
2556-
aztec::contract_self::contract_self_utility::ContractSelfUtility::<Storage<aztec::context::UtilityContext>, CallSelfUtility>::new(context, storage, call_self)
2557-
};
2560+
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = __aztec_nr_internals__create_utility_self();
25582561
aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context);
25592562
{
25602563
get_amount_in(amount_out, balance_in, balance_out)
@@ -2563,13 +2566,7 @@ pub contract AMM {
25632566

25642567
unconstrained fn __aztec_nr_internals__get_amount_out_for_exact_in(balance_in: u128, balance_out: u128, amount_in: u128) -> pub u128 {
25652568
aztec::oracle::version::assert_compatible_oracle_version();
2566-
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = {
2567-
let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new();
2568-
let storage: Storage<aztec::context::UtilityContext> = Storage::<aztec::context::UtilityContext>::init(context);
2569-
let self_address: AztecAddress = context.this_address();
2570-
let call_self: CallSelfUtility = CallSelfUtility { address: self_address};
2571-
aztec::contract_self::contract_self_utility::ContractSelfUtility::<Storage<aztec::context::UtilityContext>, CallSelfUtility>::new(context, storage, call_self)
2572-
};
2569+
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = __aztec_nr_internals__create_utility_self();
25732570
aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context);
25742571
{
25752572
get_amount_out(amount_in, balance_in, balance_out)

noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3986,15 +3986,18 @@ pub contract Token {
39863986
}
39873987
}
39883988

3989+
#[contract_library_method]
3990+
unconstrained fn __aztec_nr_internals__create_utility_self() -> aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> {
3991+
let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new();
3992+
let storage: Storage<aztec::context::UtilityContext> = Storage::<aztec::context::UtilityContext>::init(context);
3993+
let self_address: AztecAddress = context.this_address();
3994+
let call_self: CallSelfUtility = CallSelfUtility { address: self_address};
3995+
aztec::contract_self::contract_self_utility::ContractSelfUtility::<Storage<aztec::context::UtilityContext>, CallSelfUtility>::new(context, storage, call_self)
3996+
}
3997+
39893998
unconstrained fn __aztec_nr_internals__balance_of_private(owner: AztecAddress) -> pub u128 {
39903999
aztec::oracle::version::assert_compatible_oracle_version();
3991-
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = {
3992-
let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new();
3993-
let storage: Storage<aztec::context::UtilityContext> = Storage::<aztec::context::UtilityContext>::init(context);
3994-
let self_address: AztecAddress = context.this_address();
3995-
let call_self: CallSelfUtility = CallSelfUtility { address: self_address};
3996-
aztec::contract_self::contract_self_utility::ContractSelfUtility::<Storage<aztec::context::UtilityContext>, CallSelfUtility>::new(context, storage, call_self)
3997-
};
4000+
let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility<Storage<aztec::context::UtilityContext>, CallSelfUtility> = __aztec_nr_internals__create_utility_self();
39984001
aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context);
39994002
{
40004003
self.storage.balances.at(owner).balance_of()

0 commit comments

Comments
 (0)