Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1b3c2e9
chore: reverting accidental de-macroifycation of AuthRegistry
benesjan Feb 16, 2026
42cb45a
chore: reverting accidental de-macroifycation of AuthRegistry (#20532)
benesjan Feb 16, 2026
78dea70
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
e1e6ad8
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
85925f7
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
857aca2
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
896d127
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
6c67ffb
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
f706192
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
fb73eaf
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
a46d13d
docs: add delayedpublicmutable apiref, fix misc docs
nventuro Feb 16, 2026
1382d2b
docs: add delayedpublicmutable apiref, fix misc docs (#20512)
AztecBot Feb 16, 2026
2d2b690
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
41a4cfe
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
077cf24
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
104b013
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
e04dfe1
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
dfe03c9
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
b184280
Merge branch 'next' into merge-train/fairies
Feb 16, 2026
ac5bc18
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
c225e1d
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
edf2c65
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
c49786e
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
378dfd6
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
46101d8
fix: enable contract debug logs in `aztec test`
benesjan Feb 17, 2026
4888900
Merge branch 'next' into merge-train/fairies
Feb 17, 2026
1f5b442
chore: rename simulateUtility -> executeUtility
benesjan Feb 17, 2026
7b7dc2d
chore: rename simulateUtility -> executeUtility (#20572)
benesjan Feb 17, 2026
29b9ec4
fix: enable contract debug logs in `aztec test` (#20580)
benesjan Feb 18, 2026
12efeac
Merge branch 'next' into janb/unblocking-fairies-train-merge
benesjan Feb 18, 2026
a6363fa
after merge fix
benesjan Feb 18, 2026
4cdcaff
fmt
benesjan Feb 18, 2026
0b306b2
chore: merging next to merge-train/fairies (#20622)
benesjan Feb 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions docs/docs-developers/docs/resources/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ Aztec is in active development. Each version may introduce breaking changes that

## TBD

### `simulateUtility` renamed to `executeUtility`

The `simulateUtility` method and related types have been renamed to `executeUtility` across the entire stack to better reflect that utility functions are executed, not simulated.

**TypeScript:**

```diff
- import { SimulateUtilityOptions, UtilitySimulationResult } from '@aztec/aztec.js';
+ import { ExecuteUtilityOptions, UtilityExecutionResult } from '@aztec/aztec.js';

- const result: UtilitySimulationResult = await wallet.simulateUtility(functionCall, opts);
+ const result: UtilityExecutionResult = await wallet.executeUtility(functionCall, opts);
```

**Noir (test environment):**

```diff
- let result = env.simulate_utility(my_contract_address, selector);
+ let result = env.execute_utility(my_contract_address, selector);
```

### [Protocol] `include_by_timestamp` renamed to `expiration_timestamp`

The `include_by_timestamp` field has been renamed to `expiration_timestamp` across the protocol to better convey its meaning.
Expand Down Expand Up @@ -266,8 +287,6 @@ For this reason we've created place holder protocol contracts in `noir-projects/
On your side all you need to do is update the dependency in `Nargo.toml`:

```diff
-auth_contract = { path = "../../protocol/auth_registry_contract" }
+auth_contract = { path = "../../protocol_interface/auth_registry_interface" }
-instance_contract = { path = "../../protocol/contract_instance_registry" }
+instance_contract = { path = "../../protocol_interface/contract_instance_registry_interface" }
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ impl PrivateContext {
/// network as a whole. For example, if a contract interaction sets include-by to some publicly-known value (e.g.
/// the time when a contract upgrades), then the wallet might wish to set an even lower one to avoid revealing that
/// this tx is interacting with said contract. Ideally, all wallets should standardize on an approach in order to
/// provide users with a large anonymity set -- although the exact approach
/// provide users with a large privacy set -- although the exact approach
/// will need to be discussed. Wallets that deviate from a standard might accidentally reveal which wallet each
/// transaction originates from.
///
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/history/nullifier.nr
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ mod test;
///
/// ## Cost
///
/// This function performs a full merkle tree inclusion proof, which is in the order of 4k gates.
/// This function performs a single merkle tree inclusion proof, which is in the order of 4k gates.
///
/// If you don't need to assert existence at a _specific_ past block, consider using
/// [`PrivateContext::assert_nullifier_exists`](crate::context::PrivateContext::assert_nullifier_exists) instead, which
Expand Down Expand Up @@ -82,7 +82,7 @@ pub fn assert_nullifier_existed_by(block_header: BlockHeader, siloed_nullifier:
///
/// ## Cost
///
/// This function performs a full merkle tree inclusion proof, which is in the order of 4k gates.
/// This function performs a single merkle tree inclusion proof, which is in the order of 4k gates.
pub fn assert_nullifier_did_not_exist_by(block_header: BlockHeader, siloed_nullifier: Field) {
// 1) Get the membership witness of a low nullifier of the nullifier.
// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/macros/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ pub comptime fn custom_note(s: TypeDefinition) -> Quoted {
}
}

/// Asserts that the given note implements the `Packable` trait.
/// Asserts that the given note implements the [`Packable`](crate::protocol::traits::Packable) trait.
///
/// We require that notes have the `Packable` trait implemented because it is used when emitting a note in a log or as
/// an offchain message.
Expand Down
341 changes: 323 additions & 18 deletions noir-projects/aztec-nr/aztec/src/state_vars/delayed_public_mutable.nr

Large diffs are not rendered by default.

29 changes: 14 additions & 15 deletions noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ mod test;
/// A value stored in a `PublicImmutable` can be read and initialized from public contract functions.
///
/// Unlike [`PublicMutable`](crate::state_vars::PublicMutable) it is **also** possible to read a `PublicImmutable` from
/// a
/// private contract function, though it is not possible to initialize one. A common pattern is to have these functions
/// [enqueue a public self calls](crate::contract_self::ContractSelf::enqueue_self) in which the initialization
/// operation is performed.
/// a private contract function, though it is not possible to initialize one. A common pattern is to have these
/// functions [enqueue a public self calls](crate::contract_self::ContractSelf::enqueue_self) in which the
/// initialization operation is performed.
///
/// For a mutable (with restrictions) variant which also can be read from private functions see
/// [`DelayedPublicMutable`](crate::state_vars::DelayedPublicMutable).
Expand All @@ -54,26 +53,26 @@ mod test;
///
/// `PublicImmutable`'s main limitation is the immutability, which in many cases leads to
/// [`DelayedPublicMutable`](crate::state_vars::DelayedPublicMutable) being used instead. But in those cases where
/// fixed
/// values are not a problem, this is a fine choice for storage.
/// fixed values are not a problem, this is a fine choice for storage.
///
/// ## Examples
///
/// Declaring a `PublicImmutable` in the the contract's [`storage`](crate::macros::storage::storage) struct requires
/// Declaring a `PublicImmutable` in the contract's [`storage`](crate::macros::storage::storage) struct requires
/// specifying the type `T` that is stored in the variable:
///
/// ```noir
/// #[storage]
/// struct Storage<Context> {
/// decimals: PublicImmutable<u8, Context>,
/// struct Storage<C> {
/// decimals: PublicImmutable<u8, C>,
///
/// account_types: Map<AztecAddress, PublicImmutable<AccountType, Context>, Context>,
/// account_types: Map<AztecAddress, PublicImmutable<AccountType, C>, C>,
/// }
/// ```
///
/// ## Requirements
///
/// The type `T` stored in the `PublicImmutable` must implement the `Packable` trait.
/// The type `T` stored in the `PublicImmutable` must implement the `Eq` and
/// [`Packable`](crate::protocol::traits::Packable) traits.
///
/// ## Implementation Details
///
Expand Down Expand Up @@ -130,7 +129,7 @@ impl<T> PublicImmutable<T, PublicContext> {
/// #[external("public")]
/// #[initializer]
/// fn initialize(decimals: u8) {
/// self.storage.decimals.iniitalize(decimals);
/// self.storage.decimals.initialize(decimals);
/// }
/// ```
///
Expand All @@ -139,7 +138,7 @@ impl<T> PublicImmutable<T, PublicContext> {
/// // Can only be called once per account
/// #[external("public")]
/// fn set_account_type(account_type: AccountType) {
/// self.storage.account_types.at(self.msg_sender()).iniitalize(account_type);
/// self.storage.account_types.at(self.msg_sender()).initialize(account_type);
/// }
/// ```
///
Expand Down Expand Up @@ -223,7 +222,7 @@ impl<T> PublicImmutable<T, PublicContext> {
/// #[external("public")]
/// fn set_account_type_if_not_set(account_type: AccountType) {
/// if !self.storage.account_types.at(self.msg_sender()).is_initialized() {
/// self.storage.account_types.at(self.msg_sender()).iniitalize(account_type);
/// self.storage.account_types.at(self.msg_sender()).initialize(account_type);
/// }
/// }
/// ```
Expand Down Expand Up @@ -301,7 +300,7 @@ impl<T> PublicImmutable<T, &mut PrivateContext> {
/// #[storage]
/// struct Storage<Context> {
/// decimals: PublicImmutable<u8, Context>,
/// symbol: PubicImmutable<FieldCompressedString, Context>,
/// symbol: PublicImmutable<FieldCompressedString, Context>,
/// }
///
/// // Good: both `decimals` and `symbol` are retrieved in a single historical public storage read
Expand Down
21 changes: 11 additions & 10 deletions noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::state_vars::StateVariable;
/// This is suitable for any kind of global state that needs to be accessible by everyone. For example, a token may
/// have a public total supply, or a voting contract may have public vote tallies.
///
/// Note that contracts having public values does not necessarily mean the the actions that update these values must
/// Note that contracts having public values does not necessarily mean the actions that update these values must
/// themselves be wholly public. For example, the token could allow for private minting and burning, and casting a vote
/// could be kept private: these private functions would enqueue a public function that writes to the `PublicMutable`.
///
Expand All @@ -49,22 +49,23 @@ use crate::state_vars::StateVariable;
///
/// ## Examples
///
/// Declaring a `PublicMutable` in the the contract's [`storage`](crate::macros::storage::storage) struct requires
/// Declaring a `PublicMutable` in the contract's [`storage`](crate::macros::storage::storage) struct requires
/// specifying the type `T` that is stored in the variable:
///
/// ```noir
/// #[storage]
/// struct Storage<Context> {
/// total_supply: PublicMutable<u128, Context>,
/// public_balances: Map<AztecAddress, PublicMutable<u128, Context>, Context>,
/// struct Storage<C> {
/// total_supply: PublicMutable<u128, C>,
/// public_balances: Map<AztecAddress, PublicMutable<u128, C>, C>,
///
/// vote_tallies: Map<ElectionId, PublicMutable<u128, Context>, Context>,
/// vote_tallies: Map<ElectionId, PublicMutable<u128, C>, C>,
/// }
/// ```
///
/// ## Requirements
///
/// The type `T` stored in the `PublicMutable` must implement the `Packable` trait.
/// The type `T` stored in the `PublicMutable` must implement the [`Packable`](crate::protocol::traits::Packable)
/// trait.
///
/// ## Implementation Details
///
Expand Down Expand Up @@ -161,7 +162,7 @@ impl<T> PublicMutable<T, PublicContext> {
/// }
/// ```
///
/// An [`only_self`](crate::macros::functions::only_self) helper that updates public state trigered by a private
/// An [`only_self`](crate::macros::functions::only_self) helper that updates public state triggered by a private
/// function:
/// ```noir
/// #[external("private")]
Expand All @@ -174,8 +175,8 @@ impl<T> PublicMutable<T, PublicContext> {
/// #[external("public")]
/// #[only_self]
/// fn _tally_vote(election_id: ElectionId, votes: u128) {
/// let current = self.storage.vote_tallies.read();
/// self.storage.vote_tallies.write(current + votes);
/// let current = self.storage.vote_tallies.at(election_id).read();
/// self.storage.vote_tallies.at(election_id).write(current + votes);
/// }
/// ```
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,14 +550,14 @@ impl TestEnvironment {
/// ```noir
/// let caller = env.create_light_account();
/// let contract_addr = env.deploy("SampleContract").without_initializer();
/// let return_value = env.simulate_utility(SampleContract::at(contract_addr).sample_utility_function());
/// let return_value = env.execute_utility(SampleContract::at(contract_addr).sample_utility_function());
/// ```
pub unconstrained fn simulate_utility<let M: u32, let N: u32, T>(_self: Self, call: UtilityCall<M, N, T>) -> T
pub unconstrained fn execute_utility<let M: u32, let N: u32, T>(_self: Self, call: UtilityCall<M, N, T>) -> T
where
T: Deserialize,
{
let serialized_return_values =
txe_oracles::simulate_utility_function(call.target_contract, call.selector, call.args);
txe_oracles::execute_utility_function(call.target_contract, call.selector, call.args);

T::deserialize(serialized_return_values)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ pub unconstrained fn public_call_new_flow<let M: u32, let N: u32>(
public_call_new_flow_oracle(from, contract_address, calldata, is_static_call)
}

pub unconstrained fn simulate_utility_function<let M: u32, let N: u32>(
pub unconstrained fn execute_utility_function<let M: u32, let N: u32>(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; M],
) -> [Field; N] {
simulate_utility_function_oracle(contract_address, function_selector, args)
execute_utility_function_oracle(contract_address, function_selector, args)
}

#[oracle(txeGetNextBlockNumber)]
Expand Down Expand Up @@ -145,8 +145,8 @@ unconstrained fn public_call_new_flow_oracle<let M: u32, let N: u32>(
is_static_call: bool,
) -> [Field; N] {}

#[oracle(txeSimulateUtilityFunction)]
unconstrained fn simulate_utility_function_oracle<let M: u32, let N: u32>(
#[oracle(txeExecuteUtilityFunction)]
unconstrained fn execute_utility_function_oracle<let M: u32, let N: u32>(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; M],
Expand Down
1 change: 0 additions & 1 deletion noir-projects/noir-contracts/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ members = [
"contracts/protocol/fee_juice_contract",
"contracts/protocol/multi_call_entrypoint_contract",
"contracts/protocol/public_checks_contract",
"contracts/protocol_interface/auth_registry_interface",
"contracts/protocol_interface/contract_instance_registry_interface",
"contracts/protocol_interface/fee_juice_interface",
"contracts/test/generic_proxy_contract",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,17 @@ unconstrained fn add_liquidity_twice_and_remove_liquidity() {
);

// Liquidity provider 2 should have 0 token0 and the refund amount of token1
assert_eq(env.simulate_utility(token0.balance_of_private(liquidity_provider_2)), 0);
assert_eq(env.execute_utility(token0.balance_of_private(liquidity_provider_2)), 0);
assert_eq(
env.simulate_utility(token1.balance_of_private(liquidity_provider_2)),
env.execute_utility(token1.balance_of_private(liquidity_provider_2)),
expected_refund_amount1,
);

// Check liquidity provider 2 received liquidity tokens proportional to their contribution
let expected_liquidity_tokens =
(expected_amount_0_in * initial_liquidity_token_supply) / initial_amount0;
assert_eq(
env.simulate_utility(liquidity_token.balance_of_private(liquidity_provider_2)),
env.execute_utility(liquidity_token.balance_of_private(liquidity_provider_2)),
expected_liquidity_tokens,
);

Expand All @@ -111,17 +111,17 @@ unconstrained fn add_liquidity_twice_and_remove_liquidity() {
let expected_token1_back =
(liquidity_to_remove * initial_amount1) / initial_liquidity_token_supply;
assert_eq(
env.simulate_utility(token0.balance_of_private(liquidity_provider_1)),
env.execute_utility(token0.balance_of_private(liquidity_provider_1)),
expected_token0_back,
);
assert_eq(
env.simulate_utility(token1.balance_of_private(liquidity_provider_1)),
env.execute_utility(token1.balance_of_private(liquidity_provider_1)),
expected_token1_back,
);

// Check remaining liquidity tokens
assert_eq(
env.simulate_utility(liquidity_token.balance_of_private(liquidity_provider_1)),
env.execute_utility(liquidity_token.balance_of_private(liquidity_provider_1)),
// The expected remaining liquidity is the other half of the initial liquidity.
AMM::INITIAL_LIQUIDITY / 2,
);
Expand Down Expand Up @@ -182,9 +182,9 @@ unconstrained fn swap_exact_tokens_for_tokens() {
);

// Verify swap occurred - all of input tokens should be spent and hence the swapper should have 0 token0 balance.
assert_eq(env.simulate_utility(token0.balance_of_private(swapper)), 0);
assert_eq(env.execute_utility(token0.balance_of_private(swapper)), 0);
// The exact amount out depends on the AMM formula, but should be > amount_out_min
assert(env.simulate_utility(token1.balance_of_private(swapper)) >= amount_out_min);
assert(env.execute_utility(token1.balance_of_private(swapper)) >= amount_out_min);
}

#[test]
Expand Down Expand Up @@ -243,9 +243,9 @@ unconstrained fn swap_tokens_for_exact_tokens() {
);

// Verify swap occurred - should get exact amount out
assert_eq(env.simulate_utility(token1.balance_of_private(swapper)), amount_out);
assert_eq(env.execute_utility(token1.balance_of_private(swapper)), amount_out);
// Should have some token0 change returned
let swapper_token0_balance = env.simulate_utility(token0.balance_of_private(swapper));
let swapper_token0_balance = env.execute_utility(token0.balance_of_private(swapper));
assert(swapper_token0_balance > 0);
assert(swapper_token0_balance < amount_in_max);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub contract Auth {
};

// docs:start:delayed_public_mutable_storage
// Authorizing a new address has a certain delay before it goes into effect. Set to 180 seconds which is 5 slots.
// Authorizing a new address has a certain delay before it goes into effect. Set to 180 seconds.
pub(crate) global CHANGE_AUTHORIZED_DELAY: u64 = 180;

#[storage]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub unconstrained fn assert_owns_private_nft(
token_id: Field,
) {
let (private_nfts, _) =
env.simulate_utility(NFT::at(nft_contract_address).get_private_nfts(owner, 0));
env.execute_utility(NFT::at(nft_contract_address).get_private_nfts(owner, 0));

let mut nft_found = false;
for obtained_token_id in private_nfts {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ unconstrained fn full_flow() {
);

// Get order and verify it's active
let (order, is_fulfilled) = env.simulate_utility(orderbook.get_order(order_id));
let (order, is_fulfilled) = env.execute_utility(orderbook.get_order(order_id));

assert_eq(order.bid_amount, BID_AMOUNT);
assert_eq(order.ask_amount, ASK_AMOUNT);
Expand All @@ -54,7 +54,7 @@ unconstrained fn full_flow() {

// Verify that all maker's tokens were transferred to orderbook's public balance
assert_eq(env.view_public(token0.balance_of_public(orderbook_address)), BID_AMOUNT);
assert_eq(env.simulate_utility(token0.balance_of_private(maker)), 0);
assert_eq(env.execute_utility(token0.balance_of_private(maker)), 0);

// ORDER FULFILLMENT

Expand All @@ -72,13 +72,13 @@ unconstrained fn full_flow() {
env.call_private(taker, orderbook.fulfill_order(order_id, FULFILL_ORDER_AUTHWIT_NONCE));

// Verify final balances
assert_eq(env.simulate_utility(token0.balance_of_private(maker)), 0);
assert_eq(env.simulate_utility(token1.balance_of_private(maker)), ASK_AMOUNT);
assert_eq(env.simulate_utility(token0.balance_of_private(taker)), BID_AMOUNT);
assert_eq(env.simulate_utility(token1.balance_of_private(taker)), 0);
assert_eq(env.execute_utility(token0.balance_of_private(maker)), 0);
assert_eq(env.execute_utility(token1.balance_of_private(maker)), ASK_AMOUNT);
assert_eq(env.execute_utility(token0.balance_of_private(taker)), BID_AMOUNT);
assert_eq(env.execute_utility(token1.balance_of_private(taker)), 0);

// Get order and verify it's fulfilled
let (order, is_fulfilled) = env.simulate_utility(orderbook.get_order(order_id));
let (order, is_fulfilled) = env.execute_utility(orderbook.get_order(order_id));

assert_eq(order.bid_amount, BID_AMOUNT);
assert_eq(order.ask_amount, ASK_AMOUNT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub unconstrained fn check_private_balance(
address_amount: u128,
) {
assert_eq(
env.simulate_utility(Token::at(token_contract_address).balance_of_private(address)),
env.execute_utility(Token::at(token_contract_address).balance_of_private(address)),
address_amount,
);
}
Expand Down
Loading
Loading