diff --git a/.github/workflows/full-dev-path.yml b/.github/workflows/aztec-cli-acceptance-test.yml similarity index 51% rename from .github/workflows/full-dev-path.yml rename to .github/workflows/aztec-cli-acceptance-test.yml index 5eee9fa514a0..89b55e912252 100644 --- a/.github/workflows/full-dev-path.yml +++ b/.github/workflows/aztec-cli-acceptance-test.yml @@ -1,6 +1,6 @@ -# Tests that the installed Aztec toolchain works end-to-end. -# Exercises the full developer onboarding path: aztec init -> compile -> test -> start -> codegen -> TS end-to-end test. -name: Full Dev Path Test +# Validates that a published Aztec CLI release can be installed and used end-to-end. +# Runs after CI3 completes a tag release (via workflow_run), or manually via workflow_dispatch. +name: Aztec CLI Acceptance Test on: workflow_dispatch: @@ -9,22 +9,30 @@ on: description: "Version to install (e.g. latest, nightly, 4.3.0, 4.3.0-nightly.20260420)" required: true type: string - push: - tags: + workflow_run: + workflows: ["CI3"] + types: + - completed + branches: - "v*" jobs: - full-dev-path: + release-acceptance: runs-on: ubuntu-latest + if: >- + github.event_name == 'workflow_dispatch' || + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') timeout-minutes: 30 env: - VERSION: ${{ github.event.inputs.version || github.ref_name }} + VERSION: ${{ github.event.inputs.version || github.event.workflow_run.head_branch }} steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + ref: ${{ github.event.workflow_run.head_sha || github.sha }} - - name: Run full dev path test - run: ./aztec-up/test/full-dev-path/run-test.sh + - name: Run Aztec CLI acceptance test + run: ./aztec-up/test/aztec-cli-acceptance-test/run-test.sh - name: Notify Slack on success if: success() && github.event_name != 'workflow_dispatch' @@ -33,7 +41,7 @@ jobs: run: | export CI=1 ./ci3/slack_notify "#team-fairies" \ - "Full Dev Path Test passed for version ${VERSION} :white_check_mark:" + "Aztec CLI Acceptance Test passed for version ${VERSION} :white_check_mark:" - name: Notify Slack and dispatch ClaudeBox on failure if: failure() && github.event_name != 'workflow_dispatch' @@ -44,6 +52,6 @@ jobs: RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" export CI=1 ./ci3/slack_notify_with_claudebox_kickoff "#team-fairies" \ - "Full Dev Path Test FAILED (version ${VERSION}): <${RUN_URL}|View Run>" \ - "Full dev path test failed for version ${VERSION}. CI run: ${RUN_URL}. Investigate the failure and explain the root cause." \ + "Aztec CLI Acceptance Test FAILED (version ${VERSION}): <${RUN_URL}|View Run>" \ + "Aztec CLI acceptance test failed for version ${VERSION}. CI run: ${RUN_URL}. Investigate the failure and explain the root cause." \ --link "$RUN_URL" diff --git a/aztec-up/bin/0.0.1/install b/aztec-up/bin/0.0.1/install index 9d5b3f500871..5f56b6ef123f 100755 --- a/aztec-up/bin/0.0.1/install +++ b/aztec-up/bin/0.0.1/install @@ -173,11 +173,14 @@ function install_foundry { temp_foundry_dir=$(mktemp -d) || { echo "Error: Failed to create temp directory" >&2; exit 1; } mkdir -p "$temp_foundry_dir/bin" - # Always install/update foundryup - curl --max-time 30 -L https://foundry.paradigm.xyz | bash + # The foundry installer defaults to $XDG_CONFIG_HOME/.foundry when that var is set, which + # puts foundryup somewhere we don't expect. We'll pin FOUNDRY_DIR so we control the install + # location regardless of the caller's environment. + local foundry_home="$HOME/.foundry" + FOUNDRY_DIR="$foundry_home" curl --max-time 30 -L https://foundry.paradigm.xyz | FOUNDRY_DIR="$foundry_home" bash # Install foundry to temp location and move to version directory - FOUNDRY_DIR="$temp_foundry_dir" timeout 30 "$HOME/.foundry/bin/foundryup" -i "$foundry_version" + FOUNDRY_DIR="$temp_foundry_dir" timeout 30 "$foundry_home/bin/foundryup" -i "$foundry_version" # Move the foundry binaries to our version bin directory for binary in forge cast anvil chisel; do diff --git a/aztec-up/test/full-dev-path/README.md b/aztec-up/test/aztec-cli-acceptance-test/README.md similarity index 68% rename from aztec-up/test/full-dev-path/README.md rename to aztec-up/test/aztec-cli-acceptance-test/README.md index fa3ef2896770..f37c307d6418 100644 --- a/aztec-up/test/full-dev-path/README.md +++ b/aztec-up/test/aztec-cli-acceptance-test/README.md @@ -1,6 +1,6 @@ -# Full Dev Path Test +# Aztec CLI Acceptance Test -Tests that the installed Aztec toolchain works end-to-end. Exercises the complete developer onboarding path: +Tests that the installed Aztec CLI toolchain works end-to-end. Exercises the complete developer onboarding path: 1. `aztec init` - scaffold a new workspace with a Counter contract and test crate 2. `aztec compile` - compile the scaffolded contract @@ -30,6 +30,6 @@ VERSION=4.3.0 ./run-test.sh ## Architecture -- **`run-test.sh`** - Bash launcher. Runs the aztec installer (unless skipped), sets up PATH, then `exec node full-dev-path.ts`. -- **`full-dev-path.ts`** - Orchestrator. Runs each CLI step against the installed toolchain and, after codegen, copies `counter.test.ts` into the scaffolded workspace and spawns `node --test` on it. Each phase is wrapped in `step(name, fn)` so failures clearly identify which step broke. Always emits a machine-readable result line for CI/Slack integration: `TEST_RESULT=pass version=...` on success, or `TEST_RESULT=fail step=... version=... error="..."` on failure (with a full banner printed above it). +- **`run-test.sh`** - Bash launcher. Runs the aztec installer (unless skipped), sets up PATH, then `exec node aztec-cli-acceptance-test.ts`. +- **`aztec-cli-acceptance-test.ts`** - Orchestrator. Runs each CLI step against the installed toolchain and, after codegen, copies `counter.test.ts` into the scaffolded workspace and spawns `node --test` on it. Each phase is wrapped in `step(name, fn)` so failures clearly identify which step broke. Always emits a machine-readable result line for CI/Slack integration: `TEST_RESULT=pass version=...` on success, or `TEST_RESULT=fail step=... version=... error="..."` on failure (with a full banner printed above it). - **`counter.test.ts`** - The `node:test` suite that drives the deployed Counter end-to-end through the codegen'd bindings. Lives here as a template; copied into the workspace at test time so it can statically `import { CounterContract } from './artifacts/Counter.js'` with real codegen types and resolve `@aztec/*` via the workspace's `node_modules` symlink to the install. diff --git a/aztec-up/test/full-dev-path/full-dev-path.ts b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts similarity index 98% rename from aztec-up/test/full-dev-path/full-dev-path.ts rename to aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts index 93c7eaa8fb0c..adffe0dde3a6 100644 --- a/aztec-up/test/full-dev-path/full-dev-path.ts +++ b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts @@ -45,7 +45,7 @@ if (!existsSync(join(AZTEC_INSTALL_DIR, 'package.json'))) { process.exit(2); } -const TMP_DIR = mkdtempSync(join(tmpdir(), 'aztec-full-dev-path-')); +const TMP_DIR = mkdtempSync(join(tmpdir(), 'aztec-cli-acceptance-test-')); const WORKSPACE_DIR = join(TMP_DIR, 'my_workspace'); // Exit codes follow the Unix 128+signal convention for signal terminations. @@ -231,7 +231,7 @@ function reportFailure(stepName: string, aztecVersion: string, err: unknown) { const banner = '='.repeat(72); console.error(`\n${banner}`); - console.error('FULL DEV PATH TEST FAILED'); + console.error('AZTEC CLI ACCEPTANCE TEST FAILED'); console.error(banner); console.error(`Step: ${stepName}`); console.error(`Version: ${aztecVersion}`); diff --git a/aztec-up/test/full-dev-path/counter.test.ts b/aztec-up/test/aztec-cli-acceptance-test/counter.test.ts similarity index 100% rename from aztec-up/test/full-dev-path/counter.test.ts rename to aztec-up/test/aztec-cli-acceptance-test/counter.test.ts diff --git a/aztec-up/test/full-dev-path/run-test.sh b/aztec-up/test/aztec-cli-acceptance-test/run-test.sh similarity index 87% rename from aztec-up/test/full-dev-path/run-test.sh rename to aztec-up/test/aztec-cli-acceptance-test/run-test.sh index 52e79d56a2a9..2ea5413c43fd 100755 --- a/aztec-up/test/full-dev-path/run-test.sh +++ b/aztec-up/test/aztec-cli-acceptance-test/run-test.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash -# Launcher for the full-dev-path test. +# Launcher for the Aztec CLI acceptance test. # # Steps: # 1. Install Node via NVM if not present (skipped with SKIP_INSTALL=1) # 2. Install the Aztec toolchain via the public installer (skipped with SKIP_INSTALL=1) -# 3. Run full-dev-path.ts which exercises the installed toolchain end-to-end +# 3. Run aztec-cli-acceptance-test.ts which exercises the installed toolchain end-to-end # # Env vars: # SKIP_INSTALL=1 Skip steps 1-2 and use the already-installed toolchain (dev-box inner loop). @@ -37,4 +37,4 @@ export PATH="$HOME/.aztec/current/bin:$HOME/.aztec/bin:$PATH" export AZTEC_INSTALL_DIR="${AZTEC_INSTALL_DIR:-$HOME/.aztec/current}" echo ">>> Running test" -exec node --no-warnings "${script_dir}/full-dev-path.ts" +exec node --no-warnings "${script_dir}/aztec-cli-acceptance-test.ts" diff --git a/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/app.nr b/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/app.nr index 9af791d5b148..20835a9c6dbd 100644 --- a/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/app.nr +++ b/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/app.nr @@ -2,7 +2,7 @@ use crate::{authwit::entrypoint::FunctionCall, context::PrivateContext}; use crate::protocol::{ constants::DOM_SEP__SIGNATURE_PAYLOAD, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize}, + traits::{Deserialize, Hash, Serialize}, }; use std::meta::derive; @@ -12,7 +12,7 @@ global ACCOUNT_MAX_CALLS: u32 = 5; // - default_entrypoint.ts // - account_entrypoint.ts (specifically `getEntrypointAbi()`) // - default_multi_call_entrypoint.ts (specifically `getEntrypointAbi()`) -#[derive(Serialize)] +#[derive(Deserialize, Serialize)] pub struct AppPayload { function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], // A nonce that enables transaction cancellation. When the cancellable flag is enabled, this nonce is used to diff --git a/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/function_call.nr b/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/function_call.nr index 7bc365f5b3b4..6a79f9f67176 100644 --- a/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/function_call.nr +++ b/noir-projects/aztec-nr/aztec/src/authwit/entrypoint/function_call.nr @@ -1,4 +1,8 @@ -use crate::protocol::{abis::function_selector::FunctionSelector, address::AztecAddress, traits::Serialize}; +use crate::protocol::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + traits::{Deserialize, Serialize}, +}; use std::meta::derive; // @dev: If you change the following struct you have to update: @@ -6,7 +10,7 @@ use std::meta::derive; // - default_multi_call_entrypoint.ts (specifically `getEntrypointAbi()`) // - function_call.ts // - encoding.ts -#[derive(Serialize)] +#[derive(Deserialize, Serialize)] pub struct FunctionCall { // args_hash is calldata_hash if is_public is true pub args_hash: Field, diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr index ab345e9c31e2..57639f879feb 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr @@ -5,7 +5,7 @@ pub(crate) mod auth_registry; use crate::macros::{ internals_functions_generation::{external_functions_registry, internal_functions_registry}, - utils::{is_fn_external, module_has_initializer}, + utils::{assert_params_serializable, assert_return_type_serializable, is_fn_external, module_has_initializer}, }; use super::utils::{fn_has_allow_phase_change, fn_has_noinitcheck, is_fn_initializer, is_fn_only_self, is_fn_view}; use auth_registry::AUTHORIZE_ONCE_REGISTRY; @@ -342,6 +342,9 @@ pub comptime fn external(f: FunctionDefinition, f_type: CtString) { // In this function we perform basic checks on the function to ensure it is valid and then we add the function to // the external functions registry for later processing by the `#[aztec]` macro. + assert_return_type_serializable(f); + assert_params_serializable(f); + if f_type.eq("private") { assert_valid_private(f); external_functions_registry::add_private(f); diff --git a/noir-projects/aztec-nr/aztec/src/macros/utils.nr b/noir-projects/aztec-nr/aztec/src/macros/utils.nr index e806693421ae..fcd2852853fb 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/utils.nr @@ -1,5 +1,5 @@ use crate::protocol::meta::derive_serialize; -use std::meta::{ctstring::AsCtString, unquote}; +use std::meta::{ctstring::AsCtString, type_of, unquote}; pub(crate) comptime fn is_fn_external(f: FunctionDefinition) -> bool { f.has_named_attribute("external") @@ -153,6 +153,44 @@ pub(crate) comptime fn get_trait_impl_method(typ: Type, target_trait: Quoted, ta .as_typed_expr() } +/// Asserts that the return type of a contract function implements both `Serialize` and `Deserialize`. +/// Functions with a `()` return type are skipped since unit values are not serialized. +pub(crate) comptime fn assert_return_type_serializable(f: FunctionDefinition) { + let return_type = f.return_type(); + if return_type != type_of(()) { + let fn_name = f.name(); + let serialize_constraint = quote { crate::protocol::traits::Serialize }.as_trait_constraint(); + assert( + return_type.implements(serialize_constraint), + f"Contract function '{fn_name}' returns a value of type {return_type}, which does not implement the Serialize trait. Add #[derive(Serialize)] to {return_type}'s declaration.", + ); + let deserialize_constraint = quote { crate::protocol::traits::Deserialize }.as_trait_constraint(); + assert( + return_type.implements(deserialize_constraint), + f"Contract function '{fn_name}' returns a value of type {return_type}, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to {return_type}'s declaration.", + ); + } +} + +/// Asserts that all parameters of a contract function implement both `Serialize` and `Deserialize`. +pub(crate) comptime fn assert_params_serializable(f: FunctionDefinition) { + let fn_name = f.name(); + + for param in f.parameters() { + let (name, param_type) = param; + let serialize_constraint = quote { crate::protocol::traits::Serialize }.as_trait_constraint(); + assert( + param_type.implements(serialize_constraint), + f"Parameter '{name}' of contract function '{fn_name}' has type {param_type}, which does not implement the Serialize trait. Add #[derive(Serialize)] to {param_type}'s declaration.", + ); + let deserialize_constraint = quote { crate::protocol::traits::Deserialize }.as_trait_constraint(); + assert( + param_type.implements(deserialize_constraint), + f"Parameter '{name}' of contract function '{fn_name}' has type {param_type}, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to {param_type}'s declaration.", + ); + } +} + /// Generates a quote that implements `Serialize` for a given struct `s`. If the struct already implements `Serialize`, /// we return an empty quote. pub comptime fn derive_serialize_if_not_implemented(s: TypeDefinition) -> Quoted { diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml new file mode 100644 index 000000000000..5914769cb4d6 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "non_deserializable" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error new file mode 100644 index 000000000000..0752e0c1a17f --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error @@ -0,0 +1,6 @@ +Contract function 'bad_private_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. +Parameter '_p' of contract function 'bad_private_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. +Contract function 'bad_public_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. +Parameter '_p' of contract function 'bad_public_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. +Contract function 'bad_utility_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. +Parameter '_p' of contract function 'bad_utility_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/src/main.nr b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/src/main.nr new file mode 100644 index 000000000000..87dd42cdd870 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/src/main.nr @@ -0,0 +1,38 @@ +// Tests that contract functions using a type that does not implement Deserialize fail to compile, for all function types +// (private, public, utility) and both return types and parameters. +use aztec::macros::aztec; + +#[aztec] +pub contract NonDeserializable { + use aztec::macros::functions::external; + use aztec::protocol::traits::Serialize; + + #[derive(Serialize)] + pub struct NotDeserializable { + x: Field, + } + + #[external("private")] + fn bad_private_return() -> pub NotDeserializable { + NotDeserializable { x: 1 } + } + + #[external("private")] + fn bad_private_param(_p: NotDeserializable) {} + + #[external("public")] + fn bad_public_return() -> pub NotDeserializable { + NotDeserializable { x: 1 } + } + + #[external("public")] + fn bad_public_param(_p: NotDeserializable) {} + + #[external("utility")] + unconstrained fn bad_utility_return() -> pub NotDeserializable { + NotDeserializable { x: 1 } + } + + #[external("utility")] + unconstrained fn bad_utility_param(_p: NotDeserializable) {} +} diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml new file mode 100644 index 000000000000..61dd673b2bd3 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "non_serializable" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error new file mode 100644 index 000000000000..33a63c051f3a --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error @@ -0,0 +1,6 @@ +Contract function 'bad_private_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. +Parameter '_p' of contract function 'bad_private_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. +Contract function 'bad_public_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. +Parameter '_p' of contract function 'bad_public_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. +Contract function 'bad_utility_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. +Parameter '_p' of contract function 'bad_utility_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/src/main.nr b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/src/main.nr new file mode 100644 index 000000000000..b59ba8578653 --- /dev/null +++ b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/src/main.nr @@ -0,0 +1,38 @@ +// Tests that contract functions using a type that does not implement Serialize fail to compile, for all function types +// (private, public, utility) and both return types and parameters. +use aztec::macros::aztec; + +#[aztec] +pub contract NonSerializable { + use aztec::macros::functions::external; + use aztec::protocol::traits::Deserialize; + + #[derive(Deserialize)] + pub struct NotSerializable { + x: Field, + } + + #[external("private")] + fn bad_private_return() -> pub NotSerializable { + NotSerializable { x: 1 } + } + + #[external("private")] + fn bad_private_param(_p: NotSerializable) {} + + #[external("public")] + fn bad_public_return() -> pub NotSerializable { + NotSerializable { x: 1 } + } + + #[external("public")] + fn bad_public_param(_p: NotSerializable) {} + + #[external("utility")] + unconstrained fn bad_utility_return() -> pub NotSerializable { + NotSerializable { x: 1 } + } + + #[external("utility")] + unconstrained fn bad_utility_param(_p: NotSerializable) {} +} diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 6e22013335f9..61718afd5350 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -77,6 +77,7 @@ members = [ "contracts/test/storage_proof_test_contract", "contracts/test/test_contract", "contracts/test/test_log_contract", + "contracts/test/unit_return_type_contract", "contracts/test/updatable_contract", "contracts/test/updated_contract" ] diff --git a/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/dapp_payload.nr b/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/dapp_payload.nr index 69d31c7a7dbf..ddfca613a786 100644 --- a/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/dapp_payload.nr +++ b/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/dapp_payload.nr @@ -5,7 +5,7 @@ use aztec::{ address::AztecAddress, constants::DOM_SEP__SIGNATURE_PAYLOAD, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize}, + traits::{Deserialize, Hash, Serialize}, }, }; use std::meta::derive; @@ -13,7 +13,7 @@ use std::meta::derive; global DAPP_MAX_CALLS: u32 = 1; // @dev: If you change the following struct you have to update default_entrypoint.ts -#[derive(Serialize)] +#[derive(Deserialize, Serialize)] pub struct DAppPayload { function_calls: [FunctionCall; DAPP_MAX_CALLS], // A nonce that enables transaction cancellation. When the cancellable flag is enabled, this nonce is used to diff --git a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr index d7cb22c0edfe..7472b6570b30 100644 --- a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/cards.nr @@ -9,14 +9,14 @@ use aztec::{ protocol::{ address::AztecAddress, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - traits::{FromField, Hash, Packable, Serialize, ToField}, + traits::{Deserialize, FromField, Hash, Packable, Serialize, ToField}, }, state_vars::{Owned, PrivateSet, StateVariable}, }; use field_note::FieldNote; use std::meta::derive; -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct Card { // We use u32s since u16s are unsupported pub strength: u32, diff --git a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/game.nr b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/game.nr index ea1bbd90104d..7330fd228be1 100644 --- a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/game.nr +++ b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/game.nr @@ -1,11 +1,14 @@ use crate::cards::Card; -use aztec::protocol::{address::AztecAddress, traits::{Deserialize, FromField, Packable, ToField}}; +use aztec::protocol::{ + address::AztecAddress, + traits::{Deserialize, FromField, Packable, Serialize, ToField}, +}; use std::meta::derive; global NUMBER_OF_PLAYERS: u32 = 2; global NUMBER_OF_CARDS_DECK: u32 = 2; -#[derive(Deserialize, Eq)] +#[derive(Serialize, Deserialize, Eq)] pub struct PlayerEntry { pub address: AztecAddress, pub deck_strength: u32, @@ -38,6 +41,7 @@ impl PlayerEntry { pub global PLAYABLE_CARDS: u32 = 4; +#[derive(Serialize, Deserialize)] pub struct Game { players: [PlayerEntry; NUMBER_OF_PLAYERS], pub rounds_cards: [Card; PLAYABLE_CARDS], diff --git a/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr index f244eba56c97..2096f85a2340 100644 --- a/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr @@ -13,7 +13,7 @@ contract OffchainEffect { }, note::note_viewer_options::NoteViewerOptions, oracle::offchain_effect::emit_offchain_effect, - protocol::{address::AztecAddress, traits::Serialize}, + protocol::{address::AztecAddress, traits::{Deserialize, Serialize}}, state_vars::{Owned, PrivateSet}, }; use uint_note::UintNote; @@ -25,7 +25,7 @@ contract OffchainEffect { pub c: u64, } - #[derive(Serialize)] + #[derive(Deserialize, Serialize)] pub struct EffectPayload { pub data: [Field; 5], pub next_contract: AztecAddress, diff --git a/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/Nargo.toml new file mode 100644 index 000000000000..c6d3024c414c --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "unit_return_type_contract" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/src/main.nr new file mode 100644 index 000000000000..7ebeb4d06e00 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/unit_return_type_contract/src/main.nr @@ -0,0 +1,16 @@ +// Verifies that contract functions with a unit return type `()` compile without requiring Serialize or Deserialize. +use aztec::macros::aztec; + +#[aztec] +pub contract UnitReturnType { + use aztec::macros::functions::external; + + #[external("private")] + fn private_unit_return(_x: Field) {} + + #[external("public")] + fn public_unit_return(_x: Field) {} + + #[external("utility")] + unconstrained fn utility_unit_return(_x: Field) {} +}