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
2 changes: 1 addition & 1 deletion barretenberg/ts/src/types/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Fr {
const valueBigInt = typeof value === 'bigint' ? value : toBigIntBE(value);

if (valueBigInt > Fr.MAX_VALUE) {
throw new Error(`Fr out of range: ${valueBigInt}`);
throw new Error(`Value 0x${valueBigInt.toString(16)} is greater or equal to field modulus.`);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unified the message here with Fr from foundation package since I am checking the messages in tagged_log.ts. Would probably be good to tackle this one

}

this.value = typeof value === 'bigint' ? toBufferBE(value) : value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ mod test {
impl NoteInterface<ADDRESS_NOTE_LEN, ADDRESS_NOTE_BYTES_LEN> for AddressNote {
fn compute_note_content_hash(self) -> Field {1}

fn get_note_type_id() -> Field {1}
fn get_note_type_id() -> Field {
1
}

fn get_header(self) -> NoteHeader { self.header}

Expand Down
1 change: 1 addition & 0 deletions noir/noir-repo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion noir/noir-repo/aztec_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ noirc_errors.workspace = true
iter-extended.workspace = true
convert_case = "0.6.0"
regex = "1.10"

tiny-keccak = { version = "2.0.0", features = ["keccak"] }
Copy link
Contributor

Choose a reason for hiding this comment

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

👀

86 changes: 56 additions & 30 deletions noir/noir-repo/aztec_macros/src/transforms/note_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use noirc_frontend::{
Type,
};

use acvm::AcirField;
use regex::Regex;
// TODO(#7165): nuke the following dependency from here and Cargo.toml
use tiny_keccak::{Hasher, Keccak};

use crate::{
chained_dep,
Expand Down Expand Up @@ -97,7 +100,6 @@ pub fn generate_note_interface_impl(module: &mut SortedModule) -> Result<(), Azt
.collect::<Result<Vec<_>, _>>()?;
let [note_serialized_len, note_bytes_len]: [_; 2] =
note_interface_generics.try_into().unwrap();
let note_type_id = note_type_id(&note_type);

// Automatically inject the header field if it's not present
let (header_field_name, _) = if let Some(existing_header) =
Expand Down Expand Up @@ -184,8 +186,9 @@ pub fn generate_note_interface_impl(module: &mut SortedModule) -> Result<(), Azt
}

if !check_trait_method_implemented(trait_impl, "get_note_type_id") {
let note_type_id = compute_note_type_id(&note_type);
let get_note_type_id_fn =
generate_note_get_type_id(&note_type_id, note_interface_impl_span)?;
generate_get_note_type_id(note_type_id, note_interface_impl_span)?;
trait_impl.items.push(TraitImplItem::Function(get_note_type_id_fn));
}

Expand Down Expand Up @@ -324,16 +327,17 @@ fn generate_note_set_header(

// Automatically generate the note type id getter method. The id itself its calculated as the concatenation
// of the conversion of the characters in the note's struct name to unsigned integers.
fn generate_note_get_type_id(
note_type_id: &str,
fn generate_get_note_type_id(
note_type_id: u32,
impl_span: Option<Span>,
) -> Result<NoirFunction, AztecMacroError> {
// TODO(#7165): replace {} with dep::aztec::protocol_types::abis::note_selector::compute_note_selector(\"{}\") in the function source below
let function_source = format!(
"
fn get_note_type_id() -> Field {{
{}
}}
",
fn get_note_type_id() -> Field {{
{}
}}
",
note_type_id
)
.to_string();
Expand Down Expand Up @@ -387,7 +391,7 @@ fn generate_note_properties_struct(

// Generate the deserialize_content method as
//
// fn deserialize_content(serialized_note: [Field; NOTE_SERILIZED_LEN]) -> Self {
// fn deserialize_content(serialized_note: [Field; NOTE_SERIALIZED_LEN]) -> Self {
// NoteType {
// note_field1: serialized_note[0] as Field,
// note_field2: NoteFieldType2::from_field(serialized_note[1])...
Expand Down Expand Up @@ -525,10 +529,10 @@ fn generate_note_exports_global(
let struct_source = format!(
"
#[abi(notes)]
global {0}_EXPORTS: (Field, str<{1}>) = ({2},\"{0}\");
global {0}_EXPORTS: (Field, str<{1}>) = (0x{2},\"{0}\");
",
note_type,
note_type_id.len(),
note_type.len(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to do this change as note_type_id no longer has the same length as note type.

note_type_id
)
.to_string();
Expand Down Expand Up @@ -685,10 +689,18 @@ fn generate_note_deserialize_content_source(
.to_string()
}

// TODO(#7165): nuke this function
// Utility function to generate the note type id as a Field
fn note_type_id(note_type: &str) -> String {
fn compute_note_type_id(note_type: &str) -> u32 {
// TODO(#4519) Improve automatic note id generation and assignment
note_type.chars().map(|c| (c as u32).to_string()).collect::<Vec<String>>().join("")
let mut keccak = Keccak::v256();
let mut result = [0u8; 32];
keccak.update(note_type.as_bytes());
keccak.finalize(&mut result);
// Take the first 4 bytes of the hash and convert them to an integer
// If you change the following value you have to change NUM_BYTES_PER_NOTE_TYPE_ID in l1_note_payload.ts as well
let num_bytes_per_note_type_id = 4;
u32::from_be_bytes(result[0..num_bytes_per_note_type_id].try_into().unwrap())
}

pub fn inject_note_exports(
Expand Down Expand Up @@ -717,47 +729,61 @@ pub fn inject_note_exports(
},
file_id,
))?;
let init_function =
let get_note_type_id_function =
context.def_interner.function(&func_id).block(&context.def_interner);
let init_function_statement_id = init_function.statements().first().ok_or((
AztecMacroError::CouldNotExportStorageLayout {
span: None,
secondary_message: Some(format!(
"Could not retrieve note id statement from function for note {}",
note.borrow().name.0.contents
)),
},
file_id,
))?;
let note_id_statement = context.def_interner.statement(init_function_statement_id);
let get_note_type_id_statement_id =
get_note_type_id_function.statements().first().ok_or((
AztecMacroError::CouldNotExportStorageLayout {
span: None,
secondary_message: Some(format!(
"Could not retrieve note id statement from function for note {}",
note.borrow().name.0.contents
)),
},
file_id,
))?;
let note_type_id_statement =
context.def_interner.statement(get_note_type_id_statement_id);

let note_id_value = match note_id_statement {
let note_type_id = match note_type_id_statement {
HirStatement::Expression(expression_id) => {
match context.def_interner.expression(&expression_id) {
HirExpression::Literal(HirLiteral::Integer(value, _)) => Ok(value),
HirExpression::Literal(_) => Err((
AztecMacroError::CouldNotExportStorageLayout {
span: None,
secondary_message: Some(
"note_type_id statement must be a literal integer expression"
.to_string(),
),
},
file_id,
)),
_ => Err((
AztecMacroError::CouldNotExportStorageLayout {
span: None,
secondary_message: Some(
"note_id statement must be a literal expression".to_string(),
"note_type_id statement must be a literal expression"
.to_string(),
),
},
file_id,
)),
}
}
_ => Err((
AztecMacroError::CouldNotAssignStorageSlots {
AztecMacroError::CouldNotExportStorageLayout {
span: None,
secondary_message: Some(
"note_id statement must be an expression".to_string(),
"note_type_id statement must be an expression".to_string(),
),
},
file_id,
)),
}?;
let global = generate_note_exports_global(
&note.borrow().name.0.contents,
&note_id_value.to_string(),
&note_type_id.to_hex(),
)
.map_err(|err| (err, file_id))?;

Expand Down
5 changes: 2 additions & 3 deletions noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::BTreeMap;

use acvm::acir::circuit::ErrorSelector;
use acvm::AcirField;
use iter_extended::vecmap;
use noirc_abi::{Abi, AbiErrorType, AbiParameter, AbiReturnType, AbiType, AbiValue};
use noirc_frontend::ast::Visibility;
Expand Down Expand Up @@ -107,9 +108,7 @@ pub(super) fn value_from_hir_expression(context: &Context, expression: HirExpres
},
HirLiteral::Bool(value) => AbiValue::Boolean { value },
HirLiteral::Str(value) => AbiValue::String { value },
HirLiteral::Integer(field, sign) => {
AbiValue::Integer { value: field.to_string(), sign }
}
HirLiteral::Integer(field, sign) => AbiValue::Integer { value: field.to_hex(), sign },
Copy link
Contributor Author

@benesjan benesjan Jun 18, 2024

Choose a reason for hiding this comment

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

_ => unreachable!("Literal cannot be used in the abi"),
},
_ => unreachable!("Type cannot be used in the abi {:?}", expression),
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export {
waitForAccountSynch,
waitForPXE,
} from './utils/index.js';
export { NoteSelector } from '@aztec/foundation/abi';

export { createPXEClient } from './rpc_clients/index.js';

Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/rpc_clients/pxe_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
GrumpkinScalar,
Point,
} from '@aztec/circuits.js';
import { NoteSelector } from '@aztec/foundation/abi';
import { createJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client';

/**
Expand Down Expand Up @@ -53,6 +54,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false)
Point,
TxExecutionRequest,
TxHash,
NoteSelector,
},
{ Tx, SimulatedTx, TxReceipt, EncryptedNoteL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
false,
Expand Down
12 changes: 4 additions & 8 deletions yarn-project/builder/src/contract-interface-gen/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ function generateNotesGetter(input: ContractArtifact) {
.map(
([name, { id }]) =>
`${name}: {
id: new Fr(${id.toBigInt()}n),
id: new NoteSelector(${id.value}),
}`,
)
.join(',\n');
Expand Down Expand Up @@ -281,11 +281,7 @@ function generateEvents(events: any[] | undefined) {
if (payload === undefined) {
return undefined;
}
if (
!eventSelector.equals(
EventSelector.fromField(payload.eventTypeId),
)
) {
if (!eventSelector.equals(payload.eventTypeId)) {
return undefined;
}
if (payload.event.items.length !== fieldsLength) {
Expand Down Expand Up @@ -349,14 +345,14 @@ import {
DeployMethod,
EthAddress,
EthAddressLike,
EventSelector,
FieldLike,
Fr,
EventSelector,
FunctionSelector,
FunctionSelectorLike,
L1EventPayload,
loadContractArtifact,
NoirCompiledContract,
NoteSelector,
Point,
PublicKey,
Wallet,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Fr, GrumpkinScalar } from '@aztec/circuits.js';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { NoteSelector } from '@aztec/foundation/abi';
import { updateInlineTestData } from '@aztec/foundation/testing';

import { Note } from '../payload.js';
Expand All @@ -20,10 +21,10 @@ describe('encrypt log incoming body', () => {
const viewingPubKey = grumpkin.mul(Grumpkin.generator, viewingSecretKey);

const note = Note.random();
const noteTypeId = Fr.random();
const storageSlot = Fr.random();
const noteTypeId = NoteSelector.random();

const body = new EncryptedNoteLogIncomingBody(noteTypeId, storageSlot, note);
const body = new EncryptedNoteLogIncomingBody(storageSlot, noteTypeId, note);

const encrypted = body.computeCiphertext(ephSecretKey, viewingPubKey);

Expand All @@ -44,7 +45,7 @@ describe('encrypt log incoming body', () => {
const viewingPubKey = grumpkin.mul(Grumpkin.generator, viewingSecretKey);

const note = new Note([new Fr(1), new Fr(2), new Fr(3)]);
const noteTypeId = new Fr(1);
const noteTypeId = new NoteSelector(1);
const storageSlot = new Fr(2);

const body = new EncryptedNoteLogIncomingBody(storageSlot, noteTypeId, note);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Fr, type GrumpkinPrivateKey, type PublicKey } from '@aztec/circuits.js';
import { NoteSelector } from '@aztec/foundation/abi';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { Note } from '../payload.js';
import { EncryptedLogIncomingBody } from './encrypted_log_incoming_body.js';

export class EncryptedNoteLogIncomingBody extends EncryptedLogIncomingBody {
constructor(public storageSlot: Fr, public noteTypeId: Fr, public note: Note) {
constructor(public storageSlot: Fr, public noteTypeId: NoteSelector, public note: Note) {
super();
}

Expand All @@ -16,7 +17,8 @@ export class EncryptedNoteLogIncomingBody extends EncryptedLogIncomingBody {
*/
public toBuffer(): Buffer {
const noteBufferWithoutLength = this.note.toBuffer().subarray(4);
return serializeToBuffer(this.storageSlot, this.noteTypeId, noteBufferWithoutLength);
// Note: We serialize note type to field first because that's how it's done in Noir
return serializeToBuffer(this.storageSlot, this.noteTypeId.toField(), noteBufferWithoutLength);
}

/**
Expand All @@ -28,7 +30,7 @@ export class EncryptedNoteLogIncomingBody extends EncryptedLogIncomingBody {
public static fromBuffer(buf: Buffer): EncryptedNoteLogIncomingBody {
const reader = BufferReader.asReader(buf);
const storageSlot = Fr.fromBuffer(reader);
const noteTypeId = Fr.fromBuffer(reader);
const noteTypeId = NoteSelector.fromField(Fr.fromBuffer(reader));

// 2 Fields (storage slot and note type id) are not included in the note buffer
const fieldsInNote = reader.getLength() / 32 - 2;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AztecAddress, KeyValidationRequest, computeOvskApp, derivePublicKeyFromSecretKey } from '@aztec/circuits.js';
import { EventSelector } from '@aztec/foundation/abi';
import { pedersenHash } from '@aztec/foundation/crypto';
import { Fr, GrumpkinScalar } from '@aztec/foundation/fields';

Expand Down Expand Up @@ -29,7 +30,7 @@ describe('L1 Event Payload', () => {
randomness = Fr.random();
maskedContractAddress = pedersenHash([contractAddress, randomness], 0);

payload = new L1EventPayload(Event.random(), contractAddress, randomness, Fr.random());
payload = new L1EventPayload(Event.random(), contractAddress, randomness, EventSelector.random());

ovskM = GrumpkinScalar.random();
ivskM = GrumpkinScalar.random();
Expand Down
Loading