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 noir #7223

Merged
merged 17 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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 .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f2f8ecc833d4725d0829f9c339389c90d1a4fbcd
d8b9870a991b724ec337b58380b50464ba274d8a
2 changes: 1 addition & 1 deletion noir/bb-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.41.0
0.43.0
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn generate_compute_note_hash_and_optionally_a_nullifier_source(
format!(
"
unconstrained fn compute_note_hash_and_optionally_a_nullifier(
contract_address: dep::aztec::protocol_types::address::AztecAddress,
contract_address: aztec::protocol_types::address::AztecAddress,
nonce: Field,
storage_slot: Field,
note_type_id: Field,
Expand All @@ -194,7 +194,7 @@ fn generate_compute_note_hash_and_optionally_a_nullifier_source(

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_optionally_a_nullifier({0}::deserialize_content, note_header, compute_nullifier, serialized_note)
aztec::note::utils::compute_note_hash_and_optionally_a_nullifier({0}::deserialize_content, note_header, compute_nullifier, serialized_note)
}}"
, note_type)).collect();

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

{}
}}",
Expand Down
14 changes: 7 additions & 7 deletions noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ use crate::utils::{
// for i in 0..third_arg.len() {
// args_acc = args_acc.append(third_arg[i].serialize().as_slice());
// }
// let args_hash = dep::aztec::hash::hash_args(args_acc);
// assert(args_hash == dep::aztec::oracle::arguments::pack_arguments(args_acc));
// let args_hash = aztec::hash::hash_args(args_acc);
// assert(args_hash == aztec::oracle::arguments::pack_arguments(args_acc));
// PublicCallInterface {
// target_contract: self.target_contract,
// selector: FunctionSelector::from_signature("SELECTOR_PLACEHOLDER"),
Expand Down Expand Up @@ -137,8 +137,8 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call
format!(
"let mut args_acc: [Field] = &[];
{}
let args_hash = dep::aztec::hash::hash_args(args_acc);
assert(args_hash == dep::aztec::oracle::arguments::pack_arguments(args_acc));",
let args_hash = aztec::hash::hash_args(args_acc);
assert(args_hash == aztec::oracle::arguments::pack_arguments(args_acc));",
call_args
)
} else {
Expand Down Expand Up @@ -234,14 +234,14 @@ pub fn generate_contract_interface(
let contract_interface = format!(
"
struct {0} {{
target_contract: dep::aztec::protocol_types::address::AztecAddress
target_contract: aztec::protocol_types::address::AztecAddress
}}

impl {0} {{
{1}

pub fn at(
target_contract: dep::aztec::protocol_types::address::AztecAddress
target_contract: aztec::protocol_types::address::AztecAddress
) -> Self {{
Self {{ target_contract }}
}}
Expand All @@ -255,7 +255,7 @@ pub fn generate_contract_interface(

#[contract_library_method]
pub fn at(
target_contract: dep::aztec::protocol_types::address::AztecAddress
target_contract: aztec::protocol_types::address::AztecAddress
) -> {0} {{
{0} {{ target_contract }}
}}
Expand Down
21 changes: 8 additions & 13 deletions noir/noir-repo/aztec_macros/src/transforms/note_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub fn generate_note_interface_impl(module: &mut SortedModule) -> Result<(), Azt
type_span: note_struct.name.span(),
generics: vec![],
methods: vec![],
where_clause: vec![],
};
module.impls.push(default_impl.clone());
module.impls.last_mut().unwrap()
Expand Down Expand Up @@ -271,7 +272,7 @@ fn generate_note_get_header(
) -> Result<NoirFunction, AztecMacroError> {
let function_source = format!(
"
fn get_header(note: {}) -> dep::aztec::note::note_header::NoteHeader {{
fn get_header(note: {}) -> aztec::note::note_header::NoteHeader {{
note.{}
}}
",
Expand Down Expand Up @@ -302,7 +303,7 @@ fn generate_note_set_header(
) -> Result<NoirFunction, AztecMacroError> {
let function_source = format!(
"
fn set_header(self: &mut {}, header: dep::aztec::note::note_header::NoteHeader) {{
fn set_header(self: &mut {}, header: aztec::note::note_header::NoteHeader) {{
self.{} = header;
}}
",
Expand Down Expand Up @@ -492,7 +493,7 @@ fn generate_note_properties_fn(

// Automatically generate the method to compute the note's content hash as:
// fn compute_note_content_hash(self: NoteType) -> Field {
// dep::aztec::hash::pedersen_hash(self.serialize_content(), dep::aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
// aztec::hash::pedersen_hash(self.serialize_content(), aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
// }
//
fn generate_compute_note_content_hash(
Expand All @@ -502,7 +503,7 @@ fn generate_compute_note_content_hash(
let function_source = format!(
"
fn compute_note_content_hash(self: {}) -> Field {{
dep::aztec::hash::pedersen_hash(self.serialize_content(), dep::aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
aztec::hash::pedersen_hash(self.serialize_content(), aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
}}
",
note_type
Expand Down Expand Up @@ -561,10 +562,7 @@ fn generate_note_properties_struct_source(
.iter()
.filter_map(|(field_name, _)| {
if field_name != note_header_field_name {
Some(format!(
"{}: dep::aztec::note::note_getter_options::PropertySelector",
field_name
))
Some(format!("{}: aztec::note::note_getter_options::PropertySelector", field_name))
} else {
None
}
Expand Down Expand Up @@ -592,7 +590,7 @@ fn generate_note_properties_fn_source(
.filter_map(|(index, (field_name, _))| {
if field_name != note_header_field_name {
Some(format!(
"{}: dep::aztec::note::note_getter_options::PropertySelector {{ index: {}, offset: 0, length: 32 }}",
"{}: aztec::note::note_getter_options::PropertySelector {{ index: {}, offset: 0, length: 32 }}",
field_name,
index
))
Expand Down Expand Up @@ -669,10 +667,7 @@ fn generate_note_deserialize_content_source(
)
}
} else {
format!(
"{}: dep::aztec::note::note_header::NoteHeader::empty()",
note_header_field_name
)
format!("{}: aztec::note::note_header::NoteHeader::empty()", note_header_field_name)
}
})
.collect::<Vec<String>>()
Expand Down
6 changes: 4 additions & 2 deletions noir/noir-repo/aztec_macros/src/transforms/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn inject_context_in_storage(module: &mut SortedModule) -> Result<(), AztecM
r#struct.attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(storage)"))
})
.unwrap();
storage_struct.generics.push(ident("Context"));
storage_struct.generics.push(ident("Context").into());
storage_struct
.fields
.iter_mut()
Expand Down Expand Up @@ -243,9 +243,11 @@ pub fn generate_storage_implementation(
span: Some(Span::default()),
},
type_span: Span::default(),
generics: vec![generic_context_ident],
generics: vec![generic_context_ident.into()],

methods: vec![(init, Span::default())],

where_clause: vec![],
};
module.impls.push(storage_impl);

Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo/aztec_macros/src/utils/ast_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ macro_rules! chained_dep {
( $base:expr $(, $tail:expr)* ) => {
{
let mut base_path = ident_path($base);
base_path.kind = PathKind::Dep;
base_path.kind = PathKind::Plain;
$(
base_path.segments.push(ident($tail));
)*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::Path;
use noirc_driver::{file_manager_with_stdlib, prepare_crate, ErrorsAndWarnings};
use noirc_frontend::hir::{def_map::parse_file, Context};

#[ignore = "Temporarily ignoring the test until the stdlib is updated to use explicit numeric generics"]
TomAFrench marked this conversation as resolved.
Show resolved Hide resolved
#[test]
fn stdlib_does_not_produce_constant_warnings() -> Result<(), ErrorsAndWarnings> {
// We use a minimal source file so that if stdlib produces warnings then we can expect these warnings to _always_
Expand All @@ -27,7 +28,7 @@ fn stdlib_does_not_produce_constant_warnings() -> Result<(), ErrorsAndWarnings>
let ((), warnings) =
noirc_driver::check_crate(&mut context, root_crate_id, false, false, false)?;

assert_eq!(warnings, Vec::new(), "stdlib is producing warnings");
assert_eq!(warnings, Vec::new(), "stdlib is producing {} warnings", warnings.len());

Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use acvm::{acir::AcirField, FieldElement};
use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet};
use iter_extended::vecmap;
use num_bigint::BigUint;
use std::rc::Rc;

use super::brillig_black_box::convert_black_box_call;
use super::brillig_block_variables::BlockVariables;
Expand Down Expand Up @@ -1629,7 +1630,7 @@ impl<'block> BrilligBlock<'block> {
new_variable
}
}
Value::Array { array, .. } => {
Value::Array { array, typ } => {
if let Some(variable) = self.variables.get_constant(value_id, dfg) {
variable
} else {
Expand Down Expand Up @@ -1664,23 +1665,7 @@ impl<'block> BrilligBlock<'block> {

// Write the items

// Allocate a register for the iterator
let iterator_register =
self.brillig_context.make_usize_constant_instruction(0_usize.into());

for element_id in array.iter() {
let element_variable = self.convert_ssa_value(*element_id, dfg);
// Store the item in memory
self.store_variable_in_array(pointer, iterator_register, element_variable);
// Increment the iterator
self.brillig_context.codegen_usize_op_in_place(
iterator_register.address,
BrilligBinaryOp::Add,
1,
);
}

self.brillig_context.deallocate_single_addr(iterator_register);
self.initialize_constant_array(array, typ, dfg, pointer);

new_variable
}
Expand All @@ -1705,6 +1690,125 @@ impl<'block> BrilligBlock<'block> {
}
}

fn initialize_constant_array(
&mut self,
data: &im::Vector<ValueId>,
typ: &Type,
dfg: &DataFlowGraph,
pointer: MemoryAddress,
) {
if data.is_empty() {
return;
}
let item_types = typ.clone().element_types();

// Find out if we are repeating the same item over and over
let first_item = data.iter().take(item_types.len()).copied().collect();
let mut is_repeating = true;

for item_index in (item_types.len()..data.len()).step_by(item_types.len()) {
let item: Vec<_> = (0..item_types.len()).map(|i| data[item_index + i]).collect();
if first_item != item {
is_repeating = false;
break;
}
}

// If all the items are single address, and all have the same initial value, we can initialize the array in a runtime loop.
// Since the cost in instructions for a runtime loop is in the order of magnitude of 10, we only do this if the item_count is bigger than that.
let item_count = data.len() / item_types.len();

if item_count > 10
&& is_repeating
&& item_types.iter().all(|typ| matches!(typ, Type::Numeric(_)))
{
self.initialize_constant_array_runtime(
item_types, first_item, item_count, pointer, dfg,
);
} else {
self.initialize_constant_array_comptime(data, dfg, pointer);
}
}

fn initialize_constant_array_runtime(
&mut self,
item_types: Rc<Vec<Type>>,
item_to_repeat: Vec<ValueId>,
item_count: usize,
pointer: MemoryAddress,
dfg: &DataFlowGraph,
) {
let mut subitem_to_repeat_variables = Vec::with_capacity(item_types.len());
for subitem_id in item_to_repeat.into_iter() {
subitem_to_repeat_variables.push(self.convert_ssa_value(subitem_id, dfg));
}

let data_length_variable = self
.brillig_context
.make_usize_constant_instruction((item_count * item_types.len()).into());

// If this is an array with complex subitems, we need a custom step in the loop to write all the subitems while iterating.
if item_types.len() > 1 {
let step_variable =
self.brillig_context.make_usize_constant_instruction(item_types.len().into());

let subitem_pointer =
SingleAddrVariable::new_usize(self.brillig_context.allocate_register());

let initializer_fn = |ctx: &mut BrilligContext<_>, iterator: SingleAddrVariable| {
ctx.mov_instruction(subitem_pointer.address, iterator.address);
for subitem in subitem_to_repeat_variables.into_iter() {
Self::store_variable_in_array_with_ctx(ctx, pointer, subitem_pointer, subitem);
ctx.codegen_usize_op_in_place(subitem_pointer.address, BrilligBinaryOp::Add, 1);
}
};

self.brillig_context.codegen_loop_with_bound_and_step(
data_length_variable.address,
step_variable.address,
initializer_fn,
);

self.brillig_context.deallocate_single_addr(step_variable);
self.brillig_context.deallocate_single_addr(subitem_pointer);
} else {
let subitem = subitem_to_repeat_variables.into_iter().next().unwrap();

let initializer_fn = |ctx: &mut _, iterator_register| {
Self::store_variable_in_array_with_ctx(ctx, pointer, iterator_register, subitem);
};

self.brillig_context.codegen_loop(data_length_variable.address, initializer_fn);
}

self.brillig_context.deallocate_single_addr(data_length_variable);
}

fn initialize_constant_array_comptime(
&mut self,
data: &im::Vector<crate::ssa::ir::map::Id<Value>>,
dfg: &DataFlowGraph,
pointer: MemoryAddress,
) {
// Allocate a register for the iterator
let iterator_register =
self.brillig_context.make_usize_constant_instruction(0_usize.into());

for element_id in data.iter() {
let element_variable = self.convert_ssa_value(*element_id, dfg);
// Store the item in memory
self.store_variable_in_array(pointer, iterator_register, element_variable);
// Increment the iterator
self.brillig_context.codegen_usize_op_in_place(
iterator_register.address,
BrilligBinaryOp::Add,
1,
);
}

self.brillig_context.deallocate_single_addr(iterator_register);
}

/// Converts an SSA `ValueId` into a `MemoryAddress`. Initializes if necessary.
fn convert_ssa_single_addr_value(
&mut self,
Expand Down
Loading
Loading