Skip to content

Commit 3c8a9c6

Browse files
authored
feat: merge-train/fairies (#23079)
BEGIN_COMMIT_OVERRIDE fix: include sqlite binary in its npm package (#23039) fix: add sendMessagesAs to wallet api schemas (#23041) refactor(pxe): deduplicate tx hash lookups in MessageContextService (#23075) refactor(pxe): batch tagged private log queries across all secrets (#23048) refactor(pxe): batch log RPC calls in LogService.fetchLogsByTag (#23088) feat(pxe,nr): flesh out account stubs and don't exclude syncing for overrides (#23054) feat: deploy method refactor 2 (#23033) feat: fastForwardContractUpdate cheatcode for simulating contract updates (#22905) refactor(stdlib): consolidate find-function-by-selector helpers (#23008) feat(ci): Snapshots for aztec-nr contract compilation failures and nargo expand (#23061) chore: kv store test fully on vitest (#23096) refactor(pxe): skip redundant getBlock RPC when querying at anchor block (#23100) chore(playground): bump main chunk size limit 1750 → 1800 KB (#23107) feat(txe): allow authorizing cross-contract utility calls in nr tests (#23064) chore: bench public fns with emit repro (#23105) END_COMMIT_OVERRIDE
2 parents 47cf864 + ac74e9c commit 3c8a9c6

325 files changed

Lines changed: 25675 additions & 2268 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ aztec-nr: noir bb-cpp-native
301301
noir-projects-txe-tests:
302302
$(call test,$@,noir-projects/aztec-nr)
303303
$(call test,$@,noir-projects/noir-contracts)
304-
$(call test,$@,noir-projects/noir-contracts-comp-failures)
305304

306305
# Noir Projects - Aggregate target (builds all sub-projects)
307306
noir-projects: noir-protocol-circuits mock-protocol-circuits noir-contracts aztec-nr

cspell.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"cimg",
7272
"ciphertext",
7373
"ciphertexts",
74+
"clippy",
7475
"clonedeep",
7576
"clonedeepwith",
7677
"cmd",
@@ -171,6 +172,7 @@
171172
"includable",
172173
"incrementation",
173174
"indexeddb",
175+
"INSTA",
174176
"interruptible",
175177
"IPFS",
176178
"isequal",
@@ -367,8 +369,8 @@
367369
"unfinalized",
368370
"uniquified",
369371
"uniquify",
370-
"unlinkability",
371372
"unkonstrained",
373+
"unlinkability",
372374
"unnullify",
373375
"unpadded",
374376
"unprefixed",

docs/docs-developers/docs/aztec-js/how_to_test.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,24 @@ const result = await contract.methods.read_balance(account).simulate({
8383

8484
Use this to set up state preconditions, reproduce production bugs against pinned storage, or exercise rare value branches without orchestrating the contract calls that produce them.
8585

86+
### Fast-forwarding a contract update
87+
88+
`fastForwardContractUpdate` returns a `SimulationOverrides` object that simulates a deployed instance as if it had already been upgraded to a new contract class. The new class must already be registered on chain. The cheat mirrors a real `pxe.updateContract` followed by waiting out the upgrade delay: the instance's `currentContractClassId` is bumped, and the `ContractInstanceRegistry`'s delayed-public-mutable storage is rewritten to look like the upgrade was scheduled in the past.
89+
90+
```typescript
91+
import { fastForwardContractUpdate } from '@aztec/aztec.js';
92+
93+
const overrides = await fastForwardContractUpdate({
94+
instanceAddress: contract.address,
95+
newClassId: upgradedClass.id,
96+
node,
97+
});
98+
99+
const result = await contract.methods.upgraded_method().simulate({ overrides });
100+
```
101+
102+
Use this to test code paths that only execute after an upgrade, without orchestrating the full delayed-mutable upgrade flow.
103+
86104
## Further reading
87105

88106
- [How to read contract data](./how_to_read_data.md)

docs/docs-developers/docs/resources/migration_notes.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,19 @@ Direct callers of the `SimulationOverrides` constructor must switch from a posit
185185
+ new SimulationOverrides({ contracts });
186186
```
187187

188+
`overrides.contracts` swaps contract instances in the simulator's contract DB — useful for simulating a contract being on a different class than the one it was deployed with. To simulate a complete onchain upgrade flow, use the `fastForwardContractUpdate` helper which returns a `SimulationOverrides` covering both registry storage rewrites and the upgraded instance entry:
189+
190+
```typescript
191+
import { fastForwardContractUpdate } from '@aztec/aztec.js';
192+
193+
const overrides = await fastForwardContractUpdate({
194+
instanceAddress: contract.address,
195+
newClassId: upgradedClass.id,
196+
node,
197+
});
198+
const result = await contract.methods.upgraded_method().simulate({ overrides });
199+
```
200+
188201
### [PXE] `proveTx` takes an options bag
189202

190203
`PXE.proveTx` used to accept `scopes` as a positional argument; it now takes an options bag consistent with `simulateTx` and `profileTx`, and adds an optional `senderForTags` field. Update direct callers:

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

Lines changed: 113 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,22 @@ struct UtilityContextOptions {
132132
/// ```noir
133133
/// env.call_private_opts(from, CallPrivateOptions::new().with_additional_scopes([other]), call);
134134
/// ```
135-
pub struct CallPrivateOptions<let N: u32> {
135+
pub struct CallPrivateOptions<let N: u32, let T: u32> {
136136
additional_scopes: [AztecAddress; N],
137+
authorized_utility_call_targets: [AztecAddress; T],
137138
}
138139

139-
impl CallPrivateOptions<0> {
140+
impl CallPrivateOptions<0, 0> {
140141
/// Creates default `CallPrivateOptions`.
141142
///
142143
/// The default values are the same as if using [`TestEnvironment::call_private`] instead of
143144
/// [`TestEnvironment::call_private_opts`].
144145
pub fn new() -> Self {
145-
CallPrivateOptions { additional_scopes: [] }
146+
CallPrivateOptions { additional_scopes: [], authorized_utility_call_targets: [] }
146147
}
147148
}
148149

149-
impl<let N: u32> CallPrivateOptions<N> {
150+
impl<let N: u32, let T: u32> CallPrivateOptions<N, T> {
150151
/// Grants access to secrets of additional accounts.
151152
///
152153
/// By default only the secrets that belong to the `from` account can be accessed: this function lets contracts
@@ -155,10 +156,27 @@ impl<let N: u32> CallPrivateOptions<N> {
155156
/// Example usage includes accounts withdrawing from an escrow, which may require accessing the escrow's own notes
156157
/// and secrets.
157158
pub fn with_additional_scopes<let N_2: u32>(
158-
_self: Self,
159+
self,
159160
additional_scopes: [AztecAddress; N_2],
160-
) -> CallPrivateOptions<N_2> {
161-
CallPrivateOptions { additional_scopes }
161+
) -> CallPrivateOptions<N_2, T> {
162+
CallPrivateOptions {
163+
additional_scopes,
164+
authorized_utility_call_targets: self.authorized_utility_call_targets,
165+
}
166+
}
167+
168+
/// Authorizes cross-contract utility calls to the given target contracts during this call.
169+
///
170+
/// By default, cross-contract utility calls are denied. This method lets the test author specify which target
171+
/// contracts are allowed to be called via utility functions during execution.
172+
pub fn with_authorized_utility_call_targets<let T_2: u32>(
173+
self,
174+
targets: [AztecAddress; T_2],
175+
) -> CallPrivateOptions<N, T_2> {
176+
CallPrivateOptions {
177+
additional_scopes: self.additional_scopes,
178+
authorized_utility_call_targets: targets,
179+
}
162180
}
163181
}
164182

@@ -169,21 +187,22 @@ impl<let N: u32> CallPrivateOptions<N> {
169187
/// ```noir
170188
/// env.view_private_opts(from, ViewPrivateOptions::new().with_additional_scopes([other]), call);
171189
/// ```
172-
pub struct ViewPrivateOptions<let S: u32> {
190+
pub struct ViewPrivateOptions<let S: u32, let T: u32> {
173191
additional_scopes: [AztecAddress; S],
192+
authorized_utility_call_targets: [AztecAddress; T],
174193
}
175194

176-
impl ViewPrivateOptions<0> {
195+
impl ViewPrivateOptions<0, 0> {
177196
/// Creates default `ViewPrivateOptions`.
178197
///
179198
/// The default values are the same as if using [`TestEnvironment::view_private`] instead of
180199
/// [`TestEnvironment::view_private_opts`].
181200
pub fn new() -> Self {
182-
ViewPrivateOptions { additional_scopes: [] }
201+
ViewPrivateOptions { additional_scopes: [], authorized_utility_call_targets: [] }
183202
}
184203
}
185204

186-
impl<let S: u32> ViewPrivateOptions<S> {
205+
impl<let S: u32, let T: u32> ViewPrivateOptions<S, T> {
187206
/// Grants access to secrets of additional accounts.
188207
///
189208
/// By default only the secrets that belong to the `from` account can be accessed: this function lets contracts
@@ -192,10 +211,27 @@ impl<let S: u32> ViewPrivateOptions<S> {
192211
/// Example usage includes accounts querying an escrow's balance, which may require accessing the escrow's own
193212
/// notes.
194213
pub fn with_additional_scopes<let S2: u32>(
195-
_self: Self,
214+
self,
196215
additional_scopes: [AztecAddress; S2],
197-
) -> ViewPrivateOptions<S2> {
198-
ViewPrivateOptions { additional_scopes }
216+
) -> ViewPrivateOptions<S2, T> {
217+
ViewPrivateOptions {
218+
additional_scopes,
219+
authorized_utility_call_targets: self.authorized_utility_call_targets,
220+
}
221+
}
222+
223+
/// Authorizes cross-contract utility calls to the given target contracts during this call.
224+
///
225+
/// By default, cross-contract utility calls are denied. This method lets the test author specify which target
226+
/// contracts are allowed to be called via utility functions during execution.
227+
pub fn with_authorized_utility_call_targets<let T_2: u32>(
228+
self,
229+
targets: [AztecAddress; T_2],
230+
) -> ViewPrivateOptions<S, T_2> {
231+
ViewPrivateOptions {
232+
additional_scopes: self.additional_scopes,
233+
authorized_utility_call_targets: targets,
234+
}
199235
}
200236
}
201237

@@ -207,6 +243,40 @@ struct EventDiscoveryOptions {
207243
contract_address: Option<AztecAddress>,
208244
}
209245

246+
/// Configuration for [`TestEnvironment::execute_utility_opts`].
247+
///
248+
/// Constructed by calling [`ExecuteUtilityOptions::new`] and then chaining methods:
249+
///
250+
/// ```noir
251+
/// env.execute_utility_opts(
252+
/// ExecuteUtilityOptions::new().with_authorized_utility_call_targets([target]),
253+
/// SomeContract::at(addr).some_utility_function(),
254+
/// );
255+
/// ```
256+
pub struct ExecuteUtilityOptions<let T: u32> {
257+
authorized_utility_call_targets: [AztecAddress; T],
258+
}
259+
260+
impl ExecuteUtilityOptions<0> {
261+
/// Creates default `ExecuteUtilityOptions`.
262+
pub fn new() -> Self {
263+
ExecuteUtilityOptions { authorized_utility_call_targets: [] }
264+
}
265+
}
266+
267+
impl<let T: u32> ExecuteUtilityOptions<T> {
268+
/// Authorizes cross-contract utility calls to the given target contracts during this call.
269+
///
270+
/// By default, cross-contract utility calls are denied. This method lets the test author specify which target
271+
/// contracts are allowed to be called via utility functions during execution.
272+
pub fn with_authorized_utility_call_targets<let T_2: u32>(
273+
_self: Self,
274+
targets: [AztecAddress; T_2],
275+
) -> ExecuteUtilityOptions<T_2> {
276+
ExecuteUtilityOptions { authorized_utility_call_targets: targets }
277+
}
278+
}
279+
210280
/// Configuration values for [`TestEnvironment::deploy_opts`]. Meant to be used by calling `new` and then chaining
211281
/// methods setting each value, e.g.:
212282
/// ```noir
@@ -629,10 +699,10 @@ impl TestEnvironment {
629699
}
630700

631701
/// Variant of `call_private` which allows specifying multiple configuration values via `CallPrivateOptions`.
632-
pub unconstrained fn call_private_opts<let M: u32, let N: u32, let S: u32, T>(
702+
pub unconstrained fn call_private_opts<let M: u32, let N: u32, let S: u32, let U: u32, T>(
633703
_self: Self,
634704
from: AztecAddress,
635-
opts: CallPrivateOptions<S>,
705+
opts: CallPrivateOptions<S, U>,
636706
call: PrivateCall<M, N, T>,
637707
) -> T
638708
where
@@ -646,6 +716,7 @@ impl TestEnvironment {
646716
hash_args(call.args),
647717
/*is_static=*/ false,
648718
opts.additional_scopes,
719+
opts.authorized_utility_call_targets,
649720
);
650721

651722
T::deserialize(serialized_return_values)
@@ -670,10 +741,10 @@ impl TestEnvironment {
670741
}
671742

672743
/// Variant of `view_private` which allows specifying multiple configuration values via `ViewPrivateOptions`.
673-
pub unconstrained fn view_private_opts<let M: u32, let N: u32, let S: u32, T>(
744+
pub unconstrained fn view_private_opts<let M: u32, let N: u32, let S: u32, let U: u32, T>(
674745
_self: Self,
675746
from: AztecAddress,
676-
opts: ViewPrivateOptions<S>,
747+
opts: ViewPrivateOptions<S, U>,
677748
call: PrivateStaticCall<M, N, T>,
678749
) -> T
679750
where
@@ -687,6 +758,7 @@ impl TestEnvironment {
687758
hash_args(call.args),
688759
/*is_static=*/ true,
689760
opts.additional_scopes,
761+
opts.authorized_utility_call_targets,
690762
);
691763

692764
T::deserialize(serialized_return_values)
@@ -701,12 +773,32 @@ impl TestEnvironment {
701773
/// let contract_addr = env.deploy("SampleContract").without_initializer();
702774
/// let return_value = env.execute_utility(SampleContract::at(contract_addr).sample_utility_function());
703775
/// ```
704-
pub unconstrained fn execute_utility<let M: u32, let N: u32, T>(_self: Self, call: UtilityCall<M, N, T>) -> T
776+
pub unconstrained fn execute_utility<let M: u32, let N: u32, T>(
777+
self: Self,
778+
call: UtilityCall<M, N, T>,
779+
) -> T
705780
where
706781
T: Deserialize,
707782
{
708-
let serialized_return_values =
709-
txe_oracles::execute_utility_function(call.target_contract, call.selector, call.args);
783+
self.execute_utility_opts(ExecuteUtilityOptions::new(), call)
784+
}
785+
786+
/// Variant of `execute_utility` which allows specifying configuration values via `ExecuteUtilityOptions`, such as
787+
/// authorizing cross-contract utility calls.
788+
pub unconstrained fn execute_utility_opts<let M: u32, let N: u32, let U: u32, T>(
789+
_self: Self,
790+
opts: ExecuteUtilityOptions<U>,
791+
call: UtilityCall<M, N, T>,
792+
) -> T
793+
where
794+
T: Deserialize,
795+
{
796+
let serialized_return_values = txe_oracles::execute_utility_function(
797+
call.target_contract,
798+
call.selector,
799+
call.args,
800+
opts.authorized_utility_call_targets,
801+
);
710802

711803
T::deserialize(serialized_return_values)
712804
}

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ pub unconstrained fn deploy<let M: u32, let N: u32, let P: u32>(
3636
ContractInstance::deserialize(instance_fields)
3737
}
3838

39-
pub unconstrained fn private_call_new_flow<let M: u32, let N: u32, let S: u32>(
39+
pub unconstrained fn private_call_new_flow<let M: u32, let N: u32, let S: u32, let T: u32>(
4040
from: Option<AztecAddress>,
4141
contract_address: AztecAddress,
4242
function_selector: FunctionSelector,
4343
args: [Field; M],
4444
args_hash: Field,
4545
is_static_call: bool,
4646
additional_scopes: [AztecAddress; S],
47+
authorized_utility_call_targets: [AztecAddress; T],
4748
) -> [Field; N] {
4849
private_call_new_flow_oracle(
4950
from,
@@ -53,6 +54,7 @@ pub unconstrained fn private_call_new_flow<let M: u32, let N: u32, let S: u32>(
5354
args_hash,
5455
is_static_call,
5556
additional_scopes,
57+
authorized_utility_call_targets,
5658
)
5759
}
5860

@@ -68,12 +70,18 @@ pub unconstrained fn public_call_new_flow<let M: u32, let N: u32>(
6870
public_call_new_flow_oracle(from, contract_address, calldata, is_static_call)
6971
}
7072

71-
pub unconstrained fn execute_utility_function<let M: u32, let N: u32>(
73+
pub unconstrained fn execute_utility_function<let M: u32, let N: u32, let T: u32>(
7274
contract_address: AztecAddress,
7375
function_selector: FunctionSelector,
7476
args: [Field; M],
77+
authorized_utility_call_targets: [AztecAddress; T],
7578
) -> [Field; N] {
76-
execute_utility_function_oracle(contract_address, function_selector, args)
79+
execute_utility_function_oracle(
80+
contract_address,
81+
function_selector,
82+
args,
83+
authorized_utility_call_targets,
84+
)
7785
}
7886

7987
#[oracle(aztec_txe_getNextBlockNumber)]
@@ -209,14 +217,15 @@ pub unconstrained fn add_account(secret: Field) -> TestAccount {}
209217
pub unconstrained fn add_authwit(address: AztecAddress, message_hash: Field) {}
210218

211219
#[oracle(aztec_txe_privateCallNewFlow)]
212-
unconstrained fn private_call_new_flow_oracle<let M: u32, let N: u32, let S: u32>(
220+
unconstrained fn private_call_new_flow_oracle<let M: u32, let N: u32, let S: u32, let T: u32>(
213221
_from: Option<AztecAddress>,
214222
_contract_address: AztecAddress,
215223
_function_selector: FunctionSelector,
216224
_args: [Field; M],
217225
_args_hash: Field,
218226
_is_static_call: bool,
219227
_additional_scopes: [AztecAddress; S],
228+
_authorized_utility_call_targets: [AztecAddress; T],
220229
) -> [Field; N] {}
221230

222231
#[oracle(aztec_txe_publicCallNewFlow)]
@@ -228,10 +237,11 @@ unconstrained fn public_call_new_flow_oracle<let M: u32, let N: u32>(
228237
) -> [Field; N] {}
229238

230239
#[oracle(aztec_txe_executeUtilityFunction)]
231-
unconstrained fn execute_utility_function_oracle<let M: u32, let N: u32>(
240+
unconstrained fn execute_utility_function_oracle<let M: u32, let N: u32, let T: u32>(
232241
contract_address: AztecAddress,
233242
function_selector: FunctionSelector,
234243
args: [Field; M],
244+
authorized_utility_call_targets: [AztecAddress; T],
235245
) -> [Field; N] {}
236246

237247
#[oracle(aztec_txe_setTopLevelTXEContext)]

noir-projects/bootstrap.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function build {
2626
}
2727

2828
function test_cmds {
29-
parallel -k ./{}/bootstrap.sh test_cmds ::: noir-protocol-circuits noir-contracts aztec-nr noir-contracts-comp-failures
29+
parallel -k ./{}/bootstrap.sh test_cmds ::: noir-protocol-circuits noir-contracts aztec-nr contract-snapshots
3030
}
3131

3232
function test {

0 commit comments

Comments
 (0)