Skip to content

Commit b0185eb

Browse files
authored
feat: merge-train/fairies (#23141)
BEGIN_COMMIT_OVERRIDE refactor(pxe): use findLeavesIndexes for read request verification (#23123) refactor(pxe): skip storage reads for never-updated contracts (#23131) fix(pxe): skip registerContractFunctionSignatures when no public fns (#23134) refactor(pxe): prefetch updated class id hints per unique contract (#23130) chore(aztec-nr): Public self constructor function to prevent static byte code size blow up (#23062) refactor(pxe): avoid expensive toTx() call when computing tx hash (#23136) END_COMMIT_OVERRIDE
2 parents b28ea60 + cd903d9 commit b0185eb

22 files changed

Lines changed: 527 additions & 1876 deletions

File tree

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

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,52 @@ use crate::macros::{
66
},
77
};
88

9+
/// Generates the per-contract helper that builds public `self`.
10+
///
11+
/// Each public external function calls this helper instead of inlining the construction, so the same preamble does not
12+
/// appear duplicated in every public function body. We let Noir's inliner decide whether to inline the helper at each
13+
/// call site rather than forcing it via macro expansion.
14+
///
15+
/// The helper is generic over the calldata length `N` because `PublicContext::new` takes a closure that reads `N`
16+
/// fields from calldata. Noir monomorphizes one copy per distinct `N`, so public functions with the same number of
17+
/// serialized args reuse the same compiled code.
18+
pub(crate) comptime fn generate_public_self_creator(m: Module) -> Quoted {
19+
let (storage_type, storage_init) = if module_has_storage(m) {
20+
(quote { Storage<aztec::context::PublicContext> }, quote { let storage = Storage::init(context); })
21+
} else {
22+
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfPublic requires
23+
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and
24+
// higher constraint counts so we use the unit type `()` instead.
25+
(quote { () }, quote { let storage = (); })
26+
};
27+
28+
quote {
29+
#[contract_library_method]
30+
unconstrained fn __aztec_nr_internals__create_public_self<let N: u32>() -> aztec::contract_self::ContractSelfPublic<
31+
$storage_type,
32+
CallSelf<aztec::context::PublicContext>,
33+
CallSelfStatic<aztec::context::PublicContext>,
34+
CallInternal<aztec::context::PublicContext>,
35+
> {
36+
// Unlike in the private case, in public the `context` does not need to receive the hash of the original
37+
// params.
38+
let context = aztec::context::PublicContext::new(|| {
39+
// We start from 1 because we skip the selector for the dispatch function.
40+
let serialized_args : [Field; N] = aztec::oracle::avm::calldata_copy(1, N);
41+
aztec::hash::hash_args(serialized_args)
42+
});
43+
$storage_init
44+
let self_address = context.this_address();
45+
let call_self: CallSelf<aztec::context::PublicContext> = CallSelf { address: self_address, context };
46+
let call_self_static: CallSelfStatic<aztec::context::PublicContext> = CallSelfStatic { address: self_address, context };
47+
let internal: CallInternal<aztec::context::PublicContext> = CallInternal { context };
48+
aztec::contract_self::ContractSelfPublic::new(context, storage, call_self, call_self_static, internal)
49+
}
50+
}
51+
}
52+
953
pub(crate) comptime fn generate_public_external(f: FunctionDefinition) -> Quoted {
1054
let module_has_initializer = module_has_initializer(f.module());
11-
let module_has_storage = module_has_storage(f.module());
1255

1356
// Public functions undergo a lot of transformations from their Aztec.nr form.
1457
let original_params = f.parameters();
@@ -28,35 +71,9 @@ pub(crate) comptime fn generate_public_external(f: FunctionDefinition) -> Quoted
2871
.join(quote {+})
2972
};
3073

31-
let storage_init = if module_has_storage {
32-
quote {
33-
let storage = Storage::init(context);
34-
}
35-
} else {
36-
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfPublic requires
37-
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and
38-
// higher constraint counts so we use the unit type `()` instead.
39-
quote {
40-
let storage = ();
41-
}
42-
};
43-
44-
// Unlike in the private case, in public the `context` does not need to receive the hash of the original params.
4574
let contract_self_creation = quote {
4675
#[allow(unused_variables)]
47-
let mut self = {
48-
let context = aztec::context::PublicContext::new(|| {
49-
// We start from 1 because we skip the selector for the dispatch function.
50-
let serialized_args : [Field; $args_len_quote] = aztec::oracle::avm::calldata_copy(1, $args_len_quote);
51-
aztec::hash::hash_args(serialized_args)
52-
});
53-
$storage_init
54-
let self_address = context.this_address();
55-
let call_self: CallSelf<aztec::context::PublicContext> = CallSelf { address: self_address, context };
56-
let call_self_static: CallSelfStatic<aztec::context::PublicContext> = CallSelfStatic { address: self_address, context };
57-
let internal: CallInternal<aztec::context::PublicContext> = CallInternal { context };
58-
aztec::contract_self::ContractSelfPublic::new(context, storage, call_self, call_self_static, internal)
59-
};
76+
let mut self = __aztec_nr_internals__create_public_self::<$args_len_quote>();
6077
};
6178

6279
let original_function_name = f.name();

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ pub(crate) mod internal;
1212

1313
use abi_export::create_fn_abi_export;
1414
use external::{
15-
private::generate_private_external, public::generate_public_external, utility::generate_utility_external,
15+
private::generate_private_external,
16+
public::{generate_public_external, generate_public_self_creator},
17+
utility::generate_utility_external,
1618
};
1719
use internal::{generate_private_internal, generate_public_internal};
1820

@@ -47,6 +49,15 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
4749
let transformed_utility_functions =
4850
utility_functions.map(|function| generate_utility_external(function)).join(quote {});
4951

52+
// Emit a contract-level helper that constructs `self` for public functions. Each transformed public function calls
53+
// this helper rather than inlining the preamble. The helper is only useful for public external functions, so we
54+
// skip emitting it when the contract has none.
55+
let public_self_creator = if public_functions.len() > 0 {
56+
generate_public_self_creator(m)
57+
} else {
58+
quote {}
59+
};
60+
5061
// Now that we have generated quotes of the new functions based on the original function definitions, we replace
5162
// the original functions' bodies with `static_assert(false, ...)` to prevent them from being called directly from
5263
// within the contract. We also need to set the return type to `()` to avoid compilation errors.
@@ -84,6 +95,7 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
8495

8596
// We return the new functions' quotes to be injected into the contract.
8697
quote {
98+
$public_self_creator
8799
$transformed_private_functions
88100
$transformed_public_functions
89101
$transformed_utility_functions

noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,7 @@ impl<let N: u32, let T: u32> CallPrivateOptions<N, T> {
159159
self,
160160
additional_scopes: [AztecAddress; N_2],
161161
) -> CallPrivateOptions<N_2, T> {
162-
CallPrivateOptions {
163-
additional_scopes,
164-
authorized_utility_call_targets: self.authorized_utility_call_targets,
165-
}
162+
CallPrivateOptions { additional_scopes, authorized_utility_call_targets: self.authorized_utility_call_targets }
166163
}
167164

168165
/// Authorizes cross-contract utility calls to the given target contracts during this call.
@@ -173,10 +170,7 @@ impl<let N: u32, let T: u32> CallPrivateOptions<N, T> {
173170
self,
174171
targets: [AztecAddress; T_2],
175172
) -> CallPrivateOptions<N, T_2> {
176-
CallPrivateOptions {
177-
additional_scopes: self.additional_scopes,
178-
authorized_utility_call_targets: targets,
179-
}
173+
CallPrivateOptions { additional_scopes: self.additional_scopes, authorized_utility_call_targets: targets }
180174
}
181175
}
182176

@@ -214,10 +208,7 @@ impl<let S: u32, let T: u32> ViewPrivateOptions<S, T> {
214208
self,
215209
additional_scopes: [AztecAddress; S2],
216210
) -> ViewPrivateOptions<S2, T> {
217-
ViewPrivateOptions {
218-
additional_scopes,
219-
authorized_utility_call_targets: self.authorized_utility_call_targets,
220-
}
211+
ViewPrivateOptions { additional_scopes, authorized_utility_call_targets: self.authorized_utility_call_targets }
221212
}
222213

223214
/// Authorizes cross-contract utility calls to the given target contracts during this call.
@@ -228,10 +219,7 @@ impl<let S: u32, let T: u32> ViewPrivateOptions<S, T> {
228219
self,
229220
targets: [AztecAddress; T_2],
230221
) -> ViewPrivateOptions<S, T_2> {
231-
ViewPrivateOptions {
232-
additional_scopes: self.additional_scopes,
233-
authorized_utility_call_targets: targets,
234-
}
222+
ViewPrivateOptions { additional_scopes: self.additional_scopes, authorized_utility_call_targets: targets }
235223
}
236224
}
237225

@@ -773,10 +761,7 @@ impl TestEnvironment {
773761
/// let contract_addr = env.deploy("SampleContract").without_initializer();
774762
/// let return_value = env.execute_utility(SampleContract::at(contract_addr).sample_utility_function());
775763
/// ```
776-
pub unconstrained fn execute_utility<let M: u32, let N: u32, T>(
777-
self: Self,
778-
call: UtilityCall<M, N, T>,
779-
) -> T
764+
pub unconstrained fn execute_utility<let M: u32, let N: u32, T>(self: Self, call: UtilityCall<M, N, T>) -> T
780765
where
781766
T: Deserialize,
782767
{

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:46: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:46: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:97:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114: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:46: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:46: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:97:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114: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:46: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:46: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:97:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114: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:46: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:46: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:97:9
23+
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114: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

0 commit comments

Comments
 (0)