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 @@ -8,6 +8,10 @@ Aztec is in full-speed development. Literally every version breaks compatibility

## TBD

## [aztec.js] AztecNode.getPublicDataTreeWitness renamed as AztecNode.getPublicDataWitness

This change was done to have consistent naming across codebase.

## [aztec.js] Wallet interface and Authwit management

The `Wallet` interface in `aztec.js` is undergoing transformations, trying to be friendlier to wallet builders and reducing the surface of its API. This means `Wallet` no longer extends `PXE`, and instead just implements a subset of the methods of the former. This is NOT going to be its final form, but paves the way towards better interfaces and starts to clarify what the responsibilities of the wallet are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,11 @@ mod test {
test::helpers::test_environment::TestEnvironment,
};
use super::{decrypt_log, encrypt_log, PRIVATE_LOG_PLAINTEXT_SIZE_IN_FIELDS};
use protocol_types::{address::AztecAddress, traits::{FromField, Serialize}};
use protocol_types::{address::AztecAddress, traits::FromField};
use std::{embedded_curve_ops::EmbeddedCurveScalar, test::OracleMock};

#[test]
unconstrained fn test_encrypt_decrypt_log() {
unconstrained fn encrypt_decrypt_log() {
let mut env = TestEnvironment::new();
// Advance 1 block so we can read historic state from private
env.advance_block_by(1);
Expand Down Expand Up @@ -344,7 +344,7 @@ mod test {
EmbeddedCurveScalar::from_field(eph_sk),
recipient,
);
let _ = OracleMock::mock("getSharedSecret").returns(shared_secret.serialize());
let _ = OracleMock::mock("getSharedSecret").returns(shared_secret);

// Decrypt the log
let decrypted = decrypt_log(encrypted_log, recipient);
Expand Down
12 changes: 4 additions & 8 deletions noir-projects/aztec-nr/aztec/src/oracle/block_header.nr
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
use dep::protocol_types::{
block_header::BlockHeader,
constants::BLOCK_HEADER_LENGTH,
traits::{Deserialize, Hash},
use protocol_types::{
block_header::BlockHeader, merkle_tree::root::root_from_sibling_path, traits::Hash,
};
use dep::protocol_types::merkle_tree::root::root_from_sibling_path;

use crate::{
context::PrivateContext, oracle::get_membership_witness::get_archive_membership_witness,
};

#[oracle(getBlockHeader)]
unconstrained fn get_block_header_at_oracle(_block_number: u32) -> [Field; BLOCK_HEADER_LENGTH] {}
unconstrained fn get_block_header_at_oracle(_block_number: u32) -> BlockHeader {}

unconstrained fn get_block_header_at_internal(block_number: u32) -> BlockHeader {
let header = get_block_header_at_oracle(block_number);
BlockHeader::deserialize(header)
get_block_header_at_oracle(block_number)
}

pub fn get_block_header_at(block_number: u32, context: PrivateContext) -> BlockHeader {
Expand Down
20 changes: 6 additions & 14 deletions noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
use dep::protocol_types::{
address::AztecAddress,
constants::CONTRACT_INSTANCE_LENGTH,
contract_class_id::ContractClassId,
contract_instance::ContractInstance,
traits::{Deserialize, FromField},
use protocol_types::{
address::AztecAddress, contract_class_id::ContractClassId, contract_instance::ContractInstance,
traits::FromField,
};

// NOTE: this is for use in private only
#[oracle(getContractInstance)]
unconstrained fn get_contract_instance_oracle(
_address: AztecAddress,
) -> [Field; CONTRACT_INSTANCE_LENGTH] {}
unconstrained fn get_contract_instance_oracle(_address: AztecAddress) -> ContractInstance {}

// NOTE: this is for use in private only
unconstrained fn get_contract_instance_internal(
address: AztecAddress,
) -> [Field; CONTRACT_INSTANCE_LENGTH] {
unconstrained fn get_contract_instance_internal(address: AztecAddress) -> ContractInstance {
get_contract_instance_oracle(address)
}

// NOTE: this is for use in private only
pub fn get_contract_instance(address: AztecAddress) -> ContractInstance {
// Safety: The to_address function combines all values in the instance object to produce an address,
// so by checking that we get the expected address we validate the entire struct.
let instance =
unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };
let instance = unsafe { get_contract_instance_internal(address) };
assert_eq(instance.to_address(), address);

instance
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::utils::array;
use dep::protocol_types::{address::AztecAddress, constants::L1_TO_L2_MSG_TREE_HEIGHT};

/// Returns the leaf index and sibling path of an entry in the L1 to L2 messaging tree, which can then be used to prove
Expand All @@ -8,12 +7,7 @@ pub unconstrained fn get_l1_to_l2_membership_witness(
message_hash: Field,
secret: Field,
) -> (Field, [Field; L1_TO_L2_MSG_TREE_HEIGHT]) {
let returned_message =
get_l1_to_l2_membership_witness_oracle(contract_address, message_hash, secret);
let leaf_index = returned_message[0];
let sibling_path = array::subarray(returned_message, 1);

(leaf_index, sibling_path)
get_l1_to_l2_membership_witness_oracle(contract_address, message_hash, secret)
}

// Obtains membership witness (index and sibling path) for a message in the L1 to L2 message tree.
Expand All @@ -22,4 +16,4 @@ unconstrained fn get_l1_to_l2_membership_witness_oracle(
_contract_address: AztecAddress,
_message_hash: Field,
_secret: Field,
) -> [Field; L1_TO_L2_MSG_TREE_HEIGHT + 1] {}
) -> (Field, [Field; L1_TO_L2_MSG_TREE_HEIGHT]) {}
16 changes: 3 additions & 13 deletions noir-projects/aztec-nr/aztec/src/oracle/get_membership_witness.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::utils::array;
use dep::protocol_types::constants::{ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT};
use protocol_types::constants::{ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT};

global NOTE_HASH_TREE_ID: Field = 1;
global ARCHIVE_TREE_ID: Field = 4;
Expand All @@ -17,20 +16,11 @@ pub struct MembershipWitness<let N: u32, let M: u32> {
}

#[oracle(getMembershipWitness)]
unconstrained fn get_membership_witness_oracle<let M: u32>(
unconstrained fn get_membership_witness<let N: u32, let M: u32>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this oracle function not have the _oracle suffix in the name as the others that have the #[oracle] tag have ? i.e. why is this one okay to directly return where the others have wrappers ?

_block_number: u32,
_tree_id: Field,
_leaf_value: Field,
) -> [Field; M] {}

pub unconstrained fn get_membership_witness<let N: u32, let M: u32>(
block_number: u32,
tree_id: Field,
leaf_value: Field,
) -> MembershipWitness<N, M> {
let fields: [Field; M] = get_membership_witness_oracle(block_number, tree_id, leaf_value);
MembershipWitness { index: fields[0], path: array::subarray(fields, 1) }
}
) -> MembershipWitness<N, M> {}

// Note: get_nullifier_membership_witness function is implemented in get_nullifier_membership_witness.nr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,28 @@ impl NullifierMembershipWitness {
unconstrained fn get_low_nullifier_membership_witness_oracle(
_block_number: u32,
_nullifier: Field,
) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {}
) -> NullifierMembershipWitness {}

// Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower
// nullifier's next_value is bigger than the nullifier)
pub unconstrained fn get_low_nullifier_membership_witness(
block_number: u32,
nullifier: Field,
) -> NullifierMembershipWitness {
let fields = get_low_nullifier_membership_witness_oracle(block_number, nullifier);
NullifierMembershipWitness::deserialize(fields)
get_low_nullifier_membership_witness_oracle(block_number, nullifier)
}

#[oracle(getNullifierMembershipWitness)]
unconstrained fn get_nullifier_membership_witness_oracle(
_block_number: u32,
_nullifier: Field,
) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {}
) -> NullifierMembershipWitness {}

// Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower
// nullifier's next_value is bigger than the nullifier)
pub unconstrained fn get_nullifier_membership_witness(
block_number: u32,
nullifier: Field,
) -> NullifierMembershipWitness {
let fields = get_nullifier_membership_witness_oracle(block_number, nullifier);
NullifierMembershipWitness::deserialize(fields)
get_nullifier_membership_witness_oracle(block_number, nullifier)
}
20 changes: 3 additions & 17 deletions noir-projects/aztec-nr/aztec/src/oracle/get_public_data_witness.nr
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
use crate::utils::array;
use dep::protocol_types::{constants::PUBLIC_DATA_TREE_HEIGHT, data::PublicDataTreeLeafPreimage};

global LEAF_PREIMAGE_LENGTH: u32 = 4;
global PUBLIC_DATA_WITNESS: u32 = 45;

pub struct PublicDataWitness {
pub index: Field,
pub leaf_preimage: PublicDataTreeLeafPreimage,
pub path: [Field; PUBLIC_DATA_TREE_HEIGHT],
}

#[oracle(getPublicDataTreeWitness)]
#[oracle(getPublicDataWitness)]
unconstrained fn get_public_data_witness_oracle(
_block_number: u32,
_public_data_tree_index: Field,
) -> [Field; PUBLIC_DATA_WITNESS] {}
) -> PublicDataWitness {}

pub unconstrained fn get_public_data_witness(
block_number: u32,
public_data_tree_index: Field,
) -> PublicDataWitness {
let fields = get_public_data_witness_oracle(block_number, public_data_tree_index);
PublicDataWitness {
index: fields[0],
leaf_preimage: PublicDataTreeLeafPreimage {
slot: fields[1],
value: fields[2],
next_index: fields[3] as u32,
next_slot: fields[4],
},
path: array::subarray(fields, 1 + LEAF_PREIMAGE_LENGTH),
}
get_public_data_witness_oracle(block_number, public_data_tree_index)
}
19 changes: 3 additions & 16 deletions noir-projects/aztec-nr/aztec/src/oracle/key_validation_request.nr
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
use dep::protocol_types::{
abis::validation_requests::{
key_validation_request::KEY_VALIDATION_REQUEST_LENGTH, KeyValidationRequest,
},
traits::Deserialize,
};
use protocol_types::abis::validation_requests::KeyValidationRequest;

#[oracle(getKeyValidationRequest)]
unconstrained fn get_key_validation_request_oracle(
_pk_m_hash: Field,
_key_index: Field,
) -> [Field; KEY_VALIDATION_REQUEST_LENGTH] {}

unconstrained fn get_key_validation_request_internal(
npk_m_hash: Field,
key_index: Field,
) -> KeyValidationRequest {
let result = get_key_validation_request_oracle(npk_m_hash, key_index);
KeyValidationRequest::deserialize(result)
}
) -> KeyValidationRequest {}

pub unconstrained fn get_key_validation_request(
pk_m_hash: Field,
key_index: Field,
) -> KeyValidationRequest {
get_key_validation_request_internal(pk_m_hash, key_index)
get_key_validation_request_oracle(pk_m_hash, key_index)
}
20 changes: 8 additions & 12 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ unconstrained fn notify_created_note_oracle_wrapper<let N: u32>(
note_hash: Field,
counter: u32,
) {
let _ = notify_created_note_oracle(storage_slot, note_type_id, packed_note, note_hash, counter);
notify_created_note_oracle(storage_slot, note_type_id, packed_note, note_hash, counter);
}

#[oracle(notifyCreatedNote)]
Expand All @@ -64,29 +64,25 @@ unconstrained fn notify_created_note_oracle<let N: u32>(
_packed_note: [Field; N],
_note_hash: Field,
_counter: u32,
) -> Field {}
) {}

unconstrained fn notify_nullified_note_oracle_wrapper(
nullifier: Field,
note_hash: Field,
counter: u32,
) {
let _ = notify_nullified_note_oracle(nullifier, note_hash, counter);
notify_nullified_note_oracle(nullifier, note_hash, counter);
}

#[oracle(notifyNullifiedNote)]
unconstrained fn notify_nullified_note_oracle(
_nullifier: Field,
_note_hash: Field,
_counter: u32,
) -> Field {}
unconstrained fn notify_nullified_note_oracle(_nullifier: Field, _note_hash: Field, _counter: u32) {}

unconstrained fn notify_created_nullifier_oracle_wrapper(nullifier: Field) {
let _ = notify_created_nullifier_oracle(nullifier);
notify_created_nullifier_oracle(nullifier);
}

#[oracle(notifyCreatedNullifier)]
unconstrained fn notify_created_nullifier_oracle(_nullifier: Field) -> Field {}
unconstrained fn notify_created_nullifier_oracle(_nullifier: Field) {}

#[oracle(getNotes)]
unconstrained fn get_notes_oracle<let N: u32, let ORACLE_RETURN_FIELD_LENGTH: u32>(
Expand Down Expand Up @@ -213,11 +209,11 @@ where
/// current transaction is included in a block. While this might seem of little use at first, certain design patterns
/// benefit from this abstraction (see e.g. `PrivateMutable`).
pub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {
check_nullifier_exists_oracle(inner_nullifier) == 1
check_nullifier_exists_oracle(inner_nullifier)
}

#[oracle(checkNullifierExists)]
unconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}
unconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> bool {}

/// Same as `get_indexed_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.
pub unconstrained fn get_app_tag_as_sender(sender: AztecAddress, recipient: AztecAddress) -> Field {
Expand Down
14 changes: 3 additions & 11 deletions noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
use dep::protocol_types::{
address::aztec_address::AztecAddress,
point::{Point, POINT_LENGTH},
traits::Deserialize,
};
use protocol_types::{address::aztec_address::AztecAddress, point::Point};

// TODO(#12656): return an app-siloed secret + document this
#[oracle(getSharedSecret)]
unconstrained fn get_shared_secret_oracle(
address: AztecAddress,
ephPk: Point,
) -> [Field; POINT_LENGTH] {}
unconstrained fn get_shared_secret_oracle(address: AztecAddress, ephPk: Point) -> Point {}

/// Returns an app-siloed shared secret between `address` and someone who knows the secret key behind an
/// ephemeral public key `ephPk`. The app-siloing means that contracts cannot retrieve secrets that belong to
Expand All @@ -21,6 +14,5 @@ unconstrained fn get_shared_secret_oracle(
/// where `ivsk + h` is the 'preaddress' i.e. the preimage of the address, also called the address secret.
/// TODO(#12656): app-silo this secret
pub unconstrained fn get_shared_secret(address: AztecAddress, ephPk: Point) -> Point {
let fields = get_shared_secret_oracle(address, ephPk);
Point::deserialize(fields)
get_shared_secret_oracle(address, ephPk)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ unconstrained fn in_private(
) -> PrivateMutable<MockNote, &mut PrivateContext> {
let state_var = PrivateMutable::new(&mut env.private(), storage_slot);

// This oracle is called for its side effects alone - it's always expected to return 0.
let _ = OracleMock::mock("notifyCreatedNote").returns(0);
// This oracle is called for its side effects alone - it does not return anything.
let _ = OracleMock::mock("notifyCreatedNote").returns(());

state_var
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
}

async getPublicDataTreeWitness(blockNumber: L2BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
async getPublicDataWitness(blockNumber: L2BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
Copy link
Contributor Author

@benesjan benesjan Mar 19, 2025

Choose a reason for hiding this comment

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

This inconsistency was triggering me. Unfortunately this is on the public API.

If we would want to not have this change while keeping consistency we would have to rename PublicDataWitness to PublicDataTreeWitness which would result in a monster diff.

const committedDb = await this.#getWorldState(blockNumber);
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
if (!lowLeafResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@ import type { ForeignCallInput, ForeignCallOutput } from '@aztec/noir-acvm_js';

import { strict as assert } from 'assert';

function fromACVMField(field: string): Fr {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was a copy of Fr.fromString

return Fr.fromBuffer(Buffer.from(field.slice(2), 'hex'));
}

export function foreignCallHandler(name: string, args: ForeignCallInput[]): Promise<ForeignCallOutput[]> {
// ForeignCallInput is actually a string[], so the args are string[][].
const log = createLogger('noir-protocol-circuits:oracle');

if (name === 'debugLog') {
assert(args.length === 3, 'expected 3 arguments for debugLog: msg, fields_length, fields');
const [msgRaw, _ignoredFieldsSize, fields] = args;
const msg: string = msgRaw.map(acvmField => String.fromCharCode(fromACVMField(acvmField).toNumber())).join('');
const fieldsFr: Fr[] = fields.map((field: string) => fromACVMField(field));
const msg: string = msgRaw.map(acvmField => String.fromCharCode(Fr.fromString(acvmField).toNumber())).join('');
const fieldsFr: Fr[] = fields.map((field: string) => Fr.fromString(field));
log.verbose('debug_log ' + applyStringFormatting(msg, fieldsFr));
} else if (name === 'noOp') {
// Workaround for compiler issues where data is deleted because it's "unused"
Expand Down
Loading