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 #4902

Merged
merged 5 commits into from
Apr 24, 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 @@
beab8c93857536e07fa37994213fc664a5864013
2e64428af9525bd8c390931061505f7b48d729a4
22 changes: 11 additions & 11 deletions .github/actions/install-playwright/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ description: Installs Playwright and its dependencies and caches them.
runs:
using: composite
steps:
- name: Query playwright version
shell: bash
run: echo "PLAYWRIGHT_VERSION=$(yarn workspace @noir-lang/noirc_abi info @web/test-runner-playwright --json | jq .children.Version | tr -d '"')" >> $GITHUB_ENV
# - name: Query playwright version
# shell: bash
# run: echo "PLAYWRIGHT_VERSION=$(yarn workspace @noir-lang/noirc_abi info @web/test-runner-playwright --json | jq .children.Version | tr -d '"')" >> $GITHUB_ENV

- name: Cache playwright binaries
uses: actions/cache@v4
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
# - name: Cache playwright binaries
# uses: actions/cache@v4
# id: playwright-cache
# with:
# path: |
# ~/.cache/ms-playwright
# key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}

- name: Install playwright deps
shell: bash
if: steps.playwright-cache.outputs.cache-hit != 'true'
# if: steps.playwright-cache.outputs.cache-hit != 'true'
run: |
# Workaround: https://github.com/microsoft/playwright/issues/30503#issuecomment-2074783821
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
Expand Down
4 changes: 2 additions & 2 deletions acvm-repo/acvm_js/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ BROWSER_WASM=${BROWSER_DIR}/${pname}_bg.wasm
run_or_fail cargo build --lib --release --target $TARGET --package ${pname}
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $NODE_DIR --typescript --target nodejs
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $BROWSER_DIR --typescript --target web
run_or_fail wasm-opt $NODE_WASM -o $NODE_WASM -O
run_or_fail wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
run_if_available wasm-opt $NODE_WASM -o $NODE_WASM -O
run_if_available wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
13 changes: 7 additions & 6 deletions aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,18 @@
// Check for a user defined storage struct

let maybe_storage_struct_name = check_for_storage_definition(module)?;

let storage_defined = maybe_storage_struct_name.is_some();

if let Some(storage_struct_name) = maybe_storage_struct_name {
if !check_for_storage_implementation(module, &storage_struct_name) {
generate_storage_implementation(module, &storage_struct_name)?;
if let Some(ref storage_struct_name) = maybe_storage_struct_name {
if !check_for_storage_implementation(module, storage_struct_name) {
generate_storage_implementation(module, storage_struct_name)?;
}
// Make sure we're only generating the storage layout for the root crate
// In case we got a contract importing other contracts for their interface, we
// don't want to generate the storage layout for them
if crate_id == context.root_crate_id() {
generate_storage_layout(module, storage_struct_name)?;
generate_storage_layout(module, storage_struct_name.clone())?;
}
}

Expand Down Expand Up @@ -138,7 +139,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 142 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 All @@ -164,14 +165,14 @@
transform_function(
fn_type,
func,
storage_defined,
maybe_storage_struct_name.clone(),
is_initializer,
insert_init_check,
is_internal,
)?;
has_transformed_module = true;
} else if storage_defined && func.def.is_unconstrained {
transform_unconstrained(func);
transform_unconstrained(func, maybe_storage_struct_name.clone().unwrap());
has_transformed_module = true;
}
}
Expand Down
94 changes: 81 additions & 13 deletions aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

use crate::utils::{
errors::AztecMacroError,
hir_utils::{collect_crate_functions, fetch_notes, get_contract_module_data, inject_fn},
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_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
Expand All @@ -16,9 +19,9 @@
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_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_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_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_data.parameters.0.first().is_some_and(| (_, typ, _) | match typ {
Expand Down Expand Up @@ -60,13 +63,68 @@
return Ok(());
}

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 69 in aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (numberic)
.map_err(|err| {
(
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
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
// contract might use. These are the types that are marked as #[aztec(note)].
// contract might use and their serialized lengths. These are the types that are marked as #[aztec(note)].
let mut notes_and_lengths = vec![];

for (path, typ) in fetch_notes(context) {
let serialized_len: u128 = get_serialized_length(
&traits,
"NoteInterface",
&Type::Struct(typ.clone(), vec![]),
&context.def_interner,
)
.map_err(|_err| {
(
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
secondary_message: Some(format!(
"Failed to get serialized length for note type {}",
path
)),
},
file_id,
)
})?
.into();

if serialized_len > max_note_length_const {
return Err((
AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier {
secondary_message: Some(format!(
"Note type {} as {} fields, which is more than the maximum allowed length of {}.",
path,
serialized_len,
max_note_length_const
)),
},
file_id,
));
}

notes_and_lengths.push((path.to_string(), serialized_len));
}

let max_note_length: u128 =
*notes_and_lengths.iter().map(|(_, serialized_len)| serialized_len).max().unwrap_or(&0);

let note_types =
fetch_notes(context).iter().map(|(path, _)| path.to_string()).collect::<Vec<_>>();
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);
let func = generate_compute_note_hash_and_nullifier(&note_types, max_note_length);

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

Expand All @@ -86,8 +144,12 @@
Ok(())
}

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

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

fn generate_compute_note_hash_and_nullifier_source(note_types: &[String]) -> String {
fn generate_compute_note_hash_and_nullifier_source(
note_types: &[String],
max_note_length: u128,
) -> String {
// TODO(#4649): The serialized_note parameter is a fixed-size array, but we don't know what length it should have.
// For now we hardcode it to 20, which is the same as MAX_NOTE_FIELDS_LENGTH.

if note_types.is_empty() {
// Even if the contract does not include any notes, other parts of the stack expect for this function to exist,
// so we include a dummy version.
"
format!(
"
unconstrained fn compute_note_hash_and_nullifier(
contract_address: dep::aztec::protocol_types::address::AztecAddress,
nonce: Field,
storage_slot: Field,
note_type_id: Field,
serialized_note: [Field; 20]
) -> pub [Field; 4] {
serialized_note: [Field; {}]
) -> pub [Field; 4] {{
assert(false, \"This contract does not use private notes\");
[0, 0, 0, 0]
}"
.to_string()
}}",
max_note_length
)
} else {
// For contracts that include notes we do a simple if-else chain comparing note_type_id with the different
// get_note_type_id of each of the note types.
Expand All @@ -142,12 +209,13 @@
nonce: Field,
storage_slot: Field,
note_type_id: Field,
serialized_note: [Field; 20]
serialized_note: [Field; {}]
) -> pub [Field; 4] {{
let note_header = dep::aztec::prelude::NoteHeader::new(contract_address, nonce, storage_slot);

{}
}}",
max_note_length,
full_if_statement
)
}
Expand Down
19 changes: 11 additions & 8 deletions aztec_macros/src/transforms/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
pub fn transform_function(
ty: &str,
func: &mut NoirFunction,
storage_defined: bool,
storage_struct_name: Option<String>,
is_initializer: bool,
insert_init_check: bool,
is_internal: bool,
Expand Down Expand Up @@ -57,8 +57,8 @@ pub fn transform_function(
}

// Add access to the storage struct
if storage_defined {
let storage_def = abstract_storage(&ty.to_lowercase(), false);
if let Some(storage_struct_name) = storage_struct_name {
let storage_def = abstract_storage(storage_struct_name, &ty.to_lowercase(), false);
func.def.body.statements.insert(0, storage_def);
}

Expand Down Expand Up @@ -209,8 +209,11 @@ pub fn export_fn_abi(
/// ```
///
/// This will allow developers to access their contract' storage struct in unconstrained functions
pub fn transform_unconstrained(func: &mut NoirFunction) {
func.def.body.statements.insert(0, abstract_storage("Unconstrained", true));
pub fn transform_unconstrained(func: &mut NoirFunction, storage_struct_name: String) {
func.def
.body
.statements
.insert(0, abstract_storage(storage_struct_name, "Unconstrained", true));
}

/// Helper function that returns what the private context would look like in the ast
Expand Down Expand Up @@ -575,7 +578,7 @@ fn abstract_return_values(func: &NoirFunction) -> Result<Option<Vec<Statement>>,
/// unconstrained fn lol() {
/// let storage = Storage::init(Context::none());
/// }
fn abstract_storage(typ: &str, unconstrained: bool) -> Statement {
fn abstract_storage(storage_struct_name: String, typ: &str, unconstrained: bool) -> Statement {
let init_context_call = if unconstrained {
call(
variable_path(chained_dep!("aztec", "context", "Context", "none")), // Path
Expand All @@ -591,8 +594,8 @@ fn abstract_storage(typ: &str, unconstrained: bool) -> Statement {
assignment(
"storage", // Assigned to
call(
variable_path(chained_path!("Storage", "init")), // Path
vec![init_context_call], // args
variable_path(chained_path!(storage_struct_name.as_str(), "init")), // Path
vec![init_context_call], // args
),
)
}
Expand Down
6 changes: 2 additions & 4 deletions aztec_macros/src/transforms/note_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@

// Generate the deserialize_content method as
//
// fn deserialize_content(serialized_note: [Field; NOTE_SERILIZED_LEN]) -> Self {

Check warning on line 320 in aztec_macros/src/transforms/note_interface.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (SERILIZED)
// NoteType {
// note_field1: serialized_note[0] as Field,
// note_field2: NoteFieldType2::from_field(serialized_note[1])...
Expand Down Expand Up @@ -418,8 +418,7 @@

// Automatically generate the method to compute the note's content hash as:
// fn compute_note_content_hash(self: NoteType) -> Field {
// // TODO(#1205) Should use a non-zero generator index.
// dep::aztec::hash::pedersen_hash(self.serialize_content(), 0)
// dep::aztec::hash::pedersen_hash(self.serialize_content(), dep::aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
// }
//
fn generate_compute_note_content_hash(
Expand All @@ -429,8 +428,7 @@
let function_source = format!(
"
fn compute_note_content_hash(self: {}) -> Field {{
// TODO(#1205) Should use a non-zero generator index.
dep::aztec::hash::pedersen_hash(self.serialize_content(), 0)
dep::aztec::hash::pedersen_hash(self.serialize_content(), dep::aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_CONTENT_HASH)
}}
",
note_type
Expand Down
Loading
Loading