diff --git a/.aztec-sync-commit b/.aztec-sync-commit new file mode 100644 index 00000000000..67a9efeeaa9 --- /dev/null +++ b/.aztec-sync-commit @@ -0,0 +1 @@ +4550f2596b51a985d6677191fd83bb2e621c5bc3 diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 559b271bf38..00000000000 --- a/.dockerignore +++ /dev/null @@ -1,27 +0,0 @@ -Dockerfile* -.dockerignore - -# Yarn -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions - -packages -**/package.tgz -**/target -**/node_modules -**/outputs - -# Noir.js -tooling/noir_js/lib - -# Wasm build artifacts -compiler/wasm/nodejs -compiler/wasm/web -tooling/noirc_abi_wasm/nodejs -tooling/noirc_abi_wasm/web -tooling/noir_js/lib diff --git a/.gitignore b/.gitignore index 8d02d34d463..5f41566c94b 100644 --- a/.gitignore +++ b/.gitignore @@ -50,8 +50,5 @@ tooling/noirc_abi_wasm/nodejs tooling/noirc_abi_wasm/web tooling/noir_js/lib -**/package.tgz -packages - # docs autogen build /docs/docs/noir_js/reference/ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 3a478c3f95a..00000000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM rust:bullseye -WORKDIR /usr/src/noir -COPY . . -RUN ./scripts/bootstrap_native.sh - -# When running the container, mount the users home directory to same location. -FROM ubuntu:focal -# Install Tini as nargo doesn't handle signals properly. -# Install git as nargo needs it to clone. -RUN apt-get update && apt-get install -y git tini && rm -rf /var/lib/apt/lists/* && apt-get clean -COPY --from=0 /usr/src/noir/target/release/nargo /usr/src/noir/target/release/nargo -ENTRYPOINT ["/usr/bin/tini", "--", "/usr/src/noir/target/release/nargo"] diff --git a/Dockerfile.packages b/Dockerfile.packages deleted file mode 100644 index f40670c19e4..00000000000 --- a/Dockerfile.packages +++ /dev/null @@ -1,22 +0,0 @@ -FROM rust:alpine3.17 -RUN apk update \ - && apk upgrade \ - && apk add --no-cache \ - build-base \ - pkgconfig \ - openssl-dev \ - npm \ - yarn \ - bash \ - jq \ - git \ - curl - -WORKDIR /usr/src/noir -COPY . . -RUN ./scripts/bootstrap_packages.sh - -FROM scratch -COPY --from=0 /usr/src/noir/packages /usr/src/noir/packages -# For some unknown reason, on alpine only, we need this to exist. -COPY --from=0 /usr/src/noir/node_modules/@noir-lang /usr/src/noir/node_modules/@noir-lang diff --git a/acvm-repo/acvm_js/test/node/build_info.test.ts b/acvm-repo/acvm_js/test/node/build_info.test.ts index 23100505011..014bb6f422d 100644 --- a/acvm-repo/acvm_js/test/node/build_info.test.ts +++ b/acvm-repo/acvm_js/test/node/build_info.test.ts @@ -3,12 +3,20 @@ import { BuildInfo, buildInfo } from '@noir-lang/acvm_js'; import child_process from 'child_process'; import pkg from '../../package.json'; -it('returns the correct build into', () => { +it('returns the correct build info', () => { + let revision: string; + + try { + revision = child_process.execSync('git rev-parse HEAD').toString().trim(); + } catch (error) { + console.log('Failed to get revision, skipping test.'); + return; + } + const info: BuildInfo = buildInfo(); // TODO: enforce that `package.json` and `Cargo.toml` are consistent. expect(info.version).to.be.eq(pkg.version); - const revision = child_process.execSync('git rev-parse HEAD').toString().trim(); expect(info.gitHash).to.be.eq(revision); }); diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index 0ccc421d3bc..0c84c00820d 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -3,7 +3,7 @@ use std::vec; use convert_case::{Case, Casing}; use iter_extended::vecmap; -use noirc_errors::Location; +use noirc_errors::{Location, Spanned}; use noirc_frontend::hir::def_collector::dc_crate::{UnresolvedFunctions, UnresolvedTraitImpl}; use noirc_frontend::hir::def_map::{LocalModuleId, ModuleId}; use noirc_frontend::macros_api::parse_program; @@ -21,7 +21,7 @@ use noirc_frontend::macros_api::{CrateId, FileId}; use noirc_frontend::macros_api::{MacroError, MacroProcessor}; use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; use noirc_frontend::node_interner::{FuncId, TraitId, TraitImplId, TraitImplKind}; -use noirc_frontend::Lambda; +use noirc_frontend::{BinaryOpKind, ConstrainKind, ConstrainStatement, InfixExpression, Lambda}; pub struct AztecMacro; impl MacroProcessor for AztecMacro { @@ -63,17 +63,18 @@ impl MacroProcessor for AztecMacro { } const FUNCTION_TREE_HEIGHT: u32 = 5; -const MAX_CONTRACT_FUNCTIONS: usize = 2_usize.pow(FUNCTION_TREE_HEIGHT); +const MAX_CONTRACT_PRIVATE_FUNCTIONS: usize = 2_usize.pow(FUNCTION_TREE_HEIGHT); #[derive(Debug, Clone)] pub enum AztecMacroError { AztecDepNotFound, - ContractHasTooManyFunctions { span: Span }, + ContractHasTooManyPrivateFunctions { span: Span }, ContractConstructorMissing { span: Span }, UnsupportedFunctionArgumentType { span: Span, typ: UnresolvedTypeData }, UnsupportedStorageType { span: Option, typ: UnresolvedTypeData }, CouldNotAssignStorageSlots { secondary_message: Option }, EventError { span: Span, message: String }, + UnsupportedAttributes { span: Span, secondary_message: Option }, } impl From for MacroError { @@ -84,8 +85,8 @@ impl From for MacroError { secondary_message: None, span: None, }, - AztecMacroError::ContractHasTooManyFunctions { span } => MacroError { - primary_message: format!("Contract can only have a maximum of {} functions", MAX_CONTRACT_FUNCTIONS), + AztecMacroError::ContractHasTooManyPrivateFunctions { span } => MacroError { + primary_message: format!("Contract can only have a maximum of {} private functions", MAX_CONTRACT_PRIVATE_FUNCTIONS), secondary_message: None, span: Some(span), }, @@ -114,6 +115,11 @@ impl From for MacroError { secondary_message: None, span: Some(span), }, + AztecMacroError::UnsupportedAttributes { span, secondary_message } => MacroError { + primary_message: "Unsupported attributes in contract function".to_string(), + secondary_message, + span: Some(span), + }, } } } @@ -215,6 +221,14 @@ fn lambda(parameters: Vec<(Pattern, UnresolvedType)>, body: Expression) -> Expre }))) } +fn make_eq(lhs: Expression, rhs: Expression) -> Expression { + expression(ExpressionKind::Infix(Box::new(InfixExpression { + lhs, + rhs, + operator: Spanned::from(Span::default(), BinaryOpKind::Equal), + }))) +} + macro_rules! chained_path { ( $base:expr ) => { { @@ -267,10 +281,6 @@ fn index_array_variable(array: Expression, index: &str) -> Expression { }))) } -fn import(path: Path) -> ImportStatement { - ImportStatement { path, alias: None } -} - // // Create AST Nodes for Aztec // @@ -290,7 +300,6 @@ fn transform( .map_err(|(err, file_id)| (err.into(), file_id))? { check_for_aztec_dependency(crate_id, context)?; - include_relevant_imports(&mut submodule.contents); } } Ok(ast) @@ -309,21 +318,6 @@ fn transform_hir( assign_storage_slots(crate_id, context) } -/// Includes an import to the aztec library if it has not been included yet -fn include_relevant_imports(ast: &mut SortedModule) { - // Create the aztec import path using the assumed chained_dep! macro - let aztec_import_path = import(chained_dep!("aztec")); - - // Check if the aztec import already exists - let is_aztec_imported = - ast.imports.iter().any(|existing_import| existing_import.path == aztec_import_path.path); - - // If aztec is not imported, add the import at the beginning - if !is_aztec_imported { - ast.imports.insert(0, aztec_import_path); - } -} - /// Creates an error alerting the user that they have not downloaded the Aztec-noir library fn check_for_aztec_dependency( crate_id: &CrateId, @@ -429,23 +423,57 @@ fn transform_module( } } + let has_initializer = module.functions.iter().any(|func| { + func.def + .attributes + .secondary + .iter() + .any(|attr| is_custom_attribute(&attr, "aztec(initializer)")) + }); + for func in module.functions.iter_mut() { + let mut is_private = false; + let mut is_public = false; + let mut is_public_vm = false; + let mut is_initializer = false; + let mut is_internal = false; + let mut insert_init_check = has_initializer; + for secondary_attribute in func.def.attributes.secondary.clone() { - let crate_graph = &context.crate_graph[crate_id]; if is_custom_attribute(&secondary_attribute, "aztec(private)") { - transform_function("Private", func, storage_defined) - .map_err(|err| (err, crate_graph.root_file_id))?; - has_transformed_module = true; + is_private = true; + } 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)") { + insert_init_check = false; + } else if is_custom_attribute(&secondary_attribute, "aztec(internal)") { + is_internal = true; } else if is_custom_attribute(&secondary_attribute, "aztec(public)") { - transform_function("Public", func, storage_defined) - .map_err(|err| (err, crate_graph.root_file_id))?; - has_transformed_module = true; + is_public = true; } else if is_custom_attribute(&secondary_attribute, "aztec(public-vm)") { - transform_vm_function(func, storage_defined) - .map_err(|err| (err, crate_graph.root_file_id))?; - has_transformed_module = true; + is_public_vm = true; } } + + // Apply transformations to the function based on collected attributes + if is_private || is_public { + transform_function( + if is_private { "Private" } else { "Public" }, + func, + storage_defined, + is_initializer, + insert_init_check, + is_internal, + ) + .map_err(|err| (err, crate_graph.root_file_id))?; + has_transformed_module = true; + } else if is_public_vm { + transform_vm_function(func, storage_defined) + .map_err(|err| (err, crate_graph.root_file_id))?; + has_transformed_module = true; + } + // Add the storage struct to the beginning of the function if it is unconstrained in an aztec contract if storage_defined && func.def.is_unconstrained { transform_unconstrained(func); @@ -456,10 +484,22 @@ fn transform_module( if has_transformed_module { // We only want to run these checks if the macro processor has found the module to be an Aztec contract. - if module.functions.len() > MAX_CONTRACT_FUNCTIONS { + let private_functions_count = module + .functions + .iter() + .filter(|func| { + func.def + .attributes + .secondary + .iter() + .any(|attr| is_custom_attribute(attr, "aztec(private)")) + }) + .count(); + + if private_functions_count > MAX_CONTRACT_PRIVATE_FUNCTIONS { let crate_graph = &context.crate_graph[crate_id]; return Err(( - AztecMacroError::ContractHasTooManyFunctions { span: Span::default() }, + AztecMacroError::ContractHasTooManyPrivateFunctions { span: Span::default() }, crate_graph.root_file_id, )); } @@ -499,7 +539,7 @@ fn generate_storage_field_constructor( ( pattern("context"), make_type(UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), + chained_dep!("aztec", "context", "Context"), vec![], true, )), @@ -583,7 +623,7 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte &[( ident("context"), make_type(UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), + chained_dep!("aztec", "context", "Context"), vec![], true, )), @@ -615,11 +655,27 @@ fn transform_function( ty: &str, func: &mut NoirFunction, storage_defined: bool, + is_initializer: bool, + insert_init_check: bool, + is_internal: bool, ) -> Result<(), AztecMacroError> { let context_name = format!("{}Context", ty); let inputs_name = format!("{}ContextInputs", ty); let return_type_name = format!("{}CircuitPublicInputs", ty); + // Add check that msg sender equals this address and flag function as internal + if is_internal { + let is_internal_check = create_internal_check(func.name()); + func.def.body.0.insert(0, is_internal_check); + func.def.is_internal = true; + } + + // Add initialization check + if insert_init_check { + let init_check = create_init_check(); + func.def.body.0.insert(0, init_check); + } + // Add access to the storage struct if storage_defined { let storage_def = abstract_storage(&ty.to_lowercase(), false); @@ -636,9 +692,19 @@ fn transform_function( // Abstract return types such that they get added to the kernel's return_values if let Some(return_values) = abstract_return_values(func) { + // In case we are pushing return values to the context, we remove the statement that originated it + // This avoids running duplicate code, since blocks like if/else can be value returning statements + func.def.body.0.pop(); + // Add the new return statement func.def.body.0.push(return_values); } + // Before returning mark the contract as initialized + if is_initializer { + let mark_initialized = create_mark_as_initialized(ty); + func.def.body.0.push(mark_initialized); + } + // Push the finish method call to the end of the function let finish_def = create_context_finish(); func.def.body.0.push(finish_def); @@ -1012,7 +1078,7 @@ fn generate_selector_impl(structure: &NoirStruct) -> TypeImpl { make_type(UnresolvedTypeData::Named(path(structure.name.clone()), vec![], true)); let selector_path = - chained_path!("aztec", "protocol_types", "abis", "function_selector", "FunctionSelector"); + chained_dep!("aztec", "protocol_types", "abis", "function_selector", "FunctionSelector"); let mut from_signature_path = selector_path.clone(); from_signature_path.segments.push(ident("from_signature")); @@ -1067,7 +1133,7 @@ fn create_inputs(ty: &str) -> Param { let context_pattern = Pattern::Identifier(context_ident); let path_snippet = ty.to_case(Case::Snake); // e.g. private_context_inputs - let type_path = chained_path!("aztec", "context", "inputs", &path_snippet, ty); + let type_path = chained_dep!("aztec", "context", "inputs", &path_snippet, ty); let context_type = make_type(UnresolvedTypeData::Named(type_path, vec![], true)); let visibility = Visibility::Private; @@ -1075,6 +1141,52 @@ fn create_inputs(ty: &str) -> Param { Param { pattern: context_pattern, typ: context_type, visibility, span: Span::default() } } +/// Creates an initialization check to ensure that the contract has been initialized, meant to +/// be injected as the first statement of any function after the context has been created. +/// +/// ```noir +/// assert_is_initialized(&mut context); +/// ``` +fn create_init_check() -> Statement { + make_statement(StatementKind::Expression(call( + variable_path(chained_dep!("aztec", "initializer", "assert_is_initialized")), + vec![mutable_reference("context")], + ))) +} + +/// Creates a call to mark_as_initialized which emits the initialization nullifier, meant to +/// be injected as the last statement before returning in a constructor. +/// +/// ```noir +/// mark_as_initialized(&mut context); +/// ``` +fn create_mark_as_initialized(ty: &str) -> Statement { + let name = if ty == "Public" { "mark_as_initialized_public" } else { "mark_as_initialized" }; + make_statement(StatementKind::Expression(call( + variable_path(chained_dep!("aztec", "initializer", name)), + vec![mutable_reference("context")], + ))) +} + +/// Creates a check for internal functions ensuring that the caller is self. +/// +/// ```noir +/// assert(context.msg_sender() == context.this_address(), "Function can only be called internally"); +/// ``` +fn create_internal_check(fname: &str) -> Statement { + make_statement(StatementKind::Constrain(ConstrainStatement( + make_eq( + method_call(variable("context"), "msg_sender", vec![]), + method_call(variable("context"), "this_address", vec![]), + ), + Some(expression(ExpressionKind::Literal(Literal::Str(format!( + "Function {} can only be called internally", + fname + ))))), + ConstrainKind::Assert, + ))) +} + /// Creates the private context object to be accessed within the function, the parameters need to be extracted to be /// appended into the args hash object. /// @@ -1107,8 +1219,8 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac let let_hasher = mutable_assignment( "hasher", // Assigned to call( - variable_path(chained_path!("aztec", "hasher", "Hasher", "new")), // Path - vec![], // args + variable_path(chained_dep!("aztec", "hasher", "Hasher", "new")), // Path + vec![], // args ), ); @@ -1176,8 +1288,8 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac let let_context = mutable_assignment( "context", // Assigned to call( - variable_path(chained_path!("aztec", "context", &path_snippet, ty, "new")), // Path - vec![inputs_expression, hash_call], // args + variable_path(chained_dep!("aztec", "context", &path_snippet, ty, "new")), // Path + vec![inputs_expression, hash_call], // args ), ); injected_expressions.push(let_context); @@ -1207,8 +1319,8 @@ fn create_avm_context() -> Result { let let_context = mutable_assignment( "context", // Assigned to call( - variable_path(chained_path!("aztec", "context", "AVMContext", "new")), // Path - vec![], // args + variable_path(chained_dep!("aztec", "context", "AVMContext", "new")), // Path + vec![], // args ), ); @@ -1243,15 +1355,13 @@ fn create_avm_context() -> Result { /// Any primitive type that can be cast will be casted to a field and pushed to the context. fn abstract_return_values(func: &NoirFunction) -> Option { let current_return_type = func.return_type().typ; - let len = func.def.body.len(); - let last_statement = &func.def.body.0[len - 1]; + let last_statement = func.def.body.0.last(); // TODO: (length, type) => We can limit the size of the array returned to be limited by kernel size // Doesn't need done until we have settled on a kernel size // TODO: support tuples here and in inputs -> convert into an issue - // Check if the return type is an expression, if it is, we can handle it - match last_statement { + match last_statement? { Statement { kind: StatementKind::Expression(expression), .. } => { match current_return_type { // Call serialize on structs, push the whole array, calling push_array @@ -1295,13 +1405,13 @@ fn abstract_return_values(func: &NoirFunction) -> Option { fn abstract_storage(typ: &str, unconstrained: bool) -> Statement { let init_context_call = if unconstrained { call( - variable_path(chained_path!("aztec", "context", "Context", "none")), // Path - vec![], // args + variable_path(chained_dep!("aztec", "context", "Context", "none")), // Path + vec![], // args ) } else { call( - variable_path(chained_path!("aztec", "context", "Context", typ)), // Path - vec![mutable_reference("context")], // args + variable_path(chained_dep!("aztec", "context", "Context", typ)), // Path + vec![mutable_reference("context")], // args ) }; @@ -1422,7 +1532,7 @@ fn make_castable_return_type(expression: Expression) -> Statement { /// } fn create_return_type(ty: &str) -> FunctionReturnType { let path_snippet = ty.to_case(Case::Snake); // e.g. private_circuit_public_inputs or public_circuit_public_inputs - let return_path = chained_path!("aztec", "protocol_types", "abis", &path_snippet, ty); + let return_path = chained_dep!("aztec", "protocol_types", "abis", &path_snippet, ty); return_type(return_path) } @@ -1778,7 +1888,7 @@ fn generate_compute_note_hash_and_nullifier_source(note_types: &Vec) -> let if_statements: Vec = note_types.iter().map(|note_type| format!( "if (note_type_id == {0}::get_note_type_id()) {{ - note_utils::compute_note_hash_and_nullifier({0}::deserialize_content, note_header, serialized_note) + dep::aztec::note::utils::compute_note_hash_and_nullifier({0}::deserialize_content, note_header, serialized_note) }}" , note_type)).collect(); @@ -1798,7 +1908,7 @@ fn generate_compute_note_hash_and_nullifier_source(note_types: &Vec) -> note_type_id: Field, serialized_note: [Field; 20] ) -> pub [Field; 4] {{ - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let note_header = dep::aztec::prelude::NoteHeader::new(contract_address, nonce, storage_slot); {} }}", diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100755 index 1f9506904a4..00000000000 --- a/bootstrap.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -eu - -cd $(dirname "$0") - -CMD=${1:-} - -if [ -n "$CMD" ]; then - if [ "$CMD" = "clean" ]; then - git clean -fdx - exit 0 - else - echo "Unknown command: $CMD" - exit 1 - fi -fi - -# Attempt to just pull artefacts from CI and exit on success. -./bootstrap_cache.sh && exit - -./scripts/bootstrap_native.sh -./scripts/bootstrap_packages.sh \ No newline at end of file diff --git a/bootstrap_cache.sh b/bootstrap_cache.sh deleted file mode 100755 index d06aa493662..00000000000 --- a/bootstrap_cache.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -eu - -[ -z "${NO_CACHE:-}" ] && type docker &> /dev/null && [ -f ~/.aws/credentials ] || exit 1 - -cd "$(dirname "$0")" -source ../build-system/scripts/setup_env '' '' mainframe_$USER > /dev/null - -echo -e "\033[1mRetrieving noir packages from remote cache...\033[0m" -extract_repo noir-packages /usr/src/noir/packages ./ -echo -e "\033[1mRetrieving nargo from remote cache...\033[0m" -extract_repo noir /usr/src/noir/target/release ./target/ - -remove_old_images noir-packages -remove_old_images noir diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index fe12132e202..6e18dcdd776 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -661,7 +661,6 @@ pub enum Keyword { If, Impl, In, - Internal, Let, Mod, Mut, @@ -703,7 +702,6 @@ impl fmt::Display for Keyword { Keyword::If => write!(f, "if"), Keyword::Impl => write!(f, "impl"), Keyword::In => write!(f, "in"), - Keyword::Internal => write!(f, "internal"), Keyword::Let => write!(f, "let"), Keyword::Mod => write!(f, "mod"), Keyword::Mut => write!(f, "mut"), @@ -748,7 +746,6 @@ impl Keyword { "if" => Keyword::If, "impl" => Keyword::Impl, "in" => Keyword::In, - "internal" => Keyword::Internal, "let" => Keyword::Let, "mod" => Keyword::Mod, "mut" => Keyword::Mut, diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 1cb81e26a0a..d1b0f8d4b43 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -183,10 +183,11 @@ fn function_definition(allow_self: bool) -> impl NoirParser { attributes, is_unconstrained: modifiers.0, is_open: modifiers.2, - is_internal: modifiers.3, + // Whether a function is internal or not is now set through `aztec_macros` + is_internal: false, visibility: if modifiers.1 { FunctionVisibility::PublicCrate - } else if modifiers.4 { + } else if modifiers.3 { FunctionVisibility::Public } else { FunctionVisibility::Private @@ -203,24 +204,17 @@ fn function_definition(allow_self: bool) -> impl NoirParser { }) } -/// function_modifiers: 'unconstrained'? 'pub(crate)'? 'pub'? 'open'? 'internal'? +/// function_modifiers: 'unconstrained'? 'pub(crate)'? 'pub'? 'open'? /// -/// returns (is_unconstrained, is_pub_crate, is_open, is_internal, is_pub) for whether each keyword was present -fn function_modifiers() -> impl NoirParser<(bool, bool, bool, bool, bool)> { +/// returns (is_unconstrained, is_pub_crate, is_open, is_pub) for whether each keyword was present +fn function_modifiers() -> impl NoirParser<(bool, bool, bool, bool)> { keyword(Keyword::Unconstrained) .or_not() .then(is_pub_crate()) .then(keyword(Keyword::Pub).or_not()) .then(keyword(Keyword::Open).or_not()) - .then(keyword(Keyword::Internal).or_not()) - .map(|((((unconstrained, pub_crate), public), open), internal)| { - ( - unconstrained.is_some(), - pub_crate, - open.is_some(), - internal.is_some(), - public.is_some(), - ) + .map(|(((unconstrained, pub_crate), public), open)| { + (unconstrained.is_some(), pub_crate, open.is_some(), public.is_some()) }) } diff --git a/compiler/wasm/scripts/build-fixtures.sh b/compiler/wasm/scripts/build-fixtures.sh index 3a2330d4726..4c0505ef519 100755 --- a/compiler/wasm/scripts/build-fixtures.sh +++ b/compiler/wasm/scripts/build-fixtures.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash nargo compile --program-dir ./test/fixtures/simple -nargo compile --program-dir ./test/fixtures/with-deps +nargo compile --program-dir ./test/fixtures/with-deps nargo compile --program-dir ./test/fixtures/noir-contract \ No newline at end of file diff --git a/noir_stdlib/src/collections/map.nr b/noir_stdlib/src/collections/map.nr index d9eb83ff5dc..056299b4238 100644 --- a/noir_stdlib/src/collections/map.nr +++ b/noir_stdlib/src/collections/map.nr @@ -400,7 +400,7 @@ impl HashMap { // n * MAX_LOAD_FACTOR_DEN0MINATOR >= m * MAX_LOAD_FACTOR_NUMERATOR fn assert_load_factor(self) { let lhs = self._len * MAX_LOAD_FACTOR_DEN0MINATOR; - let rhs = self._table.len() as u64 * MAX_LOAD_FACTOR_NUMERATOR; + let rhs = self._table.len() * MAX_LOAD_FACTOR_NUMERATOR; let exceeded = lhs >= rhs; assert(!exceeded, "Load factor is exceeded, consider increasing the capacity."); } diff --git a/noir_stdlib/src/sha256.nr b/noir_stdlib/src/sha256.nr index 6bcc5ea74c6..2f686a64165 100644 --- a/noir_stdlib/src/sha256.nr +++ b/noir_stdlib/src/sha256.nr @@ -57,7 +57,7 @@ pub fn digest(msg: [u8; N]) -> [u8; 32] { msg_block[i as Field] = 0; i = i + 1; } else if i < 64 { - let mut len = 8 * msg.len() as u64; + let mut len = 8 * msg.len(); for j in 0..8 { msg_block[63 - j] = len as u8; len >>= 8; diff --git a/noir_stdlib/src/sha512.nr b/noir_stdlib/src/sha512.nr index 155ba593bba..f3155dd7528 100644 --- a/noir_stdlib/src/sha512.nr +++ b/noir_stdlib/src/sha512.nr @@ -136,7 +136,7 @@ pub fn digest(msg: [u8; N]) -> [u8; 64] { msg_block[i as Field] = 0; i += 1; } else if i < 128 { - let mut len = 8 * msg.len() as u64; // u128 unsupported + let mut len = 8 * msg.len(); // u128 unsupported for j in 0..16 { msg_block[127 - j] = len as u8; len >>= 8; diff --git a/package.json b/package.json index f460b3db711..753a0400b0f 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ ], "scripts": { "build": "yarn workspaces foreach --parallel --topological-dev --verbose run build", - "test": "yarn workspaces foreach run test", + "test": "yarn workspaces foreach --parallel --verbose run test", "test:integration": "yarn workspace integration-tests test", "clean:workspaces": "yarn workspaces foreach --exclude @noir-lang/root run clean", "clean:root": "rm -rf ./result ./target ./packages", diff --git a/scripts/bootstrap_native.sh b/scripts/bootstrap_native.sh deleted file mode 100755 index 974f0edcfec..00000000000 --- a/scripts/bootstrap_native.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -eu - -cd $(dirname "$0")/.. - -# If this project has been subrepod into another project, set build data manually. -export SOURCE_DATE_EPOCH=$(date +%s) -export GIT_DIRTY=false -if [ -f ".gitrepo" ]; then - export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) -else - export GIT_COMMIT=$(git rev-parse --verify HEAD) -fi - -# Check if the 'cargo' command is available in the system -if ! command -v cargo > /dev/null; then - echo "Cargo is not installed. Please install Cargo and the Rust toolchain." - exit 1 -fi - -# Build native. -if [ -n "${DEBUG:-}" ]; then - cargo build -else - cargo build --release -fi diff --git a/scripts/bootstrap_packages.sh b/scripts/bootstrap_packages.sh deleted file mode 100755 index 47ffe12beec..00000000000 --- a/scripts/bootstrap_packages.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -set -eu - -cd $(dirname "$0")/.. - -./.github/scripts/wasm-bindgen-install.sh - -# If this project has been subrepod into another project, set build data manually. -export SOURCE_DATE_EPOCH=$(date +%s) -export GIT_DIRTY=false -if [ -f ".gitrepo" ]; then - export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) -else - export GIT_COMMIT=$(git rev-parse --verify HEAD) -fi - -yarn --immutable -yarn build - -# We create a folder called packages, that contains each package as it would be published to npm, named correctly. -# These can be useful for testing, or portaling into other projects. -yarn workspaces foreach pack - -rm -rf packages && mkdir -p packages -tar zxfv acvm-repo/acvm_js/package.tgz -C packages && mv packages/package packages/acvm_js -tar zxfv compiler/wasm/package.tgz -C packages && mv packages/package packages/noir_wasm -tar zxfv tooling/noir_codegen/package.tgz -C packages && mv packages/package packages/noir_codegen -tar zxfv tooling/noir_js/package.tgz -C packages && mv packages/package packages/noir_js -tar zxfv tooling/noir_js_backend_barretenberg/package.tgz -C packages && mv packages/package packages/backend_barretenberg -tar zxfv tooling/noir_js_types/package.tgz -C packages && mv packages/package packages/types -tar zxfv tooling/noirc_abi_wasm/package.tgz -C packages && mv packages/package packages/noirc_abi diff --git a/scripts/test_js_packages.sh b/scripts/test_js_packages.sh deleted file mode 100755 index e1e10c543e0..00000000000 --- a/scripts/test_js_packages.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -set -eu - -cd $(dirname "$0")/.. - -./.github/scripts/wasm-bindgen-install.sh - -# If this project has been subrepod into another project, set build data manually. -export SOURCE_DATE_EPOCH=$(date +%s) -export GIT_DIRTY=false -if [ -f ".gitrepo" ]; then - export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) -else - export GIT_COMMIT=$(git rev-parse --verify HEAD) -fi - -cargo build --release -export PATH="${PATH}:/usr/src/noir/target/release/" - -yarn --immutable -yarn build -./.github/scripts/playwright-install.sh - -./scripts/test.sh -yarn test diff --git a/scripts/test_native.sh b/scripts/test_native.sh deleted file mode 100755 index 9b9aa0ce4d7..00000000000 --- a/scripts/test_native.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -eu - -cd $(dirname "$0")/.. - -# If this project has been subrepod into another project, set build data manually. -export SOURCE_DATE_EPOCH=$(date +%s) -export GIT_DIRTY=false -if [ -f ".gitrepo" ]; then - export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) -else - export GIT_COMMIT=$(git rev-parse --verify HEAD) -fi - -cargo fmt --all --check -cargo clippy --workspace --locked --release -cargo test --workspace --locked --release diff --git a/test_programs/compile_success_contract/simple_contract/src/main.nr b/test_programs/compile_success_contract/simple_contract/src/main.nr index fea0ae08c22..ed90ac8bd1d 100644 --- a/test_programs/compile_success_contract/simple_contract/src/main.nr +++ b/test_programs/compile_success_contract/simple_contract/src/main.nr @@ -5,10 +5,10 @@ contract Foo { fn triple(x: Field) -> pub Field { x * 3 } - internal fn quadruple(x: Field) -> pub Field { + fn quadruple(x: Field) -> pub Field { x * 4 } - open internal fn skibbidy(x: Field) -> pub Field { + open fn skibbidy(x: Field) -> pub Field { x * 5 } // Regression for issue #3344 diff --git a/test_programs/execution_success/regression/src/main.nr b/test_programs/execution_success/regression/src/main.nr index c70e2e75fa8..8dc42cb5f10 100644 --- a/test_programs/execution_success/regression/src/main.nr +++ b/test_programs/execution_success/regression/src/main.nr @@ -1,4 +1,4 @@ -global NIBBLE_LENGTH: Field = 16; +global NIBBLE_LENGTH: u64 = 16; struct U4 { inner: u8, @@ -21,8 +21,8 @@ impl Eq for U4 { } fn compact_decode(input: [u8; N], length: Field) -> ([U4; NIBBLE_LENGTH], Field) { - assert(2 * input.len() as u64 <= NIBBLE_LENGTH as u64); - assert(length as u64 <= input.len() as u64); + assert(2 * input.len() <= NIBBLE_LENGTH as u64); + assert(length as u64 <= input.len()); let mut nibble = [U4::zero(); NIBBLE_LENGTH]; diff --git a/test_programs/noir_test_failure/should_fail_suite_with_one_failure/Prover.toml b/test_programs/noir_test_failure/should_fail_suite_with_one_failure/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test_programs/noir_test_failure/should_fail_suite_with_one_failure/src/main.nr b/test_programs/noir_test_failure/should_fail_suite_with_one_failure/src/main.nr new file mode 100644 index 00000000000..8ed9003164a --- /dev/null +++ b/test_programs/noir_test_failure/should_fail_suite_with_one_failure/src/main.nr @@ -0,0 +1,11 @@ +/// Test to make sure the entire test suite fails, even if some of the tests pass! + +#[test] +fn this_will_pass() { + assert(true); +} + +#[test] +fn this_will_fail() { + assert(false); +} diff --git a/tooling/nargo_cli/src/cli/noir_template_files/contract.nr b/tooling/nargo_cli/src/cli/noir_template_files/contract.nr index e126726393d..3cd3b5b3766 100644 --- a/tooling/nargo_cli/src/cli/noir_template_files/contract.nr +++ b/tooling/nargo_cli/src/cli/noir_template_files/contract.nr @@ -1,5 +1,5 @@ contract Main { - internal fn double(x: Field) -> pub Field { x * 2 } + fn double(x: Field) -> pub Field { x * 2 } fn triple(x: Field) -> pub Field { x * 3 } fn quadruple(x: Field) -> pub Field { double(double(x)) } } diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs index 503fd5afdd4..68660d62d23 100644 --- a/tooling/nargo_cli/src/cli/test_cmd.rs +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -116,10 +116,10 @@ pub(crate) fn run( }; } - if test_report.iter().any(|(_, status)| !matches!(status, TestStatus::Fail { .. })) { - Ok(()) - } else { + if test_report.iter().any(|(_, status)| matches!(status, TestStatus::Fail { .. })) { Err(CliError::Generic(String::new())) + } else { + Ok(()) } } diff --git a/tooling/nargo_fmt/tests/expected/contract.nr b/tooling/nargo_fmt/tests/expected/contract.nr index a03b8774700..c5b19a686d2 100644 --- a/tooling/nargo_fmt/tests/expected/contract.nr +++ b/tooling/nargo_fmt/tests/expected/contract.nr @@ -8,8 +8,7 @@ contract Benchmarking { use dep::value_note::{utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}}; use dep::aztec::{ - context::{Context}, - note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + context::Context, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} diff --git a/tooling/nargo_fmt/tests/input/contract.nr b/tooling/nargo_fmt/tests/input/contract.nr index a03b8774700..c5b19a686d2 100644 --- a/tooling/nargo_fmt/tests/input/contract.nr +++ b/tooling/nargo_fmt/tests/input/contract.nr @@ -8,8 +8,7 @@ contract Benchmarking { use dep::value_note::{utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}}; use dep::aztec::{ - context::{Context}, - note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, + context::Context, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress}