Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Sync from aztec-packages #5242

Merged
merged 6 commits into from
Jun 17, 2024
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 .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
86a33140f9a65e518003b3f4c60f97d132f85b89
12af650f0d27c37dca06bb329bf76a5574534d78
4 changes: 2 additions & 2 deletions aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use noirc_errors::Location;
use transforms::{
compute_note_hash_and_nullifier::inject_compute_note_hash_and_nullifier,
compute_note_hash_and_optionally_a_nullifier::inject_compute_note_hash_and_optionally_a_nullifier,
contract_interface::{
generate_contract_interface, stub_function, update_fn_signatures_in_contract_interface,
},
Expand Down Expand Up @@ -145,7 +145,7 @@
} else if is_custom_attribute(&secondary_attribute, "aztec(initializer)") {
is_initializer = true;
insert_init_check = false;
} else if is_custom_attribute(&secondary_attribute, "aztec(noinitcheck)") {

Check warning on line 148 in aztec_macros/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (noinitcheck)
insert_init_check = false;
} else if is_custom_attribute(&secondary_attribute, "aztec(internal)") {
is_internal = true;
Expand Down Expand Up @@ -236,7 +236,7 @@
) -> Result<(), (AztecMacroError, FileId)> {
if has_aztec_dependency(crate_id, context) {
transform_events(crate_id, context)?;
inject_compute_note_hash_and_nullifier(crate_id, context)?;
inject_compute_note_hash_and_optionally_a_nullifier(crate_id, context)?;
assign_storage_slots(crate_id, context)?;
inject_note_exports(crate_id, context)?;
update_fn_signatures_in_contract_interface(crate_id, context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,30 @@
errors::AztecMacroError,
hir_utils::{
collect_crate_functions, collect_traits, fetch_notes, get_contract_module_data,
get_global_numberic_const, get_serialized_length, inject_fn,

Check warning on line 13 in aztec_macros/src/transforms/compute_note_hash_and_optionally_a_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (numberic)
},
};

// Check if "compute_note_hash_and_nullifier(AztecAddress,Field,Field,Field,[Field; N]) -> [Field; 4]" is defined
fn check_for_compute_note_hash_and_nullifier_definition(
// Check if "compute_note_hash_and_optionally_a_nullifier(AztecAddress,Field,Field,Field,bool,[Field; N]) -> [Field; 4]" is defined
fn check_for_compute_note_hash_and_optionally_a_nullifier_definition(
crate_id: &CrateId,
context: &HirContext,
) -> bool {
collect_crate_functions(crate_id, context).iter().any(|funct_id| {

Check warning on line 22 in aztec_macros/src/transforms/compute_note_hash_and_optionally_a_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funct)
let func_data = context.def_interner.function_meta(funct_id);

Check warning on line 23 in aztec_macros/src/transforms/compute_note_hash_and_optionally_a_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funct)
let func_name = context.def_interner.function_name(funct_id);

Check warning on line 24 in aztec_macros/src/transforms/compute_note_hash_and_optionally_a_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funct)
func_name == "compute_note_hash_and_nullifier"
&& func_data.parameters.len() == 5
func_name == "compute_note_hash_and_optionally_a_nullifier"
&& func_data.parameters.len() == 6
&& func_data.parameters.0.first().is_some_and(| (_, typ, _) | match typ {
Type::Struct(struct_typ, _) => struct_typ.borrow().name.0.contents == "AztecAddress",
_ => false
})
&& func_data.parameters.0.get(1).is_some_and(|(_, typ, _)| typ.is_field())
&& func_data.parameters.0.get(2).is_some_and(|(_, typ, _)| typ.is_field())
&& func_data.parameters.0.get(3).is_some_and(|(_, typ, _)| typ.is_field())
// checks if the 5th parameter is an array and contains only fields
&& func_data.parameters.0.get(4).is_some_and(|(_, typ, _)| match typ {
&& func_data.parameters.0.get(4).is_some_and(|(_, typ, _)| typ.is_bool())
// checks if the 6th parameter is an array and contains only fields
&& func_data.parameters.0.get(5).is_some_and(|(_, typ, _)| match typ {
Type::Array(_, inner_type) => inner_type.to_owned().is_field(),
_ => false
})
Expand All @@ -49,16 +50,16 @@
})
}

pub fn inject_compute_note_hash_and_nullifier(
pub fn inject_compute_note_hash_and_optionally_a_nullifier(
crate_id: &CrateId,
context: &mut HirContext,
) -> Result<(), (AztecMacroError, FileId)> {
if let Some((_, module_id, file_id)) = get_contract_module_data(context, crate_id) {
// If compute_note_hash_and_nullifier is already defined by the user, we skip auto-generation in order to provide an
// If compute_note_hash_and_optionally_a_nullifier is already defined by the user, we skip auto-generation in order to provide an
// escape hatch for this mechanism.
// TODO(#4647): improve this diagnosis and error messaging.
if context.crate_graph.root_crate_id() != crate_id
|| check_for_compute_note_hash_and_nullifier_definition(crate_id, context)
|| check_for_compute_note_hash_and_optionally_a_nullifier_definition(crate_id, context)
{
return Ok(());
}
Expand All @@ -66,17 +67,17 @@
let traits: Vec<_> = collect_traits(context);

// Get MAX_NOTE_FIELDS_LENGTH global to check if the notes in our contract are too long.
let max_note_length_const = get_global_numberic_const(context, "MAX_NOTE_FIELDS_LENGTH")

Check warning on line 70 in aztec_macros/src/transforms/compute_note_hash_and_optionally_a_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (numberic)
.map_err(|err| {
(
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
AztecMacroError::CouldNotImplementComputeNoteHashAndOptionallyANullifier {
secondary_message: Some(err.primary_message),
},
file_id,
)
})?;

// In order to implement compute_note_hash_and_nullifier, we need to know all of the different note types the
// In order to implement compute_note_hash_and_optionally_a_nullifier, we need to know all of the different note types the
// contract might use and their serialized lengths. These are the types that are marked as #[aztec(note)].
let mut notes_and_lengths = vec![];

Expand All @@ -89,7 +90,7 @@
)
.map_err(|_err| {
(
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
AztecMacroError::CouldNotImplementComputeNoteHashAndOptionallyANullifier {
secondary_message: Some(format!(
"Failed to get serialized length for note type {}",
path
Expand All @@ -102,7 +103,7 @@

if serialized_len > max_note_length_const {
return Err((
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
AztecMacroError::CouldNotImplementComputeNoteHashAndOptionallyANullifier {
secondary_message: Some(format!(
"Note type {} as {} fields, which is more than the maximum allowed length of {}.",
path,
Expand All @@ -120,11 +121,12 @@
let max_note_length: u128 =
*notes_and_lengths.iter().map(|(_, serialized_len)| serialized_len).max().unwrap_or(&0);

let note_types =
let note_types: Vec<String> =
notes_and_lengths.iter().map(|(note_type, _)| note_type.clone()).collect::<Vec<_>>();

// We can now generate a version of compute_note_hash_and_nullifier tailored for the contract in this crate.
let func = generate_compute_note_hash_and_nullifier(&note_types, max_note_length);
// We can now generate a version of compute_note_hash_and_optionally_a_nullifier tailored for the contract in this crate.
let func =
generate_compute_note_hash_and_optionally_a_nullifier(&note_types, max_note_length);

// And inject the newly created function into the contract.

Expand All @@ -134,7 +136,7 @@

inject_fn(crate_id, context, func, location, module_id, file_id).map_err(|err| {
(
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
AztecMacroError::CouldNotImplementComputeNoteHashAndOptionallyANullifier {
secondary_message: err.secondary_message,
},
file_id,
Expand All @@ -144,12 +146,12 @@
Ok(())
}

fn generate_compute_note_hash_and_nullifier(
fn generate_compute_note_hash_and_optionally_a_nullifier(
note_types: &[String],
max_note_length: u128,
) -> NoirFunction {
let function_source =
generate_compute_note_hash_and_nullifier_source(note_types, max_note_length);
generate_compute_note_hash_and_optionally_a_nullifier_source(note_types, max_note_length);

let (function_ast, errors) = parse_program(&function_source);
if !errors.is_empty() {
Expand All @@ -161,7 +163,7 @@
function_ast.functions.remove(0)
}

fn generate_compute_note_hash_and_nullifier_source(
fn generate_compute_note_hash_and_optionally_a_nullifier_source(
note_types: &[String],
max_note_length: u128,
) -> String {
Expand All @@ -173,12 +175,13 @@
// so we include a dummy version.
format!(
"
unconstrained fn compute_note_hash_and_nullifier(
unconstrained fn compute_note_hash_and_optionally_a_nullifier(
contract_address: dep::aztec::protocol_types::address::AztecAddress,
nonce: Field,
storage_slot: Field,
note_type_id: Field,
serialized_note: [Field; {}]
compute_nullifier: bool,
serialized_note: [Field; {}],
) -> pub [Field; 4] {{
assert(false, \"This contract does not use private notes\");
[0, 0, 0, 0]
Expand All @@ -191,7 +194,7 @@

let if_statements: Vec<String> = note_types.iter().map(|note_type| format!(
"if (note_type_id == {0}::get_note_type_id()) {{
dep::aztec::note::utils::compute_note_hash_and_nullifier({0}::deserialize_content, note_header, serialized_note)
dep::aztec::note::utils::compute_note_hash_and_optionally_a_nullifier({0}::deserialize_content, note_header, compute_nullifier, serialized_note)
}}"
, note_type)).collect();

Expand All @@ -204,12 +207,13 @@

format!(
"
unconstrained fn compute_note_hash_and_nullifier(
unconstrained fn compute_note_hash_and_optionally_a_nullifier(
contract_address: dep::aztec::protocol_types::address::AztecAddress,
nonce: Field,
storage_slot: Field,
note_type_id: Field,
serialized_note: [Field; {}]
compute_nullifier: bool,
serialized_note: [Field; {}],
) -> pub [Field; 4] {{
let note_header = dep::aztec::prelude::NoteHeader::new(contract_address, nonce, storage_slot);

Expand Down
2 changes: 1 addition & 1 deletion aztec_macros/src/transforms/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod compute_note_hash_and_nullifier;
pub mod compute_note_hash_and_optionally_a_nullifier;
pub mod contract_interface;
pub mod events;
pub mod functions;
Expand Down
6 changes: 3 additions & 3 deletions aztec_macros/src/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub enum AztecMacroError {
UnsupportedFunctionReturnType { span: Span, typ: ast::UnresolvedTypeData },
UnsupportedStorageType { span: Option<Span>, typ: ast::UnresolvedTypeData },
CouldNotAssignStorageSlots { secondary_message: Option<String> },
CouldNotImplementComputeNoteHashAndNullifier { secondary_message: Option<String> },
CouldNotImplementComputeNoteHashAndOptionallyANullifier { secondary_message: Option<String> },
CouldNotImplementNoteInterface { span: Option<Span>, secondary_message: Option<String> },
MultipleStorageDefinitions { span: Option<Span> },
CouldNotExportStorageLayout { span: Option<Span>, secondary_message: Option<String> },
Expand Down Expand Up @@ -57,8 +57,8 @@ impl From<AztecMacroError> for MacroError {
secondary_message,
span: None,
},
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier { secondary_message } => MacroError {
primary_message: "Could not implement compute_note_hash_and_nullifier automatically, please provide an implementation".to_string(),
AztecMacroError::CouldNotImplementComputeNoteHashAndOptionallyANullifier { secondary_message } => MacroError {
primary_message: "Could not implement compute_note_hash_and_optionally_a_nullifier automatically, please provide an implementation".to_string(),
secondary_message,
span: None,
},
Expand Down
2 changes: 1 addition & 1 deletion compiler/integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "echo Integration Test build step",
"test": "yarn test:browser && yarn test:node",
"test:node": "bash ./scripts/setup.sh && hardhat test test/node/**/*",
"test:node": "bash ./scripts/setup.sh && hardhat test test/node/prove_and_verify.test.ts && hardhat test test/node/smart_contract_verifier.test.ts && hardhat test test/node/onchain_recursive_verification.test.ts",
"test:browser": "web-test-runner",
"test:integration:browser": "web-test-runner test/browser/**/*.test.ts",
"test:integration:browser:watch": "web-test-runner test/browser/**/*.test.ts --watch",
Expand Down
36 changes: 16 additions & 20 deletions compiler/integration-tests/test/node/prove_and_verify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { CompiledCircuit } from '@noir-lang/types';
const assert_lt_program = assert_lt_json as CompiledCircuit;
const fold_fibonacci_program = fold_fibonacci_json as CompiledCircuit;

const backend = new Backend(assert_lt_program);

it('end-to-end proof creation and verification (outer)', async () => {
// Noir.Js part
const inputs = {
Expand All @@ -22,11 +24,10 @@ it('end-to-end proof creation and verification (outer)', async () => {
// bb.js part
//
// Proof creation
const prover = new Backend(assert_lt_program);
const proof = await prover.generateProof(witness);
const proof = await backend.generateProof(witness);

// Proof verification
const isValid = await prover.verifyProof(proof);
const isValid = await backend.verifyProof(proof);
expect(isValid).to.be.true;
});

Expand All @@ -42,10 +43,9 @@ it('end-to-end proof creation and verification (outer) -- Verifier API', async (
const { witness } = await program.execute(inputs);

// Generate proof
const prover = new Backend(assert_lt_program);
const proof = await prover.generateProof(witness);
const proof = await backend.generateProof(witness);

const verificationKey = await prover.getVerificationKey();
const verificationKey = await backend.getVerificationKey();

// Proof verification
const verifier = new Verifier();
Expand All @@ -68,11 +68,10 @@ it('end-to-end proof creation and verification (inner)', async () => {
// bb.js part
//
// Proof creation
const prover = new Backend(assert_lt_program);
const proof = await prover.generateProof(witness);
const proof = await backend.generateProof(witness);

// Proof verification
const isValid = await prover.verifyProof(proof);
const isValid = await backend.verifyProof(proof);
expect(isValid).to.be.true;
});

Expand All @@ -88,9 +87,7 @@ it('end-to-end proving and verification with different instances', async () => {
const { witness } = await program.execute(inputs);

// bb.js part
const prover = new Backend(assert_lt_program);

const proof = await prover.generateProof(witness);
const proof = await backend.generateProof(witness);

const verifier = new Backend(assert_lt_program);
const proof_is_valid = await verifier.verifyProof(proof);
Expand Down Expand Up @@ -119,18 +116,17 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ',
//
// Proof creation
//
const prover = new Backend(assert_lt_program);
// Create a proof using both proving systems, the majority of the time
// one would only use outer proofs.
const proofOuter = await prover.generateProof(witness);
const _proofInner = await prover.generateProof(witness);
const proofOuter = await backend.generateProof(witness);
const _proofInner = await backend.generateProof(witness);

// Proof verification
//
const isValidOuter = await prover.verifyProof(proofOuter);
const isValidOuter = await backend.verifyProof(proofOuter);
expect(isValidOuter).to.be.true;
// We can also try verifying an inner proof and it will fail.
const isValidInner = await prover.verifyProof(_proofInner);
const isValidInner = await backend.verifyProof(_proofInner);
expect(isValidInner).to.be.true;
});

Expand All @@ -147,10 +143,10 @@ it('end-to-end proof creation and verification for multiple ACIR circuits (inner
// bb.js part
//
// Proof creation
const prover = new Backend(fold_fibonacci_program);
const proof = await prover.generateProof(witness);
const backend = new Backend(fold_fibonacci_program);
const proof = await backend.generateProof(witness);

// Proof verification
const isValid = await prover.verifyProof(proof);
const isValid = await backend.verifyProof(proof);
expect(isValid).to.be.true;
});
15 changes: 10 additions & 5 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ impl<'a> Interpreter<'a> {
let mut scope = Vec::new();
if self.scopes.len() > 1 {
scope = self.scopes.drain(1..).collect();
self.push_scope();
}
self.push_scope();
(std::mem::take(&mut self.in_loop), scope)
}

Expand Down Expand Up @@ -205,10 +205,11 @@ impl<'a> Interpreter<'a> {
}
},
HirPattern::Struct(struct_type, pattern_fields, _) => {
self.push_scope();
self.type_check(typ, &argument, location)?;
self.type_check(struct_type, &argument, location)?;

match argument {
let res = match argument {
Value::Struct(fields, struct_type) if fields.len() == pattern_fields.len() => {
for (field_name, field_pattern) in pattern_fields {
let field = fields.get(&field_name.0.contents).ok_or_else(|| {
Expand All @@ -234,7 +235,9 @@ impl<'a> Interpreter<'a> {
value,
location,
}),
}
};
self.pop_scope();
res
}
}
}
Expand Down Expand Up @@ -353,13 +356,14 @@ impl<'a> Interpreter<'a> {
}
DefinitionKind::Local(_) => self.lookup(&ident),
DefinitionKind::Global(global_id) => {
// Don't need to check let_.comptime, we can evaluate non-comptime globals too.
// Avoid resetting the value if it is already known
if let Ok(value) = self.lookup(&ident) {
Ok(value)
} else {
let let_ = self.interner.get_global_let_statement(*global_id).unwrap();
self.evaluate_let(let_)?;
if let_.comptime {
self.evaluate_let(let_.clone())?;
}
self.lookup(&ident)
}
}
Expand Down Expand Up @@ -1282,6 +1286,7 @@ impl<'a> Interpreter<'a> {
Err(InterpreterError::Continue) => continue,
Err(other) => return Err(other),
}

self.pop_scope();
}

Expand Down
1 change: 0 additions & 1 deletion compiler/noirc_frontend/src/hir/comptime/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ impl<'interner> Interpreter<'interner> {
self.scan_expression(let_.expression)?;
}
}

Ok(())
}

Expand Down
Loading
Loading