Skip to content

Commit fbfddf4

Browse files
authored
feat: merge-train/fairies-v5 (#24144)
See [merge-train-readme.md](https://github.com/AztecProtocol/aztec-packages/blob/next/.github/workflows/merge-train-readme.md). This is a merge-train.
2 parents 70c9bca + 272f4fc commit fbfddf4

11 files changed

Lines changed: 68 additions & 28 deletions

File tree

docs/docs-developers/docs/aztec-nr/standards/escrow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn _get_escrow(
5555
let escrow_instance = ContractInstance {
5656
salt: context.this_address().to_field(),
5757
deployer: AztecAddress::from_field(0),
58-
contract_class_id: ContractClassId::from_field(escrow_class_id),
58+
original_contract_class_id: ContractClassId::from_field(escrow_class_id),
5959
initialization_hash: 0,
6060
public_keys: computed_public_keys,
6161
};

docs/docs-developers/docs/foundational-topics/contract_creation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ A contract instance includes:
5353

5454
- `salt`: User-generated pseudorandom value for uniqueness
5555
- `deployer`: Optional address of the contract deployer. Zero for universal deployment
56-
- `contract_class_id`: Identifier of the contract class for this instance
56+
- `original_contract_class_id`: Identifier of the contract class the instance was deployed with. Updating the instance to a new class via the ContractInstanceRegistry does not change this value, since it is part of the address preimage
5757
- `initialization_hash`: Hash of the selector and arguments to the constructor
5858
- `immutables_hash`: Hash of the contract's compile-time immutable state
5959
- `public_keys`: Public keys participating in address derivation (nullifier, incoming viewing, outgoing viewing, tagging, message-signing, and fallback keys). Only the incoming viewing key is held as an elliptic curve point; the other five are held as their `hash_public_key` digests.

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ Aztec is in active development. Each version may introduce breaking changes that
99

1010
## TBD
1111

12+
### [Aztec.nr] `ContractInstance.contract_class_id` renamed to `original_contract_class_id`
13+
14+
The `contract_class_id` field of the `ContractInstance` struct (returned by `get_contract_instance`) has been renamed to `original_contract_class_id`. The struct is the contract's *address preimage*, so this field is the class id the contract was deployed with: for contracts whose class was later updated via the `ContractInstanceRegistry`, it is NOT the class currently executing. The rename makes that explicit.
15+
16+
**Migration:**
17+
18+
```diff
19+
let instance = get_contract_instance(address);
20+
- let class_id = instance.contract_class_id;
21+
+ let class_id = instance.original_contract_class_id;
22+
```
23+
24+
Note that this value is not available during public execution, which only has access to the _current_ contract class.
25+
26+
### [Aztec.nr] `get_contract_instance_class_id_avm` renamed to `get_contract_instance_current_class_id_avm`
27+
28+
The AVM contract-instance class id getter has been renamed to make explicit that it returns the *current* class id, i.e. it reflects updates performed via the `ContractInstanceRegistry`.
29+
30+
**Migration:**
31+
32+
```diff
33+
- use aztec::oracle::get_contract_instance::get_contract_instance_class_id_avm;
34+
+ use aztec::oracle::get_contract_instance::get_contract_instance_current_class_id_avm;
35+
36+
- let class_id = get_contract_instance_class_id_avm(address);
37+
+ let class_id = get_contract_instance_current_class_id_avm(address);
38+
```
39+
1240
### [Aztec.nr] `for_each` visits elements in order; removing during iteration no longer supported
1341

1442
`CapsuleArray::for_each` and `EphemeralArray::for_each` previously iterated backwards (from the last element to the first) so that the callback could safely remove the current element. They now visit elements in order, from first to last, as is usually expected in other languages. Structurally mutating the array (e.g. via `push` or `remove`) from inside the callback is no longer supported.
@@ -32,7 +60,7 @@ let _ = array.clear();
3260
kept.for_each(|_index, value| array.push(value));
3361
```
3462

35-
`EphemeralArray`'s are cheap and by nature not persistent though, so in most cases you probably can just work with the new copy instead of going through this hassle.
63+
`EphemeralArray`'s are cheap and by nature not persistent though, so in most cases you probably can just work with the new copy instead of going through this hassle.
3664

3765
`CapsuleArray` has no `filter`, so iterate manually, backwards. Removing the current element is safe in a backward loop because it only shifts elements at higher indices:
3866

noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ fn compute_public_initialization_nullifier(address: AztecAddress) -> Field {
148148
)
149149
}
150150

151-
// Used by `create_assert_correct_initializer_args` (you won't find it through searching)
151+
// Called by code injected by the macros in `macros/internals_functions_generation/external/public.nr`.
152152
pub fn assert_initialization_matches_address_preimage_public(context: PublicContext) {
153153
let address = context.this_address();
154154
let deployer = get_contract_instance_deployer_avm(address).unwrap();
@@ -161,7 +161,7 @@ pub fn assert_initialization_matches_address_preimage_public(context: PublicCont
161161
);
162162
}
163163

164-
// Used by `create_assert_correct_initializer_args` (you won't find it through searching)
164+
// Called by code injected by the macros in `macros/internals_functions_generation/external/private.nr`.
165165
pub fn assert_initialization_matches_address_preimage_private(context: PrivateContext) {
166166
let address = context.this_address();
167167
let instance = get_contract_instance(address);

noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ unconstrained fn get_contract_instance_internal(address: AztecAddress) -> Contra
1111
get_contract_instance_oracle(address)
1212
}
1313

14-
// NOTE: this is for use in private only
14+
/// Returns `address`'s [`ContractInstance`].
1515
pub fn get_contract_instance(address: AztecAddress) -> ContractInstance {
1616
// Safety: The to_address function combines all values in the instance object to produce an address, so by checking
1717
// that we get the expected address we validate the entire struct.
@@ -30,7 +30,9 @@ struct GetContractInstanceResult {
3030
#[oracle(aztec_avm_getContractInstanceDeployer)]
3131
unconstrained fn get_contract_instance_deployer_oracle_avm(_address: AztecAddress) -> [GetContractInstanceResult; 1] {}
3232
#[oracle(aztec_avm_getContractInstanceClassId)]
33-
unconstrained fn get_contract_instance_class_id_oracle_avm(_address: AztecAddress) -> [GetContractInstanceResult; 1] {}
33+
unconstrained fn get_contract_instance_current_class_id_oracle_avm(
34+
_address: AztecAddress,
35+
) -> [GetContractInstanceResult; 1] {}
3436
#[oracle(aztec_avm_getContractInstanceInitializationHash)]
3537
unconstrained fn get_contract_instance_initialization_hash_oracle_avm(
3638
_address: AztecAddress,
@@ -43,8 +45,10 @@ unconstrained fn get_contract_instance_immutables_hash_oracle_avm(
4345
unconstrained fn get_contract_instance_deployer_internal_avm(address: AztecAddress) -> [GetContractInstanceResult; 1] {
4446
get_contract_instance_deployer_oracle_avm(address)
4547
}
46-
unconstrained fn get_contract_instance_class_id_internal_avm(address: AztecAddress) -> [GetContractInstanceResult; 1] {
47-
get_contract_instance_class_id_oracle_avm(address)
48+
unconstrained fn get_contract_instance_current_class_id_internal_avm(
49+
address: AztecAddress,
50+
) -> [GetContractInstanceResult; 1] {
51+
get_contract_instance_current_class_id_oracle_avm(address)
4852
}
4953
unconstrained fn get_contract_instance_initialization_hash_internal_avm(
5054
address: AztecAddress,
@@ -67,10 +71,15 @@ pub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option<Aztec
6771
Option::none()
6872
}
6973
}
70-
pub fn get_contract_instance_class_id_avm(address: AztecAddress) -> Option<ContractClassId> {
74+
/// Returns `address` current contract class, or `Option::none` if unpublished.
75+
///
76+
/// The current contract class is the one that would be used to determine the code of the contract's functions if it
77+
/// were to be executed in this transaction. This is not necessarily the contract's original class if it has been
78+
/// upgraded via the `ContractInstanceRegistry`, and it could similarly change in the future.
79+
pub fn get_contract_instance_current_class_id_avm(address: AztecAddress) -> Option<ContractClassId> {
7180
// Safety: AVM opcodes are constrained by the AVM itself
7281
let GetContractInstanceResult { exists, member } =
73-
unsafe { get_contract_instance_class_id_internal_avm(address)[0] };
82+
unsafe { get_contract_instance_current_class_id_internal_avm(address)[0] };
7483
if exists {
7584
Option::some(ContractClassId::from_field(member))
7685
} else {

noir-projects/aztec-nr/aztec/src/publish_contract_instance.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub fn publish_contract_instance_for_public_execution(context: &mut PrivateConte
3131
// immutables_hash) + 7 (public_keys) + 1 (universal_deploy) = 12.
3232
let mut serialized_args = [0; 12];
3333
serialized_args[0] = instance.salt;
34-
serialized_args[1] = instance.contract_class_id.to_field();
34+
serialized_args[1] = instance.original_contract_class_id.to_field();
3535
serialized_args[2] = instance.initialization_hash;
3636
serialized_args[3] = instance.immutables_hash;
3737

noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub contract AvmTest {
1515
use aztec::context::gas::GasOpts;
1616
use aztec::macros::{functions::{external, view}, storage::storage};
1717
use aztec::oracle::get_contract_instance::{
18-
get_contract_instance_class_id_avm, get_contract_instance_deployer_avm,
18+
get_contract_instance_current_class_id_avm, get_contract_instance_deployer_avm,
1919
get_contract_instance_immutables_hash_avm, get_contract_instance_initialization_hash_avm,
2020
};
2121
use aztec::protocol::abis::function_selector::FunctionSelector;
@@ -417,7 +417,7 @@ pub contract AvmTest {
417417
#[external("public")]
418418
fn test_get_contract_instance(address: AztecAddress) {
419419
let deployer = get_contract_instance_deployer_avm(address);
420-
let class_id = get_contract_instance_class_id_avm(address);
420+
let class_id = get_contract_instance_current_class_id_avm(address);
421421
let initialization_hash = get_contract_instance_initialization_hash_avm(address);
422422
let immutables_hash = get_contract_instance_immutables_hash_avm(address);
423423

@@ -459,7 +459,7 @@ pub contract AvmTest {
459459
expected_immutables_hash: Field,
460460
) {
461461
let deployer = get_contract_instance_deployer_avm(address);
462-
let class_id = get_contract_instance_class_id_avm(address);
462+
let class_id = get_contract_instance_current_class_id_avm(address);
463463
let initialization_hash = get_contract_instance_initialization_hash_avm(address);
464464
let immutables_hash = get_contract_instance_immutables_hash_avm(address);
465465

@@ -476,7 +476,7 @@ pub contract AvmTest {
476476

477477
// Get a Protocol Contract and it should exist
478478
aztec::oracle::logging::debug_log("Get Contract Instance Protocol Contract Instance");
479-
let fee_juice_class_id = get_contract_instance_class_id_avm(FEE_JUICE_ADDRESS);
479+
let fee_juice_class_id = get_contract_instance_current_class_id_avm(FEE_JUICE_ADDRESS);
480480
assert(fee_juice_class_id.is_some(), "Protocol Contract instance not found when getting CLASS_ID!");
481481
}
482482

noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ use crate::{
66
};
77
use std::meta::derive;
88

9+
/// The complete preimage of an [`AztecAddress`].
10+
///
11+
/// All of these values are hashed into the contract's `AztecAddress` (see [`Self::to_address`]), so they are fixed
12+
/// at deployment time and never change.
13+
///
14+
/// In particular, `original_contract_class_id` is the class the contract was *deployed* with. For upgradeable contracts
15+
/// which utilize the `ContractInstanceRegistry` this is NOT the class currently executing i.e. the 'current' class.
916
#[derive(Deserialize, Eq, Serialize)]
1017
pub struct ContractInstance {
1118
pub salt: Field,
1219
pub deployer: AztecAddress,
13-
pub contract_class_id: ContractClassId,
20+
pub original_contract_class_id: ContractClassId,
1421
pub initialization_hash: Field,
1522
pub immutables_hash: Field,
1623
pub public_keys: PublicKeys,
@@ -27,7 +34,7 @@ impl ContractInstance {
2734
AztecAddress::compute(
2835
self.public_keys,
2936
PartialAddress::compute(
30-
self.contract_class_id,
37+
self.original_contract_class_id,
3138
self.salt,
3239
self.initialization_hash,
3340
self.deployer,
@@ -52,7 +59,7 @@ mod test {
5259
let instance = ContractInstance {
5360
salt: 6,
5461
deployer: AztecAddress::from_field(12),
55-
contract_class_id: ContractClassId::from_field(13),
62+
original_contract_class_id: ContractClassId::from_field(13),
5663
initialization_hash: 156,
5764
immutables_hash: 789,
5865
public_keys: PublicKeys::default(),

yarn-project/pxe/src/contract_function_simulator/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export {
1616
BOUNDED_VEC,
1717
BUFFER,
1818
BYTE,
19+
CONTRACT_INSTANCE,
1920
DELIVERY_MODE,
2021
EPHEMERAL_ARRAY,
2122
EVENT_VALIDATION_REQUEST,

yarn-project/pxe/src/contract_function_simulator/oracle/oracle_type_mappings.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ export const CONTRACT_INSTANCE: TypeMapping<ContractInstance> = {
229229
fn: v => [
230230
v.salt,
231231
v.deployer.toField(),
232-
v.currentContractClassId,
232+
// Note that the nr side of this struct does not contain the current class, only original
233+
v.originalContractClassId,
233234
v.initializationHash,
234235
v.immutablesHash,
235236
...v.publicKeys.toFields(),

0 commit comments

Comments
 (0)