Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ This led us to rename the `unkonstrained` method on `TestEnvironment` as `utilit
+ SharedMutable::new(env.utility(), storage_slot)
```

### [AuthRegistry] function name change

As part of the broader transition from "top-level unconstrained" to "utility" name (detailed in the note above), the `unconstrained_is_consumable` function in AuthRegistry has been renamed to `utility_is_consumable`. The function's signature and behavior remain unchanged - only the name has been updated to align with the new convention. If you're currently using this function, a simple rename in your code will suffice.

## 0.83.0

### [aztec.js] AztecNode.getPrivateEvents API change
Expand Down
18 changes: 9 additions & 9 deletions docs/docs/protocol-specs/contract-deployment/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ artifact_crh(
sha256(f.unconstrained_bytecode)
)
);
let unconstrained_functions_artifact_tree_root: Field = merkleize(unconstrained_functions_artifact_leaves);
let utility_functions_artifact_tree_root: Field = merkleize(unconstrained_functions_artifact_leaves);

let artifact_hash: Field = sha256_modulo(
VERSION, // 8-bits
private_functions_artifact_tree_root, // 256-bits
unconstrained_functions_artifact_tree_root, // 256-bits
utility_functions_artifact_tree_root, // 256-bits
artifact_metadata_hash
);

Expand Down Expand Up @@ -265,7 +265,7 @@ Broadcasted function artifacts that do not match with their corresponding `artif
fn broadcast_private_function(
contract_class_id: Field,
artifact_metadata_hash: Field,
unconstrained_functions_artifact_tree_root: Field,
utility_functions_artifact_tree_root: Field,
private_function_tree_sibling_path: Field[],
private_function_tree_leaf_index: Field,
artifact_function_tree_sibling_path: Field[],
Expand All @@ -275,7 +275,7 @@ fn broadcast_private_function(
emit_public_log ClassPrivateFunctionBroadcasted(
contract_class_id,
artifact_metadata_hash,
unconstrained_functions_artifact_tree_root,
utility_functions_artifact_tree_root,
private_function_tree_sibling_path,
private_function_tree_leaf_index,
artifact_function_tree_sibling_path,
Expand All @@ -285,15 +285,15 @@ fn broadcast_private_function(
```

```rust
fn broadcast_unconstrained_function(
fn broadcast_utility_function(
contract_class_id: Field,
artifact_metadata_hash: Field,
private_functions_artifact_tree_root: Field,
artifact_function_tree_sibling_path: Field[],
artifact_function_tree_leaf_index: Field
function: { selector: Field, metadata_hash: Field, bytecode: Field[] }[],
)
emit_public_log ClassUnconstrainedFunctionBroadcasted(
emit_public_log ClassUtilityFunctionBroadcasted(
contract_class_id,
artifact_metadata_hash,
private_functions_artifact_tree_root,
Expand Down Expand Up @@ -321,7 +321,7 @@ assert computed_private_function_tree_root == contract_class.private_function_ro
// Compute artifact leaf and assert it belongs to the artifact
artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode))
computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path, artifact_function_tree_leaf_index)
computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, unconstrained_functions_artifact_tree_root, artifact_metadata_hash)
computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, utility_functions_artifact_tree_root, artifact_metadata_hash)
assert computed_artifact_hash == contract_class.artifact_hash
```

Expand All @@ -344,11 +344,11 @@ It is strongly recommended for developers registering new classes to broadcast t

### Encoding Bytecode

The `register`, `broadcast_unconstrained_function`, and `broadcast_private_function` functions all receive and emit variable-length bytecode in contract class logs. In every function, bytecode is encoded in a fixed-length array of field elements, which sets a maximum length for each:
The `register`, `broadcast_utility_function`, and `broadcast_private_function` functions all receive and emit variable-length bytecode in contract class logs. In every function, bytecode is encoded in a fixed-length array of field elements, which sets a maximum length for each:

- `MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS`: 3000 field elements, used for a contract's public bytecode in the `register` function.
- `MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS`: 3000 field elements, used for the ACIR and Brillig bytecode of a broadcasted private function in `broadcast_private_function`.
- `MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS`: 3000 field elements, used for the Brillig bytecode of a broadcasted unconstrained function in `broadcast_unconstrained_function`.
- `MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS`: 3000 field elements, used for the Brillig bytecode of a broadcasted utility function in `broadcast_utility_function`.

To encode the bytecode into a fixed-length array of Fields, the bytecode is first split into 31-byte chunks, and each chunk interpreted big-endian as a field element. The total length in bytes is then prepended as an initial element, and then right-padded with zeroes.

Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ library Constants {
uint256 internal constant PUBLIC_DISPATCH_SELECTOR = 3578010381;
uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 3000;
uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000;
uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 3000;
uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS = 3000;
uint256 internal constant REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 19;
uint256 internal constant REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 12;
uint256 internal constant REGISTERER_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 12;
uint256 internal constant REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE =
11121068431693264234253912047066709627593769337094408533543930778360;
uint256 internal constant REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE =
2889881020989534926461066592611988634597302675057895885580456197069;
uint256 internal constant REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE =
uint256 internal constant REGISTERER_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE =
24399338136397901754495080759185489776044879232766421623673792970137;
uint256 internal constant DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE =
14061769416655647708490531650437236735160113654556896985372298487345;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @title AuthRegistry Contract
* @notice Manages authorization of public actions through authentication witnesses (authwits)
* @dev This contract allows users to approve/reject public actions that can be performed on their behalf by other
* addresses
*/
use dep::aztec::macros::aztec;

#[aztec]
Expand All @@ -13,8 +19,10 @@ pub contract AuthRegistry {

#[storage]
struct Storage<Context> {
/// Map of addresses that have rejected all actions
reject_all: Map<AztecAddress, PublicMutable<bool, Context>, Context>,
// on_behalf_of => authwit hash => authorized
/// Nested map of approvers to their authorized message hashes
/// First key is the approver address, second key is the message hash, value is authorization status
approved_actions: Map<AztecAddress, Map<Field, PublicMutable<bool, Context>, Context>, Context>,
}

Expand Down Expand Up @@ -128,8 +136,11 @@ pub contract AuthRegistry {
storage.approved_actions.at(on_behalf_of).at(message_hash).read()
}

/**
* Just like `is_consumable`, but a utility function and not public.
*/
#[utility]
unconstrained fn unconstrained_is_consumable(
unconstrained fn utility_is_consumable(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change given this is a canonical contract

on_behalf_of: AztecAddress,
message_hash: Field,
) -> bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mod class_registered;
mod private_function_broadcasted;
mod unconstrained_function_broadcasted;
mod utility_function_broadcasted;
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct PrivateFunction {
pub struct ClassPrivateFunctionBroadcasted {
contract_class_id: ContractClassId,
artifact_metadata_hash: Field,
unconstrained_functions_artifact_tree_root: Field,
utility_functions_artifact_tree_root: Field,
private_function_tree_sibling_path: [Field; FUNCTION_TREE_HEIGHT],
private_function_tree_leaf_index: Field,
artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT],
Expand All @@ -51,7 +51,7 @@ impl ClassPrivateFunctionBroadcasted {
packed[0] = REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE;
packed[1] = self.contract_class_id.to_field();
packed[2] = self.artifact_metadata_hash;
packed[3] = self.unconstrained_functions_artifact_tree_root;
packed[3] = self.utility_functions_artifact_tree_root;
for i in 0..FUNCTION_TREE_HEIGHT {
packed[i + 4] = self.private_function_tree_sibling_path[i];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use dep::aztec::prelude::FunctionSelector;
use dep::aztec::protocol_types::{
constants::{
ARTIFACT_FUNCTION_TREE_MAX_HEIGHT,
MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS,
REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS,
REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE,
ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS,
REGISTERER_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS,
REGISTERER_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE,
},
contract_class_id::ContractClassId,
traits::Serialize,
Expand All @@ -13,38 +12,38 @@ use dep::aztec::protocol_types::traits::ToField;
use std::meta::derive;

#[derive(Serialize)]
pub struct InnerUnconstrainedFunction {
pub struct InnerUtilityFunction {
selector: FunctionSelector,
metadata_hash: Field,
}

#[derive(Serialize)]
pub struct UnconstrainedFunction {
pub struct UtilityFunction {
selector: FunctionSelector,
metadata_hash: Field,
bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS],
bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS],
}

// #[event]
pub struct ClassUnconstrainedFunctionBroadcasted {
pub struct ClassUtilityFunctionBroadcasted {
contract_class_id: ContractClassId,
artifact_metadata_hash: Field,
private_functions_artifact_tree_root: Field,
artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT],
artifact_function_tree_leaf_index: Field,
function: UnconstrainedFunction,
function: UtilityFunction,
}

impl ClassUnconstrainedFunctionBroadcasted {
impl ClassUtilityFunctionBroadcasted {
fn serialize_non_standard(
self: Self,
) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] {
) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS + REGISTERER_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] {
let mut packed = [
0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS
+ REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS
0; MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS
+ REGISTERER_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS
];
// Since we are not yet emitting selectors we'll use this magic value to identify events emitted by the ClassRegisterer.
packed[0] = REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE;
packed[0] = REGISTERER_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE;
packed[1] = self.contract_class_id.to_field();
packed[2] = self.artifact_metadata_hash;
packed[3] = self.private_functions_artifact_tree_root;
Expand All @@ -53,7 +52,7 @@ impl ClassUnconstrainedFunctionBroadcasted {
}
packed[4 + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT] = self.artifact_function_tree_leaf_index;
let packed_function = self.function.serialize();
for i in 0..MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 2 {
for i in 0..MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS + 2 {
packed[i + 5 + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT] = packed_function[i];
}
packed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub contract ContractClassRegisterer {
constants::{
ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS,
FUNCTION_TREE_HEIGHT, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS,
MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS,
MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT,
},
contract_class_id::ContractClassId,
Expand All @@ -27,9 +27,8 @@ pub contract ContractClassRegisterer {
private_function_broadcasted::{
ClassPrivateFunctionBroadcasted, InnerPrivateFunction, PrivateFunction,
},
unconstrained_function_broadcasted::{
ClassUnconstrainedFunctionBroadcasted, InnerUnconstrainedFunction,
UnconstrainedFunction,
utility_function_broadcasted::{
ClassUtilityFunctionBroadcasted, InnerUtilityFunction, UtilityFunction,
},
};

Expand Down Expand Up @@ -119,7 +118,7 @@ pub contract ContractClassRegisterer {
fn broadcast_private_function(
contract_class_id: ContractClassId,
artifact_metadata_hash: Field,
unconstrained_functions_artifact_tree_root: Field,
utility_functions_artifact_tree_root: Field,
private_function_tree_sibling_path: [Field; FUNCTION_TREE_HEIGHT],
private_function_tree_leaf_index: Field,
artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT],
Expand All @@ -137,7 +136,7 @@ pub contract ContractClassRegisterer {
let event = ClassPrivateFunctionBroadcasted {
contract_class_id,
artifact_metadata_hash,
unconstrained_functions_artifact_tree_root,
utility_functions_artifact_tree_root,
private_function_tree_sibling_path,
private_function_tree_leaf_index,
artifact_function_tree_sibling_path,
Expand All @@ -154,7 +153,7 @@ pub contract ContractClassRegisterer {
[
contract_class_id.to_field(),
artifact_metadata_hash,
unconstrained_functions_artifact_tree_root,
utility_functions_artifact_tree_root,
function_data.selector.to_field(),
function_data.vk_hash,
function_data.metadata_hash,
Expand All @@ -164,35 +163,35 @@ pub contract ContractClassRegisterer {
}

#[private]
fn broadcast_unconstrained_function(
fn broadcast_utility_function(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a breaking change (though likely would not affect externals)

contract_class_id: ContractClassId,
artifact_metadata_hash: Field,
private_functions_artifact_tree_root: Field,
artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT],
artifact_function_tree_leaf_index: Field,
function_data: InnerUnconstrainedFunction,
function_data: InnerUtilityFunction,
) {
let unconstrained_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS] = unsafe {
let utility_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS] = unsafe {
capsules::load(
context.this_address(),
REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT,
)
.unwrap()
};
let event = ClassUnconstrainedFunctionBroadcasted {
let event = ClassUtilityFunctionBroadcasted {
contract_class_id,
artifact_metadata_hash,
private_functions_artifact_tree_root,
artifact_function_tree_sibling_path,
artifact_function_tree_leaf_index,
function: UnconstrainedFunction {
function: UtilityFunction {
selector: function_data.selector,
metadata_hash: function_data.metadata_hash,
bytecode: unconstrained_bytecode,
bytecode: utility_bytecode,
},
};
dep::aztec::oracle::debug_log::debug_log_format(
"ClassUnconstrainedFunctionBroadcasted: {}",
"ClassUtilityFunctionBroadcasted: {}",
[
contract_class_id.to_field(),
artifact_metadata_hash,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ pub global MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: u32 = 3000;
// Bytecode size for private functions is per function, not for the entire contract.
// Note that private functions bytecode includes a mix of acir and brillig.
pub global MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS: u32 = 3000;
// Same for unconstrained functions: the size is per function.
pub global MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS: u32 = 3000;
// Same for utility functions: the size is per function.
pub global MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS: u32 = 3000;
// How many fields are on the serialized ClassPrivateFunctionBroadcasted event in addition to MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS.
pub global REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 = 19;
// How many fields are on the serialized ClassUnconstrainedFunctionBroadcasted event in addition to MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS.
pub global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 = 12;
// How many fields are on the serialized ClassUtilityFunctionBroadcasted event in addition to MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS.
pub global REGISTERER_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 = 12;
// Since we are not yet emitting selectors we'll use this magic value to identify events emitted by the ClassRegisterer.
// This is just a stopgap until we implement proper selectors.
// sha224sum 'struct ContractClassRegistered {contract_class_id: ContractClassId, version: Field, artifact_hash: Field, private_functions_root: Field, packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS] }'
Expand All @@ -160,8 +160,8 @@ pub global REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE: Field =
// sha224sum 'struct ClassPrivateFunctionBroadcasted'
pub global REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE: Field =
0x1b70e95fde0b70adc30496b90a327af6a5e383e028e7a43211a07bcd;
// sha224sum 'struct ClassUnconstrainedFunctionBroadcasted'
pub global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE: Field =
// sha224sum 'struct ClassUtilityFunctionBroadcasted'
pub global REGISTERER_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE: Field =
0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99;

// CONTRACT INSTANCE CONSTANTS
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/deployment/broadcast_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export async function broadcastUtilityFunction(
MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
);
return registerer.methods
.broadcast_unconstrained_function(
.broadcast_utility_function(
contractClass.id,
artifactMetadataHash,
privateFunctionsArtifactTreeRoot,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/wallet/account_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export class AccountWallet extends BaseWallet {

private getIsConsumableAbi(): FunctionAbi {
return {
name: 'unconstrained_is_consumable',
name: 'utility_is_consumable',
isInitializer: false,
functionType: FunctionType.UTILITY,
isInternal: false,
Expand Down
Loading