Skip to content

Commit 0dceb12

Browse files
author
AztecBot
committed
Merge branch 'next' into ad/chore/ci-release-pr-canary
2 parents 53b2d8a + 3c8a9c6 commit 0dceb12

328 files changed

Lines changed: 25691 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.

CLAUDE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ Do not explain *what* the code does — well-named identifiers cover that. Comme
107107
Do not reference the current task, PR, caller, or author (`// used by X`, `// fix for issue #123`, `// AI-generated`), and do not add banner-style section comments (`// ===== HELPERS =====`). Both rot the moment the surrounding code is moved.
108108
</writing_comments>
109109

110+
<jargon>
111+
Avoid recurring AI-isms in chat replies, PR descriptions, commit messages, code comments, and docs. Substitutes:
112+
113+
- **"load bearing"***important*, *critical*, *required*, or describe the actual dependency (e.g. "the scheduler relies on this invariant").
114+
- **"seam"** (for an interaction point or boundary) → *interface*, *boundary*, *call site*, *integration point*.
115+
- **"north star"***goal*, *main goal*, *objective*.
116+
- **"sharpening"** (for adding detail or refining wording) → *clarifying*, *adding detail*, *tightening*, *refining*.
117+
- **"You're absolutely right"** and effusive agreement openers (*"Great catch!"*, *"Excellent point!"*) → never lead a reply with these. A short acknowledgement (*"Right — …"*, *"Agreed."*) is fine, and a closing *"you're right"* at the end of a long reply is acceptable when warranted. Lead with substance, not validation.
118+
</jargon>
119+
110120
<attribution>
111121
Attribute work to the git author, not to Claude. Do not add `Co-Authored-By: Claude` trailers or `Generated with Claude Code` in PR descriptions. The git author (from `git config user.name`) is the author of record.
112122
</attribution>

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

barretenberg/bbup/bb-versions.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"1.0.0-beta.21": "5.0.0-nightly.20260324",
23
"1.0.0-beta.20": "5.0.0-nightly.20260324",
34
"1.0.0-beta.19": "4.0.0-nightly.20260120",
45
"1.0.0-beta.18": "3.0.0-nightly.20260102",

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:

docs/docusaurus.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ const config = {
315315
],
316316
apiKey: "gpH8o2YnqsOEj2jgtIMTULbtHi1kZ2X3", // public search-only api key, safe to commit
317317
},
318+
// aztec-nr-api pages live in /static/ as raw HTML, not React Router
319+
// routes. Without this, the dropdown calls history.push() and the SPA
320+
// 404s on click. Matching the regex makes the theme use
321+
// window.location.href for a real page load that Netlify resolves.
322+
externalUrlRegex: "/aztec-nr-api/",
318323
},
319324
colorMode: {
320325
defaultMode: "light",

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
}

0 commit comments

Comments
 (0)