diff --git a/barretenberg/acir_tests/Dockerfile.bb b/barretenberg/acir_tests/Dockerfile.bb index 0fda0d6ec15..000627d8172 100644 --- a/barretenberg/acir_tests/Dockerfile.bb +++ b/barretenberg/acir_tests/Dockerfile.bb @@ -4,7 +4,7 @@ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir-acir-tests as noir-acir-t FROM node:18-alpine RUN apk update && apk add git bash curl jq coreutils COPY --from=0 /usr/src/barretenberg/cpp/build /usr/src/barretenberg/cpp/build -COPY --from=noir-acir-tests /usr/src/noir/tooling/nargo_cli/tests /usr/src/noir/tooling/nargo_cli/tests +COPY --from=noir-acir-tests /usr/src/noir/test_programs /usr/src/noir/test_programs WORKDIR /usr/src/barretenberg/acir_tests COPY . . # Run every acir test through native bb build prove_then_verify flow. diff --git a/barretenberg/acir_tests/Dockerfile.bb.js b/barretenberg/acir_tests/Dockerfile.bb.js index 3e4ddfb91e3..1b86d6e953d 100644 --- a/barretenberg/acir_tests/Dockerfile.bb.js +++ b/barretenberg/acir_tests/Dockerfile.bb.js @@ -3,7 +3,7 @@ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir-acir-tests as noir-acir-t FROM node:18 COPY --from=0 /usr/src/barretenberg/ts /usr/src/barretenberg/ts -COPY --from=noir-acir-tests /usr/src/noir/tooling/nargo_cli/tests /usr/src/noir/tooling/nargo_cli/tests +COPY --from=noir-acir-tests /usr/src/noir/test_programs /usr/src/noir/test_programs RUN apt update && apt install -y lsof jq WORKDIR /usr/src/barretenberg/acir_tests # Build/install ts apps. diff --git a/barretenberg/acir_tests/Dockerfile.bb.sol b/barretenberg/acir_tests/Dockerfile.bb.sol index 1cbc3ce8a22..7840d0c2e4f 100644 --- a/barretenberg/acir_tests/Dockerfile.bb.sol +++ b/barretenberg/acir_tests/Dockerfile.bb.sol @@ -6,7 +6,7 @@ FROM node:18-alpine RUN apk update && apk add git bash curl jq COPY --from=0 /usr/src/barretenberg/cpp/build /usr/src/barretenberg/cpp/build COPY --from=1 /usr/src/barretenberg/sol/src/ultra/BaseUltraVerifier.sol /usr/src/barretenberg/sol/src/ultra/BaseUltraVerifier.sol -COPY --from=noir-acir-tests /usr/src/noir/tooling/nargo_cli/tests /usr/src/noir/tooling/nargo_cli/tests +COPY --from=noir-acir-tests /usr/src/noir/test_programs /usr/src/noir/test_programs COPY --from=ghcr.io/foundry-rs/foundry:latest /usr/local/bin/anvil /usr/local/bin/anvil WORKDIR /usr/src/barretenberg/acir_tests COPY . . diff --git a/barretenberg/acir_tests/Dockerfile.noir_acir_tests b/barretenberg/acir_tests/Dockerfile.noir_acir_tests index 938e55ca75e..87fdd8604a4 100644 --- a/barretenberg/acir_tests/Dockerfile.noir_acir_tests +++ b/barretenberg/acir_tests/Dockerfile.noir_acir_tests @@ -5,6 +5,6 @@ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir RUN apk add bash jq ENV PATH="/usr/src/noir/target/release:${PATH}" -WORKDIR /usr/src/noir/tooling/nargo_cli/tests +WORKDIR /usr/src/noir/test_programs COPY . . RUN ./rebuild.sh \ No newline at end of file diff --git a/barretenberg/acir_tests/clone_test_vectors.sh b/barretenberg/acir_tests/clone_test_vectors.sh index e2d4c34e2b7..c6fd6ef1bf1 100755 --- a/barretenberg/acir_tests/clone_test_vectors.sh +++ b/barretenberg/acir_tests/clone_test_vectors.sh @@ -1,7 +1,7 @@ #!/bin/bash set -eu -TEST_SRC=${TEST_SRC:-../../noir/tooling/nargo_cli/tests/acir_artifacts} +TEST_SRC=${TEST_SRC:-../../noir/test_programs/acir_artifacts} if [ ! -d acir_tests ]; then cp -R $TEST_SRC acir_tests diff --git a/build_manifest.yml b/build_manifest.yml index 6244f89393d..09c96546ecb 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -7,11 +7,11 @@ noir-packages: dockerfile: Dockerfile.packages noir-acir-tests: - buildDir: noir/tooling/nargo_cli/tests + buildDir: noir/test_programs # Awkward. Maybe change dockerfile paths to be absolute. - dockerfile: ../../../../barretenberg/acir_tests/Dockerfile.noir_acir_tests + dockerfile: ../../barretenberg/acir_tests/Dockerfile.noir_acir_tests rebuildPatterns: - - ^noir/tooling/nargo_cli/tests + - ^noir/test_programs - ^barretenberg/acir_tests/Dockerfile.noir_acir_tests dependencies: - noir diff --git a/noir/.github/workflows/auto-pr-rebuild-script.yml b/noir/.github/workflows/auto-pr-rebuild-script.yml index 4937de98e04..336f2288878 100644 --- a/noir/.github/workflows/auto-pr-rebuild-script.yml +++ b/noir/.github/workflows/auto-pr-rebuild-script.yml @@ -99,7 +99,7 @@ jobs: git config --local user.email kevtheappdev@gmail.com - name: Run rebuild script - working-directory: tooling/nargo_cli/tests + working-directory: test_programs run: | chmod +x ./rebuild.sh ./rebuild.sh @@ -108,14 +108,14 @@ jobs: uses: actions/upload-artifact@v3 with: name: acir-artifacts - path: ./tooling/nargo_cli/tests/acir_artifacts + path: ./test_programs/acir_artifacts retention-days: 10 - name: Check for changes in acir_artifacts directory id: check_changes if: ${{ github.ref_name }} == "master" run: | - git diff --quiet tooling/nargo_cli/tests/acir_artifacts/ || echo "::set-output name=changes::true" + git diff --quiet test_programs/acir_artifacts/ || echo "::set-output name=changes::true" - name: Create or Update PR if: steps.check_changes.outputs.changes == 'true' @@ -125,6 +125,6 @@ jobs: commit-message: "chore: update acir artifacts" title: "chore: Update ACIR artifacts" body: "Automatic PR to update acir artifacts" - add-paths: tooling/nargo_cli/tests/acir_artifacts/*.gz + add-paths: test_programs/acir_artifacts/*.gz labels: "auto-pr" branch: "auto-pr-rebuild-script-branch" diff --git a/noir/.github/workflows/build-aztec-feature-flag.yml b/noir/.github/workflows/build-aztec-feature-flag.yml index 888a88a7f88..bacf74ba7b1 100644 --- a/noir/.github/workflows/build-aztec-feature-flag.yml +++ b/noir/.github/workflows/build-aztec-feature-flag.yml @@ -42,4 +42,4 @@ jobs: save-if: ${{ github.event_name != 'merge_group' }} - name: Build with feature flag - run: cargo build --features="noirc_frontend/aztec" + run: cargo build --features="noirc_driver/aztec" diff --git a/noir/.github/workflows/gates_report.yml b/noir/.github/workflows/gates_report.yml index 41a68c65852..8e3ef768828 100644 --- a/noir/.github/workflows/gates_report.yml +++ b/noir/.github/workflows/gates_report.yml @@ -50,9 +50,7 @@ jobs: pull-requests: write steps: - - uses: actions/checkout@v3 - with: - submodules: recursive + - uses: actions/checkout@v4 - name: Download nargo binary uses: actions/download-artifact@v3 @@ -69,10 +67,10 @@ jobs: nargo -V - name: Generate gates report - working-directory: ./tooling/nargo_cli/tests + working-directory: ./test_programs run: | ./gates_report.sh - mv gates_report.json ../../../gates_report.json + mv gates_report.json ../gates_report.json - name: Compare gates reports id: gates_diff diff --git a/noir/.github/workflows/publish-es-packages.yml b/noir/.github/workflows/publish-es-packages.yml index 2e88ee2b77f..f421672c799 100644 --- a/noir/.github/workflows/publish-es-packages.yml +++ b/noir/.github/workflows/publish-es-packages.yml @@ -33,7 +33,7 @@ jobs: - name: Enable aztec features if: ${{ inputs.npm-tag == 'aztec' }} run: | - echo $'\n'"default = [\"aztec\"]"$'\n' >> compiler/noirc_frontend/Cargo.toml + echo $'\n'"default = [\"aztec\"]"$'\n' >> compiler/noirc_driver/Cargo.toml - name: Build wasm package run: | diff --git a/noir/.github/workflows/test-abi_wasm.yml b/noir/.github/workflows/test-abi_wasm.yml deleted file mode 100644 index 52223d874bf..00000000000 --- a/noir/.github/workflows/test-abi_wasm.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: ABI Wasm test - -on: - pull_request: - merge_group: - push: - branches: - - master - -# This will cancel previous runs when a branch or PR is updated -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build noirc_abi_wasm - run: | - nix build -L .#noirc_abi_wasm - cp -r ./result/noirc_abi_wasm/nodejs ./tooling/noirc_abi_wasm - cp -r ./result/noirc_abi_wasm/web ./tooling/noirc_abi_wasm - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f ./result/noirc_abi_wasm)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: noirc_abi_wasm - path: ${{ env.UPLOAD_PATH }} - retention-days: 10 - - test: - runs-on: ubuntu-latest - needs: [build] - - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Download wasm package artifact - uses: actions/download-artifact@v3 - with: - name: noirc_abi_wasm - path: ./tooling/noirc_abi_wasm - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Run node tests - run: yarn workspace @noir-lang/noirc_abi test - - - name: Install Playwright - uses: ./.github/actions/install-playwright - - - name: Run browser tests - run: yarn workspace @noir-lang/noirc_abi test:browser - diff --git a/noir/.github/workflows/test-acvm-js.yml b/noir/.github/workflows/test-acvm-js.yml deleted file mode 100644 index 14ce5d916c0..00000000000 --- a/noir/.github/workflows/test-acvm-js.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: Test acvm_js - -on: - pull_request: - merge_group: - push: - branches: - - master - -# This will cancel previous runs when a branch or PR is updated -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-acvm-js-package: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build acvm-js - run: | - nix build -L .#acvm_js - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: acvm-js - path: ${{ env.UPLOAD_PATH }} - retention-days: 3 - - test-acvm_js-node: - needs: [build-acvm-js-package] - name: Node.js Tests - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: acvm-js - path: ./result - - - name: Move build artifacts - run: | - mv ./result/acvm_js/nodejs ./acvm-repo/acvm_js/nodejs - mv ./result/acvm_js/web ./acvm-repo/acvm_js/web - - - name: Set up test environment - uses: ./.github/actions/setup - - - name: Run node tests - run: yarn workspace @noir-lang/acvm_js test - - test-acvm_js-browser: - needs: [build-acvm-js-package] - name: Browser Tests - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: acvm-js - path: ./result - - - name: Move build artifacts - run: | - mv ./result/acvm_js/nodejs ./acvm-repo/acvm_js/nodejs - mv ./result/acvm_js/web ./acvm-repo/acvm_js/web - - - name: Set up test environment - uses: ./.github/actions/setup - - - name: Install playwright deps - run: | - npx playwright install - npx playwright install-deps - - - name: Run browser tests - working-directory: ./acvm-repo/acvm_js - run: yarn workspace @noir-lang/acvm_js test:browser diff --git a/noir/.github/workflows/test-integration.yml b/noir/.github/workflows/test-integration.yml deleted file mode 100644 index ad28d9c8e86..00000000000 --- a/noir/.github/workflows/test-integration.yml +++ /dev/null @@ -1,199 +0,0 @@ -name: test-integration - -on: - workflow_dispatch: - pull_request: - merge_group: - schedule: - - cron: "0 2 * * *" # Run nightly at 2 AM UTC - -jobs: - build-nargo: - runs-on: ubuntu-latest - strategy: - matrix: - target: [x86_64-unknown-linux-gnu] - - steps: - - name: Checkout Noir repo - uses: actions/checkout@v4 - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.71.1 - - - uses: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.target }} - cache-on-failure: true - save-if: ${{ github.event_name != 'merge_group' }} - - - name: Build Nargo - run: cargo build --package nargo_cli --release - - - name: Package artifacts - run: | - mkdir dist - cp ./target/release/nargo ./dist/nargo - 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: nargo - path: ./dist/* - retention-days: 3 - - build-acvm-js: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build acvm-js - run: | - nix build -L .#acvm_js - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f result/acvm_js)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: acvm-js - path: ${{ env.UPLOAD_PATH }} - retention-days: 3 - - build-wasm: - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build wasm package - run: | - nix build -L .#noir_wasm - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f ./result/noir_wasm)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: noir_wasm - path: ${{ env.UPLOAD_PATH }} - retention-days: 3 - - build-noirc: - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build noirc_abi_wasm - run: | - nix build -L .#noirc_abi_wasm - cp -r ./result/noirc_abi_wasm/nodejs ./tooling/noirc_abi_wasm - cp -r ./result/noirc_abi_wasm/web ./tooling/noirc_abi_wasm - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f ./result/noirc_abi_wasm)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: noirc_abi_wasm - path: ${{ env.UPLOAD_PATH }} - retention-days: 10 - - test-solidity-verifier: - runs-on: ubuntu-latest - needs: [build-acvm-js, build-wasm, build-nargo, build-noirc] - env: - CACHED_PATH: /tmp/nix-cache - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Download nargo binary - uses: actions/download-artifact@v3 - with: - name: nargo - path: ./nargo - - - name: Download acvm_js package artifact - uses: actions/download-artifact@v3 - with: - name: acvm-js - path: ./acvm-repo/acvm_js - - - name: Download noir_wasm package artifact - uses: actions/download-artifact@v3 - with: - name: noir_wasm - path: ./compiler/wasm - - - name: Download noirc_abi package artifact - uses: actions/download-artifact@v3 - with: - name: noirc_abi_wasm - path: ./tooling/noirc_abi_wasm - - - name: Set nargo on PATH - run: | - nargo_binary="${{ github.workspace }}/nargo/nargo" - chmod +x $nargo_binary - echo "$(dirname $nargo_binary)" >> $GITHUB_PATH - export PATH="$PATH:$(dirname $nargo_binary)" - nargo -V - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Install Playwright - uses: ./.github/actions/install-playwright - - - name: Setup `integration-tests` - run: | - yarn workspace @noir-lang/source-resolver build - yarn workspace @noir-lang/types build - yarn workspace @noir-lang/backend_barretenberg build - yarn workspace @noir-lang/noir_js build - - - name: Run `integration-tests` - run: | - yarn test:integration - - - name: Alert on nightly test failure - uses: JasonEtco/create-an-issue@v2 - if: ${{ failure() && github.event_name == 'schedule' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - WORKFLOW_NAME: ${{ github.workflow }} - WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - with: - update_existing: true - filename: .github/NIGHTLY_TEST_FAILURE.md diff --git a/noir/.github/workflows/test-js-packages.yml b/noir/.github/workflows/test-js-packages.yml new file mode 100644 index 00000000000..9ac61f34203 --- /dev/null +++ b/noir/.github/workflows/test-js-packages.yml @@ -0,0 +1,439 @@ +name: Javascript Tests + +on: + pull_request: + merge_group: + push: + branches: + - master + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-nargo: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout Noir repo + uses: actions/checkout@v4 + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.71.1 + + - uses: Swatinem/rust-cache@v2 + with: + key: x86_64-unknown-linux-gnu + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Build Nargo + run: cargo build --package nargo_cli --release + + - name: Package artifacts + run: | + mkdir dist + cp ./target/release/nargo ./dist/nargo + 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: nargo + path: ./dist/* + retention-days: 3 + + build-noir-wasm: + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Setup Nix + uses: ./.github/actions/nix + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + nix-cache-name: "noir" + cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} + + - name: Build wasm package + run: | + nix build -L .#noir_wasm + + - name: Dereference symlink + run: echo "UPLOAD_PATH=$(readlink -f ./result/noir_wasm)" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: noir_wasm + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + + build-acvm-js: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Setup Nix + uses: ./.github/actions/nix + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + nix-cache-name: "noir" + cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} + + - name: Build acvm-js + run: | + nix build -L .#acvm_js + + - name: Dereference symlink + run: echo "UPLOAD_PATH=$(readlink -f result/acvm_js)" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: acvm-js + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + build-noirc-abi: + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Setup Nix + uses: ./.github/actions/nix + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + nix-cache-name: "noir" + cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} + + - name: Build noirc_abi_wasm + run: | + nix build -L .#noirc_abi_wasm + + - name: Dereference symlink + run: echo "UPLOAD_PATH=$(readlink -f ./result/noirc_abi_wasm)" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: noirc_abi_wasm + path: ${{ env.UPLOAD_PATH }} + retention-days: 10 + + test-acvm_js-node: + needs: [build-acvm-js] + name: ACVM JS (Node.js) + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/acvm_js + + - name: Set up test environment + uses: ./.github/actions/setup + + - name: Run node tests + run: yarn workspace @noir-lang/acvm_js test + + test-acvm_js-browser: + needs: [build-acvm-js] + name: ACVM JS (Browser) + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/acvm_js + + - name: Set up test environment + uses: ./.github/actions/setup + + - name: Install playwright deps + run: | + npx playwright install + npx playwright install-deps + + - name: Run browser tests + run: yarn workspace @noir-lang/acvm_js test:browser + + test-noirc-abi: + needs: [build-noirc-abi] + name: noirc_abi + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Download wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Run node tests + run: yarn workspace @noir-lang/noirc_abi test + + - name: Install Playwright + uses: ./.github/actions/install-playwright + + - name: Run browser tests + run: yarn workspace @noir-lang/noirc_abi test:browser + + test-noir-js-backend-barretenberg: + needs: [build-noirc-abi] + name: noir-js-backend-barretenberg + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build noir_js_types + run: yarn workspace @noir-lang/types build + + - name: Run barretenberg wrapper tests + run: | + yarn workspace @noir-lang/backend_barretenberg test + + test-noir-js: + needs: [build-acvm-js, build-noirc-abi] + name: Noir JS + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/acvm_js + + - name: Download wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build noir_js_types + run: yarn workspace @noir-lang/types build + + - name: Build barretenberg wrapper + run: yarn workspace @noir-lang/backend_barretenberg build + + - name: Run noir_js tests + run: | + yarn workspace @noir-lang/noir_js build + yarn workspace @noir-lang/noir_js test + + test-source-resolver: + name: source-resolver + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build @noir-lang/source-resolver + run: yarn workspace @noir-lang/source-resolver build + + - name: Run tests + run: yarn workspace @noir-lang/source-resolver test + + test-noir-wasm: + needs: [build-noir-wasm, build-nargo] + name: noir_wasm + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Download wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noir_wasm + path: ./compiler/wasm + + - name: Download nargo binary + uses: actions/download-artifact@v3 + with: + name: nargo + path: ./nargo + + - name: Compile fixtures with Nargo CLI + working-directory: ./compiler/wasm/fixtures + run: | + nargo_binary=${{ github.workspace }}/nargo/nargo + chmod +x $nargo_binary + for dir in $(ls -d */); do + pushd $dir/noir-script + $nargo_binary compile + popd + done + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Install Playwright + uses: ./.github/actions/install-playwright + + - name: Install dependencies + run: | + yarn workspace @noir-lang/source-resolver build + + - name: Run node tests + run: yarn workspace @noir-lang/noir_wasm test:node + + - name: Run browser tests + run: yarn workspace @noir-lang/noir_wasm test:browser + + test-noir-codegen: + needs: [build-acvm-js, build-noirc-abi] + name: noir_codegen + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download acvm_js package artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/acvm_js + + - name: Download noirc_abi package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build noir_js_types + run: yarn workspace @noir-lang/types build + + - name: Build noir_js + run: yarn workspace @noir-lang/noir_js build + + - name: Run noir_codegen tests + run: yarn workspace @noir-lang/noir_codegen test + + test-integration: + name: Integration Tests + runs-on: ubuntu-latest + needs: [build-acvm-js, build-noir-wasm, build-nargo, build-noirc-abi] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download nargo binary + uses: actions/download-artifact@v3 + with: + name: nargo + path: ./nargo + + - name: Download acvm_js package artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/acvm_js + + - name: Download noir_wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noir_wasm + path: ./compiler/wasm + + - name: Download noirc_abi package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Set nargo on PATH + run: | + nargo_binary="${{ github.workspace }}/nargo/nargo" + chmod +x $nargo_binary + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" + nargo -V + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Install Playwright + uses: ./.github/actions/install-playwright + + - name: Setup `integration-tests` + run: | + # Note the lack of spaces between package names. + PACKAGES_TO_BUILD="@noir-lang/source-resolver,@noir-lang/types,@noir-lang/backend_barretenberg,@noir-lang/noir_js" + yarn workspaces foreach -vp --from "{$PACKAGES_TO_BUILD}" run build + + - name: Run `integration-tests` + run: | + yarn test:integration + + # This is a noop job which depends on all test jobs + # This allows us to add/remove test jobs without having to update the required workflows. + tests-end: + name: End + runs-on: ubuntu-latest + needs: + - test-acvm_js-node + - test-acvm_js-browser + - test-noirc-abi + - test-noir-js-backend-barretenberg + - test-noir-js + - test-source-resolver + - test-noir-wasm + - test-noir-codegen + - test-integration + + steps: + - name: Noop + run: echo "noop" diff --git a/noir/.github/workflows/test-noir-js.yml b/noir/.github/workflows/test-noir-js.yml deleted file mode 100644 index e74f2ee6015..00000000000 --- a/noir/.github/workflows/test-noir-js.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Test Noir Js - -on: - pull_request: - merge_group: - push: - branches: - - master - -jobs: - test-noir-js: - name: Test Noir JS - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.71.1 - with: - targets: wasm32-unknown-unknown - - - uses: Swatinem/rust-cache@v2 - with: - key: wasm32-unknown-unknown-noir-js - cache-on-failure: true - save-if: ${{ github.event_name != 'merge_group' }} - - - name: Install jq - run: sudo apt-get install jq - - - name: Install wasm-bindgen-cli - uses: taiki-e/install-action@v2 - with: - tool: wasm-bindgen-cli@0.2.86 - - - name: Install wasm-opt - run: | - npm i wasm-opt -g - - - name: Build acvm_js - run: yarn workspace @noir-lang/acvm_js build - - - name: Build noirc_abi - run: yarn workspace @noir-lang/noirc_abi build - - - name: Build noir_js_types - run: yarn workspace @noir-lang/types build - - - name: Build barretenberg wrapper - run: yarn workspace @noir-lang/backend_barretenberg build - - - name: Run noir_js tests - run: | - yarn workspace @noir-lang/noir_js build - yarn workspace @noir-lang/noir_js test diff --git a/noir/.github/workflows/test-noir_codegen.yml b/noir/.github/workflows/test-noir_codegen.yml deleted file mode 100644 index d5a04a9dcd0..00000000000 --- a/noir/.github/workflows/test-noir_codegen.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: noir_codegen - -on: - pull_request: - merge_group: - push: - branches: - - master - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-nargo: - runs-on: ubuntu-22.04 - strategy: - matrix: - target: [x86_64-unknown-linux-gnu] - - steps: - - name: Checkout Noir repo - uses: actions/checkout@v4 - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.71.1 - - - uses: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.target }} - cache-on-failure: true - save-if: ${{ github.event_name != 'merge_group' }} - - - name: Build Nargo - run: cargo build --package nargo_cli --release - - - name: Package artifacts - run: | - mkdir dist - cp ./target/release/nargo ./dist/nargo - 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: nargo - path: ./dist/* - retention-days: 3 - - test: - needs: [build-nargo] - name: Test noir_codegen - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.71.1 - with: - targets: wasm32-unknown-unknown - - - uses: Swatinem/rust-cache@v2 - with: - key: wasm32-unknown-unknown-noir-js - cache-on-failure: true - save-if: ${{ github.event_name != 'merge_group' }} - - - name: Install jq - run: sudo apt-get install jq - - - name: Install wasm-bindgen-cli - uses: taiki-e/install-action@v2 - with: - tool: wasm-bindgen-cli@0.2.86 - - - name: Install wasm-opt - run: | - npm i wasm-opt -g - - - name: Build acvm_js - run: yarn workspace @noir-lang/acvm_js build - - - name: Build noirc_abi - run: yarn workspace @noir-lang/noirc_abi build - - - name: Build noir_js_types - run: yarn workspace @noir-lang/types build - - - name: Build noir_js - run: yarn workspace @noir-lang/noir_js build - - - name: Run noir_codegen tests - run: yarn workspace @noir-lang/noir_codegen test diff --git a/noir/.github/workflows/test-noir_wasm.yml b/noir/.github/workflows/test-noir_wasm.yml deleted file mode 100644 index 2175e20acd7..00000000000 --- a/noir/.github/workflows/test-noir_wasm.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: Wasm - -on: - pull_request: - merge_group: - push: - branches: - - master - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-nargo: - runs-on: ubuntu-22.04 - strategy: - matrix: - target: [x86_64-unknown-linux-gnu] - - steps: - - name: Checkout Noir repo - uses: actions/checkout@v4 - - - name: Setup toolchain - uses: dtolnay/rust-toolchain@1.71.1 - - - uses: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.target }} - cache-on-failure: true - save-if: ${{ github.event_name != 'merge_group' }} - - - name: Build Nargo - run: cargo build --package nargo_cli --release - - - name: Package artifacts - run: | - mkdir dist - cp ./target/release/nargo ./dist/nargo - 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: nargo - path: ./dist/* - retention-days: 3 - - build-wasm: - runs-on: ubuntu-latest - - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Setup Nix - uses: ./.github/actions/nix - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build wasm package - run: | - nix build -L .#noir_wasm - - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f ./result/noir_wasm)" >> $GITHUB_ENV - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: noir_wasm - path: ${{ env.UPLOAD_PATH }} - retention-days: 3 - - test: - needs: [build-wasm, build-nargo] - name: Test noir_wasm - runs-on: ubuntu-latest - steps: - - name: Checkout noir-lang/noir - uses: actions/checkout@v4 - - - name: Download wasm package artifact - uses: actions/download-artifact@v3 - with: - name: noir_wasm - path: ./compiler/wasm/downloaded - - - name: Download nargo binary - uses: actions/download-artifact@v3 - with: - name: nargo - path: ./nargo - - - name: Compile fixtures with Nargo CLI - working-directory: ./compiler/wasm/fixtures - run: | - nargo_binary=${{ github.workspace }}/nargo/nargo - chmod +x $nargo_binary - for dir in $(ls -d */); do - pushd $dir/noir-script - $nargo_binary compile - popd - done - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Install Playwright - uses: ./.github/actions/install-playwright - - - name: Install dependencies - run: | - cp -r ./compiler/wasm/downloaded/nodejs ./compiler/wasm - cp -r ./compiler/wasm/downloaded/web ./compiler/wasm - yarn workspace @noir-lang/source-resolver build - - - name: Run node tests - run: yarn workspace @noir-lang/noir_wasm test:node - - - name: Run browser tests - run: yarn workspace @noir-lang/noir_wasm test:browser diff --git a/noir/.github/workflows/test-source-resolver.yml b/noir/.github/workflows/test-source-resolver.yml deleted file mode 100644 index 5dafe4c5fd9..00000000000 --- a/noir/.github/workflows/test-source-resolver.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Test Source Resolver - -on: - push: - paths: - - "compiler/source-resolver/**" - pull_request: - paths: - - "compiler/source-resolver/**" - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Yarn dependencies - uses: ./.github/actions/setup - - - name: Build @noir-lang/source-resolver - run: yarn workspace @noir-lang/source-resolver build - - - name: Run tests - run: yarn workspace @noir-lang/source-resolver test diff --git a/noir/.gitignore b/noir/.gitignore index 355ae67f11c..11f0ae3b975 100644 --- a/noir/.gitignore +++ b/noir/.gitignore @@ -36,9 +36,10 @@ result *.pk *.vk **/Verifier.toml +**/contract **/target -!tooling/nargo_cli/tests/acir_artifacts/*/target -!tooling/nargo_cli/tests/acir_artifacts/*/target/witness.gz +!test_programs/acir_artifacts/*/target +!test_programs/acir_artifacts/*/target/witness.gz !compiler/wasm/noir-script/target gates_report.json diff --git a/noir/.gitrepo b/noir/.gitrepo index c615890741b..79be89511b5 100644 --- a/noir/.gitrepo +++ b/noir/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/noir-lang/noir branch = aztec - commit = 6743afcc77014fac575469395116b77dd205caf7 - parent = a1bfe2d4dd45a94ecc00da963887bf96f86bc34f + commit = 7f1b85708783338043c88adfa1e258c262652377 + parent = 1621f3a1cec3ad16fe7e87160f9b43d3f9490dbd method = merge cmdver = 0.4.6 diff --git a/noir/.release-please-manifest.json b/noir/.release-please-manifest.json index 73b991cb8af..8a6f95c33e0 100644 --- a/noir/.release-please-manifest.json +++ b/noir/.release-please-manifest.json @@ -1,4 +1,4 @@ { - ".": "0.19.3", - "acvm-repo": "0.34.0" + ".": "0.19.4", + "acvm-repo": "0.35.0" } \ No newline at end of file diff --git a/noir/CHANGELOG.md b/noir/CHANGELOG.md index d6077b06b05..077c9973806 100644 --- a/noir/CHANGELOG.md +++ b/noir/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [0.19.4](https://github.com/noir-lang/noir/compare/v0.19.3...v0.19.4) (2023-11-28) + + +### Features + +* Add --check option to nargo fmt for dry-run formatting verification ([#3530](https://github.com/noir-lang/noir/issues/3530)) ([4469707](https://github.com/noir-lang/noir/commit/4469707d97085fab0f7ade8d015dc827c56156ee)) +* Add support for tuple values in `noir_codegen` ([#3592](https://github.com/noir-lang/noir/issues/3592)) ([346d75f](https://github.com/noir-lang/noir/commit/346d75f9dd9261996d4d7bb80eb7e4118e8f8ce2)) +* Codegen typed interfaces for functions in `noir_codegen` ([#3533](https://github.com/noir-lang/noir/issues/3533)) ([290c463](https://github.com/noir-lang/noir/commit/290c463622a93a34293f73b5bf2aea7ade30a11c)) +* Export `CompiledCircuit` from codegened TS ([#3589](https://github.com/noir-lang/noir/issues/3589)) ([e06c675](https://github.com/noir-lang/noir/commit/e06c67500da11518caffe0e98bdb9cd7f5f89049)) +* Remove type arrays for flat slices ([#3466](https://github.com/noir-lang/noir/issues/3466)) ([8225b2b](https://github.com/noir-lang/noir/commit/8225b2b379ddf145f9418f8517478704f9aac350)) +* Send and receive unflattened public inputs to backend ([#3543](https://github.com/noir-lang/noir/issues/3543)) ([a7bdc67](https://github.com/noir-lang/noir/commit/a7bdc67ef3ec2037bffc4f1f472907cad786c319)) + + +### Bug Fixes + +* Compiler version error message ([#3558](https://github.com/noir-lang/noir/issues/3558)) ([026a358](https://github.com/noir-lang/noir/commit/026a3587b01ddc8f444ff588a7b3f3fd1a0bb386)) +* Remove quotes from println output ([#3574](https://github.com/noir-lang/noir/issues/3574)) ([127b6aa](https://github.com/noir-lang/noir/commit/127b6aa1ec8893275fdfa7795db7c52c4fc1d4dd)) +* Somewhat reduce mem2reg memory usage ([#3572](https://github.com/noir-lang/noir/issues/3572)) ([9b9ed89](https://github.com/noir-lang/noir/commit/9b9ed890e68b6c7f0671b05919bdc86f593c5df5)) +* Use 128 bits for constant bit shift ([#3586](https://github.com/noir-lang/noir/issues/3586)) ([2ca9b05](https://github.com/noir-lang/noir/commit/2ca9b059317f0513ea21153ebdb468c4f6633de5)) + ## [0.19.3](https://github.com/noir-lang/noir/compare/v0.19.2...v0.19.3) (2023-11-22) diff --git a/noir/Cargo.lock b/noir/Cargo.lock index 9536508436b..43958d2f1cb 100644 --- a/noir/Cargo.lock +++ b/noir/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir_field", "base64", @@ -23,7 +23,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.34.0" +version = "0.35.0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -37,7 +37,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -54,7 +54,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir", "blake2", @@ -67,7 +67,7 @@ dependencies = [ [[package]] name = "acvm_js" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acvm", "barretenberg_blackbox_solver", @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "acvm_stdlib" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir", ] @@ -217,7 +217,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arena" -version = "0.19.3" +version = "0.19.4" dependencies = [ "generational-arena", ] @@ -413,6 +413,14 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aztec_macros" +version = "0.19.4" +dependencies = [ + "iter-extended", + "noirc_frontend", +] + [[package]] name = "backend-interface" version = "0.11.0" @@ -449,7 +457,7 @@ dependencies = [ [[package]] name = "barretenberg_blackbox_solver" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -573,7 +581,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir_field", "serde", @@ -581,7 +589,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.34.0" +version = "0.35.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -1596,7 +1604,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.19.3" +version = "0.19.4" dependencies = [ "codespan-reporting", "iter-extended", @@ -2158,7 +2166,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.19.3" +version = "0.19.4" [[package]] name = "itertools" @@ -2380,7 +2388,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "codespan-reporting", @@ -2400,7 +2408,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "assert_cmd", @@ -2449,7 +2457,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.19.3" +version = "0.19.4" dependencies = [ "bytecount", "noirc_frontend", @@ -2461,7 +2469,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.19.3" +version = "0.19.4" dependencies = [ "dirs", "fm", @@ -2510,7 +2518,7 @@ dependencies = [ [[package]] name = "noir_debugger" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "codespan-reporting", @@ -2524,7 +2532,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "async-lsp", @@ -2549,7 +2557,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "build-data", @@ -2571,7 +2579,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "iter-extended", @@ -2588,7 +2596,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "build-data", @@ -2605,9 +2613,10 @@ dependencies = [ [[package]] name = "noirc_driver" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", + "aztec_macros", "build-data", "clap", "fm", @@ -2622,7 +2631,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "chumsky", @@ -2635,7 +2644,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "fxhash", @@ -2650,7 +2659,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "arena", @@ -2672,7 +2681,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.19.3" +version = "0.19.4" dependencies = [ "acvm", "iter-extended", diff --git a/noir/Cargo.toml b/noir/Cargo.toml index b891aa7d935..1a37a4f53e1 100644 --- a/noir/Cargo.toml +++ b/noir/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ + "aztec_macros", "compiler/noirc_evaluator", "compiler/noirc_frontend", "compiler/noirc_errors", @@ -38,7 +39,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.19.3" +version = "0.19.4" # x-release-please-end authors = ["The Noir Team "] edition = "2021" diff --git a/noir/acvm-repo/CHANGELOG.md b/noir/acvm-repo/CHANGELOG.md index 9c55a1ad0c2..ff3ba716680 100644 --- a/noir/acvm-repo/CHANGELOG.md +++ b/noir/acvm-repo/CHANGELOG.md @@ -5,6 +5,54 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.35.0](https://github.com/noir-lang/noir/compare/v0.34.0...v0.35.0) (2023-11-28) + + +### ⚠ BREAKING CHANGES + +* Move circuit serialization circuit into acir ([#3345](https://github.com/noir-lang/noir/issues/3345)) +* expose pedersen hash in acir and bb solver ([#3269](https://github.com/noir-lang/noir/issues/3269)) +* Switch to new pedersen implementation ([#3151](https://github.com/noir-lang/noir/issues/3151)) +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) +* **wasm:** improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) +* Maintain shape of foreign call arguments ([#2935](https://github.com/noir-lang/noir/issues/2935)) + +### Features + +* **acvm_js:** Export black box solver functions ([#2812](https://github.com/noir-lang/noir/issues/2812)) ([da8a98e](https://github.com/noir-lang/noir/commit/da8a98ed312fe69cb0bdb8f9d0a70ee7a981398f)) +* **acvm:** Separate ACVM optimizations and transformations ([#2979](https://github.com/noir-lang/noir/issues/2979)) ([5865d1a](https://github.com/noir-lang/noir/commit/5865d1a1bca16e1853663c71f893ff81fa3f7185)) +* Add ACIR serializer C++ codegen ([#2961](https://github.com/noir-lang/noir/issues/2961)) ([7556982](https://github.com/noir-lang/noir/commit/7556982dbebe25eaa17240abbe270b771b55de45)) +* Add conditional compilation of methods based on the underlying field being used ([#3045](https://github.com/noir-lang/noir/issues/3045)) ([2e008e2](https://github.com/noir-lang/noir/commit/2e008e2438795bbc41b0641e830378b76bf2e194)) +* Add debugger commands to introspect (and modify) the current state ([#3391](https://github.com/noir-lang/noir/issues/3391)) ([9e1ad85](https://github.com/noir-lang/noir/commit/9e1ad858cf8a1d9aba0137abe6a749267498bfaf)) +* Expose pedersen hash in acir and bb solver ([#3269](https://github.com/noir-lang/noir/issues/3269)) ([0108b6c](https://github.com/noir-lang/noir/commit/0108b6c1e8dc0dfc766ab3c4944deae9354dec36)) +* Extract Brillig VM to allow step debugging ([#3259](https://github.com/noir-lang/noir/issues/3259)) ([f6431f9](https://github.com/noir-lang/noir/commit/f6431f99711f15a96a4f7fed2f413daece94b5e1)) +* Implement euclidean division and signed division in terms of `AcirVar`s ([#3230](https://github.com/noir-lang/noir/issues/3230)) ([b8b7782](https://github.com/noir-lang/noir/commit/b8b77825410c0e1f95549259a51e2c40de1ec342)) +* Maintain shape of foreign call arguments ([#2935](https://github.com/noir-lang/noir/issues/2935)) ([f7869e6](https://github.com/noir-lang/noir/commit/f7869e6fb492b617e776e538ac4babfa56261d26)) +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) ([b3a9c34](https://github.com/noir-lang/noir/commit/b3a9c343993ce3207de62106bda6cb2b2ef3de50)) +* Pass brillig bytecode to VM by reference ([#3030](https://github.com/noir-lang/noir/issues/3030)) ([4ee290b](https://github.com/noir-lang/noir/commit/4ee290b8b6f75bc1974a5750248570eeca8d244e)) +* Refactor debugger and separate core from UI ([#3308](https://github.com/noir-lang/noir/issues/3308)) ([8466810](https://github.com/noir-lang/noir/commit/846681079ab7295b201480a5c8baebc45e858c6f)) +* Replace boolean range constraints with arithmetic opcodes ([#3234](https://github.com/noir-lang/noir/issues/3234)) ([949222c](https://github.com/noir-lang/noir/commit/949222c20d9e65152e3814d02da1c4c41ffc23a5)) +* Save Brillig execution state in ACVM ([#3026](https://github.com/noir-lang/noir/issues/3026)) ([88682da](https://github.com/noir-lang/noir/commit/88682da87ffc9e26da5c9e4b5a4d8e62a6ee43c6)) +* Solve `fixed_base_scalar_mul` black box functions in rust ([#3153](https://github.com/noir-lang/noir/issues/3153)) ([1c1afbc](https://github.com/noir-lang/noir/commit/1c1afbcddf0b5fdb39f00ad28ae90caf699d1265)) +* Switch to new pedersen implementation ([#3151](https://github.com/noir-lang/noir/issues/3151)) ([35fb3f7](https://github.com/noir-lang/noir/commit/35fb3f7076d52db7ca3bef0a70a3dbccaf82f58d)) +* **wasm:** Improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) ([1b5124b](https://github.com/noir-lang/noir/commit/1b5124bc74f7ac5360db04b34d1b7b2284061fd3)) + + +### Bug Fixes + +* ACIR optimizer should update assertion messages ([#3010](https://github.com/noir-lang/noir/issues/3010)) ([758b6b6](https://github.com/noir-lang/noir/commit/758b6b62918907c1a39f3090a77419003551745e)) +* **acvm:** Return false rather than panicking on invalid ECDSA signatures ([#2783](https://github.com/noir-lang/noir/issues/2783)) ([155abc0](https://github.com/noir-lang/noir/commit/155abc0d99fff41c79163c16bf297d41e5dff0fa)) +* Determinism of fallback transformer ([#3100](https://github.com/noir-lang/noir/issues/3100)) ([12daad1](https://github.com/noir-lang/noir/commit/12daad19c902caf5ee9e2eb4b6847bde5a924353)) +* Fix method `program_counter`, change method signature ([#3012](https://github.com/noir-lang/noir/issues/3012)) ([5ea522b](https://github.com/noir-lang/noir/commit/5ea522b840ca0f6f90d02ca00f0de32f515d450f)) +* Minor problems with `aztec` publishing ([#3095](https://github.com/noir-lang/noir/issues/3095)) ([0fc8f20](https://github.com/noir-lang/noir/commit/0fc8f20b8b87d033d27ce18db039399c17f81837)) +* Prevent duplicated assert message transformation ([#3038](https://github.com/noir-lang/noir/issues/3038)) ([082a6d0](https://github.com/noir-lang/noir/commit/082a6d02dad67a25692bed15c340a16a848a320e)) +* Return error rather than panicking on unreadable circuits ([#3179](https://github.com/noir-lang/noir/issues/3179)) ([d4f61d3](https://github.com/noir-lang/noir/commit/d4f61d3d51d515e40a5fd02d35315889f841bf53)) + + +### Miscellaneous Chores + +* Move circuit serialization circuit into acir ([#3345](https://github.com/noir-lang/noir/issues/3345)) ([122119b](https://github.com/noir-lang/noir/commit/122119b7377cec1b7c42c586c64b69b3bdf4d539)) + ## [0.34.0](https://github.com/noir-lang/noir/compare/v0.33.0...v0.34.0) (2023-11-22) diff --git a/noir/acvm-repo/acir/Cargo.toml b/noir/acvm-repo/acir/Cargo.toml index 3bd07e56212..8dd6a69a07d 100644 --- a/noir/acvm-repo/acir/Cargo.toml +++ b/noir/acvm-repo/acir/Cargo.toml @@ -2,7 +2,7 @@ name = "acir" description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 22278bdc635..70821913836 100644 --- a/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -120,75 +120,6 @@ pub enum BlackBoxFuncCall { } impl BlackBoxFuncCall { - #[deprecated = "BlackBoxFuncCall::dummy() is unnecessary and will be removed in ACVM 0.24.0"] - pub fn dummy(bb_func: BlackBoxFunc) -> Self { - match bb_func { - BlackBoxFunc::AND => BlackBoxFuncCall::AND { - lhs: FunctionInput::dummy(), - rhs: FunctionInput::dummy(), - output: Witness(0), - }, - BlackBoxFunc::XOR => BlackBoxFuncCall::XOR { - lhs: FunctionInput::dummy(), - rhs: FunctionInput::dummy(), - output: Witness(0), - }, - BlackBoxFunc::RANGE => BlackBoxFuncCall::RANGE { input: FunctionInput::dummy() }, - BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { inputs: vec![], outputs: vec![] }, - BlackBoxFunc::Blake2s => BlackBoxFuncCall::Blake2s { inputs: vec![], outputs: vec![] }, - BlackBoxFunc::SchnorrVerify => BlackBoxFuncCall::SchnorrVerify { - public_key_x: FunctionInput::dummy(), - public_key_y: FunctionInput::dummy(), - signature: vec![], - message: vec![], - output: Witness(0), - }, - BlackBoxFunc::PedersenCommitment => BlackBoxFuncCall::PedersenCommitment { - inputs: vec![], - domain_separator: 0, - outputs: (Witness(0), Witness(0)), - }, - BlackBoxFunc::PedersenHash => BlackBoxFuncCall::PedersenHash { - inputs: vec![], - domain_separator: 0, - output: Witness(0), - }, - BlackBoxFunc::HashToField128Security => { - BlackBoxFuncCall::HashToField128Security { inputs: vec![], output: Witness(0) } - } - BlackBoxFunc::EcdsaSecp256k1 => BlackBoxFuncCall::EcdsaSecp256k1 { - public_key_x: vec![], - public_key_y: vec![], - signature: vec![], - hashed_message: vec![], - output: Witness(0), - }, - BlackBoxFunc::EcdsaSecp256r1 => BlackBoxFuncCall::EcdsaSecp256r1 { - public_key_x: vec![], - public_key_y: vec![], - signature: vec![], - hashed_message: vec![], - output: Witness(0), - }, - BlackBoxFunc::FixedBaseScalarMul => BlackBoxFuncCall::FixedBaseScalarMul { - low: FunctionInput::dummy(), - high: FunctionInput::dummy(), - outputs: (Witness(0), Witness(0)), - }, - BlackBoxFunc::Keccak256 => { - BlackBoxFuncCall::Keccak256 { inputs: vec![], outputs: vec![] } - } - BlackBoxFunc::RecursiveAggregation => BlackBoxFuncCall::RecursiveAggregation { - verification_key: vec![], - proof: vec![], - public_inputs: vec![], - key_hash: FunctionInput::dummy(), - input_aggregation_object: None, - output_aggregation_object: vec![], - }, - } - } - pub fn get_black_box_func(&self) -> BlackBoxFunc { match self { BlackBoxFuncCall::AND { .. } => BlackBoxFunc::AND, diff --git a/noir/acvm-repo/acir_field/Cargo.toml b/noir/acvm-repo/acir_field/Cargo.toml index c80271ce539..4039a14ce73 100644 --- a/noir/acvm-repo/acir_field/Cargo.toml +++ b/noir/acvm-repo/acir_field/Cargo.toml @@ -2,7 +2,7 @@ name = "acir_field" description = "The field implementation being used by ACIR." # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/acvm/Cargo.toml b/noir/acvm-repo/acvm/Cargo.toml index 332399808a1..ca43c54b204 100644 --- a/noir/acvm-repo/acvm/Cargo.toml +++ b/noir/acvm-repo/acvm/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm" description = "The virtual machine that processes ACIR given a backend/proof system." # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/acvm_js/Cargo.toml b/noir/acvm-repo/acvm_js/Cargo.toml index 2efc618b3f5..190675da35c 100644 --- a/noir/acvm-repo/acvm_js/Cargo.toml +++ b/noir/acvm-repo/acvm_js/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_js" description = "Typescript wrapper around the ACVM allowing execution of ACIR code" # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/acvm_js/package.json b/noir/acvm-repo/acvm_js/package.json index 55516059540..6b3efc35d1a 100644 --- a/noir/acvm-repo/acvm_js/package.json +++ b/noir/acvm-repo/acvm_js/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/acvm_js", - "version": "0.34.0", + "version": "0.35.0", "repository": { "type": "git", "url": "https://github.com/noir-lang/acvm.git" diff --git a/noir/acvm-repo/barretenberg_blackbox_solver/Cargo.toml b/noir/acvm-repo/barretenberg_blackbox_solver/Cargo.toml index c2c5a4f98a1..9669a4184a4 100644 --- a/noir/acvm-repo/barretenberg_blackbox_solver/Cargo.toml +++ b/noir/acvm-repo/barretenberg_blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "barretenberg_blackbox_solver" description = "A wrapper around a barretenberg WASM binary to execute black box functions for which there is no rust implementation" # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/blackbox_solver/Cargo.toml b/noir/acvm-repo/blackbox_solver/Cargo.toml index 60f6dedc766..170de76875b 100644 --- a/noir/acvm-repo/blackbox_solver/Cargo.toml +++ b/noir/acvm-repo/blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_blackbox_solver" description = "A solver for the blackbox functions found in ACIR and Brillig" # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/brillig/Cargo.toml b/noir/acvm-repo/brillig/Cargo.toml index 15b99f2f07d..19488c8fbe8 100644 --- a/noir/acvm-repo/brillig/Cargo.toml +++ b/noir/acvm-repo/brillig/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig" description = "Brillig is the bytecode ACIR uses for non-determinism." # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/brillig_vm/Cargo.toml b/noir/acvm-repo/brillig_vm/Cargo.toml index 2c7b486ecea..21c5cd3a5f5 100644 --- a/noir/acvm-repo/brillig_vm/Cargo.toml +++ b/noir/acvm-repo/brillig_vm/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig_vm" description = "The virtual machine that processes Brillig bytecode, used to introduce non-determinism to the ACVM" # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/acvm-repo/stdlib/Cargo.toml b/noir/acvm-repo/stdlib/Cargo.toml index 44c88954b7a..9e0e08e1338 100644 --- a/noir/acvm-repo/stdlib/Cargo.toml +++ b/noir/acvm-repo/stdlib/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_stdlib" description = "The ACVM standard library." # x-release-please-start-version -version = "0.34.0" +version = "0.35.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/aztec_macros/Cargo.toml b/noir/aztec_macros/Cargo.toml new file mode 100644 index 00000000000..04f74d3b022 --- /dev/null +++ b/noir/aztec_macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "aztec_macros" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +noirc_frontend.workspace = true +iter-extended.workspace = true diff --git a/noir/compiler/noirc_frontend/src/hir/aztec_library.rs b/noir/aztec_macros/src/lib.rs similarity index 90% rename from noir/compiler/noirc_frontend/src/hir/aztec_library.rs rename to noir/aztec_macros/src/lib.rs index 3b4703dc60f..6d3aa0d8b01 100644 --- a/noir/compiler/noirc_frontend/src/hir/aztec_library.rs +++ b/noir/aztec_macros/src/lib.rs @@ -1,28 +1,58 @@ -use acvm::FieldElement; use iter_extended::vecmap; -use noirc_errors::Span; - -use crate::graph::CrateId; -use crate::hir::def_collector::errors::DefCollectorErrorKind; -use crate::hir_def::expr::{HirExpression, HirLiteral}; -use crate::hir_def::stmt::HirStatement; -use crate::node_interner::{NodeInterner, StructId}; -use crate::parser::SortedModule; -use crate::token::SecondaryAttribute; -use crate::{ - hir::Context, BlockExpression, CallExpression, CastExpression, Distinctness, Expression, - ExpressionKind, FunctionReturnType, Ident, IndexExpression, LetStatement, Literal, - MemberAccessExpression, MethodCallExpression, NoirFunction, Path, PathKind, Pattern, Statement, - UnresolvedType, UnresolvedTypeData, Visibility, -}; -use crate::{ - ForLoopStatement, ForRange, FunctionDefinition, FunctionVisibility, ImportStatement, - NoirStruct, Param, PrefixExpression, Signedness, StatementKind, StructType, Type, TypeImpl, - UnaryOp, + +use noirc_frontend::macros_api::FieldElement; +use noirc_frontend::macros_api::{ + BlockExpression, CallExpression, CastExpression, Distinctness, Expression, ExpressionKind, + ForLoopStatement, ForRange, FunctionDefinition, FunctionReturnType, FunctionVisibility, + HirContext, HirExpression, HirLiteral, HirStatement, Ident, ImportStatement, IndexExpression, + LetStatement, Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, NoirStruct, + Param, Path, PathKind, Pattern, PrefixExpression, SecondaryAttribute, Signedness, Span, + Statement, StatementKind, StructType, Type, TypeImpl, UnaryOp, UnresolvedType, + UnresolvedTypeData, Visibility, }; -use fm::FileId; +use noirc_frontend::macros_api::{CrateId, FileId}; +use noirc_frontend::macros_api::{MacroError, MacroProcessor}; +use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; + +pub struct AztecMacro; + +impl MacroProcessor for AztecMacro { + fn process_untyped_ast( + &self, + ast: SortedModule, + crate_id: &CrateId, + context: &HirContext, + ) -> Result { + transform(ast, crate_id, context) + } + + fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext) { + transform_hir(crate_id, context) + } +} + +#[derive(Debug, Clone)] +pub enum AztecMacroError { + AztecNotFound, + AztecComputeNoteHashAndNullifierNotFound { span: Span }, +} -use super::def_map::ModuleDefId; +impl From for MacroError { + fn from(err: AztecMacroError) -> Self { + match err { + AztecMacroError::AztecNotFound {} => MacroError { + primary_message: "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml. For more information go to https://docs.aztec.network/dev_docs/debugging/aztecnr-errors#aztec-dependency-not-found-please-add-aztec-as-a-dependency-in-your-nargotoml".to_owned(), + secondary_message: None, + span: None, + }, + AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span } => MacroError { + primary_message: "compute_note_hash_and_nullifier function not found. Define it in your contract. For more information go to https://docs.aztec.network/dev_docs/debugging/aztecnr-errors#compute_note_hash_and_nullifier-function-not-found-define-it-in-your-contract".to_owned(), + secondary_message: None, + span: Some(span), + }, + } + } +} // // Helper macros for creating noir ast nodes @@ -162,11 +192,11 @@ fn import(path: Path) -> ImportStatement { /// Traverses every function in the ast, calling `transform_function` which /// determines if further processing is required -pub(crate) fn transform( +fn transform( mut ast: SortedModule, crate_id: &CrateId, - context: &Context, -) -> Result { + context: &HirContext, +) -> Result { // Usage -> mut ast -> aztec_library::transform(&mut ast) // Covers all functions in the ast @@ -184,7 +214,7 @@ pub(crate) fn transform( // /// Completes the Hir with data gathered from type resolution -pub(crate) fn transform_hir(crate_id: &CrateId, context: &mut Context) { +fn transform_hir(crate_id: &CrateId, context: &mut HirContext) { transform_events(crate_id, context); } @@ -206,14 +236,14 @@ fn include_relevant_imports(ast: &mut SortedModule) { /// Creates an error alerting the user that they have not downloaded the Aztec-noir library fn check_for_aztec_dependency( crate_id: &CrateId, - context: &Context, -) -> Result<(), (DefCollectorErrorKind, FileId)> { + context: &HirContext, +) -> Result<(), (MacroError, FileId)> { let crate_graph = &context.crate_graph[crate_id]; let has_aztec_dependency = crate_graph.dependencies.iter().any(|dep| dep.as_name() == "aztec"); if has_aztec_dependency { Ok(()) } else { - Err((DefCollectorErrorKind::AztecNotFound {}, crate_graph.root_file_id)) + Err((AztecMacroError::AztecNotFound.into(), crate_graph.root_file_id)) } } @@ -234,10 +264,7 @@ fn check_for_compute_note_hash_and_nullifier_definition(module: &SortedModule) - // Array(Option, Box) contains only fields && match &func.def.parameters[3].typ.typ { UnresolvedTypeData::Array(_, inner_type) => { - match inner_type.typ { - UnresolvedTypeData::FieldElement => true, - _ => false, - } + matches!(inner_type.typ, UnresolvedTypeData::FieldElement) }, _ => false, } @@ -247,10 +274,7 @@ fn check_for_compute_note_hash_and_nullifier_definition(module: &SortedModule) - FunctionReturnType::Ty(unresolved_type) => { match &unresolved_type.typ { UnresolvedTypeData::Array(_, inner_type) => { - match inner_type.typ { - UnresolvedTypeData::FieldElement => true, - _ => false, - } + matches!(inner_type.typ, UnresolvedTypeData::FieldElement) }, _ => false, } @@ -274,19 +298,18 @@ fn is_custom_attribute(attr: &SecondaryAttribute, attribute_name: &str) -> bool fn transform_module( module: &mut SortedModule, crate_id: &CrateId, - context: &Context, -) -> Result { + context: &HirContext, +) -> Result { let mut has_transformed_module = false; // Check for a user defined storage struct - let storage_defined = check_for_storage_definition(&module); + let storage_defined = check_for_storage_definition(module); - if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(&module) { + if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { let crate_graph = &context.crate_graph[crate_id]; return Err(( - DefCollectorErrorKind::AztecComputeNoteHashAndNullifierNotFound { - span: Span::default(), // Add a default span so we know which contract file the error originates from - }, + AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span: Span::default() } + .into(), crate_graph.root_file_id, )); } @@ -374,7 +397,7 @@ fn transform_unconstrained(func: &mut NoirFunction) { func.def.body.0.insert(0, abstract_storage("Unconstrained", true)); } -fn collect_crate_structs(crate_id: &CrateId, context: &Context) -> Vec { +fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec { context .def_map(crate_id) .expect("ICE: Missing crate in def_map") @@ -444,7 +467,7 @@ fn transform_event(struct_id: StructId, interner: &mut NodeInterner) { } } -fn transform_events(crate_id: &CrateId, context: &mut Context) { +fn transform_events(crate_id: &CrateId, context: &mut HirContext) { for struct_id in collect_crate_structs(crate_id, context) { let attributes = context.def_interner.struct_attributes(&struct_id); if attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Event)) { @@ -514,7 +537,7 @@ fn generate_selector_impl(structure: &NoirStruct) -> TypeImpl { /// fn foo() { /// // ... /// } -pub(crate) fn create_inputs(ty: &str) -> Param { +fn create_inputs(ty: &str) -> Param { let context_ident = ident("inputs"); let context_pattern = Pattern::Identifier(context_ident); let type_path = chained_path!("aztec", "abi", ty); @@ -574,7 +597,7 @@ fn create_context(ty: &str, params: &[Param]) -> Vec { // `hasher.add_multiple({ident}.serialize())` UnresolvedTypeData::Named(..) => add_struct_to_hasher(identifier), UnresolvedTypeData::Array(_, arr_type) => { - add_array_to_hasher(identifier, &arr_type) + add_array_to_hasher(identifier, arr_type) } // `hasher.add({ident})` UnresolvedTypeData::FieldElement => add_field_to_hasher(identifier), @@ -819,7 +842,7 @@ fn make_castable_return_type(expression: Expression) -> Statement { /// fn foo() { /// // ... /// } -pub(crate) fn create_return_type(ty: &str) -> FunctionReturnType { +fn create_return_type(ty: &str) -> FunctionReturnType { let return_path = chained_path!("aztec", "abi", ty); let ty = make_type(UnresolvedTypeData::Named(return_path, vec![])); @@ -844,7 +867,7 @@ pub(crate) fn create_return_type(ty: &str) -> FunctionReturnType { /// fn foo() { /// // ... /// } -pub(crate) fn create_context_finish() -> Statement { +fn create_context_finish() -> Statement { let method_call = method_call( variable("context"), // variable "finish", // method name @@ -875,7 +898,7 @@ fn add_struct_to_hasher(identifier: &Ident) -> Statement { fn create_loop_over(var: Expression, loop_body: Vec) -> Statement { // If this is an array of primitive types (integers / fields) we can add them each to the hasher // casted to a field - let span = var.span.clone(); + let span = var.span; // `array.len()` let end_range_expression = method_call( diff --git a/noir/compiler/integration-tests/scripts/codegen-verifiers.sh b/noir/compiler/integration-tests/scripts/codegen-verifiers.sh index d9d9d4f243f..13667038728 100644 --- a/noir/compiler/integration-tests/scripts/codegen-verifiers.sh +++ b/noir/compiler/integration-tests/scripts/codegen-verifiers.sh @@ -5,16 +5,16 @@ self_path=$(dirname "$(readlink -f "$0")") repo_root=$self_path/../../.. # Run codegen-verifier for 1_mul -mul_dir=$repo_root/tooling/nargo_cli/tests/execution_success/1_mul +mul_dir=$repo_root/test_programs/execution_success/1_mul nargo --program-dir $mul_dir codegen-verifier -# Run codegen-verifier for main -main_dir=$repo_root/compiler/integration-tests/circuits/main -nargo --program-dir $main_dir codegen-verifier +# Run codegen-verifier for assert_statement +assert_statement_dir=$repo_root/test_programs/execution_success/assert_statement +nargo --program-dir $assert_statement_dir codegen-verifier # Copy compiled contracts from the root of compiler/integration-tests contracts_dir=$self_path/../contracts mkdir $contracts_dir cp $mul_dir/contract/1_mul/plonk_vk.sol $contracts_dir/1_mul.sol -cp $main_dir/contract/main/plonk_vk.sol $contracts_dir/main.sol +cp $assert_statement_dir/contract/assert_statement/plonk_vk.sol $contracts_dir/assert_statement.sol diff --git a/noir/compiler/integration-tests/test/browser/compile_prove_verify.test.ts b/noir/compiler/integration-tests/test/browser/compile_prove_verify.test.ts index 95a1aa502ad..2aef56c23f9 100644 --- a/noir/compiler/integration-tests/test/browser/compile_prove_verify.test.ts +++ b/noir/compiler/integration-tests/test/browser/compile_prove_verify.test.ts @@ -19,11 +19,11 @@ compilerLogLevel('INFO'); const test_cases = [ { - case: 'tooling/nargo_cli/tests/execution_success/1_mul', + case: 'test_programs/execution_success/1_mul', numPublicInputs: 0, }, { - case: 'compiler/integration-tests/circuits/main', + case: 'test_programs/execution_success/assert_statement', numPublicInputs: 1, }, ]; diff --git a/noir/compiler/integration-tests/test/browser/recursion.test.ts b/noir/compiler/integration-tests/test/browser/recursion.test.ts index dbf74882654..308be81417f 100644 --- a/noir/compiler/integration-tests/test/browser/recursion.test.ts +++ b/noir/compiler/integration-tests/test/browser/recursion.test.ts @@ -23,7 +23,7 @@ await initACVM(); compilerLogLevel('INFO'); const base_relative_path = '../../../../..'; -const circuit_main = 'compiler/integration-tests/circuits/main'; +const circuit_main = 'test_programs/execution_success/assert_statement'; const circuit_recursion = 'compiler/integration-tests/circuits/recursion'; function getCircuit(noirSource: string): CompiledProgram { diff --git a/noir/compiler/integration-tests/test/node/smart_contract_verifier.test.ts b/noir/compiler/integration-tests/test/node/smart_contract_verifier.test.ts index 738bc2df8dd..57199fc8667 100644 --- a/noir/compiler/integration-tests/test/node/smart_contract_verifier.test.ts +++ b/noir/compiler/integration-tests/test/node/smart_contract_verifier.test.ts @@ -7,19 +7,19 @@ import toml from 'toml'; import { compile, init_log_level as compilerLogLevel } from '@noir-lang/noir_wasm'; import { Noir } from '@noir-lang/noir_js'; -import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; +import { BarretenbergBackend, flattenPublicInputs } from '@noir-lang/backend_barretenberg'; compilerLogLevel('INFO'); const test_cases = [ { - case: 'tooling/nargo_cli/tests/execution_success/1_mul', + case: 'test_programs/execution_success/1_mul', compiled: 'contracts/1_mul.sol:UltraVerifier', numPublicInputs: 0, }, { - case: 'compiler/integration-tests/circuits/main', - compiled: 'contracts/main.sol:UltraVerifier', + case: 'test_programs/execution_success/assert_statement', + compiled: 'contracts/assert_statement.sol:UltraVerifier', numPublicInputs: 1, }, ]; @@ -59,7 +59,7 @@ test_cases.forEach((testInfo) => { const contract = await ethers.deployContract(testInfo.compiled, [], {}); - const result = await contract.verify(proofData.proof, proofData.publicInputs); + const result = await contract.verify(proofData.proof, flattenPublicInputs(proofData.publicInputs)); expect(result).to.be.true; }); diff --git a/noir/compiler/noirc_driver/Cargo.toml b/noir/compiler/noirc_driver/Cargo.toml index 09044b39323..c717efed6f5 100644 --- a/noir/compiler/noirc_driver/Cargo.toml +++ b/noir/compiler/noirc_driver/Cargo.toml @@ -21,3 +21,8 @@ iter-extended.workspace = true fm.workspace = true serde.workspace = true fxhash.workspace = true + +aztec_macros ={path = "../../aztec_macros", optional = true} + +[features] +aztec = ["aztec_macros"] \ No newline at end of file diff --git a/noir/compiler/noirc_driver/src/lib.rs b/noir/compiler/noirc_driver/src/lib.rs index 456c2c49609..93ed26fb91a 100644 --- a/noir/compiler/noirc_driver/src/lib.rs +++ b/noir/compiler/noirc_driver/src/lib.rs @@ -13,6 +13,7 @@ use noirc_evaluator::errors::RuntimeError; use noirc_frontend::graph::{CrateId, CrateName}; use noirc_frontend::hir::def_map::{Contract, CrateDefMap}; use noirc_frontend::hir::Context; +use noirc_frontend::macros_api::MacroProcessor; use noirc_frontend::monomorphization::monomorphize; use noirc_frontend::node_interner::FuncId; use serde::{Deserialize, Serialize}; @@ -121,8 +122,13 @@ pub fn check_crate( crate_id: CrateId, deny_warnings: bool, ) -> CompilationResult<()> { + #[cfg(not(feature = "aztec"))] + let macros: Vec<&dyn MacroProcessor> = Vec::new(); + #[cfg(feature = "aztec")] + let macros = vec![&aztec_macros::AztecMacro as &dyn MacroProcessor]; + let mut errors = vec![]; - let diagnostics = CrateDefMap::collect_defs(crate_id, context); + let diagnostics = CrateDefMap::collect_defs(crate_id, context, macros); errors.extend(diagnostics.into_iter().map(|(error, file_id)| { let diagnostic: CustomDiagnostic = error.into(); diagnostic.in_file(file_id) diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index 0d97dd12601..9979bf0cd29 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -1,9 +1,9 @@ -use acvm::acir::{ - brillig::{BlackBoxOp, HeapVector, RegisterOrMemory}, - BlackBoxFunc, -}; +use acvm::acir::{brillig::BlackBoxOp, BlackBoxFunc}; -use crate::brillig::brillig_ir::BrilligContext; +use crate::brillig::brillig_ir::{ + brillig_variable::{BrilligVariable, BrilligVector}, + BrilligContext, +}; /// Transforms SSA's black box function calls into the corresponding brillig instructions /// Extracting arguments and results from the SSA function call @@ -11,31 +11,31 @@ use crate::brillig::brillig_ir::BrilligContext; pub(crate) fn convert_black_box_call( brillig_context: &mut BrilligContext, bb_func: &BlackBoxFunc, - function_arguments: &[RegisterOrMemory], - function_results: &[RegisterOrMemory], + function_arguments: &[BrilligVariable], + function_results: &[BrilligVariable], ) { match bb_func { BlackBoxFunc::SHA256 => { - if let ([message], [RegisterOrMemory::HeapArray(result_array)]) = + if let ([message], [BrilligVariable::BrilligArray(result_array)]) = (function_arguments, function_results) { let message_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::Sha256 { - message: message_vector, - output: *result_array, + message: message_vector.to_heap_vector(), + output: result_array.to_heap_array(), }); } else { unreachable!("ICE: SHA256 expects one array argument and one array result") } } BlackBoxFunc::Blake2s => { - if let ([message], [RegisterOrMemory::HeapArray(result_array)]) = + if let ([message], [BrilligVariable::BrilligArray(result_array)]) = (function_arguments, function_results) { let message_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::Blake2s { - message: message_vector, - output: *result_array, + message: message_vector.to_heap_vector(), + output: result_array.to_heap_array(), }); } else { unreachable!("ICE: Blake2s expects one array argument and one array result") @@ -43,28 +43,28 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::Keccak256 => { if let ( - [message, RegisterOrMemory::RegisterIndex(array_size)], - [RegisterOrMemory::HeapArray(result_array)], + [message, BrilligVariable::Simple(array_size)], + [BrilligVariable::BrilligArray(result_array)], ) = (function_arguments, function_results) { let mut message_vector = convert_array_or_vector(brillig_context, message, bb_func); message_vector.size = *array_size; brillig_context.black_box_op_instruction(BlackBoxOp::Keccak256 { - message: message_vector, - output: *result_array, + message: message_vector.to_heap_vector(), + output: result_array.to_heap_array(), }); } else { unreachable!("ICE: Keccak256 expects message, message size and result array") } } BlackBoxFunc::HashToField128Security => { - if let ([message], [RegisterOrMemory::RegisterIndex(result_register)]) = + if let ([message], [BrilligVariable::Simple(result_register)]) = (function_arguments, function_results) { let message_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::HashToField128Security { - message: message_vector, + message: message_vector.to_heap_vector(), output: *result_register, }); } else { @@ -73,17 +73,17 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::EcdsaSecp256k1 => { if let ( - [RegisterOrMemory::HeapArray(public_key_x), RegisterOrMemory::HeapArray(public_key_y), RegisterOrMemory::HeapArray(signature), message], - [RegisterOrMemory::RegisterIndex(result_register)], + [BrilligVariable::BrilligArray(public_key_x), BrilligVariable::BrilligArray(public_key_y), BrilligVariable::BrilligArray(signature), message], + [BrilligVariable::Simple(result_register)], ) = (function_arguments, function_results) { let message_hash_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::EcdsaSecp256k1 { - hashed_msg: message_hash_vector, - public_key_x: *public_key_x, - public_key_y: *public_key_y, - signature: *signature, + hashed_msg: message_hash_vector.to_heap_vector(), + public_key_x: public_key_x.to_heap_array(), + public_key_y: public_key_y.to_heap_array(), + signature: signature.to_heap_array(), result: *result_register, }); } else { @@ -94,15 +94,15 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::PedersenCommitment => { if let ( - [message, RegisterOrMemory::RegisterIndex(domain_separator)], - [RegisterOrMemory::HeapArray(result_array)], + [message, BrilligVariable::Simple(domain_separator)], + [BrilligVariable::BrilligArray(result_array)], ) = (function_arguments, function_results) { let message_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::PedersenCommitment { - inputs: message_vector, + inputs: message_vector.to_heap_vector(), domain_separator: *domain_separator, - output: *result_array, + output: result_array.to_heap_array(), }); } else { unreachable!("ICE: Pedersen expects one array argument, a register for the domain separator, and one array result") @@ -110,13 +110,13 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::PedersenHash => { if let ( - [message, RegisterOrMemory::RegisterIndex(domain_separator)], - [RegisterOrMemory::RegisterIndex(result)], + [message, BrilligVariable::Simple(domain_separator)], + [BrilligVariable::Simple(result)], ) = (function_arguments, function_results) { let message_vector = convert_array_or_vector(brillig_context, message, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::PedersenHash { - inputs: message_vector, + inputs: message_vector.to_heap_vector(), domain_separator: *domain_separator, output: *result, }); @@ -126,8 +126,8 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::SchnorrVerify => { if let ( - [RegisterOrMemory::RegisterIndex(public_key_x), RegisterOrMemory::RegisterIndex(public_key_y), RegisterOrMemory::HeapArray(signature), message], - [RegisterOrMemory::RegisterIndex(result_register)], + [BrilligVariable::Simple(public_key_x), BrilligVariable::Simple(public_key_y), BrilligVariable::BrilligArray(signature), message], + [BrilligVariable::Simple(result_register)], ) = (function_arguments, function_results) { let message_hash = convert_array_or_vector(brillig_context, message, bb_func); @@ -135,8 +135,8 @@ pub(crate) fn convert_black_box_call( brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify { public_key_x: *public_key_x, public_key_y: *public_key_y, - message: message_hash, - signature, + message: message_hash.to_heap_vector(), + signature: signature.to_heap_vector(), result: *result_register, }); } else { @@ -145,14 +145,14 @@ pub(crate) fn convert_black_box_call( } BlackBoxFunc::FixedBaseScalarMul => { if let ( - [RegisterOrMemory::RegisterIndex(low), RegisterOrMemory::RegisterIndex(high)], - [RegisterOrMemory::HeapArray(result_array)], + [BrilligVariable::Simple(low), BrilligVariable::Simple(high)], + [BrilligVariable::BrilligArray(result_array)], ) = (function_arguments, function_results) { brillig_context.black_box_op_instruction(BlackBoxOp::FixedBaseScalarMul { low: *low, high: *high, - result: *result_array, + result: result_array.to_heap_array(), }); } else { unreachable!( @@ -166,12 +166,12 @@ pub(crate) fn convert_black_box_call( fn convert_array_or_vector( brillig_context: &mut BrilligContext, - array_or_vector: &RegisterOrMemory, + array_or_vector: &BrilligVariable, bb_func: &BlackBoxFunc, -) -> HeapVector { +) -> BrilligVector { match array_or_vector { - RegisterOrMemory::HeapArray(array) => brillig_context.array_to_vector(array), - RegisterOrMemory::HeapVector(vector) => *vector, + BrilligVariable::BrilligArray(array) => brillig_context.array_to_vector(array), + BrilligVariable::BrilligVector(vector) => *vector, _ => unreachable!( "ICE: {} expected an array or a vector, but got {:?}", bb_func.name(), diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 18fd822b07d..0e06a36fd94 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -1,6 +1,6 @@ +use crate::brillig::brillig_ir::brillig_variable::{BrilligArray, BrilligVariable, BrilligVector}; use crate::brillig::brillig_ir::{ - extract_heap_array, extract_register, extract_registers, BrilligBinaryOp, BrilligContext, - BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE, + BrilligBinaryOp, BrilligContext, BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE, }; use crate::ssa::ir::dfg::CallStack; use crate::ssa::ir::{ @@ -13,7 +13,7 @@ use crate::ssa::ir::{ types::{NumericType, Type}, value::{Value, ValueId}, }; -use acvm::acir::brillig::{BinaryFieldOp, BinaryIntOp, HeapArray, RegisterIndex, RegisterOrMemory}; +use acvm::acir::brillig::{BinaryFieldOp, BinaryIntOp, RegisterIndex, RegisterOrMemory}; use acvm::brillig_vm::brillig::HeapVector; use acvm::FieldElement; use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; @@ -53,7 +53,7 @@ impl<'block> BrilligBlock<'block> { variables .get_available_variables(function_context) .into_iter() - .flat_map(extract_registers) + .flat_map(|variable| variable.extract_registers()) .collect(), ); let last_uses = function_context.liveness.get_last_uses(&block_id).clone(); @@ -159,7 +159,7 @@ impl<'block> BrilligBlock<'block> { .iter() .flat_map(|value_id| { let return_variable = self.convert_ssa_value(*value_id, dfg); - extract_registers(return_variable) + return_variable.extract_registers() }) .collect(); self.brillig_context.return_instruction(&return_registers); @@ -168,32 +168,44 @@ impl<'block> BrilligBlock<'block> { } /// Passes an arbitrary variable from the registers of the source to the registers of the destination - fn pass_variable(&mut self, source: RegisterOrMemory, destination: RegisterOrMemory) { + fn pass_variable(&mut self, source: BrilligVariable, destination: BrilligVariable) { match (source, destination) { ( - RegisterOrMemory::RegisterIndex(source_register), - RegisterOrMemory::RegisterIndex(destination_register), + BrilligVariable::Simple(source_register), + BrilligVariable::Simple(destination_register), ) => { self.brillig_context.mov_instruction(destination_register, source_register); } ( - RegisterOrMemory::HeapArray(HeapArray { pointer: source_pointer, .. }), - RegisterOrMemory::HeapArray(HeapArray { pointer: destination_pointer, .. }), + BrilligVariable::BrilligArray(BrilligArray { + pointer: source_pointer, + size: _, + rc: source_rc, + }), + BrilligVariable::BrilligArray(BrilligArray { + pointer: destination_pointer, + size: _, + rc: destination_rc, + }), ) => { self.brillig_context.mov_instruction(destination_pointer, source_pointer); + self.brillig_context.mov_instruction(destination_rc, source_rc); } ( - RegisterOrMemory::HeapVector(HeapVector { + BrilligVariable::BrilligVector(BrilligVector { pointer: source_pointer, size: source_size, + rc: source_rc, }), - RegisterOrMemory::HeapVector(HeapVector { + BrilligVariable::BrilligVector(BrilligVector { pointer: destination_pointer, size: destination_size, + rc: destination_rc, }), ) => { self.brillig_context.mov_instruction(destination_pointer, source_pointer); self.brillig_context.mov_instruction(destination_size, source_size); + self.brillig_context.mov_instruction(destination_rc, source_rc); } (_, _) => { unreachable!("ICE: Cannot pass value from {:?} to {:?}", source, destination); @@ -214,7 +226,7 @@ impl<'block> BrilligBlock<'block> { // In the case of arrays, the values should already be in memory and the register should // Be a valid pointer to the array. // For slices, two registers are passed, the pointer to the data and a register holding the size of the slice. - Type::Numeric(_) | Type::Array(..) | Type::Slice(..) | Type::Reference => { + Type::Numeric(_) | Type::Array(..) | Type::Slice(..) | Type::Reference(_) => { self.variables.get_block_param( self.function_context, self.block_id, @@ -264,7 +276,25 @@ impl<'block> BrilligBlock<'block> { result_value, dfg, ); - self.brillig_context.allocate_variable_instruction(address_register); + match dfg.type_of_value(result_value) { + Type::Reference(element) => match *element { + Type::Array(..) => { + self.brillig_context + .allocate_array_reference_instruction(address_register); + } + Type::Slice(..) => { + self.brillig_context + .allocate_vector_reference_instruction(address_register); + } + _ => { + self.brillig_context + .allocate_simple_reference_instruction(address_register); + } + }, + _ => { + unreachable!("ICE: Allocate on non-reference type") + } + } } Instruction::Store { address, value } => { let address_register = self.convert_ssa_register_value(*address, dfg); @@ -299,10 +329,11 @@ impl<'block> BrilligBlock<'block> { Value::ForeignFunction(func_name) => { let result_ids = dfg.instruction_results(instruction_id); - let input_registers = - vecmap(arguments, |value_id| self.convert_ssa_value(*value_id, dfg)); + let input_registers = vecmap(arguments, |value_id| { + self.convert_ssa_value(*value_id, dfg).to_register_or_memory() + }); let output_registers = vecmap(result_ids, |value_id| { - self.allocate_external_call_result(*value_id, dfg) + self.allocate_external_call_result(*value_id, dfg).to_register_or_memory() }); self.brillig_context.foreign_call_instruction( func_name.to_owned(), @@ -388,7 +419,7 @@ impl<'block> BrilligBlock<'block> { // or an array in the case of an array. if let Type::Numeric(_) = dfg.type_of_value(param_id) { let len_variable = self.convert_ssa_value(arguments[0], dfg); - let len_register_index = extract_register(len_variable); + let len_register_index = len_variable.extract_register(); self.brillig_context.mov_instruction(result_register, len_register_index); } else { self.convert_ssa_array_len(arguments[0], result_register, dfg); @@ -416,29 +447,29 @@ impl<'block> BrilligBlock<'block> { let results = dfg.instruction_results(instruction_id); - let target_len_variable = self.variables.define_variable( + let target_len = self.variables.define_register_variable( self.function_context, self.brillig_context, results[0], dfg, ); - let target_len = extract_register(target_len_variable); - let target_slice = self.variables.define_variable( - self.function_context, - self.brillig_context, - results[1], - dfg, - ); - - let heap_vec = self.brillig_context.extract_heap_vector(target_slice); + let target_vector = self + .variables + .define_variable( + self.function_context, + self.brillig_context, + results[1], + dfg, + ) + .extract_vector(); // Update the user-facing slice length self.brillig_context.mov_instruction(target_len, limb_count); self.brillig_context.radix_instruction( source, - heap_vec, + target_vector, radix, limb_count, matches!(endianness, Endian::Big), @@ -456,24 +487,29 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ); - let target_len = extract_register(target_len_variable); + let target_len = target_len_variable.extract_register(); - let target_slice = self.variables.define_variable( + let target_vector = match self.variables.define_variable( self.function_context, self.brillig_context, results[1], dfg, - ); + ) { + BrilligVariable::BrilligArray(array) => { + self.brillig_context.array_to_vector(&array) + } + BrilligVariable::BrilligVector(vector) => vector, + BrilligVariable::Simple(..) => unreachable!("ICE: ToBits on non-array"), + }; let radix = self.brillig_context.make_constant(2_usize.into()); - let heap_vec = self.brillig_context.extract_heap_vector(target_slice); // Update the user-facing slice length self.brillig_context.mov_instruction(target_len, limb_count); self.brillig_context.radix_instruction( source, - heap_vec, + target_vector, radix, limb_count, matches!(endianness, Endian::Big), @@ -523,8 +559,8 @@ impl<'block> BrilligBlock<'block> { let array_variable = self.convert_ssa_value(*array, dfg); let array_pointer = match array_variable { - RegisterOrMemory::HeapArray(HeapArray { pointer, .. }) => pointer, - RegisterOrMemory::HeapVector(HeapVector { pointer, .. }) => pointer, + BrilligVariable::BrilligArray(BrilligArray { pointer, .. }) => pointer, + BrilligVariable::BrilligVector(BrilligVector { pointer, .. }) => pointer, _ => unreachable!("ICE: array get on non-array"), }; @@ -574,6 +610,14 @@ impl<'block> BrilligBlock<'block> { self.brillig_context.deallocate_register(condition); self.brillig_context.deallocate_register(right); } + Instruction::IncrementRc { value } => { + let rc_register = match self.convert_ssa_value(*value, dfg) { + BrilligVariable::BrilligArray(BrilligArray { rc, .. }) + | BrilligVariable::BrilligVector(BrilligVector { rc, .. }) => rc, + _ => unreachable!("ICE: increment rc on non-array"), + }; + self.brillig_context.usize_op_in_place(rc_register, BinaryIntOp::Add, 1); + } _ => todo!("ICE: Instruction not supported {instruction:?}"), }; @@ -598,10 +642,7 @@ impl<'block> BrilligBlock<'block> { // Convert the arguments to registers casting those to the types of the receiving function let argument_registers: Vec = arguments .iter() - .flat_map(|argument_id| { - let variable_to_pass = self.convert_ssa_value(*argument_id, dfg); - extract_registers(variable_to_pass) - }) + .flat_map(|argument_id| self.convert_ssa_value(*argument_id, dfg).extract_registers()) .collect(); let result_ids = dfg.instruction_results(instruction_id); @@ -637,7 +678,7 @@ impl<'block> BrilligBlock<'block> { // Collect the registers that should have been returned let returned_registers: Vec = variables_assigned_to .iter() - .flat_map(|returned_variable| extract_registers(*returned_variable)) + .flat_map(|returned_variable| returned_variable.extract_registers()) .collect(); assert!( @@ -654,17 +695,13 @@ impl<'block> BrilligBlock<'block> { &mut self, array_pointer: RegisterIndex, index_register: RegisterIndex, - destination_variable: RegisterOrMemory, + destination_variable: BrilligVariable, ) { match destination_variable { - RegisterOrMemory::RegisterIndex(destination_register) => { + BrilligVariable::Simple(destination_register) => { self.brillig_context.array_get(array_pointer, index_register, destination_register); } - RegisterOrMemory::HeapArray(HeapArray { pointer, .. }) => { - self.brillig_context.array_get(array_pointer, index_register, pointer); - } - RegisterOrMemory::HeapVector(..) => { - // Vectors are stored as references inside arrays to be able to match SSA indexes + BrilligVariable::BrilligArray(..) | BrilligVariable::BrilligVector(..) => { let reference = self.brillig_context.allocate_register(); self.brillig_context.array_get(array_pointer, index_register, reference); self.brillig_context.load_variable_instruction(destination_variable, reference); @@ -677,25 +714,30 @@ impl<'block> BrilligBlock<'block> { /// With a specific value changed. fn convert_ssa_array_set( &mut self, - source_variable: RegisterOrMemory, - destination_variable: RegisterOrMemory, + source_variable: BrilligVariable, + destination_variable: BrilligVariable, index_register: RegisterIndex, - value_variable: RegisterOrMemory, + value_variable: BrilligVariable, ) { let destination_pointer = match destination_variable { - RegisterOrMemory::HeapArray(HeapArray { pointer, .. }) => pointer, - RegisterOrMemory::HeapVector(HeapVector { pointer, .. }) => pointer, + BrilligVariable::BrilligArray(BrilligArray { pointer, .. }) => pointer, + BrilligVariable::BrilligVector(BrilligVector { pointer, .. }) => pointer, _ => unreachable!("ICE: array set returns non-array"), }; - // First issue a array copy to the destination + let reference_count = match source_variable { + BrilligVariable::BrilligArray(BrilligArray { rc, .. }) + | BrilligVariable::BrilligVector(BrilligVector { rc, .. }) => rc, + _ => unreachable!("ICE: array set on non-array"), + }; + let (source_pointer, source_size_as_register) = match source_variable { - RegisterOrMemory::HeapArray(HeapArray { size, pointer }) => { + BrilligVariable::BrilligArray(BrilligArray { size, pointer, rc: _ }) => { let source_size_register = self.brillig_context.allocate_register(); self.brillig_context.const_instruction(source_size_register, size.into()); (pointer, source_size_register) } - RegisterOrMemory::HeapVector(HeapVector { size, pointer }) => { + BrilligVariable::BrilligVector(BrilligVector { size, pointer, rc: _ }) => { let source_size_register = self.brillig_context.allocate_register(); self.brillig_context.mov_instruction(source_size_register, size); (pointer, source_size_register) @@ -703,51 +745,96 @@ impl<'block> BrilligBlock<'block> { _ => unreachable!("ICE: array set on non-array"), }; - self.brillig_context - .allocate_array_instruction(destination_pointer, source_size_as_register); + let one = self.brillig_context.make_constant(1_usize.into()); + let condition = self.brillig_context.allocate_register(); - self.brillig_context.copy_array_instruction( - source_pointer, - destination_pointer, - source_size_as_register, + self.brillig_context.binary_instruction( + reference_count, + one, + condition, + BrilligBinaryOp::Field { op: BinaryFieldOp::Equals }, ); - if let RegisterOrMemory::HeapVector(HeapVector { size: target_size, .. }) = - destination_variable - { - self.brillig_context.mov_instruction(target_size, source_size_as_register); + self.brillig_context.branch_instruction(condition, |ctx, cond| { + if cond { + // Reference count is 1, we can mutate the array directly + ctx.mov_instruction(destination_pointer, source_pointer); + } else { + // First issue a array copy to the destination + ctx.allocate_array_instruction(destination_pointer, source_size_as_register); + + ctx.copy_array_instruction( + source_pointer, + destination_pointer, + source_size_as_register, + ); + } + }); + + match destination_variable { + BrilligVariable::BrilligArray(BrilligArray { rc: target_rc, .. }) => { + self.brillig_context.const_instruction(target_rc, 1_usize.into()); + } + BrilligVariable::BrilligVector(BrilligVector { + size: target_size, + rc: target_rc, + .. + }) => { + self.brillig_context.mov_instruction(target_size, source_size_as_register); + self.brillig_context.const_instruction(target_rc, 1_usize.into()); + } + _ => unreachable!("ICE: array set on non-array"), } // Then set the value in the newly created array self.store_variable_in_array(destination_pointer, index_register, value_variable); self.brillig_context.deallocate_register(source_size_as_register); + self.brillig_context.deallocate_register(one); + self.brillig_context.deallocate_register(condition); } - pub(crate) fn store_variable_in_array( - &mut self, + pub(crate) fn store_variable_in_array_with_ctx( + ctx: &mut BrilligContext, destination_pointer: RegisterIndex, index_register: RegisterIndex, - value_variable: RegisterOrMemory, + value_variable: BrilligVariable, ) { match value_variable { - RegisterOrMemory::RegisterIndex(value_register) => { - self.brillig_context.array_set(destination_pointer, index_register, value_register); + BrilligVariable::Simple(value_register) => { + ctx.array_set(destination_pointer, index_register, value_register); } - RegisterOrMemory::HeapArray(HeapArray { pointer, .. }) => { - self.brillig_context.array_set(destination_pointer, index_register, pointer); + BrilligVariable::BrilligArray(_) => { + let reference: RegisterIndex = ctx.allocate_register(); + ctx.allocate_array_reference_instruction(reference); + ctx.store_variable_instruction(reference, value_variable); + ctx.array_set(destination_pointer, index_register, reference); + ctx.deallocate_register(reference); } - RegisterOrMemory::HeapVector(_) => { - // Vectors are stored as references inside arrays to be able to match SSA indexes - let reference = self.brillig_context.allocate_register(); - self.brillig_context.allocate_variable_instruction(reference); - self.brillig_context.store_variable_instruction(reference, value_variable); - self.brillig_context.array_set(destination_pointer, index_register, reference); - self.brillig_context.deallocate_register(reference); + BrilligVariable::BrilligVector(_) => { + let reference = ctx.allocate_register(); + ctx.allocate_vector_reference_instruction(reference); + ctx.store_variable_instruction(reference, value_variable); + ctx.array_set(destination_pointer, index_register, reference); + ctx.deallocate_register(reference); } } } + pub(crate) fn store_variable_in_array( + &mut self, + destination_pointer: RegisterIndex, + index_register: RegisterIndex, + value_variable: BrilligVariable, + ) { + Self::store_variable_in_array_with_ctx( + self.brillig_context, + destination_pointer, + index_register, + value_variable, + ); + } + /// Convert the SSA slice operations to brillig slice operations fn convert_ssa_slice_intrinsic_call( &mut self, @@ -770,7 +857,7 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -781,7 +868,7 @@ impl<'block> BrilligBlock<'block> { dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); let item_values = vecmap(&arguments[2..element_size + 2], |arg| { self.convert_ssa_value(*arg, dfg) }); @@ -797,7 +884,7 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -807,7 +894,7 @@ impl<'block> BrilligBlock<'block> { results[1], dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); let item_values = vecmap(&arguments[2..element_size + 2], |arg| { self.convert_ssa_value(*arg, dfg) }); @@ -823,7 +910,7 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -834,7 +921,7 @@ impl<'block> BrilligBlock<'block> { dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); let pop_variables = vecmap(&results[2..element_size + 2], |result| { self.variables.define_variable( @@ -856,7 +943,7 @@ impl<'block> BrilligBlock<'block> { results[element_size], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -875,7 +962,7 @@ impl<'block> BrilligBlock<'block> { results[element_size + 1], dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); self.update_slice_length(target_len, arguments[0], dfg, BinaryIntOp::Sub); @@ -888,7 +975,7 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -900,7 +987,7 @@ impl<'block> BrilligBlock<'block> { dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); // Remove if indexing in insert is changed to flattened indexing // https://github.com/noir-lang/noir/issues/1889#issuecomment-1668048587 @@ -931,7 +1018,7 @@ impl<'block> BrilligBlock<'block> { results[0], dfg, ) { - RegisterOrMemory::RegisterIndex(register_index) => register_index, + BrilligVariable::Simple(register_index) => register_index, _ => unreachable!("ICE: first value of a slice must be a register index"), }; @@ -943,7 +1030,7 @@ impl<'block> BrilligBlock<'block> { target_id, dfg, ); - let target_vector = self.brillig_context.extract_heap_vector(target_variable); + let target_vector = target_variable.extract_vector(); // Remove if indexing in remove is changed to flattened indexing // https://github.com/noir-lang/noir/issues/1889#issuecomment-1668048587 @@ -998,7 +1085,7 @@ impl<'block> BrilligBlock<'block> { binary_op: BinaryIntOp, ) { let source_len_variable = self.convert_ssa_value(source_value, dfg); - let source_len = extract_register(source_len_variable); + let source_len = source_len_variable.extract_register(); self.brillig_context.usize_op(source_len, target_len, binary_op, 1); } @@ -1064,7 +1151,7 @@ impl<'block> BrilligBlock<'block> { } /// Converts an SSA `ValueId` into a `RegisterOrMemory`. Initializes if necessary. - fn convert_ssa_value(&mut self, value_id: ValueId, dfg: &DataFlowGraph) -> RegisterOrMemory { + fn convert_ssa_value(&mut self, value_id: ValueId, dfg: &DataFlowGraph) -> BrilligVariable { let value_id = dfg.resolve(value_id); let value = &dfg[value_id]; @@ -1082,7 +1169,7 @@ impl<'block> BrilligBlock<'block> { } else { let new_variable = self.variables.allocate_constant(self.brillig_context, value_id, dfg); - let register_index = extract_register(new_variable); + let register_index = new_variable.extract_register(); self.brillig_context.const_instruction(register_index, (*constant).into()); new_variable @@ -1097,19 +1184,21 @@ impl<'block> BrilligBlock<'block> { // Initialize the variable let pointer = match new_variable { - RegisterOrMemory::HeapArray(heap_array) => { + BrilligVariable::BrilligArray(brillig_array) => { self.brillig_context - .allocate_fixed_length_array(heap_array.pointer, array.len()); + .allocate_fixed_length_array(brillig_array.pointer, array.len()); + self.brillig_context + .const_instruction(brillig_array.rc, 1_usize.into()); - heap_array.pointer + brillig_array.pointer } - RegisterOrMemory::HeapVector(heap_vector) => { - self.brillig_context - .const_instruction(heap_vector.size, array.len().into()); + BrilligVariable::BrilligVector(vector) => { + self.brillig_context.const_instruction(vector.size, array.len().into()); self.brillig_context - .allocate_array_instruction(heap_vector.pointer, heap_vector.size); + .allocate_array_instruction(vector.pointer, vector.size); + self.brillig_context.const_instruction(vector.rc, 1_usize.into()); - heap_vector.pointer + vector.pointer } _ => unreachable!( "ICE: Cannot initialize array value created as {new_variable:?}" @@ -1138,7 +1227,7 @@ impl<'block> BrilligBlock<'block> { new_variable } } - _ => { + Value::Function(_) | Value::Intrinsic(_) | Value::ForeignFunction(_) => { todo!("ICE: Cannot convert value {value:?}") } } @@ -1151,14 +1240,14 @@ impl<'block> BrilligBlock<'block> { dfg: &DataFlowGraph, ) -> RegisterIndex { let variable = self.convert_ssa_value(value_id, dfg); - extract_register(variable) + variable.extract_register() } fn allocate_external_call_result( &mut self, result: ValueId, dfg: &DataFlowGraph, - ) -> RegisterOrMemory { + ) -> BrilligVariable { let typ = dfg[result].get_type(); match typ { Type::Numeric(_) => self.variables.define_variable( @@ -1175,8 +1264,10 @@ impl<'block> BrilligBlock<'block> { result, dfg, ); - let array = extract_heap_array(variable); + let array = variable.extract_array(); self.brillig_context.allocate_fixed_length_array(array.pointer, array.size); + self.brillig_context.const_instruction(array.rc, 1_usize.into()); + variable } Type::Slice(_) => { @@ -1186,12 +1277,14 @@ impl<'block> BrilligBlock<'block> { result, dfg, ); - let vector = self.brillig_context.extract_heap_vector(variable); + let vector = variable.extract_vector(); // Set the pointer to the current stack frame // The stack pointer will then be updated by the caller of this method // once the external call is resolved and the array size is known self.brillig_context.set_array_pointer(vector.pointer); + self.brillig_context.const_instruction(vector.rc, 1_usize.into()); + variable } _ => { @@ -1201,7 +1294,7 @@ impl<'block> BrilligBlock<'block> { } /// Gets the "user-facing" length of an array. - /// An array of structs with two fields would be stored as an 2 * array.len() heap array/heap vector. + /// An array of structs with two fields would be stored as an 2 * array.len() array/vector. /// So we divide the length by the number of subitems in an item to get the user-facing length. fn convert_ssa_array_len( &mut self, @@ -1213,11 +1306,11 @@ impl<'block> BrilligBlock<'block> { let element_size = dfg.type_of_value(array_id).element_size(); match array_variable { - RegisterOrMemory::HeapArray(HeapArray { size, .. }) => { + BrilligVariable::BrilligArray(BrilligArray { size, .. }) => { self.brillig_context .const_instruction(result_register, (size / element_size).into()); } - RegisterOrMemory::HeapVector(HeapVector { size, .. }) => { + BrilligVariable::BrilligVector(BrilligVector { size, .. }) => { self.brillig_context.usize_op( size, result_register, @@ -1240,7 +1333,7 @@ pub(crate) fn type_of_binary_operation(lhs_type: &Type, rhs_type: &Type) -> Type (_, Type::Function) | (Type::Function, _) => { unreachable!("Functions are invalid in binary operations") } - (_, Type::Reference) | (Type::Reference, _) => { + (_, Type::Reference(_)) | (Type::Reference(_), _) => { unreachable!("References are invalid in binary operations") } (_, Type::Array(..)) | (Type::Array(..), _) => { diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs index eb7bab8c971..f2e698c0aa9 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs @@ -1,8 +1,11 @@ -use acvm::brillig_vm::brillig::{HeapArray, HeapVector, RegisterIndex, RegisterOrMemory}; +use acvm::brillig_vm::brillig::RegisterIndex; use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; use crate::{ - brillig::brillig_ir::{extract_register, BrilligContext}, + brillig::brillig_ir::{ + brillig_variable::{BrilligArray, BrilligVariable, BrilligVector}, + BrilligContext, + }, ssa::ir::{ basic_block::BasicBlockId, dfg::DataFlowGraph, @@ -16,7 +19,7 @@ use super::brillig_fn::FunctionContext; #[derive(Debug, Default)] pub(crate) struct BlockVariables { available_variables: HashSet, - available_constants: HashMap, + available_constants: HashMap, } impl BlockVariables { @@ -32,7 +35,7 @@ impl BlockVariables { pub(crate) fn get_available_variables( &self, function_context: &FunctionContext, - ) -> Vec { + ) -> Vec { self.available_variables .iter() .map(|value_id| { @@ -52,7 +55,7 @@ impl BlockVariables { brillig_context: &mut BrilligContext, value_id: ValueId, dfg: &DataFlowGraph, - ) -> RegisterOrMemory { + ) -> BrilligVariable { let value_id = dfg.resolve(value_id); let variable = allocate_value(value_id, brillig_context, dfg); @@ -74,7 +77,7 @@ impl BlockVariables { dfg: &DataFlowGraph, ) -> RegisterIndex { let variable = self.define_variable(function_context, brillig_context, value, dfg); - extract_register(variable) + variable.extract_register() } /// Removes a variable so it's not used anymore within this block. @@ -88,7 +91,7 @@ impl BlockVariables { function_context: &FunctionContext, value_id: ValueId, dfg: &DataFlowGraph, - ) -> RegisterOrMemory { + ) -> BrilligVariable { let value_id = dfg.resolve(value_id); if let Some(constant) = self.available_constants.get(&value_id) { *constant @@ -112,7 +115,7 @@ impl BlockVariables { brillig_context: &mut BrilligContext, value_id: ValueId, dfg: &DataFlowGraph, - ) -> RegisterOrMemory { + ) -> BrilligVariable { let value_id = dfg.resolve(value_id); let constant = allocate_value(value_id, brillig_context, dfg); self.available_constants.insert(value_id, constant); @@ -124,7 +127,7 @@ impl BlockVariables { &mut self, value_id: ValueId, dfg: &DataFlowGraph, - ) -> Option { + ) -> Option { let value_id = dfg.resolve(value_id); self.available_constants.get(&value_id).cloned() } @@ -141,7 +144,7 @@ impl BlockVariables { block_id: BasicBlockId, value_id: ValueId, dfg: &DataFlowGraph, - ) -> RegisterOrMemory { + ) -> BrilligVariable { let value_id = dfg.resolve(value_id); assert!( function_context @@ -166,25 +169,34 @@ pub(crate) fn allocate_value( value_id: ValueId, brillig_context: &mut BrilligContext, dfg: &DataFlowGraph, -) -> RegisterOrMemory { +) -> BrilligVariable { let typ = dfg.type_of_value(value_id); match typ { - Type::Numeric(_) | Type::Reference => { + Type::Numeric(_) | Type::Reference(_) => { let register = brillig_context.allocate_register(); - RegisterOrMemory::RegisterIndex(register) + BrilligVariable::Simple(register) } Type::Array(item_typ, elem_count) => { let pointer_register = brillig_context.allocate_register(); + let rc_register = brillig_context.allocate_register(); let size = compute_array_length(&item_typ, elem_count); - RegisterOrMemory::HeapArray(HeapArray { pointer: pointer_register, size }) + + BrilligVariable::BrilligArray(BrilligArray { + pointer: pointer_register, + size, + rc: rc_register, + }) } Type::Slice(_) => { let pointer_register = brillig_context.allocate_register(); let size_register = brillig_context.allocate_register(); - RegisterOrMemory::HeapVector(HeapVector { + let rc_register = brillig_context.allocate_register(); + + BrilligVariable::BrilligVector(BrilligVector { pointer: pointer_register, size: size_register, + rc: rc_register, }) } Type::Function => { diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs index ec72ceb2909..026def4ef11 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs @@ -1,9 +1,9 @@ -use acvm::brillig_vm::brillig::RegisterOrMemory; use iter_extended::vecmap; use crate::{ brillig::brillig_ir::{ artifact::{BrilligParameter, Label}, + brillig_variable::BrilligVariable, BrilligContext, }, ssa::ir::{ @@ -21,7 +21,7 @@ use super::{brillig_block_variables::allocate_value, variable_liveness::Variable pub(crate) struct FunctionContext { pub(crate) function_id: FunctionId, /// Map from SSA values its allocation. Since values can be only defined once in SSA form, we insert them here on when we allocate them at their definition. - pub(crate) ssa_value_allocations: HashMap, + pub(crate) ssa_value_allocations: HashMap, /// Block parameters are pre allocated at the function level. pub(crate) block_parameters: HashMap>, /// The block ids of the function in reverse post order. @@ -72,7 +72,7 @@ impl FunctionContext { fn ssa_type_to_parameter(typ: &Type) -> BrilligParameter { match typ { - Type::Numeric(_) | Type::Reference => BrilligParameter::Simple, + Type::Numeric(_) | Type::Reference(_) => BrilligParameter::Simple, Type::Array(item_type, size) => BrilligParameter::Array( vecmap(item_type.iter(), |item_typ| { FunctionContext::ssa_type_to_parameter(item_typ) diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs index 211d670e7d8..6402e6f9d97 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs @@ -1,13 +1,15 @@ -use acvm::brillig_vm::brillig::{BinaryIntOp, HeapVector, RegisterIndex, RegisterOrMemory}; +use acvm::brillig_vm::brillig::{BinaryIntOp, RegisterIndex}; + +use crate::brillig::brillig_ir::brillig_variable::{BrilligVariable, BrilligVector}; use super::brillig_block::BrilligBlock; impl<'block> BrilligBlock<'block> { pub(crate) fn slice_push_back_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, - variables_to_insert: &[RegisterOrMemory], + target_vector: BrilligVector, + source_vector: BrilligVector, + variables_to_insert: &[BrilligVariable], ) { // First we need to allocate the target vector incrementing the size by variables_to_insert.len() self.brillig_context.usize_op( @@ -17,6 +19,8 @@ impl<'block> BrilligBlock<'block> { variables_to_insert.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Now we copy the source vector into the target vector self.brillig_context.copy_array_instruction( @@ -40,9 +44,9 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn slice_push_front_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, - variables_to_insert: &[RegisterOrMemory], + target_vector: BrilligVector, + source_vector: BrilligVector, + variables_to_insert: &[BrilligVariable], ) { // First we need to allocate the target vector incrementing the size by variables_to_insert.len() self.brillig_context.usize_op( @@ -52,6 +56,8 @@ impl<'block> BrilligBlock<'block> { variables_to_insert.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Now we offset the target pointer by variables_to_insert.len() let destination_copy_pointer = self.brillig_context.allocate_register(); @@ -81,9 +87,9 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn slice_pop_front_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, - removed_items: &[RegisterOrMemory], + target_vector: BrilligVector, + source_vector: BrilligVector, + removed_items: &[BrilligVariable], ) { // First we need to allocate the target vector decrementing the size by removed_items.len() self.brillig_context.usize_op( @@ -93,6 +99,8 @@ impl<'block> BrilligBlock<'block> { removed_items.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Now we offset the source pointer by removed_items.len() let source_copy_pointer = self.brillig_context.allocate_register(); @@ -121,9 +129,9 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn slice_pop_back_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, - removed_items: &[RegisterOrMemory], + target_vector: BrilligVector, + source_vector: BrilligVector, + removed_items: &[BrilligVariable], ) { // First we need to allocate the target vector decrementing the size by removed_items.len() self.brillig_context.usize_op( @@ -133,6 +141,8 @@ impl<'block> BrilligBlock<'block> { removed_items.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Now we copy all elements except the last items into the target vector self.brillig_context.copy_array_instruction( @@ -156,10 +166,10 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn slice_insert_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, + target_vector: BrilligVector, + source_vector: BrilligVector, index: RegisterIndex, - items: &[RegisterOrMemory], + items: &[BrilligVariable], ) { // First we need to allocate the target vector incrementing the size by items.len() self.brillig_context.usize_op( @@ -169,6 +179,8 @@ impl<'block> BrilligBlock<'block> { items.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Copy the elements to the left of the index self.brillig_context.copy_array_instruction( @@ -226,10 +238,10 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn slice_remove_operation( &mut self, - target_vector: HeapVector, - source_vector: HeapVector, + target_vector: BrilligVector, + source_vector: BrilligVector, index: RegisterIndex, - removed_items: &[RegisterOrMemory], + removed_items: &[BrilligVariable], ) { // First we need to allocate the target vector decrementing the size by removed_items.len() self.brillig_context.usize_op( @@ -239,6 +251,8 @@ impl<'block> BrilligBlock<'block> { removed_items.len(), ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); + // We initialize the RC of the target vector to 1 + self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); // Copy the elements to the left of the index self.brillig_context.copy_array_instruction( @@ -297,11 +311,11 @@ impl<'block> BrilligBlock<'block> { pub(crate) fn convert_array_or_vector_to_vector( &mut self, - source_variable: RegisterOrMemory, - ) -> HeapVector { + source_variable: BrilligVariable, + ) -> BrilligVector { match source_variable { - RegisterOrMemory::HeapVector(source_vector) => source_vector, - RegisterOrMemory::HeapArray(source_array) => { + BrilligVariable::BrilligVector(source_vector) => source_vector, + BrilligVariable::BrilligArray(source_array) => { self.brillig_context.array_to_vector(&source_array) } _ => unreachable!("ICE: unsupported slice push back source {:?}", source_variable), @@ -313,13 +327,16 @@ impl<'block> BrilligBlock<'block> { mod tests { use std::vec; - use acvm::acir::brillig::{HeapVector, Value}; - use acvm::brillig_vm::brillig::{RegisterIndex, RegisterOrMemory}; + use acvm::acir::brillig::Value; + use acvm::brillig_vm::brillig::RegisterIndex; use crate::brillig::brillig_gen::brillig_block::BrilligBlock; use crate::brillig::brillig_gen::brillig_block_variables::BlockVariables; use crate::brillig::brillig_gen::brillig_fn::FunctionContext; use crate::brillig::brillig_ir::artifact::BrilligParameter; + use crate::brillig::brillig_ir::brillig_variable::{ + BrilligArray, BrilligVariable, BrilligVector, + }; use crate::brillig::brillig_ir::tests::{ create_and_run_vm, create_context, create_entry_point_bytecode, }; @@ -373,33 +390,44 @@ mod tests { let (_, mut function_context, mut context) = create_test_environment(); // Allocate the parameters - let array_pointer = context.allocate_register(); + let array_variable = BrilligArray { + pointer: context.allocate_register(), + size: array.len(), + rc: context.allocate_register(), + }; let item_to_insert = context.allocate_register(); // Cast the source array to a vector - let array_size = context.make_constant(array.len().into()); + let source_vector = context.array_to_vector(&array_variable); // Allocate the results - let copied_array_pointer = context.allocate_register(); - let copied_array_size = context.allocate_register(); + let target_vector = BrilligVector { + pointer: context.allocate_register(), + size: context.allocate_register(), + rc: context.allocate_register(), + }; let mut block = create_brillig_block(&mut function_context, &mut context); if push_back { block.slice_push_back_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, - &[RegisterOrMemory::RegisterIndex(item_to_insert)], + target_vector, + source_vector, + &[BrilligVariable::Simple(item_to_insert)], ); } else { block.slice_push_front_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, - &[RegisterOrMemory::RegisterIndex(item_to_insert)], + target_vector, + source_vector, + &[BrilligVariable::Simple(item_to_insert)], ); } - context.return_instruction(&[copied_array_pointer, copied_array_size]); + context.return_instruction(&[ + target_vector.pointer, + target_vector.rc, + target_vector.size, + ]); let bytecode = create_entry_point_bytecode(context, arguments, returns).byte_code; let vm = create_and_run_vm( @@ -465,34 +493,45 @@ mod tests { let (_, mut function_context, mut context) = create_test_environment(); // Allocate the parameters - let array_pointer = context.allocate_register(); + let array_variable = BrilligArray { + pointer: context.allocate_register(), + size: array.len(), + rc: context.allocate_register(), + }; // Cast the source array to a vector - let array_size = context.make_constant(array.len().into()); + let source_vector = context.array_to_vector(&array_variable); // Allocate the results - let copied_array_pointer = context.allocate_register(); + let target_vector = BrilligVector { + pointer: context.allocate_register(), + size: context.allocate_register(), + rc: context.allocate_register(), + }; let removed_item = context.allocate_register(); - let copied_array_size = context.allocate_register(); - let mut block = create_brillig_block(&mut function_context, &mut context); if pop_back { block.slice_pop_back_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, - &[RegisterOrMemory::RegisterIndex(removed_item)], + target_vector, + source_vector, + &[BrilligVariable::Simple(removed_item)], ); } else { block.slice_pop_front_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, - &[RegisterOrMemory::RegisterIndex(removed_item)], + target_vector, + source_vector, + &[BrilligVariable::Simple(removed_item)], ); } - context.return_instruction(&[copied_array_pointer, copied_array_size, removed_item]); + context.return_instruction(&[ + target_vector.pointer, + target_vector.rc, + target_vector.size, + removed_item, + ]); let bytecode = create_entry_point_bytecode(context, arguments, returns).byte_code; let vm = create_and_run_vm(array.clone(), vec![Value::from(0_usize)], &bytecode); @@ -557,28 +596,38 @@ mod tests { let (_, mut function_context, mut context) = create_test_environment(); // Allocate the parameters - let array_pointer = context.allocate_register(); + let array_variable = BrilligArray { + pointer: context.allocate_register(), + size: array.len(), + rc: context.allocate_register(), + }; let item_to_insert = context.allocate_register(); let index_to_insert = context.allocate_register(); // Cast the source array to a vector - let array_size = context.make_constant(array.len().into()); + let source_vector = context.array_to_vector(&array_variable); // Allocate the results - let copied_array_pointer = context.allocate_register(); - - let copied_array_size = context.allocate_register(); + let target_vector = BrilligVector { + pointer: context.allocate_register(), + size: context.allocate_register(), + rc: context.allocate_register(), + }; let mut block = create_brillig_block(&mut function_context, &mut context); block.slice_insert_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, + target_vector, + source_vector, index_to_insert, - &[RegisterOrMemory::RegisterIndex(item_to_insert)], + &[BrilligVariable::Simple(item_to_insert)], ); - context.return_instruction(&[copied_array_pointer, copied_array_size]); + context.return_instruction(&[ + target_vector.pointer, + target_vector.rc, + target_vector.size, + ]); let bytecode = create_entry_point_bytecode(context, arguments, returns).byte_code; let vm = create_and_run_vm( @@ -679,28 +728,39 @@ mod tests { let (_, mut function_context, mut context) = create_test_environment(); // Allocate the parameters - let array_pointer = context.allocate_register(); + let array_variable = BrilligArray { + pointer: context.allocate_register(), + size: array.len(), + rc: context.allocate_register(), + }; let index_to_insert = context.allocate_register(); // Cast the source array to a vector - let array_size = context.make_constant(array.len().into()); + let source_vector = context.array_to_vector(&array_variable); // Allocate the results - let copied_array_pointer = context.allocate_register(); + let target_vector = BrilligVector { + pointer: context.allocate_register(), + size: context.allocate_register(), + rc: context.allocate_register(), + }; let removed_item = context.allocate_register(); - let copied_array_size = context.allocate_register(); - let mut block = create_brillig_block(&mut function_context, &mut context); block.slice_remove_operation( - HeapVector { pointer: copied_array_pointer, size: copied_array_size }, - HeapVector { pointer: array_pointer, size: array_size }, + target_vector, + source_vector, index_to_insert, - &[RegisterOrMemory::RegisterIndex(removed_item)], + &[BrilligVariable::Simple(removed_item)], ); - context.return_instruction(&[copied_array_pointer, copied_array_size, removed_item]); + context.return_instruction(&[ + target_vector.pointer, + target_vector.rc, + target_vector.size, + removed_item, + ]); let bytecode = create_entry_point_bytecode(context, arguments, returns).byte_code; let vm = create_and_run_vm(array.clone(), vec![Value::from(0_usize), index], &bytecode); diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs index d57196288bf..05978c2c6ab 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/variable_liveness.rs @@ -332,7 +332,7 @@ mod test { let v0 = builder.add_parameter(Type::field()); let v1 = builder.add_parameter(Type::field()); - let v3 = builder.insert_allocate(); + let v3 = builder.insert_allocate(Type::field()); let zero = builder.numeric_constant(0u128, Type::field()); builder.insert_store(v3, zero); @@ -439,7 +439,7 @@ mod test { let v0 = builder.add_parameter(Type::field()); let v1 = builder.add_parameter(Type::field()); - let v3 = builder.insert_allocate(); + let v3 = builder.insert_allocate(Type::field()); let zero = builder.numeric_constant(0u128, Type::field()); builder.insert_store(v3, zero); diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 880ae95dcd7..ff182aaa7d2 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -5,6 +5,7 @@ //! ssa types and types in this module. //! A similar paradigm can be seen with the `acir_ir` module. pub(crate) mod artifact; +pub(crate) mod brillig_variable; pub(crate) mod debug_show; pub(crate) mod registers; @@ -14,12 +15,13 @@ use crate::ssa::ir::dfg::CallStack; use self::{ artifact::{BrilligArtifact, UnresolvedJumpLocation}, + brillig_variable::{BrilligArray, BrilligVariable, BrilligVector}, registers::BrilligRegistersContext, }; use acvm::{ acir::brillig::{ - BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapArray, HeapVector, Opcode as BrilligOpcode, - RegisterIndex, RegisterOrMemory, Value, + BinaryFieldOp, BinaryIntOp, BlackBoxOp, Opcode as BrilligOpcode, RegisterIndex, + RegisterOrMemory, Value, }, FieldElement, }; @@ -88,6 +90,8 @@ pub(crate) struct BrilligContext { context_label: String, /// Section label, used to separate sections of code section_label: usize, + /// Stores the next available section + next_section: usize, /// IR printer debug_show: DebugShow, } @@ -100,6 +104,7 @@ impl BrilligContext { registers: BrilligRegistersContext::new(), context_label: String::default(), section_label: 0, + next_section: 1, debug_show: DebugShow::new(enable_debug_trace), } } @@ -161,10 +166,14 @@ impl BrilligContext { /// Allocates a variable in memory and stores the /// pointer to the array in `pointer_register` - pub(crate) fn allocate_variable_instruction(&mut self, pointer_register: RegisterIndex) { + fn allocate_variable_reference_instruction( + &mut self, + pointer_register: RegisterIndex, + size: usize, + ) { self.debug_show.allocate_instruction(pointer_register); - // A variable can be stored in up to two values, so we reserve two values for that. - let size_register = self.make_constant(2_u128.into()); + // A variable can be stored in up to three values, so we reserve three values for that. + let size_register = self.make_constant(size.into()); self.push_opcode(BrilligOpcode::Mov { destination: pointer_register, source: ReservedRegisters::stack_pointer(), @@ -177,6 +186,30 @@ impl BrilligContext { ); } + pub(crate) fn allocate_simple_reference_instruction( + &mut self, + pointer_register: RegisterIndex, + ) { + self.allocate_variable_reference_instruction(pointer_register, 1); + } + + pub(crate) fn allocate_array_reference_instruction(&mut self, pointer_register: RegisterIndex) { + self.allocate_variable_reference_instruction( + pointer_register, + BrilligArray::registers_count(), + ); + } + + pub(crate) fn allocate_vector_reference_instruction( + &mut self, + pointer_register: RegisterIndex, + ) { + self.allocate_variable_reference_instruction( + pointer_register, + BrilligVector::registers_count(), + ); + } + /// Gets the value in the array at index `index` and stores it in `result` pub(crate) fn array_get( &mut self, @@ -253,8 +286,8 @@ impl BrilligContext { { let iterator_register = self.make_constant(0_u128.into()); - let loop_label = self.next_section_label(); - self.enter_next_section(); + let (loop_section, loop_label) = self.reserve_next_section_label(); + self.enter_section(loop_section); // Loop body @@ -267,7 +300,7 @@ impl BrilligContext { BinaryIntOp::LessThan, ); - let exit_loop_label = self.next_section_label(); + let (exit_loop_section, exit_loop_label) = self.reserve_next_section_label(); self.not_instruction(iterator_less_than_iterations, 1, iterator_less_than_iterations); self.jump_if_instruction(iterator_less_than_iterations, exit_loop_label); @@ -281,12 +314,41 @@ impl BrilligContext { self.jump_instruction(loop_label); // Exit the loop - self.enter_next_section(); + self.enter_section(exit_loop_section); + // Deallocate our temporary registers self.deallocate_register(iterator_less_than_iterations); self.deallocate_register(iterator_register); } + /// This instruction will issue an if-then branch that will check if the condition is true + /// and if so, perform the instructions given in `f(self, true)` and otherwise perform the + /// instructions given in `f(self, false)`. A boolean is passed instead of two separate + /// functions to allow the given function to mutably alias its environment. + pub(crate) fn branch_instruction( + &mut self, + condition: RegisterIndex, + mut f: impl FnMut(&mut BrilligContext, bool), + ) { + // Reserve 3 sections + let (then_section, then_label) = self.reserve_next_section_label(); + let (otherwise_section, otherwise_label) = self.reserve_next_section_label(); + let (end_section, end_label) = self.reserve_next_section_label(); + + self.jump_if_instruction(condition, then_label.clone()); + self.jump_instruction(otherwise_label.clone()); + + self.enter_section(then_section); + f(self, true); + self.jump_instruction(end_label.clone()); + + self.enter_section(otherwise_section); + f(self, false); + self.jump_instruction(end_label.clone()); + + self.enter_section(end_section); + } + /// Adds a label to the next opcode pub(crate) fn enter_context(&mut self, label: T) { self.debug_show.enter_context(label.to_string()); @@ -299,23 +361,25 @@ impl BrilligContext { .add_label_at_position(self.current_section_label(), self.obj.index_of_next_opcode()); } - /// Increments the section label and adds a section label to the next opcode - fn enter_next_section(&mut self) { - self.section_label += 1; + /// Enter the given section + fn enter_section(&mut self, section: usize) { + self.section_label = section; self.obj .add_label_at_position(self.current_section_label(), self.obj.index_of_next_opcode()); } + /// Create, reserve, and return a new section label. + fn reserve_next_section_label(&mut self) -> (usize, String) { + let section = self.next_section; + self.next_section += 1; + (section, self.compute_section_label(section)) + } + /// Internal function used to compute the section labels fn compute_section_label(&self, section: usize) -> String { format!("{}-{}", self.context_label, section) } - /// Returns the next section label - fn next_section_label(&self) -> String { - self.compute_section_label(self.section_label + 1) - } - /// Returns the current section label fn current_section_label(&self) -> String { self.compute_section_label(self.section_label) @@ -371,15 +435,13 @@ impl BrilligContext { assert_message: Option, ) { self.debug_show.constrain_instruction(condition); - self.add_unresolved_jump( - BrilligOpcode::JumpIf { condition, location: 0 }, - self.next_section_label(), - ); + let (next_section, next_label) = self.reserve_next_section_label(); + self.add_unresolved_jump(BrilligOpcode::JumpIf { condition, location: 0 }, next_label); self.push_opcode(BrilligOpcode::Trap); if let Some(assert_message) = assert_message { self.obj.add_assert_message_to_last_opcode(assert_message); } - self.enter_next_section(); + self.enter_section(next_section); } /// Processes a return instruction. @@ -528,17 +590,24 @@ impl BrilligContext { /// Loads a variable stored previously pub(crate) fn load_variable_instruction( &mut self, - destination: RegisterOrMemory, + destination: BrilligVariable, variable_pointer: RegisterIndex, ) { match destination { - RegisterOrMemory::RegisterIndex(register_index) => { + BrilligVariable::Simple(register_index) => { self.load_instruction(register_index, variable_pointer); } - RegisterOrMemory::HeapArray(HeapArray { pointer, .. }) => { + BrilligVariable::BrilligArray(BrilligArray { pointer, size: _, rc }) => { self.load_instruction(pointer, variable_pointer); + + let rc_pointer = self.allocate_register(); + self.mov_instruction(rc_pointer, variable_pointer); + self.usize_op_in_place(rc_pointer, BinaryIntOp::Add, 1_usize); + + self.load_instruction(rc, rc_pointer); + self.deallocate_register(rc_pointer); } - RegisterOrMemory::HeapVector(HeapVector { pointer, size }) => { + BrilligVariable::BrilligVector(BrilligVector { pointer, size, rc }) => { self.load_instruction(pointer, variable_pointer); let size_pointer = self.allocate_register(); @@ -547,6 +616,13 @@ impl BrilligContext { self.load_instruction(size, size_pointer); self.deallocate_register(size_pointer); + + let rc_pointer = self.allocate_register(); + self.mov_instruction(rc_pointer, variable_pointer); + self.usize_op_in_place(rc_pointer, BinaryIntOp::Add, 2_usize); + + self.load_instruction(rc, rc_pointer); + self.deallocate_register(rc_pointer); } } } @@ -565,32 +641,38 @@ impl BrilligContext { pub(crate) fn store_variable_instruction( &mut self, variable_pointer: RegisterIndex, - source: RegisterOrMemory, + source: BrilligVariable, ) { - let size_pointer = self.allocate_register(); - self.mov_instruction(size_pointer, variable_pointer); - self.usize_op_in_place(size_pointer, BinaryIntOp::Add, 1_usize); - match source { - RegisterOrMemory::RegisterIndex(register_index) => { + BrilligVariable::Simple(register_index) => { self.store_instruction(variable_pointer, register_index); - let size_constant = self.make_constant(Value::from(1_usize)); - self.store_instruction(size_pointer, size_constant); - self.deallocate_register(size_constant); } - RegisterOrMemory::HeapArray(HeapArray { pointer, size }) => { + BrilligVariable::BrilligArray(BrilligArray { pointer, size: _, rc }) => { self.store_instruction(variable_pointer, pointer); - let size_constant = self.make_constant(Value::from(size)); - self.store_instruction(size_pointer, size_constant); - self.deallocate_register(size_constant); + + let rc_pointer: RegisterIndex = self.allocate_register(); + self.mov_instruction(rc_pointer, variable_pointer); + self.usize_op_in_place(rc_pointer, BinaryIntOp::Add, 1_usize); + self.store_instruction(rc_pointer, rc); + self.deallocate_register(rc_pointer); } - RegisterOrMemory::HeapVector(HeapVector { pointer, size }) => { + BrilligVariable::BrilligVector(BrilligVector { pointer, size, rc }) => { self.store_instruction(variable_pointer, pointer); + + let size_pointer = self.allocate_register(); + self.mov_instruction(size_pointer, variable_pointer); + self.usize_op_in_place(size_pointer, BinaryIntOp::Add, 1_usize); self.store_instruction(size_pointer, size); + + let rc_pointer: RegisterIndex = self.allocate_register(); + self.mov_instruction(rc_pointer, variable_pointer); + self.usize_op_in_place(rc_pointer, BinaryIntOp::Add, 2_usize); + self.store_instruction(rc_pointer, rc); + + self.deallocate_register(size_pointer); + self.deallocate_register(rc_pointer); } } - - self.deallocate_register(size_pointer); } /// Emits a truncate instruction. @@ -725,14 +807,14 @@ impl BrilligContext { } /// Saves all of the registers that have been used up until this point. - fn save_registers_of_vars(&mut self, vars: &[RegisterOrMemory]) -> Vec { + fn save_registers_of_vars(&mut self, vars: &[BrilligVariable]) -> Vec { // Save all of the used registers at this point in memory // because the function call will/may overwrite them. // // Note that here it is important that the stack pointer register is at register 0, // as after the first register save we add to the pointer. let mut used_registers: Vec<_> = - vars.iter().flat_map(|var| extract_registers(*var)).collect(); + vars.iter().flat_map(|var| var.extract_registers()).collect(); // Also dump the previous stack pointer used_registers.push(ReservedRegisters::previous_stack_pointer()); @@ -811,7 +893,7 @@ impl BrilligContext { pub(crate) fn pre_call_save_registers_prep_args( &mut self, arguments: &[RegisterIndex], - variables_to_save: &[RegisterOrMemory], + variables_to_save: &[BrilligVariable], ) -> Vec { // Save all the registers we have used to the stack. let saved_registers = self.save_registers_of_vars(variables_to_save); @@ -852,9 +934,9 @@ impl BrilligContext { } /// Utility method to transform a HeapArray to a HeapVector by making a runtime constant with the size. - pub(crate) fn array_to_vector(&mut self, array: &HeapArray) -> HeapVector { + pub(crate) fn array_to_vector(&mut self, array: &BrilligArray) -> BrilligVector { let size_register = self.make_constant(array.size.into()); - HeapVector { size: size_register, pointer: array.pointer } + BrilligVector { size: size_register, pointer: array.pointer, rc: array.rc } } /// Issues a blackbox operation. @@ -868,12 +950,13 @@ impl BrilligContext { pub(crate) fn radix_instruction( &mut self, source: RegisterIndex, - target_vector: HeapVector, + target_vector: BrilligVector, radix: RegisterIndex, limb_count: RegisterIndex, big_endian: bool, ) { self.mov_instruction(target_vector.size, limb_count); + self.const_instruction(target_vector.rc, 1_usize.into()); self.allocate_array_instruction(target_vector.pointer, target_vector.size); let shifted_register = self.allocate_register(); @@ -914,7 +997,7 @@ impl BrilligContext { } /// This instruction will reverse the order of the elements in a vector. - pub(crate) fn reverse_vector_in_place_instruction(&mut self, vector: HeapVector) { + pub(crate) fn reverse_vector_in_place_instruction(&mut self, vector: BrilligVector) { let iteration_count = self.allocate_register(); self.usize_op(vector.size, iteration_count, BinaryIntOp::UnsignedDiv, 2); @@ -949,51 +1032,12 @@ impl BrilligContext { self.deallocate_register(index_at_end_of_array); } - pub(crate) fn extract_heap_vector(&mut self, variable: RegisterOrMemory) -> HeapVector { - match variable { - RegisterOrMemory::HeapVector(vector) => vector, - RegisterOrMemory::HeapArray(array) => { - let size = self.allocate_register(); - self.const_instruction(size, array.size.into()); - HeapVector { pointer: array.pointer, size } - } - _ => unreachable!("ICE: Expected vector, got {variable:?}"), - } - } - /// Sets a current call stack that the next pushed opcodes will be associated with. pub(crate) fn set_call_stack(&mut self, call_stack: CallStack) { self.obj.set_call_stack(call_stack); } } -pub(crate) fn extract_register(variable: RegisterOrMemory) -> RegisterIndex { - match variable { - RegisterOrMemory::RegisterIndex(register_index) => register_index, - _ => unreachable!("ICE: Expected register, got {variable:?}"), - } -} - -pub(crate) fn extract_heap_array(variable: RegisterOrMemory) -> HeapArray { - match variable { - RegisterOrMemory::HeapArray(array) => array, - _ => unreachable!("ICE: Expected array, got {variable:?}"), - } -} - -/// Collects the registers that a given variable is stored in. -pub(crate) fn extract_registers(variable: RegisterOrMemory) -> Vec { - match variable { - RegisterOrMemory::RegisterIndex(register_index) => vec![register_index], - RegisterOrMemory::HeapArray(array) => { - vec![array.pointer] - } - RegisterOrMemory::HeapVector(vector) => { - vec![vector.pointer, vector.size] - } - } -} - /// Type to encapsulate the binary operation types in Brillig #[derive(Clone)] pub(crate) enum BrilligBinaryOp { diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs new file mode 100644 index 00000000000..46c54d55ecb --- /dev/null +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs @@ -0,0 +1,99 @@ +use acvm::brillig_vm::brillig::{HeapArray, HeapVector, RegisterIndex, RegisterOrMemory}; +use serde::{Deserialize, Serialize}; + +/// The representation of a noir array in the Brillig IR +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy)] +pub(crate) struct BrilligArray { + pub(crate) pointer: RegisterIndex, + pub(crate) size: usize, + pub(crate) rc: RegisterIndex, +} + +impl BrilligArray { + pub(crate) fn to_heap_array(self) -> HeapArray { + HeapArray { pointer: self.pointer, size: self.size } + } + + pub(crate) fn registers_count() -> usize { + 2 + } + + pub(crate) fn extract_registers(self) -> Vec { + vec![self.pointer, self.rc] + } +} + +/// The representation of a noir slice in the Brillig IR +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy)] +pub(crate) struct BrilligVector { + pub(crate) pointer: RegisterIndex, + pub(crate) size: RegisterIndex, + pub(crate) rc: RegisterIndex, +} + +impl BrilligVector { + pub(crate) fn to_heap_vector(self) -> HeapVector { + HeapVector { pointer: self.pointer, size: self.size } + } + + pub(crate) fn registers_count() -> usize { + 3 + } + + pub(crate) fn extract_registers(self) -> Vec { + vec![self.pointer, self.size, self.rc] + } +} + +/// The representation of a noir value in the Brillig IR +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy)] +pub(crate) enum BrilligVariable { + Simple(RegisterIndex), + BrilligArray(BrilligArray), + BrilligVector(BrilligVector), +} + +impl BrilligVariable { + pub(crate) fn extract_register(self) -> RegisterIndex { + match self { + BrilligVariable::Simple(register_index) => register_index, + _ => unreachable!("ICE: Expected register, got {self:?}"), + } + } + + pub(crate) fn extract_array(self) -> BrilligArray { + match self { + BrilligVariable::BrilligArray(array) => array, + _ => unreachable!("ICE: Expected array, got {self:?}"), + } + } + + pub(crate) fn extract_vector(self) -> BrilligVector { + match self { + BrilligVariable::BrilligVector(vector) => vector, + _ => unreachable!("ICE: Expected vector, got {self:?}"), + } + } + + pub(crate) fn extract_registers(self) -> Vec { + match self { + BrilligVariable::Simple(register_index) => vec![register_index], + BrilligVariable::BrilligArray(array) => array.extract_registers(), + BrilligVariable::BrilligVector(vector) => vector.extract_registers(), + } + } + + pub(crate) fn to_register_or_memory(self) -> RegisterOrMemory { + match self { + BrilligVariable::Simple(register_index) => { + RegisterOrMemory::RegisterIndex(register_index) + } + BrilligVariable::BrilligArray(array) => { + RegisterOrMemory::HeapArray(array.to_heap_array()) + } + BrilligVariable::BrilligVector(vector) => { + RegisterOrMemory::HeapVector(vector.to_heap_vector()) + } + } + } +} diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index fb426ad6876..48615988238 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -2,6 +2,7 @@ use crate::brillig::brillig_ir::ReservedRegisters; use super::{ artifact::{BrilligArtifact, BrilligParameter}, + brillig_variable::{BrilligArray, BrilligVariable}, debug_show::DebugShow, registers::BrilligRegistersContext, BrilligContext, @@ -20,6 +21,7 @@ impl BrilligContext { registers: BrilligRegistersContext::new(), context_label: String::default(), section_label: 0, + next_section: 1, debug_show: DebugShow::new(false), }; @@ -32,18 +34,39 @@ impl BrilligContext { } /// Adds the instructions needed to handle entry point parameters - /// - /// And sets the starting value of the reserved registers + /// The runtime will leave the parameters in the first `n` registers. + /// Arrays will be passed as pointers to the first element, with all the nested arrays flattened. + /// First, reserve the registers that contain the parameters. + /// This function also sets the starting value of the reserved registers fn entry_point_instruction(&mut self, arguments: Vec) { - // Translate the inputs by the reserved registers offset - for i in (0..arguments.len()).rev() { - self.push_opcode(BrilligOpcode::Mov { - destination: ReservedRegisters::user_register_index(i), - source: RegisterIndex::from(i), - }); - // Make sure we don't overwrite the arguments - self.allocate_register(); - } + let preallocated_registers: Vec<_> = + arguments.iter().enumerate().map(|(i, _)| RegisterIndex::from(i)).collect(); + self.set_allocated_registers(preallocated_registers.clone()); + + // Then allocate and initialize the variables that will hold the parameters + let argument_variables: Vec<_> = arguments + .iter() + .zip(preallocated_registers) + .map(|(argument, param_register)| match argument { + BrilligParameter::Simple => { + let variable_register = self.allocate_register(); + self.mov_instruction(variable_register, param_register); + BrilligVariable::Simple(variable_register) + } + BrilligParameter::Array(item_types, item_count) => { + let pointer_register = self.allocate_register(); + let rc_register = self.allocate_register(); + self.mov_instruction(pointer_register, param_register); + self.const_instruction(rc_register, 1_usize.into()); + BrilligVariable::BrilligArray(BrilligArray { + pointer: pointer_register, + size: item_types.len() * item_count, + rc: rc_register, + }) + } + BrilligParameter::Slice(_) => unimplemented!("Unsupported slices as parameter"), + }) + .collect(); // Calculate the initial value for the stack pointer register let size_arguments_memory: usize = arguments @@ -65,16 +88,24 @@ impl BrilligContext { value: 0_usize.into(), }); - for (index, parameter) in arguments.iter().enumerate() { + // Deflatten the arrays + for (parameter, assigned_variable) in arguments.iter().zip(&argument_variables) { if let BrilligParameter::Array(item_type, item_count) = parameter { if item_type.iter().any(|param| !matches!(param, BrilligParameter::Simple)) { - let pointer_register = ReservedRegisters::user_register_index(index); + let pointer_register = assigned_variable.extract_array().pointer; let deflattened_register = self.deflatten_array(item_type, *item_count, pointer_register); self.mov_instruction(pointer_register, deflattened_register); } } } + + // Move the parameters to the first user defined registers, to follow function call convention. + for (i, register) in + argument_variables.into_iter().flat_map(|arg| arg.extract_registers()).enumerate() + { + self.mov_instruction(ReservedRegisters::user_register_index(i), register); + } } /// Computes the size of a parameter if it was flattened @@ -92,6 +123,7 @@ impl BrilligContext { } /// Deflatten an array by recursively allocating nested arrays and copying the plain values. + /// Returns the pointer to the deflattened items. fn deflatten_array( &mut self, item_type: &[BrilligParameter], @@ -139,13 +171,25 @@ impl BrilligContext { *nested_array_item_count, nested_array_pointer, ); - self.array_set( - deflattened_array_pointer, - target_index, - deflattened_nested_array_pointer, + let reference = self.allocate_register(); + let rc = self.allocate_register(); + self.const_instruction(rc, 1_usize.into()); + + self.allocate_array_reference_instruction(reference); + self.store_variable_instruction( + reference, + BrilligVariable::BrilligArray(BrilligArray { + pointer: deflattened_nested_array_pointer, + size: nested_array_item_type.len() * nested_array_item_count, + rc, + }), ); + self.array_set(deflattened_array_pointer, target_index, reference); + self.deallocate_register(nested_array_pointer); + self.deallocate_register(reference); + self.deallocate_register(rc); source_offset += BrilligContext::flattened_size(subitem); } @@ -163,21 +207,36 @@ impl BrilligContext { } /// Adds the instructions needed to handle return parameters + /// The runtime expects the results in the first `n` registers. + /// Arrays are expected to be returned as pointers to the first element with all the nested arrays flattened. + /// However, the function called returns variables (that have extra data) and the returned arrays are unflattened. fn exit_point_instruction(&mut self, return_parameters: Vec) { - // Make sure we don't overwrite the return parameters - return_parameters.iter().for_each(|_| { - self.allocate_register(); - }); - - for (index, ret) in return_parameters.iter().enumerate() { - if let BrilligParameter::Array(item_type, item_count) = ret { + // First, we allocate the registers that hold the returned variables from the function call. + self.set_allocated_registers(vec![]); + let returned_variables: Vec<_> = return_parameters + .iter() + .map(|return_parameter| match return_parameter { + BrilligParameter::Simple => BrilligVariable::Simple(self.allocate_register()), + BrilligParameter::Array(item_types, item_count) => { + BrilligVariable::BrilligArray(BrilligArray { + pointer: self.allocate_register(), + size: item_types.len() * item_count, + rc: self.allocate_register(), + }) + } + BrilligParameter::Slice(..) => unreachable!("ICE: Cannot return slices"), + }) + .collect(); + // Now, we unflatten the returned arrays + for (return_param, returned_variable) in return_parameters.iter().zip(&returned_variables) { + if let BrilligParameter::Array(item_type, item_count) = return_param { if item_type.iter().any(|item| !matches!(item, BrilligParameter::Simple)) { - let returned_pointer = ReservedRegisters::user_register_index(index); + let returned_pointer = returned_variable.extract_array().pointer; let flattened_array_pointer = self.allocate_register(); self.allocate_fixed_length_array( flattened_array_pointer, - BrilligContext::flattened_size(ret), + BrilligContext::flattened_size(return_param), ); self.flatten_array( @@ -191,16 +250,18 @@ impl BrilligContext { } } } - // We want all functions to follow the calling convention of returning + // The VM expects us to follow the calling convention of returning // their results in the first `n` registers. So we to move the return values // to the first `n` registers once completed. // Move the results to registers 0..n - for i in 0..return_parameters.len() { - self.push_opcode(BrilligOpcode::Mov { - destination: i.into(), - source: ReservedRegisters::user_register_index(i), - }); + for (i, returned_variable) in returned_variables.into_iter().enumerate() { + let register = match returned_variable { + BrilligVariable::Simple(register) => register, + BrilligVariable::BrilligArray(array) => array.pointer, + BrilligVariable::BrilligVector(vector) => vector.pointer, + }; + self.push_opcode(BrilligOpcode::Mov { destination: i.into(), source: register }); } self.push_opcode(BrilligOpcode::Stop); } @@ -237,11 +298,22 @@ impl BrilligContext { target_offset += 1; } BrilligParameter::Array(nested_array_item_type, nested_array_item_count) => { - let nested_array_pointer = self.allocate_register(); + let nested_array_reference = self.allocate_register(); self.array_get( deflattened_array_pointer, source_index, - nested_array_pointer, + nested_array_reference, + ); + + let nested_array_variable = BrilligVariable::BrilligArray(BrilligArray { + pointer: self.allocate_register(), + size: nested_array_item_type.len() * nested_array_item_count, + rc: self.allocate_register(), + }); + + self.load_variable_instruction( + nested_array_variable, + nested_array_reference, ); let flattened_nested_array_pointer = self.allocate_register(); @@ -262,11 +334,15 @@ impl BrilligContext { nested_array_item_type, *nested_array_item_count, flattened_nested_array_pointer, - nested_array_pointer, + nested_array_variable.extract_array().pointer, ); - self.deallocate_register(nested_array_pointer); + self.deallocate_register(nested_array_reference); self.deallocate_register(flattened_nested_array_pointer); + nested_array_variable + .extract_registers() + .into_iter() + .for_each(|register| self.deallocate_register(register)); target_offset += BrilligContext::flattened_size(subitem); } @@ -288,6 +364,7 @@ mod tests { use crate::brillig::brillig_ir::{ artifact::BrilligParameter, + brillig_variable::BrilligArray, tests::{create_and_run_vm, create_context, create_entry_point_bytecode}, }; @@ -332,18 +409,24 @@ mod tests { Value::from(4_usize), Value::from(5_usize), Value::from(6_usize), - // The pointer to the nested array of the first item - Value::from(10_usize), - Value::from(3_usize), - // The pointer to the nested array of the second item + // The pointer to the nested reference of the first item Value::from(12_usize), + Value::from(3_usize), + // The pointer to the nested reference of the second item + Value::from(16_usize), Value::from(6_usize), // The nested array of the first item Value::from(1_usize), Value::from(2_usize), + // The nested reference of the first item + Value::from(10_usize), + Value::from(1_usize), // The nested array of the second item Value::from(4_usize), Value::from(5_usize), + // The nested reference of the second item + Value::from(14_usize), + Value::from(1_usize), ] ); } @@ -358,35 +441,31 @@ mod tests { Value::from(5_usize), Value::from(6_usize), ]; - let array_param = BrilligParameter::Array( vec![ - BrilligParameter::Simple, BrilligParameter::Array(vec![BrilligParameter::Simple], 2), + BrilligParameter::Simple, ], 2, ); - let arguments = vec![array_param.clone()]; let returns = vec![array_param]; let mut context = create_context(); // Allocate the parameter - let array_pointer = context.allocate_register(); + let brillig_array = BrilligArray { + pointer: context.allocate_register(), + size: 2, + rc: context.allocate_register(), + }; - context.return_instruction(&[array_pointer]); + context.return_instruction(&brillig_array.extract_registers()); let bytecode = create_entry_point_bytecode(context, arguments, returns).byte_code; let vm = create_and_run_vm(flattened_array.clone(), vec![Value::from(0_usize)], &bytecode); let memory = vm.get_memory(); - assert_eq!( - vm.get_registers().get(RegisterIndex(0)), - // The returned value will be past the original array and the deflattened array - Value::from(flattened_array.len() + (flattened_array.len() + 2)), - ); - assert_eq!( memory, &vec![ @@ -397,19 +476,25 @@ mod tests { Value::from(4_usize), Value::from(5_usize), Value::from(6_usize), - // The pointer to the nested array of the first item - Value::from(1_usize), - Value::from(10_usize), - // The pointer to the nested array of the second item - Value::from(4_usize), + // The pointer to the nested reference of the first item Value::from(12_usize), + Value::from(3_usize), + // The pointer to the nested reference of the second item + Value::from(16_usize), + Value::from(6_usize), // The nested array of the first item + Value::from(1_usize), Value::from(2_usize), - Value::from(3_usize), + // The nested reference of the first item + Value::from(10_usize), + Value::from(1_usize), // The nested array of the second item + Value::from(4_usize), Value::from(5_usize), - Value::from(6_usize), - // The values flattened again + // The nested reference of the second item + Value::from(14_usize), + Value::from(1_usize), + // The original flattened again Value::from(1_usize), Value::from(2_usize), Value::from(3_usize), @@ -418,5 +503,6 @@ mod tests { Value::from(6_usize), ] ); + assert_eq!(vm.get_registers().get(RegisterIndex(0)), 18_usize.into()); } } diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index c4b19379ecc..09a3bd4e44b 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -380,9 +380,15 @@ impl AcirContext { rhs: AcirVar, typ: AcirType, ) -> Result { - let inputs = vec![AcirValue::Var(lhs, typ.clone()), AcirValue::Var(rhs, typ)]; - let outputs = self.black_box_function(BlackBoxFunc::AND, inputs, 1)?; - Ok(outputs[0]) + let bit_size = typ.bit_size(); + if bit_size == 1 { + // Operands are booleans. + self.mul_var(lhs, rhs) + } else { + let inputs = vec![AcirValue::Var(lhs, typ.clone()), AcirValue::Var(rhs, typ)]; + let outputs = self.black_box_function(BlackBoxFunc::AND, inputs, 1)?; + Ok(outputs[0]) + } } /// Returns an `AcirVar` that is the OR result of `lhs` & `rhs`. diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 2f58957c73d..331c837a521 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -101,14 +101,16 @@ pub(crate) struct AcirDynamicArray { len: usize, /// Identification for the ACIR dynamic array /// inner element type sizes array - element_type_sizes: BlockId, + element_type_sizes: Option, } impl Debug for AcirDynamicArray { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "id: {}, len: {}, element_type_sizes: {:?}", - self.block_id.0, self.len, self.element_type_sizes.0 + self.block_id.0, + self.len, + self.element_type_sizes.map(|block_id| block_id.0) ) } } @@ -563,6 +565,9 @@ impl Context { Instruction::Load { .. } => { unreachable!("Expected all load instructions to be removed before acir_gen") } + Instruction::IncrementRc { .. } => { + // Do nothing. Only Brillig needs to worry about reference counted arrays + } Instruction::RangeCheck { value, max_bit_size, assert_message } => { let acir_var = self.convert_numeric_value(*value, dfg)?; self.acir_context.range_constrain_var( @@ -921,7 +926,7 @@ impl Context { // Read the value from the array at the specified index let read = self.acir_context.read_from_memory(block_id, var_index)?; - // Incremement the var_index in case of a nested array + // Increment the var_index in case of a nested array *var_index = self.acir_context.add_var(*var_index, one)?; let typ = AcirType::NumericType(numeric_type); @@ -1036,8 +1041,11 @@ impl Context { } } - let element_type_sizes = - self.init_element_type_sizes_array(&array_typ, array_id, None, dfg)?; + let element_type_sizes = if !can_omit_element_sizes_array(&array_typ) { + Some(self.init_element_type_sizes_array(&array_typ, array_id, None, dfg)?) + } else { + None + }; let result_value = AcirValue::DynamicArray(AcirDynamicArray { block_id: result_block_id, len: array_len, @@ -1162,27 +1170,29 @@ impl Context { element_type_sizes: inner_elem_type_sizes, .. }) => { - if self.initialized_arrays.contains(&inner_elem_type_sizes) { - let type_sizes_array_len = self.internal_mem_block_lengths.get(&inner_elem_type_sizes).copied().ok_or_else(|| - InternalError::General { - message: format!("Array {array_id}'s inner element type sizes array does not have a tracked length"), + if let Some(inner_elem_type_sizes) = inner_elem_type_sizes { + if self.initialized_arrays.contains(&inner_elem_type_sizes) { + let type_sizes_array_len = self.internal_mem_block_lengths.get(&inner_elem_type_sizes).copied().ok_or_else(|| + InternalError::General { + message: format!("Array {array_id}'s inner element type sizes array does not have a tracked length"), + call_stack: self.acir_context.get_call_stack(), + } + )?; + self.copy_dynamic_array( + inner_elem_type_sizes, + element_type_sizes, + type_sizes_array_len, + )?; + self.internal_mem_block_lengths + .insert(element_type_sizes, type_sizes_array_len); + return Ok(element_type_sizes); + } else { + return Err(InternalError::General { + message: format!("Array {array_id}'s inner element type sizes array should be initialized"), call_stack: self.acir_context.get_call_stack(), } - )?; - self.copy_dynamic_array( - inner_elem_type_sizes, - element_type_sizes, - type_sizes_array_len, - )?; - self.internal_mem_block_lengths - .insert(element_type_sizes, type_sizes_array_len); - return Ok(element_type_sizes); - } else { - return Err(InternalError::General { - message: format!("Array {array_id}'s inner element type sizes array should be initialized"), - call_stack: self.acir_context.get_call_stack(), + .into()); } - .into()); } } AcirValue::Array(values) => { @@ -1298,15 +1308,19 @@ impl Context { var_index: AcirVar, dfg: &DataFlowGraph, ) -> Result { - let element_type_sizes = - self.init_element_type_sizes_array(array_typ, array_id, None, dfg)?; + if !can_omit_element_sizes_array(array_typ) { + let element_type_sizes = + self.init_element_type_sizes_array(array_typ, array_id, None, dfg)?; - let predicate_index = - self.acir_context.mul_var(var_index, self.current_side_effects_enabled_var)?; - let flat_element_size_var = - self.acir_context.read_from_memory(element_type_sizes, &predicate_index)?; + let predicate_index = + self.acir_context.mul_var(var_index, self.current_side_effects_enabled_var)?; - Ok(flat_element_size_var) + self.acir_context + .read_from_memory(element_type_sizes, &predicate_index) + .map_err(RuntimeError::from) + } else { + Ok(var_index) + } } fn flattened_slice_size(&mut self, array_id: ValueId, dfg: &DataFlowGraph) -> usize { @@ -1565,7 +1579,7 @@ impl Context { (_, Type::Function) | (Type::Function, _) => { unreachable!("all functions should be inlined") } - (_, Type::Reference) | (Type::Reference, _) => { + (_, Type::Reference(_)) | (Type::Reference(_), _) => { unreachable!("References are invalid in binary operations") } (_, Type::Array(..)) | (Type::Array(..), _) => { @@ -1781,15 +1795,20 @@ impl Context { let mut var_index = slice_length; self.array_set_value(element, result_block_id, &mut var_index)?; - let result = AcirValue::DynamicArray(AcirDynamicArray { - block_id: result_block_id, - len: len + new_elem_size, - element_type_sizes: self.init_element_type_sizes_array( + let element_type_sizes = if !can_omit_element_sizes_array(&array_typ) { + Some(self.init_element_type_sizes_array( &array_typ, array_id, Some(new_slice_val), dfg, - )?, + )?) + } else { + None + }; + let result = AcirValue::DynamicArray(AcirDynamicArray { + block_id: result_block_id, + len: len + new_elem_size, + element_type_sizes, }); Ok(vec![AcirValue::Var(new_slice_length, AcirType::field()), result]) } @@ -2041,3 +2060,16 @@ impl Context { } } } + +// We can omit the element size array for arrays which have elements of size 1 and do not contain slices. +// TODO: remove restriction on size 1 elements. +fn can_omit_element_sizes_array(array_typ: &Type) -> bool { + if array_typ.contains_slice_element() { + return false; + } + let Type::Array(types, _) = array_typ else { + panic!("ICE: expected array type"); + }; + + types.len() == 1 && types[0].flattened_size() == 1 +} diff --git a/noir/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/noir/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index 47423841a3b..e01e1fe1a1d 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -170,8 +170,9 @@ impl FunctionBuilder { /// Insert an allocate instruction at the end of the current block, allocating the /// given amount of field elements. Returns the result of the allocate instruction, /// which is always a Reference to the allocated data. - pub(crate) fn insert_allocate(&mut self) -> ValueId { - self.insert_instruction(Instruction::Allocate, None).first() + pub(crate) fn insert_allocate(&mut self, element_type: Type) -> ValueId { + let reference_type = Type::Reference(Rc::new(element_type)); + self.insert_instruction(Instruction::Allocate, Some(vec![reference_type])).first() } pub(crate) fn set_location(&mut self, location: Location) -> &mut FunctionBuilder { @@ -458,6 +459,27 @@ impl FunctionBuilder { _ => None, } } + + /// Insert instructions to increment the reference count of any array(s) stored + /// within the given value. If the given value is not an array and does not contain + /// any arrays, this does nothing. + pub(crate) fn increment_array_reference_count(&mut self, value: ValueId) { + match self.type_of_value(value) { + Type::Numeric(_) => (), + Type::Function => (), + Type::Reference(element) => { + if element.contains_an_array() { + let value = self.insert_load(value, element.as_ref().clone()); + self.increment_array_reference_count(value); + } + } + Type::Array(..) | Type::Slice(..) => { + self.insert_instruction(Instruction::IncrementRc { value }, None); + // If there are nested arrays or slices, we wait until ArrayGet + // is issued to increment the count of that array. + } + } + } } impl std::ops::Index for FunctionBuilder { diff --git a/noir/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/noir/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 3cb6736007d..75b2cf962f7 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -318,7 +318,7 @@ impl DataFlowGraph { /// True if the type of this value is Type::Reference. /// Using this method over type_of_value avoids cloning the value's type. pub(crate) fn value_is_reference(&self, value: ValueId) -> bool { - matches!(self.values[value].get_type(), Type::Reference) + matches!(self.values[value].get_type(), Type::Reference(_)) } /// Appends a result type to the instruction. @@ -521,13 +521,13 @@ impl<'dfg> InsertInstructionResult<'dfg> { #[cfg(test)] mod tests { use super::DataFlowGraph; - use crate::ssa::ir::instruction::Instruction; + use crate::ssa::ir::{instruction::Instruction, types::Type}; #[test] fn make_instruction() { let mut dfg = DataFlowGraph::default(); let ins = Instruction::Allocate; - let ins_id = dfg.make_instruction(ins, None); + let ins_id = dfg.make_instruction(ins, Some(vec![Type::field()])); let results = dfg.instruction_results(ins_id); assert_eq!(results.len(), 1); diff --git a/noir/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/noir/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 71401201715..63b32766f62 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -182,6 +182,13 @@ pub(crate) enum Instruction { /// Creates a new array with the new value at the given index. All other elements are identical /// to those in the given array. This will not modify the original array. ArraySet { array: ValueId, index: ValueId, value: ValueId }, + + /// An instruction to increment the reference count of a value. + /// + /// This currently only has an effect in Brillig code where array sharing and copy on write is + /// implemented via reference counting. In ACIR code this is done with im::Vector and these + /// IncrementRc instructions are ignored. + IncrementRc { value: ValueId }, } impl Instruction { @@ -195,18 +202,19 @@ impl Instruction { match self { Instruction::Binary(binary) => binary.result_type(), Instruction::Cast(_, typ) => InstructionResultType::Known(typ.clone()), - Instruction::Allocate { .. } => InstructionResultType::Known(Type::Reference), Instruction::Not(value) | Instruction::Truncate { value, .. } => { InstructionResultType::Operand(*value) } Instruction::ArraySet { array, .. } => InstructionResultType::Operand(*array), Instruction::Constrain(..) | Instruction::Store { .. } - | Instruction::EnableSideEffects { .. } - | Instruction::RangeCheck { .. } => InstructionResultType::None, - Instruction::Load { .. } | Instruction::ArrayGet { .. } | Instruction::Call { .. } => { - InstructionResultType::Unknown - } + | Instruction::IncrementRc { .. } + | Instruction::RangeCheck { .. } + | Instruction::EnableSideEffects { .. } => InstructionResultType::None, + Instruction::Allocate { .. } + | Instruction::Load { .. } + | Instruction::ArrayGet { .. } + | Instruction::Call { .. } => InstructionResultType::Unknown, } } @@ -235,6 +243,7 @@ impl Instruction { | Allocate | Load { .. } | Store { .. } + | IncrementRc { .. } | RangeCheck { .. } => false, Call { func, .. } => match dfg[*func] { @@ -266,7 +275,11 @@ impl Instruction { | ArrayGet { .. } | ArraySet { .. } => false, - Constrain(..) | Store { .. } | EnableSideEffects { .. } | RangeCheck { .. } => true, + Constrain(..) + | Store { .. } + | EnableSideEffects { .. } + | IncrementRc { .. } + | RangeCheck { .. } => true, // Some `Intrinsic`s have side effects so we must check what kind of `Call` this is. Call { func, .. } => match dfg[*func] { @@ -323,6 +336,7 @@ impl Instruction { Instruction::ArraySet { array, index, value } => { Instruction::ArraySet { array: f(*array), index: f(*index), value: f(*value) } } + Instruction::IncrementRc { value } => Instruction::IncrementRc { value: f(*value) }, Instruction::RangeCheck { value, max_bit_size, assert_message } => { Instruction::RangeCheck { value: f(*value), @@ -374,7 +388,7 @@ impl Instruction { Instruction::EnableSideEffects { condition } => { f(*condition); } - Instruction::RangeCheck { value, .. } => { + Instruction::IncrementRc { value } | Instruction::RangeCheck { value, .. } => { f(*value); } } @@ -474,6 +488,7 @@ impl Instruction { Instruction::Allocate { .. } => None, Instruction::Load { .. } => None, Instruction::Store { .. } => None, + Instruction::IncrementRc { .. } => None, Instruction::RangeCheck { value, max_bit_size, .. } => { if let Some(numeric_constant) = dfg.get_numeric_constant(*value) { if numeric_constant.num_bits() < *max_bit_size { diff --git a/noir/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/noir/compiler/noirc_evaluator/src/ssa/ir/printer.rs index c6b1f3c7528..2899b987c1d 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -172,6 +172,9 @@ pub(crate) fn display_instruction( show(*value) ) } + Instruction::IncrementRc { value } => { + writeln!(f, "inc_rc {}", show(*value)) + } Instruction::RangeCheck { value, max_bit_size, .. } => { writeln!(f, "range_check {} to {} bits", show(*value), *max_bit_size,) } diff --git a/noir/compiler/noirc_evaluator/src/ssa/ir/types.rs b/noir/compiler/noirc_evaluator/src/ssa/ir/types.rs index 7fe0713e748..8f2fe2d236b 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ir/types.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ir/types.rs @@ -25,7 +25,7 @@ pub(crate) enum Type { Numeric(NumericType), /// A reference to some value, such as an array - Reference, + Reference(Rc), /// An immutable array value with the given element type and length Array(Rc, usize), @@ -86,24 +86,31 @@ impl Type { } Type::Slice(_) => true, Type::Numeric(_) => false, - Type::Reference => false, + Type::Reference(_) => false, Type::Function => false, } } /// Returns the flattened size of a Type pub(crate) fn flattened_size(&self) -> usize { - let mut size = 0; match self { Type::Array(elements, len) => { - size = elements.iter().fold(size, |sum, elem| sum + (elem.flattened_size() * len)); + elements.iter().fold(0, |sum, elem| sum + (elem.flattened_size() * len)) } Type::Slice(_) => { unimplemented!("ICE: cannot fetch flattened slice size"); } - _ => size += 1, + _ => 1, + } + } + + /// True if this type is an array (or slice) or internally contains an array (or slice) + pub(crate) fn contains_an_array(&self) -> bool { + match self { + Type::Numeric(_) | Type::Function => false, + Type::Array(_, _) | Type::Slice(_) => true, + Type::Reference(element) => element.contains_an_array(), } - size } } @@ -136,7 +143,7 @@ impl std::fmt::Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Type::Numeric(numeric) => numeric.fmt(f), - Type::Reference => write!(f, "reference"), + Type::Reference(element) => write!(f, "&mut {element}"), Type::Array(element, length) => { let elements = vecmap(element.iter(), |element| element.to_string()); write!(f, "[{}; {length}]", elements.join(", ")) diff --git a/noir/compiler/noirc_evaluator/src/ssa/opt/die.rs b/noir/compiler/noirc_evaluator/src/ssa/opt/die.rs index 3db95f6ad99..53cdf72bbbf 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/opt/die.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/opt/die.rs @@ -7,7 +7,7 @@ use crate::ssa::{ basic_block::{BasicBlock, BasicBlockId}, dfg::DataFlowGraph, function::Function, - instruction::InstructionId, + instruction::{Instruction, InstructionId}, post_order::PostOrder, value::{Value, ValueId}, }, @@ -38,6 +38,8 @@ fn dead_instruction_elimination(function: &mut Function) { for block in blocks.as_slice() { context.remove_unused_instructions_in_block(function, *block); } + + context.remove_increment_rc_instructions(&mut function.dfg); } /// Per function context for tracking unused values and which instructions to remove. @@ -45,6 +47,11 @@ fn dead_instruction_elimination(function: &mut Function) { struct Context { used_values: HashSet, instructions_to_remove: HashSet, + + /// IncrementRc instructions must be revisited after the main DIE pass since + /// they are technically side-effectful but we stil want to remove them if their + /// `value` parameter is not used elsewhere. + increment_rc_instructions: Vec<(InstructionId, BasicBlockId)>, } impl Context { @@ -67,14 +74,19 @@ impl Context { let block = &function.dfg[block_id]; self.mark_terminator_values_as_used(function, block); - for instruction in block.instructions().iter().rev() { - if self.is_unused(*instruction, function) { - self.instructions_to_remove.insert(*instruction); + for instruction_id in block.instructions().iter().rev() { + if self.is_unused(*instruction_id, function) { + self.instructions_to_remove.insert(*instruction_id); } else { - let instruction = &function.dfg[*instruction]; - instruction.for_each_value(|value| { - self.mark_used_instruction_results(&function.dfg, value); - }); + let instruction = &function.dfg[*instruction_id]; + + if let Instruction::IncrementRc { .. } = instruction { + self.increment_rc_instructions.push((*instruction_id, block_id)); + } else { + instruction.for_each_value(|value| { + self.mark_used_instruction_results(&function.dfg, value); + }); + } } } @@ -119,11 +131,28 @@ impl Context { self.mark_used_instruction_results(dfg, *elem); } } + Value::Param { .. } => { + self.used_values.insert(value_id); + } _ => { // Does not comprise of any instruction results } } } + + fn remove_increment_rc_instructions(self, dfg: &mut DataFlowGraph) { + for (increment_rc, block) in self.increment_rc_instructions { + let value = match &dfg[increment_rc] { + Instruction::IncrementRc { value } => *value, + other => unreachable!("Expected IncrementRc instruction, found {other:?}"), + }; + + // This could be more efficient if we have to remove multiple IncrementRcs in a single block + if !self.used_values.contains(&value) { + dfg[block].instructions_mut().retain(|instruction| *instruction != increment_rc); + } + } + } } #[cfg(test)] @@ -176,10 +205,10 @@ mod test { builder.switch_to_block(b1); let _v3 = builder.add_block_parameter(b1, Type::field()); - let v4 = builder.insert_allocate(); + let v4 = builder.insert_allocate(Type::field()); let _v5 = builder.insert_load(v4, Type::field()); - let v6 = builder.insert_allocate(); + let v6 = builder.insert_allocate(Type::field()); builder.insert_store(v6, one); let v7 = builder.insert_load(v6, Type::field()); let v8 = builder.insert_binary(v7, BinaryOp::Add, one); diff --git a/noir/compiler/noirc_evaluator/src/ssa/opt/fill_internal_slices.rs b/noir/compiler/noirc_evaluator/src/ssa/opt/fill_internal_slices.rs index d12b01b9196..57e85f076da 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/opt/fill_internal_slices.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/opt/fill_internal_slices.rs @@ -398,7 +398,7 @@ impl<'f> Context<'f> { self.inserter.function.dfg.make_array(slice, typ.clone()) } } - Type::Reference => { + Type::Reference(_) => { unreachable!("ICE: Generating dummy data for references is unsupported") } Type::Function => { diff --git a/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index d2ed21c60d7..29df9d3c76d 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -817,7 +817,7 @@ mod test { #[test] fn merge_stores() { // fn main f0 { - // b0(v0: u1, v1: ref): + // b0(v0: u1, v1: &mut Field): // jmpif v0, then: b1, else: b2 // b1(): // store v1, Field 5 @@ -832,7 +832,7 @@ mod test { let b2 = builder.insert_block(); let v0 = builder.add_parameter(Type::bool()); - let v1 = builder.add_parameter(Type::Reference); + let v1 = builder.add_parameter(Type::Reference(Rc::new(Type::field()))); builder.terminate_with_jmpif(v0, b1, b2); @@ -894,7 +894,7 @@ mod test { let b3 = builder.insert_block(); let v0 = builder.add_parameter(Type::bool()); - let v1 = builder.add_parameter(Type::Reference); + let v1 = builder.add_parameter(Type::Reference(Rc::new(Type::field()))); builder.terminate_with_jmpif(v0, b1, b2); @@ -993,7 +993,7 @@ mod test { let c1 = builder.add_parameter(Type::bool()); let c4 = builder.add_parameter(Type::bool()); - let r1 = builder.insert_allocate(); + let r1 = builder.insert_allocate(Type::field()); let store_value = |builder: &mut FunctionBuilder, value: u128| { let value = builder.field_constant(value); @@ -1144,7 +1144,7 @@ mod test { builder.terminate_with_jmpif(v0, b1, b2); builder.switch_to_block(b1); - let v2 = builder.insert_allocate(); + let v2 = builder.insert_allocate(Type::field()); let zero = builder.field_constant(0u128); builder.insert_store(v2, zero); let _v4 = builder.insert_load(v2, Type::field()); @@ -1313,7 +1313,7 @@ mod test { let v8 = builder.insert_binary(v6, BinaryOp::Mod, i_two); let v9 = builder.insert_cast(v8, Type::bool()); - let v10 = builder.insert_allocate(); + let v10 = builder.insert_allocate(Type::field()); builder.insert_store(v10, zero); builder.terminate_with_jmpif(v9, b1, b2); @@ -1412,9 +1412,9 @@ mod test { let ten = builder.field_constant(10u128); let one_hundred = builder.field_constant(100u128); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::field()); builder.insert_store(v0, zero); - let v2 = builder.insert_allocate(); + let v2 = builder.insert_allocate(Type::field()); builder.insert_store(v2, two); let v4 = builder.insert_load(v2, Type::field()); let v5 = builder.insert_binary(v4, BinaryOp::Lt, two); diff --git a/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs b/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs index 32979f78632..446560f45f1 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs @@ -60,7 +60,7 @@ impl<'a> ValueMerger<'a> { typ @ Type::Slice(_) => { self.merge_slice_values(typ, then_condition, else_condition, then_value, else_value) } - Type::Reference => panic!("Cannot return references from an if expression"), + Type::Reference(_) => panic!("Cannot return references from an if expression"), Type::Function => panic!("Cannot return functions from an if expression"), } } @@ -333,7 +333,7 @@ impl<'a> ValueMerger<'a> { // to accurately construct dummy data unreachable!("ICE: Cannot return a slice of slices from an if expression") } - Type::Reference => { + Type::Reference(_) => { unreachable!("ICE: Merging references is unsupported") } Type::Function => { diff --git a/noir/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/noir/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index e5fffaccdd0..fba6e6ab989 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -326,7 +326,7 @@ impl<'f> PerFunctionContext<'f> { match typ { Type::Numeric(_) => false, Type::Function => false, - Type::Reference => true, + Type::Reference(_) => true, Type::Array(elements, _) | Type::Slice(elements) => { elements.iter().any(Self::contains_references) } @@ -427,7 +427,7 @@ mod tests { let func_id = Id::test_new(0); let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::Array(Rc::new(vec![Type::field()]), 2)); let one = builder.field_constant(FieldElement::one()); let two = builder.field_constant(FieldElement::one()); @@ -468,7 +468,7 @@ mod tests { let func_id = Id::test_new(0); let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::field()); let one = builder.field_constant(FieldElement::one()); builder.insert_store(v0, one); let v1 = builder.insert_load(v0, Type::field()); @@ -502,7 +502,7 @@ mod tests { let func_id = Id::test_new(0); let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::field()); let const_one = builder.field_constant(FieldElement::one()); builder.insert_store(v0, const_one); builder.terminate_with_return(vec![v0]); @@ -562,7 +562,7 @@ mod tests { let main_id = Id::test_new(0); let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::field()); let five = builder.field_constant(5u128); builder.insert_store(v0, five); @@ -642,12 +642,12 @@ mod tests { let main_id = Id::test_new(0); let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); - let v0 = builder.insert_allocate(); + let v0 = builder.insert_allocate(Type::field()); let zero = builder.field_constant(0u128); builder.insert_store(v0, zero); - let v2 = builder.insert_allocate(); + let v2 = builder.insert_allocate(Type::Reference(Rc::new(Type::field()))); builder.insert_store(v2, v0); let v3 = builder.insert_load(v2, Type::field()); diff --git a/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs b/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs index 72b94e575a9..9d27ffc60d8 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs @@ -152,7 +152,8 @@ impl<'a> FunctionContext<'a> { /// Allocate a single slot of memory and store into it the given initial value of the variable. /// Always returns a Value::Mutable wrapping the allocate instruction. pub(super) fn new_mutable_variable(&mut self, value_to_store: ValueId) -> Value { - let alloc = self.builder.insert_allocate(); + let element_type = self.builder.current_function.dfg.type_of_value(value_to_store); + let alloc = self.builder.insert_allocate(element_type); self.builder.insert_store(alloc, value_to_store); let typ = self.builder.type_of_value(value_to_store); Value::Mutable(alloc, typ) @@ -177,7 +178,7 @@ impl<'a> FunctionContext<'a> { // A mutable reference wraps each element into a reference. // This can be multiple values if the element type is a tuple. ast::Type::MutableReference(element) => { - Self::map_type_helper(element, &mut |_| f(Type::Reference)) + Self::map_type_helper(element, &mut |typ| f(Type::Reference(Rc::new(typ)))) } ast::Type::FmtString(len, fields) => { // A format string is represented by multiple values @@ -231,8 +232,8 @@ impl<'a> FunctionContext<'a> { ast::Type::Slice(_) => panic!("convert_non_tuple_type called on a slice: {typ}"), ast::Type::MutableReference(element) => { // Recursive call to panic if element is a tuple - Self::convert_non_tuple_type(element); - Type::Reference + let element = Self::convert_non_tuple_type(element); + Type::Reference(Rc::new(element)) } } } @@ -600,7 +601,7 @@ impl<'a> FunctionContext<'a> { let loop_end = self.builder.insert_block(); // pre-loop - let result_alloc = self.builder.set_location(location).insert_allocate(); + let result_alloc = self.builder.set_location(location).insert_allocate(Type::bool()); let true_value = self.builder.numeric_constant(1u128, Type::bool()); self.builder.insert_store(result_alloc, true_value); let zero = self.builder.field_constant(0u128); diff --git a/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs index 7677f5669cb..53f1bc863be 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -210,6 +210,13 @@ impl<'a> FunctionContext<'a> { for element in elements { element.for_each(|element| { let element = element.eval(self); + + // If we're referencing a sub-array in a larger nested array we need to + // increase the reference count of the sub array. This maintains a + // pessimistic reference count (since some are likely moved rather than shared) + // which is important for Brillig's copy on write optimization. This has no + // effect in ACIR code. + self.builder.increment_array_reference_count(element); array.push_back(element); }); } @@ -248,11 +255,12 @@ impl<'a> FunctionContext<'a> { Ok(self.codegen_reference(&unary.rhs)?.map(|rhs| { match rhs { value::Value::Normal(value) => { - let alloc = self.builder.insert_allocate(); + let rhs_type = self.builder.current_function.dfg.type_of_value(value); + let alloc = self.builder.insert_allocate(rhs_type); self.builder.insert_store(alloc, value); Tree::Leaf(value::Value::Normal(alloc)) } - // NOTE: The `.into()` here converts the Value::Mutable into + // The `.into()` here converts the Value::Mutable into // a Value::Normal so it is no longer automatically dereferenced. value::Value::Mutable(reference, _) => reference.into(), } @@ -300,6 +308,7 @@ impl<'a> FunctionContext<'a> { } else { (array_or_slice[0], None) }; + self.codegen_array_index( array, index_value, @@ -344,7 +353,13 @@ impl<'a> FunctionContext<'a> { } _ => unreachable!("must have array or slice but got {array_type}"), } - self.builder.insert_array_get(array, offset, typ).into() + + // Reference counting in brillig relies on us incrementing reference + // counts when nested arrays/slices are constructed or indexed. This + // has no effect in ACIR code. + let result = self.builder.insert_array_get(array, offset, typ); + self.builder.increment_array_reference_count(result); + result.into() })) } @@ -534,6 +549,11 @@ impl<'a> FunctionContext<'a> { arguments.append(&mut values); } + // If an array is passed as an argument we increase its reference count + for argument in &arguments { + self.builder.increment_array_reference_count(*argument); + } + self.codegen_intrinsic_call_checks(function, &arguments, call.location); Ok(self.insert_call(function, arguments, &call.return_type, call.location)) @@ -575,12 +595,18 @@ impl<'a> FunctionContext<'a> { fn codegen_let(&mut self, let_expr: &ast::Let) -> Result { let mut values = self.codegen_expression(&let_expr.expression)?; - if let_expr.mutable { - values = values.map(|value| { - let value = value.eval(self); - Tree::Leaf(self.new_mutable_variable(value)) - }); - } + values = values.map(|value| { + let value = value.eval(self); + + // Make sure to increment array reference counts on each let binding + self.builder.increment_array_reference_count(value); + + Tree::Leaf(if let_expr.mutable { + self.new_mutable_variable(value) + } else { + value::Value::Normal(value) + }) + }); self.define(let_expr.id, values); Ok(Self::unit_value()) diff --git a/noir/compiler/noirc_frontend/Cargo.toml b/noir/compiler/noirc_frontend/Cargo.toml index 246d6617c94..6f3c35a814a 100644 --- a/noir/compiler/noirc_frontend/Cargo.toml +++ b/noir/compiler/noirc_frontend/Cargo.toml @@ -26,6 +26,3 @@ regex = "1.9.1" [dev-dependencies] strum = "0.24" strum_macros = "0.24" - -[features] -aztec = [] diff --git a/noir/compiler/noirc_frontend/src/ast/expression.rs b/noir/compiler/noirc_frontend/src/ast/expression.rs index d29e1670944..41807d7eca7 100644 --- a/noir/compiler/noirc_frontend/src/ast/expression.rs +++ b/noir/compiler/noirc_frontend/src/ast/expression.rs @@ -76,6 +76,10 @@ impl ExpressionKind { ExpressionKind::Literal(Literal::Str(contents)) } + pub fn raw_string(contents: String, hashes: u8) -> ExpressionKind { + ExpressionKind::Literal(Literal::RawStr(contents, hashes)) + } + pub fn format_string(contents: String) -> ExpressionKind { ExpressionKind::Literal(Literal::FmtStr(contents)) } @@ -312,6 +316,7 @@ pub enum Literal { Bool(bool), Integer(FieldElement), Str(String), + RawStr(String, u8), FmtStr(String), Unit, } @@ -507,6 +512,11 @@ impl Display for Literal { Literal::Bool(boolean) => write!(f, "{}", if *boolean { "true" } else { "false" }), Literal::Integer(integer) => write!(f, "{}", integer.to_u128()), Literal::Str(string) => write!(f, "\"{string}\""), + Literal::RawStr(string, num_hashes) => { + let hashes: String = + std::iter::once('#').cycle().take(*num_hashes as usize).collect(); + write!(f, "r{hashes}\"{string}\"{hashes}") + } Literal::FmtStr(string) => write!(f, "f\"{string}\""), Literal::Unit => write!(f, "()"), } diff --git a/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index ce1cf675a07..86122530cde 100644 --- a/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -1,33 +1,32 @@ use super::dc_mod::collect_defs; use super::errors::{DefCollectorErrorKind, DuplicateType}; use crate::graph::CrateId; -use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleData, ModuleDefId, ModuleId}; +use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; use crate::hir::resolution::errors::ResolverError; -use crate::hir::resolution::import::PathResolutionError; -use crate::hir::resolution::path_resolver::PathResolver; + +use crate::hir::resolution::import::{resolve_imports, ImportDirective}; use crate::hir::resolution::resolver::Resolver; use crate::hir::resolution::{ - import::{resolve_imports, ImportDirective}, - path_resolver::StandardPathResolver, + collect_impls, collect_trait_impls, resolve_free_functions, resolve_globals, resolve_impls, + resolve_structs, resolve_trait_by_path, resolve_trait_impls, resolve_traits, + resolve_type_aliases, }; use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::hir_def::traits::{Trait, TraitConstant, TraitFunction, TraitImpl, TraitType}; -use crate::node_interner::{ - FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplId, TypeAliasId, -}; + +use crate::macros_api::MacroProcessor; +use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; use crate::parser::{ParserError, SortedModule}; use crate::{ - ExpressionKind, Generics, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, - NoirTypeAlias, Path, Shared, StructType, TraitItem, Type, TypeBinding, TypeVariableKind, - UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, + ExpressionKind, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait, NoirTypeAlias, + Path, Type, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, }; use fm::FileId; use iter_extended::vecmap; use noirc_errors::{CustomDiagnostic, Span}; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::rc::Rc; +use std::collections::{BTreeMap, HashMap}; + use std::vec; /// Stores all of the unresolved functions in a particular file/mod @@ -124,6 +123,16 @@ pub struct DefCollector { pub(crate) collected_traits_impls: Vec, } +/// Maps the type and the module id in which the impl is defined to the functions contained in that +/// impl along with the generics declared on the impl itself. This also contains the Span +/// of the object_type of the impl, used to issue an error if the object type fails to resolve. +/// +/// Note that because these are keyed by unresolved types, the impl map is one of the few instances +/// of HashMap rather than BTreeMap. For this reason, we should be careful not to iterate over it +/// since it would be non-deterministic. +pub(crate) type ImplMap = + HashMap<(UnresolvedType, LocalModuleId), Vec<(UnresolvedGenerics, Span, UnresolvedFunctions)>>; + #[derive(Debug, Clone)] pub enum CompilationError { ParseError(ParserError), @@ -166,16 +175,6 @@ impl From for CompilationError { } } -/// Maps the type and the module id in which the impl is defined to the functions contained in that -/// impl along with the generics declared on the impl itself. This also contains the Span -/// of the object_type of the impl, used to issue an error if the object type fails to resolve. -/// -/// Note that because these are keyed by unresolved types, the impl map is one of the few instances -/// of HashMap rather than BTreeMap. For this reason, we should be careful not to iterate over it -/// since it would be non-deterministic. -type ImplMap = - HashMap<(UnresolvedType, LocalModuleId), Vec<(UnresolvedGenerics, Span, UnresolvedFunctions)>>; - impl DefCollector { fn new(def_map: CrateDefMap) -> DefCollector { DefCollector { @@ -199,6 +198,7 @@ impl DefCollector { context: &mut Context, ast: SortedModule, root_file_id: FileId, + macro_processors: Vec<&dyn MacroProcessor>, ) -> Vec<(CompilationError, FileId)> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; let crate_id = def_map.krate; @@ -211,7 +211,11 @@ impl DefCollector { let crate_graph = &context.crate_graph[crate_id]; for dep in crate_graph.dependencies.clone() { - errors.extend(CrateDefMap::collect_defs(dep.crate_id, context)); + errors.extend(CrateDefMap::collect_defs( + dep.crate_id, + context, + macro_processors.clone(), + )); let dep_def_root = context.def_map(&dep.crate_id).expect("ice: def map was just created").root; @@ -341,10 +345,9 @@ impl DefCollector { errors.extend(resolved_globals.errors); - // We run hir transformations before type checks - #[cfg(feature = "aztec")] - crate::hir::aztec_library::transform_hir(&crate_id, context); - + for macro_processor in macro_processors { + macro_processor.process_typed_ast(&crate_id, context); + } errors.extend(type_check_globals(&mut context.def_interner, resolved_globals.globals)); // Type check all of the functions in the crate @@ -355,264 +358,6 @@ impl DefCollector { } } -/// Go through the list of impls and add each function within to the scope -/// of the module defined by its type. -fn collect_impls( - context: &mut Context, - crate_id: CrateId, - collected_impls: &ImplMap, -) -> Vec<(CompilationError, FileId)> { - let interner = &mut context.def_interner; - let def_maps = &mut context.def_maps; - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - - for ((unresolved_type, module_id), methods) in collected_impls { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: *module_id, krate: crate_id }); - - let file = def_maps[&crate_id].file_id(*module_id); - - for (generics, span, unresolved) in methods { - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(generics); - let typ = resolver.resolve_type(unresolved_type.clone()); - - errors.extend(take_errors(unresolved.file_id, resolver)); - - if let Some(struct_type) = get_struct_type(&typ) { - let struct_type = struct_type.borrow(); - - // `impl`s are only allowed on types defined within the current crate - if struct_type.id.krate() != crate_id { - let span = *span; - let type_name = struct_type.name.to_string(); - let error = DefCollectorErrorKind::ForeignImpl { span, type_name }; - errors.push((error.into(), unresolved.file_id)); - continue; - } - - // Grab the module defined by the struct type. Note that impls are a case - // where the module the methods are added to is not the same as the module - // they are resolved in. - let module = get_module_mut(def_maps, struct_type.id.module_id()); - - for (_, method_id, method) in &unresolved.functions { - // If this method was already declared, remove it from the module so it cannot - // be accessed with the `TypeName::method` syntax. We'll check later whether the - // object types in each method overlap or not. If they do, we issue an error. - // If not, that is specialization which is allowed. - if module.declare_function(method.name_ident().clone(), *method_id).is_err() { - module.remove_function(method.name_ident()); - } - } - // Prohibit defining impls for primitive types if we're not in the stdlib - } else if typ != Type::Error && !crate_id.is_stdlib() { - let span = *span; - let error = DefCollectorErrorKind::NonStructTypeInImpl { span }; - errors.push((error.into(), unresolved.file_id)); - } - } - } - errors -} - -fn get_module_mut( - def_maps: &mut BTreeMap, - module: ModuleId, -) -> &mut ModuleData { - &mut def_maps.get_mut(&module.krate).unwrap().modules[module.local_id.0] -} - -fn collect_trait_impl_methods( - interner: &mut NodeInterner, - def_maps: &BTreeMap, - crate_id: CrateId, - trait_id: TraitId, - trait_impl: &mut UnresolvedTraitImpl, -) -> Vec<(CompilationError, FileId)> { - // In this Vec methods[i] corresponds to trait.methods[i]. If the impl has no implementation - // for a particular method, the default implementation will be added at that slot. - let mut ordered_methods = Vec::new(); - - let the_trait = interner.get_trait(trait_id); - - // check whether the trait implementation is in the same crate as either the trait or the type - let mut errors = - check_trait_impl_crate_coherence(interner, &the_trait, trait_impl, crate_id, def_maps); - // set of function ids that have a corresponding method in the trait - let mut func_ids_in_trait = HashSet::new(); - - for method in &the_trait.methods { - let overrides: Vec<_> = trait_impl - .methods - .functions - .iter() - .filter(|(_, _, f)| f.name() == method.name.0.contents) - .collect(); - - if overrides.is_empty() { - if let Some(default_impl) = &method.default_impl { - let func_id = interner.push_empty_fn(); - let module = ModuleId { local_id: trait_impl.module_id, krate: crate_id }; - interner.push_function(func_id, &default_impl.def, module); - func_ids_in_trait.insert(func_id); - ordered_methods.push(( - method.default_impl_module_id, - func_id, - *default_impl.clone(), - )); - } else { - let error = DefCollectorErrorKind::TraitMissingMethod { - trait_name: the_trait.name.clone(), - method_name: method.name.clone(), - trait_impl_span: trait_impl.object_type.span.expect("type must have a span"), - }; - errors.push((error.into(), trait_impl.file_id)); - } - } else { - for (_, func_id, _) in &overrides { - func_ids_in_trait.insert(*func_id); - } - - if overrides.len() > 1 { - let error = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::TraitAssociatedFunction, - first_def: overrides[0].2.name_ident().clone(), - second_def: overrides[1].2.name_ident().clone(), - }; - errors.push((error.into(), trait_impl.file_id)); - } - - ordered_methods.push(overrides[0].clone()); - } - } - - // Emit MethodNotInTrait error for methods in the impl block that - // don't have a corresponding method signature defined in the trait - for (_, func_id, func) in &trait_impl.methods.functions { - if !func_ids_in_trait.contains(func_id) { - let error = DefCollectorErrorKind::MethodNotInTrait { - trait_name: the_trait.name.clone(), - impl_method: func.name_ident().clone(), - }; - errors.push((error.into(), trait_impl.file_id)); - } - } - - trait_impl.methods.functions = ordered_methods; - trait_impl.methods.trait_id = Some(trait_id); - errors -} - -fn collect_trait_impl( - context: &mut Context, - crate_id: CrateId, - trait_impl: &mut UnresolvedTraitImpl, -) -> Vec<(CompilationError, FileId)> { - let interner = &mut context.def_interner; - let def_maps = &mut context.def_maps; - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - let unresolved_type = trait_impl.object_type.clone(); - let module = ModuleId { local_id: trait_impl.module_id, krate: crate_id }; - trait_impl.trait_id = - match resolve_trait_by_path(def_maps, module, trait_impl.trait_path.clone()) { - Ok(trait_id) => Some(trait_id), - Err(error) => { - errors.push((error.into(), trait_impl.file_id)); - None - } - }; - - if let Some(trait_id) = trait_impl.trait_id { - errors - .extend(collect_trait_impl_methods(interner, def_maps, crate_id, trait_id, trait_impl)); - - let path_resolver = StandardPathResolver::new(module); - let file = def_maps[&crate_id].file_id(trait_impl.module_id); - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(&trait_impl.generics); - let typ = resolver.resolve_type(unresolved_type); - errors.extend(take_errors(trait_impl.file_id, resolver)); - - if let Some(struct_type) = get_struct_type(&typ) { - let struct_type = struct_type.borrow(); - let module = get_module_mut(def_maps, struct_type.id.module_id()); - - for (_, method_id, method) in &trait_impl.methods.functions { - // If this method was already declared, remove it from the module so it cannot - // be accessed with the `TypeName::method` syntax. We'll check later whether the - // object types in each method overlap or not. If they do, we issue an error. - // If not, that is specialization which is allowed. - if module.declare_function(method.name_ident().clone(), *method_id).is_err() { - module.remove_function(method.name_ident()); - } - } - } - } - errors -} - -fn collect_trait_impls( - context: &mut Context, - crate_id: CrateId, - collected_impls: &mut [UnresolvedTraitImpl], -) -> Vec<(CompilationError, FileId)> { - collected_impls - .iter_mut() - .flat_map(|trait_impl| collect_trait_impl(context, crate_id, trait_impl)) - .collect() -} - -fn check_trait_impl_crate_coherence( - interner: &mut NodeInterner, - the_trait: &Trait, - trait_impl: &UnresolvedTraitImpl, - current_crate: CrateId, - def_maps: &BTreeMap, -) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - - let module = ModuleId { krate: current_crate, local_id: trait_impl.module_id }; - let file = def_maps[¤t_crate].file_id(trait_impl.module_id); - let path_resolver = StandardPathResolver::new(module); - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - - let object_crate = match resolver.resolve_type(trait_impl.object_type.clone()) { - Type::Struct(struct_type, _) => struct_type.borrow().id.krate(), - _ => CrateId::Dummy, - }; - - if current_crate != the_trait.crate_id && current_crate != object_crate { - let error = DefCollectorErrorKind::TraitImplOrphaned { - span: trait_impl.object_type.span.expect("object type must have a span"), - }; - errors.push((error.into(), trait_impl.file_id)); - } - - errors -} - -fn resolve_trait_by_path( - def_maps: &BTreeMap, - module: ModuleId, - path: Path, -) -> Result { - let path_resolver = StandardPathResolver::new(module); - - match path_resolver.resolve(def_maps, path.clone()) { - Ok(ModuleDefId::TraitId(trait_id)) => Ok(trait_id), - Ok(_) => Err(DefCollectorErrorKind::NotATrait { not_a_trait_name: path }), - Err(_) => Err(DefCollectorErrorKind::TraitNotFound { trait_path: path }), - } -} - -fn get_struct_type(typ: &Type) -> Option<&Shared> { - match typ { - Type::Struct(definition, _) => Some(definition), - _ => None, - } -} - /// Separate the globals Vec into two. The first element in the tuple will be the /// literal globals, except for arrays, and the second will be all other globals. /// We exclude array literals as they can contain complex types @@ -625,50 +370,6 @@ fn filter_literal_globals( }) } -pub struct ResolvedGlobals { - pub globals: Vec<(FileId, StmtId)>, - pub errors: Vec<(CompilationError, FileId)>, -} - -impl ResolvedGlobals { - pub fn extend(&mut self, oth: Self) { - self.globals.extend(oth.globals); - self.errors.extend(oth.errors); - } -} - -fn resolve_globals( - context: &mut Context, - globals: Vec, - crate_id: CrateId, -) -> ResolvedGlobals { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - let globals = vecmap(globals, |global| { - let module_id = ModuleId { local_id: global.module_id, krate: crate_id }; - let path_resolver = StandardPathResolver::new(module_id); - let storage_slot = context.next_storage_slot(module_id); - - let mut resolver = Resolver::new( - &mut context.def_interner, - &path_resolver, - &context.def_maps, - global.file_id, - ); - - let name = global.stmt_def.pattern.name_ident().clone(); - - let hir_stmt = resolver.resolve_global_let(global.stmt_def); - errors.extend(take_errors(global.file_id, resolver)); - - context.def_interner.update_global(global.stmt_id, hir_stmt); - - context.def_interner.push_global(global.stmt_id, name, global.module_id, storage_slot); - - (global.file_id, global.stmt_id) - }); - ResolvedGlobals { globals, errors } -} - fn type_check_globals( interner: &mut NodeInterner, global_ids: Vec<(FileId, StmtId)>, @@ -701,360 +402,8 @@ fn type_check_functions( .collect() } -/// Create the mappings from TypeId -> StructType -/// so that expressions can access the fields of structs -fn resolve_structs( - context: &mut Context, - structs: BTreeMap, - crate_id: CrateId, -) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - // Resolve each field in each struct. - // Each struct should already be present in the NodeInterner after def collection. - for (type_id, typ) in structs { - let file_id = typ.file_id; - let (generics, fields, resolver_errors) = resolve_struct_fields(context, crate_id, typ); - errors.extend(vecmap(resolver_errors, |err| (err.into(), file_id))); - context.def_interner.update_struct(type_id, |struct_def| { - struct_def.set_fields(fields); - struct_def.generics = generics; - }); - } - errors -} - -fn resolve_trait_types( - _context: &mut Context, - _crate_id: CrateId, - _unresolved_trait: &UnresolvedTrait, -) -> (Vec, Vec<(CompilationError, FileId)>) { - // TODO - (vec![], vec![]) -} -fn resolve_trait_constants( - _context: &mut Context, - _crate_id: CrateId, - _unresolved_trait: &UnresolvedTrait, -) -> (Vec, Vec<(CompilationError, FileId)>) { - // TODO - (vec![], vec![]) -} - -fn resolve_trait_methods( - context: &mut Context, - trait_id: TraitId, - crate_id: CrateId, - unresolved_trait: &UnresolvedTrait, -) -> (Vec, Vec<(CompilationError, FileId)>) { - let interner = &mut context.def_interner; - let def_maps = &mut context.def_maps; - - let path_resolver = StandardPathResolver::new(ModuleId { - local_id: unresolved_trait.module_id, - krate: crate_id, - }); - let file = def_maps[&crate_id].file_id(unresolved_trait.module_id); - - let mut res = vec![]; - let mut resolver_errors = vec![]; - for item in &unresolved_trait.trait_def.items { - if let TraitItem::Function { - name, - generics, - parameters, - return_type, - where_clause: _, - body: _, - } = item - { - let the_trait = interner.get_trait(trait_id); - let self_type = - Type::TypeVariable(the_trait.self_type_typevar.clone(), TypeVariableKind::Normal); - - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(generics); - resolver.set_self_type(Some(self_type)); - - let arguments = vecmap(parameters, |param| resolver.resolve_type(param.1.clone())); - let resolved_return_type = resolver.resolve_type(return_type.get_type().into_owned()); - let generics = resolver.get_generics().to_vec(); - - let name = name.clone(); - let span: Span = name.span(); - let default_impl_list: Vec<_> = unresolved_trait - .fns_with_default_impl - .functions - .iter() - .filter(|(_, _, q)| q.name() == name.0.contents) - .collect(); - let default_impl = if default_impl_list.len() == 1 { - Some(Box::new(default_impl_list[0].2.clone())) - } else { - None - }; - - let f = TraitFunction { - name, - generics, - arguments, - return_type: resolved_return_type, - span, - default_impl, - default_impl_file_id: unresolved_trait.file_id, - default_impl_module_id: unresolved_trait.module_id, - }; - res.push(f); - resolver_errors.extend(take_errors_filter_self_not_resolved(file, resolver)); - } - } - (res, resolver_errors) -} - -fn take_errors_filter_self_not_resolved( - file_id: FileId, - resolver: Resolver<'_>, -) -> Vec<(CompilationError, FileId)> { - resolver - .take_errors() - .iter() - .filter(|resolution_error| match resolution_error { - ResolverError::PathResolutionError(PathResolutionError::Unresolved(ident)) => { - &ident.0.contents != "Self" - } - _ => true, - }) - .cloned() - .map(|resolution_error| (resolution_error.into(), file_id)) - .collect() -} - -fn take_errors(file_id: FileId, resolver: Resolver<'_>) -> Vec<(CompilationError, FileId)> { - vecmap(resolver.take_errors(), |e| (e.into(), file_id)) -} - -/// Create the mappings from TypeId -> TraitType -/// so that expressions can access the elements of traits -fn resolve_traits( - context: &mut Context, - traits: BTreeMap, - crate_id: CrateId, -) -> Vec<(CompilationError, FileId)> { - for (trait_id, unresolved_trait) in &traits { - context.def_interner.push_empty_trait(*trait_id, unresolved_trait); - } - let mut res: Vec<(CompilationError, FileId)> = vec![]; - for (trait_id, unresolved_trait) in traits { - // Resolve order - // 1. Trait Types ( Trait constants can have a trait type, therefore types before constants) - let _ = resolve_trait_types(context, crate_id, &unresolved_trait); - // 2. Trait Constants ( Trait's methods can use trait types & constants, therefore they should be after) - let _ = resolve_trait_constants(context, crate_id, &unresolved_trait); - // 3. Trait Methods - let (methods, errors) = - resolve_trait_methods(context, trait_id, crate_id, &unresolved_trait); - res.extend(errors); - context.def_interner.update_trait(trait_id, |trait_def| { - trait_def.set_methods(methods); - }); - } - res -} - -fn resolve_struct_fields( - context: &mut Context, - krate: CrateId, - unresolved: UnresolvedStruct, -) -> (Generics, Vec<(Ident, Type)>, Vec) { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: unresolved.module_id, krate }); - let file_id = unresolved.file_id; - let (generics, fields, errors) = - Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file_id) - .resolve_struct_fields(unresolved.struct_def); - (generics, fields, errors) -} - -fn resolve_type_aliases( - context: &mut Context, - type_aliases: BTreeMap, - crate_id: CrateId, -) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; - for (type_id, unresolved_typ) in type_aliases { - let path_resolver = StandardPathResolver::new(ModuleId { - local_id: unresolved_typ.module_id, - krate: crate_id, - }); - let file = unresolved_typ.file_id; - let (typ, generics, resolver_errors) = - Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) - .resolve_type_aliases(unresolved_typ.type_alias_def); - errors.extend(resolver_errors.iter().cloned().map(|e| (e.into(), file))); - context.def_interner.set_type_alias(type_id, typ, generics); - } - errors -} - -fn resolve_impls( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &BTreeMap, - collected_impls: ImplMap, - errors: &mut Vec<(CompilationError, FileId)>, -) -> Vec<(FileId, FuncId)> { - let mut file_method_ids = Vec::new(); - - for ((unresolved_type, module_id), methods) in collected_impls { - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: module_id, krate: crate_id }); - - let file = def_maps[&crate_id].file_id(module_id); - - for (generics, _, functions) in methods { - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); - resolver.add_generics(&generics); - let generics = resolver.get_generics().to_vec(); - let self_type = resolver.resolve_type(unresolved_type.clone()); - - let mut file_func_ids = resolve_function_set( - interner, - crate_id, - def_maps, - functions, - Some(self_type.clone()), - None, - generics, - errors, - ); - if self_type != Type::Error { - for (file_id, method_id) in &file_func_ids { - let method_name = interner.function_name(method_id).to_owned(); - - if let Some(first_fn) = - interner.add_method(&self_type, method_name.clone(), *method_id, false) - { - let error = ResolverError::DuplicateDefinition { - name: method_name, - first_span: interner.function_ident(&first_fn).span(), - second_span: interner.function_ident(method_id).span(), - }; - errors.push((error.into(), *file_id)); - } - } - } - file_method_ids.append(&mut file_func_ids); - } - } - - file_method_ids -} - -fn resolve_trait_impls( - context: &mut Context, - traits: Vec, - crate_id: CrateId, - errors: &mut Vec<(CompilationError, FileId)>, -) -> Vec<(FileId, FuncId)> { - let interner = &mut context.def_interner; - let mut methods = Vec::<(FileId, FuncId)>::new(); - - for trait_impl in traits { - let unresolved_type = trait_impl.object_type; - let local_mod_id = trait_impl.module_id; - let module_id = ModuleId { krate: crate_id, local_id: local_mod_id }; - let path_resolver = StandardPathResolver::new(module_id); - - let self_type_span = unresolved_type.span; - - let mut resolver = - Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); - resolver.add_generics(&trait_impl.generics); - let self_type = resolver.resolve_type(unresolved_type.clone()); - let generics = resolver.get_generics().to_vec(); - - let impl_id = interner.next_trait_impl_id(); - - let mut impl_methods = resolve_function_set( - interner, - crate_id, - &context.def_maps, - trait_impl.methods.clone(), - Some(self_type.clone()), - Some(impl_id), - generics.clone(), - errors, - ); - - let maybe_trait_id = trait_impl.trait_id; - if let Some(trait_id) = maybe_trait_id { - for (_, func) in &impl_methods { - interner.set_function_trait(*func, self_type.clone(), trait_id); - } - } - - if matches!(self_type, Type::MutableReference(_)) { - let span = self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()); - let error = DefCollectorErrorKind::MutableReferenceInTraitImpl { span }; - errors.push((error.into(), trait_impl.file_id)); - } - - let mut new_resolver = - Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); - - new_resolver.set_generics(generics); - new_resolver.set_self_type(Some(self_type.clone())); - - if let Some(trait_id) = maybe_trait_id { - check_methods_signatures( - &mut new_resolver, - &impl_methods, - trait_id, - trait_impl.generics.len(), - errors, - ); - - let where_clause = trait_impl - .where_clause - .into_iter() - .flat_map(|item| new_resolver.resolve_trait_constraint(item)) - .collect(); - - let resolved_trait_impl = Shared::new(TraitImpl { - ident: trait_impl.trait_path.last_segment().clone(), - typ: self_type.clone(), - trait_id, - file: trait_impl.file_id, - where_clause, - methods: vecmap(&impl_methods, |(_, func_id)| *func_id), - }); - - if let Err((prev_span, prev_file)) = interner.add_trait_implementation( - self_type.clone(), - trait_id, - impl_id, - resolved_trait_impl, - ) { - let error = DefCollectorErrorKind::OverlappingImpl { - typ: self_type.clone(), - span: self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()), - }; - errors.push((error.into(), trait_impl.file_id)); - - // The 'previous impl defined here' note must be a separate error currently - // since it may be in a different file and all errors have the same file id. - let error = DefCollectorErrorKind::OverlappingImplNote { span: prev_span }; - errors.push((error.into(), prev_file)); - } - - methods.append(&mut impl_methods); - } - } - - methods -} - // TODO(vitkov): Move this out of here and into type_check -fn check_methods_signatures( +pub(crate) fn check_methods_signatures( resolver: &mut Resolver, impl_methods: &Vec<(FileId, FuncId)>, trait_id: TraitId, @@ -1147,72 +496,3 @@ fn check_methods_signatures( the_trait.self_type_typevar.borrow_mut().unbind(the_trait.self_type_typevar_id); } - -fn resolve_free_functions( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &BTreeMap, - collected_functions: Vec, - self_type: Option, - errors: &mut Vec<(CompilationError, FileId)>, -) -> Vec<(FileId, FuncId)> { - // Lower each function in the crate. This is now possible since imports have been resolved - collected_functions - .into_iter() - .flat_map(|unresolved_functions| { - resolve_function_set( - interner, - crate_id, - def_maps, - unresolved_functions, - self_type.clone(), - None, - vec![], // no impl generics - errors, - ) - }) - .collect() -} - -#[allow(clippy::too_many_arguments)] -fn resolve_function_set( - interner: &mut NodeInterner, - crate_id: CrateId, - def_maps: &BTreeMap, - mut unresolved_functions: UnresolvedFunctions, - self_type: Option, - trait_impl_id: Option, - impl_generics: Vec<(Rc, Shared, Span)>, - errors: &mut Vec<(CompilationError, FileId)>, -) -> Vec<(FileId, FuncId)> { - let file_id = unresolved_functions.file_id; - - let where_clause_errors = - unresolved_functions.resolve_trait_bounds_trait_ids(def_maps, crate_id); - errors.extend(where_clause_errors.iter().cloned().map(|e| (e.into(), file_id))); - - vecmap(unresolved_functions.functions, |(mod_id, func_id, func)| { - let module_id = ModuleId { krate: crate_id, local_id: mod_id }; - let path_resolver = StandardPathResolver::new(module_id); - - let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file_id); - // Must use set_generics here to ensure we re-use the same generics from when - // the impl was originally collected. Otherwise the function will be using different - // TypeVariables for the same generic, causing it to instantiate incorrectly. - resolver.set_generics(impl_generics.clone()); - resolver.set_self_type(self_type.clone()); - resolver.set_trait_id(unresolved_functions.trait_id); - resolver.set_trait_impl_id(trait_impl_id); - - // Without this, impl methods can accidentally be placed in contracts. See #3254 - if self_type.is_some() { - resolver.set_in_contract(false); - } - - let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id); - interner.push_fn_meta(func_meta, func_id); - interner.update_fn(func_id, hir_func); - errors.extend(errs.iter().cloned().map(|e| (e.into(), file_id))); - (file_id, func_id) - }) -} diff --git a/noir/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/noir/compiler/noirc_frontend/src/hir/def_collector/errors.rs index edb39fe68d7..2b91c4b36c5 100644 --- a/noir/compiler/noirc_frontend/src/hir/def_collector/errors.rs +++ b/noir/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -73,15 +73,16 @@ pub enum DefCollectorErrorKind { "Either the type or the trait must be from the same crate as the trait implementation" )] TraitImplOrphaned { span: Span }, + #[error("macro error : {0:?}")] + MacroError(MacroError), +} - // Aztec feature flag errors - // TODO(benesjan): https://github.com/AztecProtocol/aztec-packages/issues/2905 - #[cfg(feature = "aztec")] - #[error("Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml")] - AztecNotFound {}, - #[cfg(feature = "aztec")] - #[error("compute_note_hash_and_nullifier function not found. Define it in your contract.")] - AztecComputeNoteHashAndNullifierNotFound { span: Span }, +/// An error struct that macro processors can return. +#[derive(Debug, Clone)] +pub struct MacroError { + pub primary_message: String, + pub secondary_message: Option, + pub span: Option, } impl DefCollectorErrorKind { @@ -245,16 +246,9 @@ impl From for Diagnostic { "Either the type or the trait must be from the same crate as the trait implementation".into(), span, ), - #[cfg(feature = "aztec")] - DefCollectorErrorKind::AztecNotFound {} => Diagnostic::from_message( - "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml", - ), - #[cfg(feature = "aztec")] - DefCollectorErrorKind::AztecComputeNoteHashAndNullifierNotFound {span} => Diagnostic::simple_error( - "compute_note_hash_and_nullifier function not found. Define it in your contract.".into(), - "".into(), - span - ), + DefCollectorErrorKind::MacroError(macro_error) => { + Diagnostic::simple_error(macro_error.primary_message, macro_error.secondary_message.unwrap_or_default(), macro_error.span.unwrap_or_default()) + }, } } } diff --git a/noir/compiler/noirc_frontend/src/hir/def_map/mod.rs b/noir/compiler/noirc_frontend/src/hir/def_map/mod.rs index 345e5447bf5..5f38c80a5fe 100644 --- a/noir/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/noir/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -1,6 +1,7 @@ use crate::graph::CrateId; use crate::hir::def_collector::dc_crate::{CompilationError, DefCollector}; use crate::hir::Context; +use crate::macros_api::MacroProcessor; use crate::node_interner::{FuncId, NodeInterner, StructId}; use crate::parser::{parse_program, ParsedModule, ParserError}; use crate::token::{FunctionAttribute, SecondaryAttribute, TestScope}; @@ -17,6 +18,8 @@ pub use module_data::*; mod namespace; pub use namespace::*; +use super::def_collector::errors::DefCollectorErrorKind; + /// The name that is used for a non-contract program's entry-point function. pub const MAIN_FUNCTION: &str = "main"; @@ -69,6 +72,7 @@ impl CrateDefMap { pub fn collect_defs( crate_id: CrateId, context: &mut Context, + macro_processors: Vec<&dyn MacroProcessor>, ) -> Vec<(CompilationError, FileId)> { // Check if this Crate has already been compiled // XXX: There is probably a better alternative for this. @@ -83,16 +87,18 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; let (ast, parsing_errors) = parse_file(&context.file_manager, root_file_id); - let ast = ast.into_sorted(); - - #[cfg(feature = "aztec")] - let ast = match super::aztec_library::transform(ast, &crate_id, context) { - Ok(ast) => ast, - Err((error, file_id)) => { - errors.push((error.into(), file_id)); - return errors; - } - }; + let mut ast = ast.into_sorted(); + + for macro_processor in ¯o_processors { + ast = match macro_processor.process_untyped_ast(ast, &crate_id, context) { + Ok(ast) => ast, + Err((error, file_id)) => { + let def_error = DefCollectorErrorKind::MacroError(error); + errors.push((def_error.into(), file_id)); + return errors; + } + }; + } // Allocate a default Module for the root, giving it a ModuleId let mut modules: Arena = Arena::default(); @@ -107,7 +113,13 @@ impl CrateDefMap { }; // Now we want to populate the CrateDefMap using the DefCollector - errors.extend(DefCollector::collect(def_map, context, ast, root_file_id)); + errors.extend(DefCollector::collect( + def_map, + context, + ast, + root_file_id, + macro_processors.clone(), + )); errors.extend( parsing_errors.iter().map(|e| (e.clone().into(), root_file_id)).collect::>(), diff --git a/noir/compiler/noirc_frontend/src/hir/mod.rs b/noir/compiler/noirc_frontend/src/hir/mod.rs index 5a28d7b779a..154b695d552 100644 --- a/noir/compiler/noirc_frontend/src/hir/mod.rs +++ b/noir/compiler/noirc_frontend/src/hir/mod.rs @@ -4,9 +4,6 @@ pub mod resolution; pub mod scope; pub mod type_check; -#[cfg(feature = "aztec")] -pub(crate) mod aztec_library; - use crate::graph::{CrateGraph, CrateId}; use crate::hir_def::function::FuncMeta; use crate::node_interner::{FuncId, NodeInterner, StructId}; @@ -29,10 +26,6 @@ pub struct Context { /// A map of each file that already has been visited from a prior `mod foo;` declaration. /// This is used to issue an error if a second `mod foo;` is declared to the same file. pub visited_files: BTreeMap, - - /// Maps a given (contract) module id to the next available storage slot - /// for that contract. - pub storage_slots: BTreeMap, } #[derive(Debug, Copy, Clone)] @@ -42,8 +35,6 @@ pub enum FunctionNameMatch<'a> { Contains(&'a str), } -pub type StorageSlot = u32; - impl Context { pub fn new(file_manager: FileManager, crate_graph: CrateGraph) -> Context { Context { @@ -52,7 +43,6 @@ impl Context { visited_files: BTreeMap::new(), crate_graph, file_manager, - storage_slots: BTreeMap::new(), } } @@ -200,16 +190,4 @@ impl Context { fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData { module_id.module(&self.def_maps) } - - /// Returns the next available storage slot in the given module. - /// Returns None if the given module is not a contract module. - fn next_storage_slot(&mut self, module_id: def_map::ModuleId) -> Option { - let module = self.module(module_id); - - module.is_contract.then(|| { - let next_slot = self.storage_slots.entry(module_id).or_insert(0); - *next_slot += 1; - *next_slot - }) - } } diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/functions.rs b/noir/compiler/noirc_frontend/src/hir/resolution/functions.rs new file mode 100644 index 00000000000..387f94e129c --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/functions.rs @@ -0,0 +1,85 @@ +use std::{collections::BTreeMap, rc::Rc}; + +use fm::FileId; +use iter_extended::vecmap; +use noirc_errors::Span; + +use crate::{ + graph::CrateId, + hir::{ + def_collector::dc_crate::{CompilationError, UnresolvedFunctions}, + def_map::{CrateDefMap, ModuleId}, + }, + node_interner::{FuncId, NodeInterner, TraitImplId}, + Shared, Type, TypeBinding, +}; + +use super::{path_resolver::StandardPathResolver, resolver::Resolver}; + +#[allow(clippy::too_many_arguments)] +pub(crate) fn resolve_function_set( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + mut unresolved_functions: UnresolvedFunctions, + self_type: Option, + trait_impl_id: Option, + impl_generics: Vec<(Rc, Shared, Span)>, + errors: &mut Vec<(CompilationError, FileId)>, +) -> Vec<(FileId, FuncId)> { + let file_id = unresolved_functions.file_id; + + let where_clause_errors = + unresolved_functions.resolve_trait_bounds_trait_ids(def_maps, crate_id); + errors.extend(where_clause_errors.iter().cloned().map(|e| (e.into(), file_id))); + + vecmap(unresolved_functions.functions, |(mod_id, func_id, func)| { + let module_id = ModuleId { krate: crate_id, local_id: mod_id }; + let path_resolver = StandardPathResolver::new(module_id); + + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file_id); + // Must use set_generics here to ensure we re-use the same generics from when + // the impl was originally collected. Otherwise the function will be using different + // TypeVariables for the same generic, causing it to instantiate incorrectly. + resolver.set_generics(impl_generics.clone()); + resolver.set_self_type(self_type.clone()); + resolver.set_trait_id(unresolved_functions.trait_id); + resolver.set_trait_impl_id(trait_impl_id); + + // Without this, impl methods can accidentally be placed in contracts. See #3254 + if self_type.is_some() { + resolver.set_in_contract(false); + } + + let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id); + interner.push_fn_meta(func_meta, func_id); + interner.update_fn(func_id, hir_func); + errors.extend(errs.iter().cloned().map(|e| (e.into(), file_id))); + (file_id, func_id) + }) +} + +pub(crate) fn resolve_free_functions( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + collected_functions: Vec, + self_type: Option, + errors: &mut Vec<(CompilationError, FileId)>, +) -> Vec<(FileId, FuncId)> { + collected_functions + .into_iter() + .flat_map(|unresolved_functions| { + resolve_function_set( + interner, + crate_id, + def_maps, + unresolved_functions, + self_type.clone(), + None, + vec![], // no impl generics + errors, + ) + }) + .collect() +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/globals.rs b/noir/compiler/noirc_frontend/src/hir/resolution/globals.rs new file mode 100644 index 00000000000..b5aec212dbf --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/globals.rs @@ -0,0 +1,55 @@ +use super::{path_resolver::StandardPathResolver, resolver::Resolver, take_errors}; +use crate::{ + graph::CrateId, + hir::{ + def_collector::dc_crate::{CompilationError, UnresolvedGlobal}, + def_map::ModuleId, + Context, + }, + node_interner::StmtId, +}; +use fm::FileId; +use iter_extended::vecmap; + +pub(crate) struct ResolvedGlobals { + pub(crate) globals: Vec<(FileId, StmtId)>, + pub(crate) errors: Vec<(CompilationError, FileId)>, +} + +impl ResolvedGlobals { + pub(crate) fn extend(&mut self, oth: Self) { + self.globals.extend(oth.globals); + self.errors.extend(oth.errors); + } +} + +pub(crate) fn resolve_globals( + context: &mut Context, + globals: Vec, + crate_id: CrateId, +) -> ResolvedGlobals { + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + let globals = vecmap(globals, |global| { + let module_id = ModuleId { local_id: global.module_id, krate: crate_id }; + let path_resolver = StandardPathResolver::new(module_id); + + let mut resolver = Resolver::new( + &mut context.def_interner, + &path_resolver, + &context.def_maps, + global.file_id, + ); + + let name = global.stmt_def.pattern.name_ident().clone(); + + let hir_stmt = resolver.resolve_global_let(global.stmt_def); + errors.extend(take_errors(global.file_id, resolver)); + + context.def_interner.update_global(global.stmt_id, hir_stmt); + + context.def_interner.push_global(global.stmt_id, name, global.module_id); + + (global.file_id, global.stmt_id) + }); + ResolvedGlobals { globals, errors } +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/impls.rs b/noir/compiler/noirc_frontend/src/hir/resolution/impls.rs new file mode 100644 index 00000000000..4aa70f00cfc --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/impls.rs @@ -0,0 +1,137 @@ +use std::collections::BTreeMap; + +use fm::FileId; + +use crate::{ + graph::CrateId, + hir::{ + def_collector::{ + dc_crate::{CompilationError, ImplMap}, + errors::DefCollectorErrorKind, + }, + def_map::{CrateDefMap, ModuleId}, + Context, + }, + node_interner::{FuncId, NodeInterner}, + Type, +}; + +use super::{ + errors::ResolverError, functions, get_module_mut, get_struct_type, + path_resolver::StandardPathResolver, resolver::Resolver, take_errors, +}; + +/// Go through the list of impls and add each function within to the scope +/// of the module defined by its type. +pub(crate) fn collect_impls( + context: &mut Context, + crate_id: CrateId, + collected_impls: &ImplMap, +) -> Vec<(CompilationError, FileId)> { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + + for ((unresolved_type, module_id), methods) in collected_impls { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: *module_id, krate: crate_id }); + + let file = def_maps[&crate_id].file_id(*module_id); + + for (generics, span, unresolved) in methods { + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(generics); + let typ = resolver.resolve_type(unresolved_type.clone()); + + errors.extend(take_errors(unresolved.file_id, resolver)); + + if let Some(struct_type) = get_struct_type(&typ) { + let struct_type = struct_type.borrow(); + + // `impl`s are only allowed on types defined within the current crate + if struct_type.id.krate() != crate_id { + let span = *span; + let type_name = struct_type.name.to_string(); + let error = DefCollectorErrorKind::ForeignImpl { span, type_name }; + errors.push((error.into(), unresolved.file_id)); + continue; + } + + // Grab the module defined by the struct type. Note that impls are a case + // where the module the methods are added to is not the same as the module + // they are resolved in. + let module = get_module_mut(def_maps, struct_type.id.module_id()); + + for (_, method_id, method) in &unresolved.functions { + // If this method was already declared, remove it from the module so it cannot + // be accessed with the `TypeName::method` syntax. We'll check later whether the + // object types in each method overlap or not. If they do, we issue an error. + // If not, that is specialization which is allowed. + if module.declare_function(method.name_ident().clone(), *method_id).is_err() { + module.remove_function(method.name_ident()); + } + } + // Prohibit defining impls for primitive types if we're not in the stdlib + } else if typ != Type::Error && !crate_id.is_stdlib() { + let span = *span; + let error = DefCollectorErrorKind::NonStructTypeInImpl { span }; + errors.push((error.into(), unresolved.file_id)); + } + } + } + errors +} + +pub(crate) fn resolve_impls( + interner: &mut NodeInterner, + crate_id: CrateId, + def_maps: &BTreeMap, + collected_impls: ImplMap, + errors: &mut Vec<(CompilationError, FileId)>, +) -> Vec<(FileId, FuncId)> { + let mut file_method_ids = Vec::new(); + + for ((unresolved_type, module_id), methods) in collected_impls { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: module_id, krate: crate_id }); + + let file = def_maps[&crate_id].file_id(module_id); + + for (generics, _, functions) in methods { + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(&generics); + let generics = resolver.get_generics().to_vec(); + let self_type = resolver.resolve_type(unresolved_type.clone()); + + let mut file_func_ids = functions::resolve_function_set( + interner, + crate_id, + def_maps, + functions, + Some(self_type.clone()), + None, + generics, + errors, + ); + if self_type != Type::Error { + for (file_id, method_id) in &file_func_ids { + let method_name = interner.function_name(method_id).to_owned(); + + if let Some(first_fn) = + interner.add_method(&self_type, method_name.clone(), *method_id, false) + { + let error = ResolverError::DuplicateDefinition { + name: method_name, + first_span: interner.function_ident(&first_fn).span(), + second_span: interner.function_ident(method_id).span(), + }; + errors.push((error.into(), *file_id)); + } + } + } + file_method_ids.append(&mut file_func_ids); + } + } + + file_method_ids +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/mod.rs b/noir/compiler/noirc_frontend/src/hir/resolution/mod.rs index 601e78015ca..8c16a9cca80 100644 --- a/noir/compiler/noirc_frontend/src/hir/resolution/mod.rs +++ b/noir/compiler/noirc_frontend/src/hir/resolution/mod.rs @@ -9,3 +9,50 @@ pub mod errors; pub mod import; pub mod path_resolver; pub mod resolver; + +mod functions; +mod globals; +mod impls; +mod structs; +mod traits; +mod type_aliases; + +pub(crate) use functions::resolve_free_functions; +pub(crate) use globals::resolve_globals; +pub(crate) use impls::{collect_impls, resolve_impls}; +pub(crate) use structs::resolve_structs; +pub(crate) use traits::{ + collect_trait_impls, resolve_trait_by_path, resolve_trait_impls, resolve_traits, +}; +pub(crate) use type_aliases::resolve_type_aliases; + +use crate::{ + graph::CrateId, + hir::{ + def_collector::dc_crate::CompilationError, + def_map::{CrateDefMap, ModuleData, ModuleId}, + }, + Shared, StructType, Type, +}; +use fm::FileId; +use iter_extended::vecmap; +use resolver::Resolver; +use std::collections::BTreeMap; + +fn take_errors(file_id: FileId, resolver: Resolver<'_>) -> Vec<(CompilationError, FileId)> { + vecmap(resolver.take_errors(), |e| (e.into(), file_id)) +} + +fn get_module_mut( + def_maps: &mut BTreeMap, + module: ModuleId, +) -> &mut ModuleData { + &mut def_maps.get_mut(&module.krate).unwrap().modules[module.local_id.0] +} + +fn get_struct_type(typ: &Type) -> Option<&Shared> { + match typ { + Type::Struct(definition, _) => Some(definition), + _ => None, + } +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/noir/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 4b829932b76..52d592404c8 100644 --- a/noir/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/noir/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1203,6 +1203,7 @@ impl<'a> Resolver<'a> { } Literal::Integer(integer) => HirLiteral::Integer(integer), Literal::Str(str) => HirLiteral::Str(str), + Literal::RawStr(str, _) => HirLiteral::Str(str), Literal::FmtStr(str) => self.resolve_fmt_str_literal(str, expr.span), Literal::Unit => HirLiteral::Unit, }), diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/structs.rs b/noir/compiler/noirc_frontend/src/hir/resolution/structs.rs new file mode 100644 index 00000000000..72a7b736436 --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/structs.rs @@ -0,0 +1,53 @@ +use std::collections::BTreeMap; + +use fm::FileId; +use iter_extended::vecmap; + +use crate::{ + graph::CrateId, + hir::{ + def_collector::dc_crate::{CompilationError, UnresolvedStruct}, + def_map::ModuleId, + Context, + }, + node_interner::StructId, + Generics, Ident, Type, +}; + +use super::{errors::ResolverError, path_resolver::StandardPathResolver, resolver::Resolver}; + +/// Create the mappings from TypeId -> StructType +/// so that expressions can access the fields of structs +pub(crate) fn resolve_structs( + context: &mut Context, + structs: BTreeMap, + crate_id: CrateId, +) -> Vec<(CompilationError, FileId)> { + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + // Resolve each field in each struct. + // Each struct should already be present in the NodeInterner after def collection. + for (type_id, typ) in structs { + let file_id = typ.file_id; + let (generics, fields, resolver_errors) = resolve_struct_fields(context, crate_id, typ); + errors.extend(vecmap(resolver_errors, |err| (err.into(), file_id))); + context.def_interner.update_struct(type_id, |struct_def| { + struct_def.set_fields(fields); + struct_def.generics = generics; + }); + } + errors +} + +fn resolve_struct_fields( + context: &mut Context, + krate: CrateId, + unresolved: UnresolvedStruct, +) -> (Generics, Vec<(Ident, Type)>, Vec) { + let path_resolver = + StandardPathResolver::new(ModuleId { local_id: unresolved.module_id, krate }); + let file_id = unresolved.file_id; + let (generics, fields, errors) = + Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file_id) + .resolve_struct_fields(unresolved.struct_def); + (generics, fields, errors) +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/traits.rs b/noir/compiler/noirc_frontend/src/hir/resolution/traits.rs new file mode 100644 index 00000000000..702e96362a6 --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/traits.rs @@ -0,0 +1,450 @@ +use std::collections::{BTreeMap, HashSet}; + +use fm::FileId; +use iter_extended::vecmap; +use noirc_errors::Span; + +use crate::{ + graph::CrateId, + hir::{ + def_collector::{ + dc_crate::{ + check_methods_signatures, CompilationError, UnresolvedTrait, UnresolvedTraitImpl, + }, + errors::{DefCollectorErrorKind, DuplicateType}, + }, + def_map::{CrateDefMap, ModuleDefId, ModuleId}, + Context, + }, + hir_def::traits::{Trait, TraitConstant, TraitFunction, TraitImpl, TraitType}, + node_interner::{FuncId, NodeInterner, TraitId}, + Path, Shared, TraitItem, Type, TypeVariableKind, +}; + +use super::{ + errors::ResolverError, + functions, get_module_mut, get_struct_type, + import::PathResolutionError, + path_resolver::{PathResolver, StandardPathResolver}, + resolver::Resolver, + take_errors, +}; + +/// Create the mappings from TypeId -> TraitType +/// so that expressions can access the elements of traits +pub(crate) fn resolve_traits( + context: &mut Context, + traits: BTreeMap, + crate_id: CrateId, +) -> Vec<(CompilationError, FileId)> { + for (trait_id, unresolved_trait) in &traits { + context.def_interner.push_empty_trait(*trait_id, unresolved_trait); + } + let mut res: Vec<(CompilationError, FileId)> = vec![]; + for (trait_id, unresolved_trait) in traits { + // Resolve order + // 1. Trait Types ( Trait constants can have a trait type, therefore types before constants) + let _ = resolve_trait_types(context, crate_id, &unresolved_trait); + // 2. Trait Constants ( Trait's methods can use trait types & constants, therefore they should be after) + let _ = resolve_trait_constants(context, crate_id, &unresolved_trait); + // 3. Trait Methods + let (methods, errors) = + resolve_trait_methods(context, trait_id, crate_id, &unresolved_trait); + res.extend(errors); + context.def_interner.update_trait(trait_id, |trait_def| { + trait_def.set_methods(methods); + }); + } + res +} + +fn resolve_trait_types( + _context: &mut Context, + _crate_id: CrateId, + _unresolved_trait: &UnresolvedTrait, +) -> (Vec, Vec<(CompilationError, FileId)>) { + // TODO + (vec![], vec![]) +} +fn resolve_trait_constants( + _context: &mut Context, + _crate_id: CrateId, + _unresolved_trait: &UnresolvedTrait, +) -> (Vec, Vec<(CompilationError, FileId)>) { + // TODO + (vec![], vec![]) +} + +fn resolve_trait_methods( + context: &mut Context, + trait_id: TraitId, + crate_id: CrateId, + unresolved_trait: &UnresolvedTrait, +) -> (Vec, Vec<(CompilationError, FileId)>) { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_trait.module_id, + krate: crate_id, + }); + let file = def_maps[&crate_id].file_id(unresolved_trait.module_id); + + let mut res = vec![]; + let mut resolver_errors = vec![]; + for item in &unresolved_trait.trait_def.items { + if let TraitItem::Function { + name, + generics, + parameters, + return_type, + where_clause: _, + body: _, + } = item + { + let the_trait = interner.get_trait(trait_id); + let self_type = + Type::TypeVariable(the_trait.self_type_typevar.clone(), TypeVariableKind::Normal); + + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(generics); + resolver.set_self_type(Some(self_type)); + + let arguments = vecmap(parameters, |param| resolver.resolve_type(param.1.clone())); + let resolved_return_type = resolver.resolve_type(return_type.get_type().into_owned()); + let generics = resolver.get_generics().to_vec(); + + let name = name.clone(); + let span: Span = name.span(); + let default_impl_list: Vec<_> = unresolved_trait + .fns_with_default_impl + .functions + .iter() + .filter(|(_, _, q)| q.name() == name.0.contents) + .collect(); + let default_impl = if default_impl_list.len() == 1 { + Some(Box::new(default_impl_list[0].2.clone())) + } else { + None + }; + + let f = TraitFunction { + name, + generics, + arguments, + return_type: resolved_return_type, + span, + default_impl, + default_impl_file_id: unresolved_trait.file_id, + default_impl_module_id: unresolved_trait.module_id, + }; + res.push(f); + resolver_errors.extend(take_errors_filter_self_not_resolved(file, resolver)); + } + } + (res, resolver_errors) +} + +fn collect_trait_impl_methods( + interner: &mut NodeInterner, + def_maps: &BTreeMap, + crate_id: CrateId, + trait_id: TraitId, + trait_impl: &mut UnresolvedTraitImpl, +) -> Vec<(CompilationError, FileId)> { + // In this Vec methods[i] corresponds to trait.methods[i]. If the impl has no implementation + // for a particular method, the default implementation will be added at that slot. + let mut ordered_methods = Vec::new(); + + let the_trait = interner.get_trait(trait_id); + + // check whether the trait implementation is in the same crate as either the trait or the type + let mut errors = + check_trait_impl_crate_coherence(interner, &the_trait, trait_impl, crate_id, def_maps); + // set of function ids that have a corresponding method in the trait + let mut func_ids_in_trait = HashSet::new(); + + for method in &the_trait.methods { + let overrides: Vec<_> = trait_impl + .methods + .functions + .iter() + .filter(|(_, _, f)| f.name() == method.name.0.contents) + .collect(); + + if overrides.is_empty() { + if let Some(default_impl) = &method.default_impl { + let func_id = interner.push_empty_fn(); + let module = ModuleId { local_id: trait_impl.module_id, krate: crate_id }; + interner.push_function(func_id, &default_impl.def, module); + func_ids_in_trait.insert(func_id); + ordered_methods.push(( + method.default_impl_module_id, + func_id, + *default_impl.clone(), + )); + } else { + let error = DefCollectorErrorKind::TraitMissingMethod { + trait_name: the_trait.name.clone(), + method_name: method.name.clone(), + trait_impl_span: trait_impl.object_type.span.expect("type must have a span"), + }; + errors.push((error.into(), trait_impl.file_id)); + } + } else { + for (_, func_id, _) in &overrides { + func_ids_in_trait.insert(*func_id); + } + + if overrides.len() > 1 { + let error = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TraitAssociatedFunction, + first_def: overrides[0].2.name_ident().clone(), + second_def: overrides[1].2.name_ident().clone(), + }; + errors.push((error.into(), trait_impl.file_id)); + } + + ordered_methods.push(overrides[0].clone()); + } + } + + // Emit MethodNotInTrait error for methods in the impl block that + // don't have a corresponding method signature defined in the trait + for (_, func_id, func) in &trait_impl.methods.functions { + if !func_ids_in_trait.contains(func_id) { + let error = DefCollectorErrorKind::MethodNotInTrait { + trait_name: the_trait.name.clone(), + impl_method: func.name_ident().clone(), + }; + errors.push((error.into(), trait_impl.file_id)); + } + } + + trait_impl.methods.functions = ordered_methods; + trait_impl.methods.trait_id = Some(trait_id); + errors +} + +fn collect_trait_impl( + context: &mut Context, + crate_id: CrateId, + trait_impl: &mut UnresolvedTraitImpl, +) -> Vec<(CompilationError, FileId)> { + let interner = &mut context.def_interner; + let def_maps = &mut context.def_maps; + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + let unresolved_type = trait_impl.object_type.clone(); + let module = ModuleId { local_id: trait_impl.module_id, krate: crate_id }; + trait_impl.trait_id = + match resolve_trait_by_path(def_maps, module, trait_impl.trait_path.clone()) { + Ok(trait_id) => Some(trait_id), + Err(error) => { + errors.push((error.into(), trait_impl.file_id)); + None + } + }; + + if let Some(trait_id) = trait_impl.trait_id { + errors + .extend(collect_trait_impl_methods(interner, def_maps, crate_id, trait_id, trait_impl)); + + let path_resolver = StandardPathResolver::new(module); + let file = def_maps[&crate_id].file_id(trait_impl.module_id); + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + resolver.add_generics(&trait_impl.generics); + let typ = resolver.resolve_type(unresolved_type); + errors.extend(take_errors(trait_impl.file_id, resolver)); + + if let Some(struct_type) = get_struct_type(&typ) { + let struct_type = struct_type.borrow(); + let module = get_module_mut(def_maps, struct_type.id.module_id()); + + for (_, method_id, method) in &trait_impl.methods.functions { + // If this method was already declared, remove it from the module so it cannot + // be accessed with the `TypeName::method` syntax. We'll check later whether the + // object types in each method overlap or not. If they do, we issue an error. + // If not, that is specialization which is allowed. + if module.declare_function(method.name_ident().clone(), *method_id).is_err() { + module.remove_function(method.name_ident()); + } + } + } + } + errors +} + +pub(crate) fn collect_trait_impls( + context: &mut Context, + crate_id: CrateId, + collected_impls: &mut [UnresolvedTraitImpl], +) -> Vec<(CompilationError, FileId)> { + collected_impls + .iter_mut() + .flat_map(|trait_impl| collect_trait_impl(context, crate_id, trait_impl)) + .collect() +} + +fn check_trait_impl_crate_coherence( + interner: &mut NodeInterner, + the_trait: &Trait, + trait_impl: &UnresolvedTraitImpl, + current_crate: CrateId, + def_maps: &BTreeMap, +) -> Vec<(CompilationError, FileId)> { + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + + let module = ModuleId { krate: current_crate, local_id: trait_impl.module_id }; + let file = def_maps[¤t_crate].file_id(trait_impl.module_id); + let path_resolver = StandardPathResolver::new(module); + let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); + + let object_crate = match resolver.resolve_type(trait_impl.object_type.clone()) { + Type::Struct(struct_type, _) => struct_type.borrow().id.krate(), + _ => CrateId::Dummy, + }; + + if current_crate != the_trait.crate_id && current_crate != object_crate { + let error = DefCollectorErrorKind::TraitImplOrphaned { + span: trait_impl.object_type.span.expect("object type must have a span"), + }; + errors.push((error.into(), trait_impl.file_id)); + } + + errors +} + +pub(crate) fn resolve_trait_by_path( + def_maps: &BTreeMap, + module: ModuleId, + path: Path, +) -> Result { + let path_resolver = StandardPathResolver::new(module); + + match path_resolver.resolve(def_maps, path.clone()) { + Ok(ModuleDefId::TraitId(trait_id)) => Ok(trait_id), + Ok(_) => Err(DefCollectorErrorKind::NotATrait { not_a_trait_name: path }), + Err(_) => Err(DefCollectorErrorKind::TraitNotFound { trait_path: path }), + } +} +pub(crate) fn resolve_trait_impls( + context: &mut Context, + traits: Vec, + crate_id: CrateId, + errors: &mut Vec<(CompilationError, FileId)>, +) -> Vec<(FileId, FuncId)> { + let interner = &mut context.def_interner; + let mut methods = Vec::<(FileId, FuncId)>::new(); + + for trait_impl in traits { + let unresolved_type = trait_impl.object_type; + let local_mod_id = trait_impl.module_id; + let module_id = ModuleId { krate: crate_id, local_id: local_mod_id }; + let path_resolver = StandardPathResolver::new(module_id); + + let self_type_span = unresolved_type.span; + + let mut resolver = + Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); + resolver.add_generics(&trait_impl.generics); + let self_type = resolver.resolve_type(unresolved_type.clone()); + let generics = resolver.get_generics().to_vec(); + + let impl_id = interner.next_trait_impl_id(); + + let mut impl_methods = functions::resolve_function_set( + interner, + crate_id, + &context.def_maps, + trait_impl.methods.clone(), + Some(self_type.clone()), + Some(impl_id), + generics.clone(), + errors, + ); + + let maybe_trait_id = trait_impl.trait_id; + if let Some(trait_id) = maybe_trait_id { + for (_, func) in &impl_methods { + interner.set_function_trait(*func, self_type.clone(), trait_id); + } + } + + if matches!(self_type, Type::MutableReference(_)) { + let span = self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()); + let error = DefCollectorErrorKind::MutableReferenceInTraitImpl { span }; + errors.push((error.into(), trait_impl.file_id)); + } + + let mut new_resolver = + Resolver::new(interner, &path_resolver, &context.def_maps, trait_impl.file_id); + + new_resolver.set_generics(generics); + new_resolver.set_self_type(Some(self_type.clone())); + + if let Some(trait_id) = maybe_trait_id { + check_methods_signatures( + &mut new_resolver, + &impl_methods, + trait_id, + trait_impl.generics.len(), + errors, + ); + + let where_clause = trait_impl + .where_clause + .into_iter() + .flat_map(|item| new_resolver.resolve_trait_constraint(item)) + .collect(); + + let resolved_trait_impl = Shared::new(TraitImpl { + ident: trait_impl.trait_path.last_segment().clone(), + typ: self_type.clone(), + trait_id, + file: trait_impl.file_id, + where_clause, + methods: vecmap(&impl_methods, |(_, func_id)| *func_id), + }); + + if let Err((prev_span, prev_file)) = interner.add_trait_implementation( + self_type.clone(), + trait_id, + impl_id, + resolved_trait_impl, + ) { + let error = DefCollectorErrorKind::OverlappingImpl { + typ: self_type.clone(), + span: self_type_span.unwrap_or_else(|| trait_impl.trait_path.span()), + }; + errors.push((error.into(), trait_impl.file_id)); + + // The 'previous impl defined here' note must be a separate error currently + // since it may be in a different file and all errors have the same file id. + let error = DefCollectorErrorKind::OverlappingImplNote { span: prev_span }; + errors.push((error.into(), prev_file)); + } + + methods.append(&mut impl_methods); + } + } + + methods +} + +pub(crate) fn take_errors_filter_self_not_resolved( + file_id: FileId, + resolver: Resolver<'_>, +) -> Vec<(CompilationError, FileId)> { + resolver + .take_errors() + .iter() + .filter(|resolution_error| match resolution_error { + ResolverError::PathResolutionError(PathResolutionError::Unresolved(ident)) => { + &ident.0.contents != "Self" + } + _ => true, + }) + .cloned() + .map(|resolution_error| (resolution_error.into(), file_id)) + .collect() +} diff --git a/noir/compiler/noirc_frontend/src/hir/resolution/type_aliases.rs b/noir/compiler/noirc_frontend/src/hir/resolution/type_aliases.rs new file mode 100644 index 00000000000..f66f6c8dfa7 --- /dev/null +++ b/noir/compiler/noirc_frontend/src/hir/resolution/type_aliases.rs @@ -0,0 +1,33 @@ +use super::{path_resolver::StandardPathResolver, resolver::Resolver}; +use crate::{ + graph::CrateId, + hir::{ + def_collector::dc_crate::{CompilationError, UnresolvedTypeAlias}, + def_map::ModuleId, + Context, + }, + node_interner::TypeAliasId, +}; +use fm::FileId; +use std::collections::BTreeMap; + +pub(crate) fn resolve_type_aliases( + context: &mut Context, + type_aliases: BTreeMap, + crate_id: CrateId, +) -> Vec<(CompilationError, FileId)> { + let mut errors: Vec<(CompilationError, FileId)> = vec![]; + for (type_id, unresolved_typ) in type_aliases { + let path_resolver = StandardPathResolver::new(ModuleId { + local_id: unresolved_typ.module_id, + krate: crate_id, + }); + let file = unresolved_typ.file_id; + let (typ, generics, resolver_errors) = + Resolver::new(&mut context.def_interner, &path_resolver, &context.def_maps, file) + .resolve_type_aliases(unresolved_typ.type_alias_def); + errors.extend(resolver_errors.iter().cloned().map(|e| (e.into(), file))); + context.def_interner.set_type_alias(type_id, typ, generics); + } + errors +} diff --git a/noir/compiler/noirc_frontend/src/lexer/lexer.rs b/noir/compiler/noirc_frontend/src/lexer/lexer.rs index be24c1249c6..7a2197ebb93 100644 --- a/noir/compiler/noirc_frontend/src/lexer/lexer.rs +++ b/noir/compiler/noirc_frontend/src/lexer/lexer.rs @@ -126,6 +126,7 @@ impl<'a> Lexer<'a> { Some(']') => self.single_char_token(Token::RightBracket), Some('"') => self.eat_string_literal(), Some('f') => self.eat_format_string_or_alpha_numeric(), + Some('r') => self.eat_raw_string_or_alpha_numeric(), Some('#') => self.eat_attribute(), Some(ch) if ch.is_ascii_alphanumeric() || ch == '_' => self.eat_alpha_numeric(ch), Some(ch) => { @@ -400,6 +401,78 @@ impl<'a> Lexer<'a> { } } + fn eat_raw_string(&mut self) -> SpannedTokenResult { + let start = self.position; + + let beginning_hashes = self.eat_while(None, |ch| ch == '#'); + let beginning_hashes_count = beginning_hashes.chars().count(); + if beginning_hashes_count > 255 { + // too many hashes (unlikely in practice) + // also, Rust disallows 256+ hashes as well + return Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(start + 255), + found: Some('#'), + expected: "\"".to_owned(), + }); + } + + if !self.peek_char_is('"') { + return Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(self.position), + found: self.next_char(), + expected: "\"".to_owned(), + }); + } + self.next_char(); + + let mut str_literal = String::new(); + loop { + let chars = self.eat_while(None, |ch| ch != '"'); + str_literal.push_str(&chars[..]); + if !self.peek_char_is('"') { + return Err(LexerErrorKind::UnexpectedCharacter { + span: Span::single_char(self.position), + found: self.next_char(), + expected: "\"".to_owned(), + }); + } + self.next_char(); + let mut ending_hashes_count = 0; + while let Some('#') = self.peek_char() { + if ending_hashes_count == beginning_hashes_count { + break; + } + self.next_char(); + ending_hashes_count += 1; + } + if ending_hashes_count == beginning_hashes_count { + break; + } else { + str_literal.push('"'); + for _ in 0..ending_hashes_count { + str_literal.push('#'); + } + } + } + + let str_literal_token = Token::RawStr(str_literal, beginning_hashes_count as u8); + + let end = self.position; + Ok(str_literal_token.into_span(start, end)) + } + + fn eat_raw_string_or_alpha_numeric(&mut self) -> SpannedTokenResult { + // Problem: we commit to eating raw strings once we see one or two characters. + // This is unclean, but likely ok in all practical cases, and works with existing + // `Lexer` methods. + let peek1 = self.peek_char().unwrap_or('X'); + let peek2 = self.peek2_char().unwrap_or('X'); + match (peek1, peek2) { + ('#', '#') | ('#', '"') | ('"', _) => self.eat_raw_string(), + _ => self.eat_alpha_numeric('r'), + } + } + fn parse_comment(&mut self, start: u32) -> SpannedTokenResult { let doc_style = match self.peek_char() { Some('!') => { diff --git a/noir/compiler/noirc_frontend/src/lexer/token.rs b/noir/compiler/noirc_frontend/src/lexer/token.rs index 72be71865cc..b16de42c0ba 100644 --- a/noir/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/compiler/noirc_frontend/src/lexer/token.rs @@ -15,6 +15,7 @@ pub enum Token { Int(FieldElement), Bool(bool), Str(String), + RawStr(String, u8), FmtStr(String), Keyword(Keyword), IntType(IntType), @@ -157,6 +158,10 @@ impl fmt::Display for Token { Token::Bool(b) => write!(f, "{b}"), Token::Str(ref b) => write!(f, "{b}"), Token::FmtStr(ref b) => write!(f, "f{b}"), + Token::RawStr(ref b, hashes) => { + let h: String = std::iter::once('#').cycle().take(hashes as usize).collect(); + write!(f, "r{h}\"{b}\"{h}") + } Token::Keyword(k) => write!(f, "{k}"), Token::Attribute(ref a) => write!(f, "{a}"), Token::LineComment(ref s, _style) => write!(f, "//{s}"), @@ -227,7 +232,11 @@ impl Token { pub fn kind(&self) -> TokenKind { match *self { Token::Ident(_) => TokenKind::Ident, - Token::Int(_) | Token::Bool(_) | Token::Str(_) | Token::FmtStr(_) => TokenKind::Literal, + Token::Int(_) + | Token::Bool(_) + | Token::Str(_) + | Token::RawStr(..) + | Token::FmtStr(_) => TokenKind::Literal, Token::Keyword(_) => TokenKind::Keyword, Token::Attribute(_) => TokenKind::Attribute, ref tok => TokenKind::Token(tok.clone()), diff --git a/noir/compiler/noirc_frontend/src/lib.rs b/noir/compiler/noirc_frontend/src/lib.rs index 74057240de1..77107d3e7db 100644 --- a/noir/compiler/noirc_frontend/src/lib.rs +++ b/noir/compiler/noirc_frontend/src/lib.rs @@ -34,3 +34,46 @@ pub use hir_def::types::*; // Unit tests that involve all modules pub mod tests; + +// API for experimental macros feature +pub mod macros_api { + + pub use acvm::FieldElement; + pub use fm::FileId; + pub use noirc_errors::Span; + + pub use crate::graph::CrateId; + pub use crate::hir::def_collector::errors::MacroError; + pub use crate::hir_def::expr::{HirExpression, HirLiteral}; + pub use crate::hir_def::stmt::HirStatement; + pub use crate::node_interner::{NodeInterner, StructId}; + pub use crate::parser::SortedModule; + pub use crate::token::SecondaryAttribute; + + pub use crate::hir::def_map::ModuleDefId; + pub use crate::{ + hir::Context as HirContext, BlockExpression, CallExpression, CastExpression, Distinctness, + Expression, ExpressionKind, FunctionReturnType, Ident, IndexExpression, LetStatement, + Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, Path, PathKind, + Pattern, Statement, UnresolvedType, UnresolvedTypeData, Visibility, + }; + pub use crate::{ + ForLoopStatement, ForRange, FunctionDefinition, FunctionVisibility, ImportStatement, + NoirStruct, Param, PrefixExpression, Signedness, StatementKind, StructType, Type, TypeImpl, + UnaryOp, + }; + + /// Methods to process the AST before and after type checking + pub trait MacroProcessor { + /// Function to manipulate the AST before type checking has been completed. + fn process_untyped_ast( + &self, + ast: SortedModule, + crate_id: &CrateId, + context: &HirContext, + ) -> Result; + /// Function to manipulate the AST after type checking has been completed. + /// The AST after type checking has been done is called the HIR. + fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext); + } +} diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index 300a95f819c..e66a6d57605 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -9,7 +9,6 @@ use crate::ast::Ident; use crate::graph::CrateId; use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias}; use crate::hir::def_map::{LocalModuleId, ModuleId}; -use crate::hir::StorageSlot; use crate::hir_def::stmt::HirLetStatement; use crate::hir_def::traits::TraitImpl; use crate::hir_def::traits::{Trait, TraitConstraint}; @@ -399,10 +398,6 @@ impl DefinitionKind { pub struct GlobalInfo { pub ident: Ident, pub local_id: LocalModuleId, - - /// Global definitions have an associated storage slot if they are defined within - /// a contract. If they're defined elsewhere, this value is None. - pub storage_slot: Option, } impl Default for NodeInterner { @@ -578,14 +573,8 @@ impl NodeInterner { self.id_to_type.insert(definition_id.into(), typ); } - pub fn push_global( - &mut self, - stmt_id: StmtId, - ident: Ident, - local_id: LocalModuleId, - storage_slot: Option, - ) { - self.globals.insert(stmt_id, GlobalInfo { ident, local_id, storage_slot }); + pub fn push_global(&mut self, stmt_id: StmtId, ident: Ident, local_id: LocalModuleId) { + self.globals.insert(stmt_id, GlobalInfo { ident, local_id }); } /// Intern an empty global stmt. Used for collecting globals diff --git a/noir/compiler/noirc_frontend/src/parser/parser.rs b/noir/compiler/noirc_frontend/src/parser/parser.rs index 6b8589cc6e5..7f0bf6376c6 100644 --- a/noir/compiler/noirc_frontend/src/parser/parser.rs +++ b/noir/compiler/noirc_frontend/src/parser/parser.rs @@ -1657,6 +1657,7 @@ fn literal() -> impl NoirParser { Token::Int(x) => ExpressionKind::integer(x), Token::Bool(b) => ExpressionKind::boolean(b), Token::Str(s) => ExpressionKind::string(s), + Token::RawStr(s, hashes) => ExpressionKind::raw_string(s, hashes), Token::FmtStr(s) => ExpressionKind::format_string(s), unexpected => unreachable!("Non-literal {} parsed as a literal", unexpected), }) @@ -2549,4 +2550,79 @@ mod test { check_cases_with_errors(&cases[..], block(fresh_statement())); } + + #[test] + fn parse_raw_string_expr() { + let cases = vec![ + Case { source: r##" r"foo" "##, expect: r##"r"foo""##, errors: 0 }, + Case { source: r##" r#"foo"# "##, expect: r##"r#"foo"#"##, errors: 0 }, + // backslash + Case { source: r##" r"\\" "##, expect: r##"r"\\""##, errors: 0 }, + Case { source: r##" r#"\"# "##, expect: r##"r#"\"#"##, errors: 0 }, + Case { source: r##" r#"\\"# "##, expect: r##"r#"\\"#"##, errors: 0 }, + Case { source: r##" r#"\\\"# "##, expect: r##"r#"\\\"#"##, errors: 0 }, + // escape sequence + Case { + source: r##" r#"\t\n\\t\\n\\\t\\\n\\\\"# "##, + expect: r##"r#"\t\n\\t\\n\\\t\\\n\\\\"#"##, + errors: 0, + }, + Case { source: r##" r#"\\\\\\\\"# "##, expect: r##"r#"\\\\\\\\"#"##, errors: 0 }, + // mismatch - errors: + Case { source: r###" r#"foo"## "###, expect: r###"r#"foo"#"###, errors: 1 }, + Case { source: r###" r##"foo"# "###, expect: "(none)", errors: 2 }, + // mismatch: short: + Case { source: r###" r"foo"# "###, expect: r###"r"foo""###, errors: 1 }, + Case { source: r###" r#"foo" "###, expect: "(none)", errors: 2 }, + // empty string + Case { source: r####"r"""####, expect: r####"r"""####, errors: 0 }, + Case { source: r####"r###""###"####, expect: r####"r###""###"####, errors: 0 }, + // miscellaneous + Case { source: r###" r#\"foo\"# "###, expect: "plain::r", errors: 2 }, + Case { source: r###" r\"foo\" "###, expect: "plain::r", errors: 1 }, + Case { source: r###" r##"foo"# "###, expect: "(none)", errors: 2 }, + // missing 'r' letter + Case { source: r###" ##"foo"# "###, expect: r#""foo""#, errors: 2 }, + Case { source: r###" #"foo" "###, expect: "plain::foo", errors: 2 }, + // whitespace + Case { source: r###" r #"foo"# "###, expect: "plain::r", errors: 2 }, + Case { source: r###" r# "foo"# "###, expect: "plain::r", errors: 3 }, + Case { source: r###" r#"foo" # "###, expect: "(none)", errors: 2 }, + // after identifier + Case { source: r###" bar#"foo"# "###, expect: "plain::bar", errors: 2 }, + // nested + Case { + source: r###"r##"foo r#"bar"# r"baz" ### bye"##"###, + expect: r###"r##"foo r#"bar"# r"baz" ### bye"##"###, + errors: 0, + }, + ]; + + check_cases_with_errors(&cases[..], expression()); + } + + #[test] + fn parse_raw_string_lit() { + let lit_cases = vec![ + Case { source: r##" r"foo" "##, expect: r##"r"foo""##, errors: 0 }, + Case { source: r##" r#"foo"# "##, expect: r##"r#"foo"#"##, errors: 0 }, + // backslash + Case { source: r##" r"\\" "##, expect: r##"r"\\""##, errors: 0 }, + Case { source: r##" r#"\"# "##, expect: r##"r#"\"#"##, errors: 0 }, + Case { source: r##" r#"\\"# "##, expect: r##"r#"\\"#"##, errors: 0 }, + Case { source: r##" r#"\\\"# "##, expect: r##"r#"\\\"#"##, errors: 0 }, + // escape sequence + Case { + source: r##" r#"\t\n\\t\\n\\\t\\\n\\\\"# "##, + expect: r##"r#"\t\n\\t\\n\\\t\\\n\\\\"#"##, + errors: 0, + }, + Case { source: r##" r#"\\\\\\\\"# "##, expect: r##"r#"\\\\\\\\"#"##, errors: 0 }, + // mismatch - errors: + Case { source: r###" r#"foo"## "###, expect: r###"r#"foo"#"###, errors: 1 }, + Case { source: r###" r##"foo"# "###, expect: "(none)", errors: 2 }, + ]; + + check_cases_with_errors(&lit_cases[..], literal()); + } } diff --git a/noir/compiler/noirc_frontend/src/tests.rs b/noir/compiler/noirc_frontend/src/tests.rs index 6a1cf80accd..13ce71c4616 100644 --- a/noir/compiler/noirc_frontend/src/tests.rs +++ b/noir/compiler/noirc_frontend/src/tests.rs @@ -18,6 +18,7 @@ mod test { use crate::hir::resolution::import::PathResolutionError; use crate::hir::type_check::TypeCheckError; use crate::hir::Context; + use crate::macros_api::MacroProcessor; use crate::node_interner::{NodeInterner, StmtId}; use crate::graph::CrateGraph; @@ -79,12 +80,16 @@ mod test { krate: root_crate_id, extern_prelude: BTreeMap::new(), }; + + let empty_macro_processors: Vec<&dyn MacroProcessor> = Vec::new(); + // Now we want to populate the CrateDefMap using the DefCollector errors.extend(DefCollector::collect( def_map, &mut context, program.clone().into_sorted(), root_file_id, + empty_macro_processors, )); } (program, context, errors) diff --git a/noir/compiler/source-resolver/package.json b/noir/compiler/source-resolver/package.json index 23cb1c729a3..85d6c4343aa 100644 --- a/noir/compiler/source-resolver/package.json +++ b/noir/compiler/source-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/source-resolver", - "version": "0.19.3", + "version": "0.19.4", "license": "MIT", "main": "./lib-node/index_node.js", "types": "./types/index_node.d.ts", diff --git a/noir/compiler/wasm/package.json b/noir/compiler/wasm/package.json index 932dbb4a7b6..eb1163ad62b 100644 --- a/noir/compiler/wasm/package.json +++ b/noir/compiler/wasm/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.19.3", + "version": "0.19.4", "license": "(MIT OR Apache-2.0)", "main": "./nodejs/noir_wasm.js", "types": "./web/noir_wasm.d.ts", diff --git a/noir/docs/docs/language_concepts/data_types/03_strings.md b/noir/docs/docs/language_concepts/data_types/03_strings.md index c42f34ec3ad..e647a58472f 100644 --- a/noir/docs/docs/language_concepts/data_types/03_strings.md +++ b/noir/docs/docs/language_concepts/data_types/03_strings.md @@ -61,3 +61,19 @@ Example: let s = "Hello \"world" // prints "Hello "world" let s = "hey \tyou"; // prints "hey you" ``` + +## Raw strings + +A raw string begins with the letter `r` and is optionally delimited by a number of hashes `#`. + +Escape characters are *not* processed within raw strings. All contents are interpreted literally. + +Example: + +```rust +let s = r"Hello world"; +let s = r#"Simon says "hello world""#; + +// Any number of hashes may be used (>= 1) as long as the string also terminates with the same number of hashes +let s = r#####"One "#, Two "##, Three "###, Four "####, Five will end the string."#####; +``` diff --git a/noir/docs/docs/standard_library/cryptographic_primitives/00_hashes.mdx b/noir/docs/docs/standard_library/cryptographic_primitives/00_hashes.mdx index 76745196681..38077af1ce1 100644 --- a/noir/docs/docs/standard_library/cryptographic_primitives/00_hashes.mdx +++ b/noir/docs/docs/standard_library/cryptographic_primitives/00_hashes.mdx @@ -124,8 +124,8 @@ example: ```rust fn main() { - let hash1 = std::hash::poseidon::bn254::hash_2([1, 2]); - assert(hash1 == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a); + let hash_2 = std::hash::poseidon::bn254::hash_2([1, 2]); + assert(hash2 == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a); } ``` diff --git a/noir/flake.nix b/noir/flake.nix index f9c458dc6ea..ac858c1714f 100644 --- a/noir/flake.nix +++ b/noir/flake.nix @@ -73,7 +73,7 @@ # Configuration shared between builds config = { # x-release-please-start-version - version = "0.19.3"; + version = "0.19.4"; # x-release-please-end src = pkgs.lib.cleanSourceWith { diff --git a/noir/release-tests/test/6_array.test.js b/noir/release-tests/test/6_array.test.js index 530b7f85bf4..43d4a389264 100644 --- a/noir/release-tests/test/6_array.test.js +++ b/noir/release-tests/test/6_array.test.js @@ -19,27 +19,27 @@ test("promise resolved", async () => { promiseResolved = true; }); -test("nargo builds ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo builds ../test_programs/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../tooling/nargo_cli/tests/execution_success/6_array"); + cd("../test_programs/execution_success/6_array"); const command = `${NARGO_BIN} check`; await $`${command}`.nothrow(); }); }); -test("nargo creates proof ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo creates proof ../test_programs/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../tooling/nargo_cli/tests/execution_success/6_array"); + cd("../test_programs/execution_success/6_array"); const command = `${NARGO_BIN} prove 6_array`; await $`${command}`.nothrow(); }); }); -test("nargo verifies proof ../tooling/nargo_cli/tests/execution_success/6_array sucessfully", async () => { +test("nargo verifies proof ../test_programs/execution_success/6_array sucessfully", async () => { await within(async () => { - cd("../tooling/nargo_cli/tests/execution_success/6_array"); + cd("../test_programs/execution_success/6_array"); const command = `${NARGO_BIN} verify 6_array`; await $`${command}`.nothrow(); diff --git a/noir/scripts/bootstrap_native.sh b/noir/scripts/bootstrap_native.sh index 26cd44704aa..693a9d9678e 100755 --- a/noir/scripts/bootstrap_native.sh +++ b/noir/scripts/bootstrap_native.sh @@ -4,11 +4,13 @@ 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 SOURCE_DATE_EPOCH=$(date +%s) - export GIT_DIRTY=false export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) +else + export GIT_COMMIT=$(git rev-parse --verify HEAD) fi # Build native. -cargo build --features="noirc_frontend/aztec" --release \ No newline at end of file +cargo build --features="noirc_driver/aztec" --release diff --git a/noir/scripts/bootstrap_packages.sh b/noir/scripts/bootstrap_packages.sh index 552ddd7597a..5fce2675037 100755 --- a/noir/scripts/bootstrap_packages.sh +++ b/noir/scripts/bootstrap_packages.sh @@ -6,13 +6,15 @@ cd $(dirname "$0")/.. ./scripts/install_wasm-bindgen.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 SOURCE_DATE_EPOCH=$(date +%s) - export GIT_DIRTY=false export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) +else + export GIT_COMMIT=$(git rev-parse --verify HEAD) fi -export cargoExtraArgs="--features noirc_frontend/aztec" +export cargoExtraArgs="--features noirc_driver/aztec" yarn yarn build diff --git a/noir/tooling/nargo_cli/tests/README.md b/noir/test_programs/README.md similarity index 100% rename from noir/tooling/nargo_cli/tests/README.md rename to noir/test_programs/README.md diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/acir.gz b/noir/test_programs/acir_artifacts/1327_concrete_in_generic/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/acir.gz rename to noir/test_programs/acir_artifacts/1327_concrete_in_generic/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/witness.gz b/noir/test_programs/acir_artifacts/1327_concrete_in_generic/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/1327_concrete_in_generic/target/witness.gz rename to noir/test_programs/acir_artifacts/1327_concrete_in_generic/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz b/noir/test_programs/acir_artifacts/1_mul/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/acir.gz rename to noir/test_programs/acir_artifacts/1_mul/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/witness.gz b/noir/test_programs/acir_artifacts/1_mul/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/1_mul/target/witness.gz rename to noir/test_programs/acir_artifacts/1_mul/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz b/noir/test_programs/acir_artifacts/2_div/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/2_div/target/acir.gz rename to noir/test_programs/acir_artifacts/2_div/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/2_div/target/witness.gz b/noir/test_programs/acir_artifacts/2_div/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/2_div/target/witness.gz rename to noir/test_programs/acir_artifacts/2_div/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz b/noir/test_programs/acir_artifacts/3_add/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/3_add/target/acir.gz rename to noir/test_programs/acir_artifacts/3_add/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/3_add/target/witness.gz b/noir/test_programs/acir_artifacts/3_add/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/3_add/target/witness.gz rename to noir/test_programs/acir_artifacts/3_add/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz b/noir/test_programs/acir_artifacts/4_sub/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/acir.gz rename to noir/test_programs/acir_artifacts/4_sub/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/witness.gz b/noir/test_programs/acir_artifacts/4_sub/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/4_sub/target/witness.gz rename to noir/test_programs/acir_artifacts/4_sub/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz b/noir/test_programs/acir_artifacts/5_over/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/5_over/target/acir.gz rename to noir/test_programs/acir_artifacts/5_over/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/5_over/target/witness.gz b/noir/test_programs/acir_artifacts/5_over/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/5_over/target/witness.gz rename to noir/test_programs/acir_artifacts/5_over/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz b/noir/test_programs/acir_artifacts/6/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz rename to noir/test_programs/acir_artifacts/6/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/6/target/witness.gz b/noir/test_programs/acir_artifacts/6/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/6/target/witness.gz rename to noir/test_programs/acir_artifacts/6/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz b/noir/test_programs/acir_artifacts/6_array/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz rename to noir/test_programs/acir_artifacts/6_array/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz b/noir/test_programs/acir_artifacts/6_array/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/6_array/target/witness.gz rename to noir/test_programs/acir_artifacts/6_array/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz b/noir/test_programs/acir_artifacts/7/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz rename to noir/test_programs/acir_artifacts/7/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/7/target/witness.gz b/noir/test_programs/acir_artifacts/7/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/7/target/witness.gz rename to noir/test_programs/acir_artifacts/7/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz b/noir/test_programs/acir_artifacts/7_function/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz rename to noir/test_programs/acir_artifacts/7_function/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/7_function/target/witness.gz b/noir/test_programs/acir_artifacts/7_function/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/7_function/target/witness.gz rename to noir/test_programs/acir_artifacts/7_function/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz b/noir/test_programs/acir_artifacts/arithmetic_binary_operations/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/acir.gz rename to noir/test_programs/acir_artifacts/arithmetic_binary_operations/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/witness.gz b/noir/test_programs/acir_artifacts/arithmetic_binary_operations/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/arithmetic_binary_operations/target/witness.gz rename to noir/test_programs/acir_artifacts/arithmetic_binary_operations/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/array_dynamic/target/acir.gz b/noir/test_programs/acir_artifacts/array_dynamic/target/acir.gz new file mode 100644 index 00000000000..e6111539302 Binary files /dev/null and b/noir/test_programs/acir_artifacts/array_dynamic/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/array_dynamic/target/witness.gz b/noir/test_programs/acir_artifacts/array_dynamic/target/witness.gz new file mode 100644 index 00000000000..102bb7ad178 Binary files /dev/null and b/noir/test_programs/acir_artifacts/array_dynamic/target/witness.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz b/noir/test_programs/acir_artifacts/array_eq/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz rename to noir/test_programs/acir_artifacts/array_eq/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/witness.gz b/noir/test_programs/acir_artifacts/array_eq/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_eq/target/witness.gz rename to noir/test_programs/acir_artifacts/array_eq/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz b/noir/test_programs/acir_artifacts/array_len/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz rename to noir/test_programs/acir_artifacts/array_len/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_len/target/witness.gz b/noir/test_programs/acir_artifacts/array_len/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_len/target/witness.gz rename to noir/test_programs/acir_artifacts/array_len/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz b/noir/test_programs/acir_artifacts/array_neq/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz rename to noir/test_programs/acir_artifacts/array_neq/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/witness.gz b/noir/test_programs/acir_artifacts/array_neq/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_neq/target/witness.gz rename to noir/test_programs/acir_artifacts/array_neq/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz b/noir/test_programs/acir_artifacts/array_sort/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz rename to noir/test_programs/acir_artifacts/array_sort/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/witness.gz b/noir/test_programs/acir_artifacts/array_sort/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/array_sort/target/witness.gz rename to noir/test_programs/acir_artifacts/array_sort/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assert/target/acir.gz b/noir/test_programs/acir_artifacts/assert/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assert/target/acir.gz rename to noir/test_programs/acir_artifacts/assert/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assert/target/witness.gz b/noir/test_programs/acir_artifacts/assert/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assert/target/witness.gz rename to noir/test_programs/acir_artifacts/assert/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/acir.gz b/noir/test_programs/acir_artifacts/assert_statement/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/acir.gz rename to noir/test_programs/acir_artifacts/assert_statement/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/witness.gz b/noir/test_programs/acir_artifacts/assert_statement/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assert_statement/target/witness.gz rename to noir/test_programs/acir_artifacts/assert_statement/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/acir.gz b/noir/test_programs/acir_artifacts/assign_ex/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/acir.gz rename to noir/test_programs/acir_artifacts/assign_ex/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/witness.gz b/noir/test_programs/acir_artifacts/assign_ex/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/assign_ex/target/witness.gz rename to noir/test_programs/acir_artifacts/assign_ex/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz b/noir/test_programs/acir_artifacts/bit_and/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/acir.gz rename to noir/test_programs/acir_artifacts/bit_and/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/witness.gz b/noir/test_programs/acir_artifacts/bit_and/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_and/target/witness.gz rename to noir/test_programs/acir_artifacts/bit_and/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz b/noir/test_programs/acir_artifacts/bit_shifts_comptime/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/acir.gz rename to noir/test_programs/acir_artifacts/bit_shifts_comptime/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/witness.gz b/noir/test_programs/acir_artifacts/bit_shifts_comptime/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_comptime/target/witness.gz rename to noir/test_programs/acir_artifacts/bit_shifts_comptime/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz b/noir/test_programs/acir_artifacts/bit_shifts_runtime/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/acir.gz rename to noir/test_programs/acir_artifacts/bit_shifts_runtime/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/witness.gz b/noir/test_programs/acir_artifacts/bit_shifts_runtime/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bit_shifts_runtime/target/witness.gz rename to noir/test_programs/acir_artifacts/bit_shifts_runtime/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/acir.gz b/noir/test_programs/acir_artifacts/bool_not/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/acir.gz rename to noir/test_programs/acir_artifacts/bool_not/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/witness.gz b/noir/test_programs/acir_artifacts/bool_not/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bool_not/target/witness.gz rename to noir/test_programs/acir_artifacts/bool_not/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/acir.gz b/noir/test_programs/acir_artifacts/bool_or/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/acir.gz rename to noir/test_programs/acir_artifacts/bool_or/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/witness.gz b/noir/test_programs/acir_artifacts/bool_or/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/bool_or/target/witness.gz rename to noir/test_programs/acir_artifacts/bool_or/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_acir_as_brillig/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_acir_as_brillig/target/acir.gz new file mode 100644 index 00000000000..dfcbcfe2d5b Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_acir_as_brillig/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_acir_as_brillig/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_acir_as_brillig/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_arrays/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_arrays/target/acir.gz new file mode 100644 index 00000000000..afadfe0d7c8 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_arrays/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_arrays/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_arrays/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_assert/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_assert/target/acir.gz new file mode 100644 index 00000000000..10c49ba04e3 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_assert/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_assert/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_assert/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_blake2s/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_blake2s/target/acir.gz new file mode 100644 index 00000000000..5511eedede9 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_blake2s/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_blake2s/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_blake2s/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_calls/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_calls/target/acir.gz new file mode 100644 index 00000000000..71a5956d1f4 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_calls/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_calls/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_calls/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_calls_array/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_calls_array/target/acir.gz new file mode 100644 index 00000000000..970c95756c7 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_calls_array/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_calls_array/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_calls_array/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_calls_conditionals/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_calls_conditionals/target/acir.gz new file mode 100644 index 00000000000..1c06691acfe Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_calls_conditionals/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_calls_conditionals/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_calls_conditionals/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_conditional/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_conditional/target/acir.gz new file mode 100644 index 00000000000..09f123508f7 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_conditional/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_conditional/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_conditional/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_ecdsa/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_ecdsa/target/acir.gz new file mode 100644 index 00000000000..5514ad75442 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_ecdsa/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_ecdsa/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_ecdsa/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_fns_as_values/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_fns_as_values/target/acir.gz new file mode 100644 index 00000000000..db2717ae656 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_fns_as_values/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_fns_as_values/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_fns_as_values/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_hash_to_field/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_hash_to_field/target/acir.gz new file mode 100644 index 00000000000..4ef5ef5d1cb Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_hash_to_field/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_hash_to_field/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_hash_to_field/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_identity_function/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_identity_function/target/acir.gz new file mode 100644 index 00000000000..080769c4fe7 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_identity_function/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_identity_function/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_identity_function/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_keccak/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_keccak/target/acir.gz new file mode 100644 index 00000000000..6f22b23625c Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_keccak/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_keccak/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_keccak/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_loop/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/acir.gz rename to noir/test_programs/acir_artifacts/brillig_loop/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_loop/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_loop/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_loop/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_nested_arrays/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_nested_arrays/target/acir.gz new file mode 100644 index 00000000000..2fe7430584b Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_nested_arrays/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_nested_arrays/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_nested_arrays/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_nested_slices/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_nested_slices/target/acir.gz new file mode 100644 index 00000000000..2247d8a8baa Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_nested_slices/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_nested_slices/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_nested_slices/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_not/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_not/target/acir.gz new file mode 100644 index 00000000000..f97dbde95da Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_not/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_not/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_not/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_oracle/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_oracle/target/acir.gz new file mode 100644 index 00000000000..a1854cf090a Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_oracle/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/brillig_oracle/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_oracle/target/witness.gz new file mode 100644 index 00000000000..bd1fe47aade Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_oracle/target/witness.gz differ diff --git a/noir/test_programs/acir_artifacts/brillig_pedersen/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_pedersen/target/acir.gz new file mode 100644 index 00000000000..a8971591478 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_pedersen/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_pedersen/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_pedersen/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_recursion/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_recursion/target/acir.gz new file mode 100644 index 00000000000..88daa302398 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_recursion/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_recursion/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_recursion/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_references/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_references/target/acir.gz new file mode 100644 index 00000000000..d28e62ff67e Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_references/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_references/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_references/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_scalar_mul/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_scalar_mul/target/acir.gz new file mode 100644 index 00000000000..51c25758d37 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_scalar_mul/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_scalar_mul/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_scalar_mul/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_schnorr/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_schnorr/target/acir.gz new file mode 100644 index 00000000000..95af8d0743f Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_schnorr/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_schnorr/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_schnorr/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_sha256/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_sha256/target/acir.gz new file mode 100644 index 00000000000..f497023135a Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_sha256/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_sha256/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_sha256/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_slices/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_slices/target/acir.gz new file mode 100644 index 00000000000..c58474d160c Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_slices/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_slices/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_slices/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_to_be_bytes/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_to_be_bytes/target/acir.gz new file mode 100644 index 00000000000..011371d0bf5 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_to_be_bytes/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_to_be_bytes/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_to_be_bytes/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_to_bytes_integration/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_to_bytes_integration/target/acir.gz new file mode 100644 index 00000000000..e235e8e3134 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_to_bytes_integration/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_to_bytes_integration/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_to_bytes_integration/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_to_le_bytes/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_to_le_bytes/target/acir.gz new file mode 100644 index 00000000000..b2a486c7176 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_to_le_bytes/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_to_le_bytes/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_to_le_bytes/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_top_level/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_top_level/target/acir.gz new file mode 100644 index 00000000000..c200de2ac0e Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_top_level/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_top_level/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/witness.gz rename to noir/test_programs/acir_artifacts/brillig_top_level/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/acir.gz b/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/acir.gz new file mode 100644 index 00000000000..3b1f545133d Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/witness.gz b/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/witness.gz new file mode 100644 index 00000000000..9724de0f1d9 Binary files /dev/null and b/noir/test_programs/acir_artifacts/brillig_unitialised_arrays/target/witness.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz b/noir/test_programs/acir_artifacts/cast_bool/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/acir.gz rename to noir/test_programs/acir_artifacts/cast_bool/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/witness.gz b/noir/test_programs/acir_artifacts/cast_bool/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/cast_bool/target/witness.gz rename to noir/test_programs/acir_artifacts/cast_bool/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/acir.gz b/noir/test_programs/acir_artifacts/closures_mut_ref/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/acir.gz rename to noir/test_programs/acir_artifacts/closures_mut_ref/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/witness.gz b/noir/test_programs/acir_artifacts/closures_mut_ref/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/closures_mut_ref/target/witness.gz rename to noir/test_programs/acir_artifacts/closures_mut_ref/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/conditional_1/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_1/target/acir.gz new file mode 100644 index 00000000000..16ec8f28b53 Binary files /dev/null and b/noir/test_programs/acir_artifacts/conditional_1/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/conditional_1/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_1/target/witness.gz new file mode 100644 index 00000000000..30cc2834841 Binary files /dev/null and b/noir/test_programs/acir_artifacts/conditional_1/target/witness.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_2/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/acir.gz rename to noir/test_programs/acir_artifacts/conditional_2/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_2/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_2/target/witness.gz rename to noir/test_programs/acir_artifacts/conditional_2/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_regression_421/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/acir.gz rename to noir/test_programs/acir_artifacts/conditional_regression_421/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_regression_421/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_421/target/witness.gz rename to noir/test_programs/acir_artifacts/conditional_regression_421/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_regression_661/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/acir.gz rename to noir/test_programs/acir_artifacts/conditional_regression_661/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_regression_661/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_661/target/witness.gz rename to noir/test_programs/acir_artifacts/conditional_regression_661/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_regression_short_circuit/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/acir.gz rename to noir/test_programs/acir_artifacts/conditional_regression_short_circuit/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_regression_short_circuit/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_short_circuit/target/witness.gz rename to noir/test_programs/acir_artifacts/conditional_regression_short_circuit/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_underflow/target/acir.gz b/noir/test_programs/acir_artifacts/conditional_regression_underflow/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_underflow/target/acir.gz rename to noir/test_programs/acir_artifacts/conditional_regression_underflow/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_underflow/target/witness.gz b/noir/test_programs/acir_artifacts/conditional_regression_underflow/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_underflow/target/witness.gz rename to noir/test_programs/acir_artifacts/conditional_regression_underflow/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/acir.gz b/noir/test_programs/acir_artifacts/custom_entry/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/acir.gz rename to noir/test_programs/acir_artifacts/custom_entry/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/witness.gz b/noir/test_programs/acir_artifacts/custom_entry/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/custom_entry/target/witness.gz rename to noir/test_programs/acir_artifacts/custom_entry/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/debug_logs/target/acir.gz b/noir/test_programs/acir_artifacts/debug_logs/target/acir.gz new file mode 100644 index 00000000000..49568a14320 Binary files /dev/null and b/noir/test_programs/acir_artifacts/debug_logs/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/witness.gz b/noir/test_programs/acir_artifacts/debug_logs/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/witness.gz rename to noir/test_programs/acir_artifacts/debug_logs/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/acir.gz b/noir/test_programs/acir_artifacts/diamond_deps_0/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/acir.gz rename to noir/test_programs/acir_artifacts/diamond_deps_0/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/witness.gz b/noir/test_programs/acir_artifacts/diamond_deps_0/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/diamond_deps_0/target/witness.gz rename to noir/test_programs/acir_artifacts/diamond_deps_0/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/acir.gz b/noir/test_programs/acir_artifacts/distinct_keyword/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/acir.gz rename to noir/test_programs/acir_artifacts/distinct_keyword/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/witness.gz b/noir/test_programs/acir_artifacts/distinct_keyword/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/distinct_keyword/target/witness.gz rename to noir/test_programs/acir_artifacts/distinct_keyword/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/acir.gz b/noir/test_programs/acir_artifacts/double_verify_proof/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/acir.gz rename to noir/test_programs/acir_artifacts/double_verify_proof/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/witness.gz b/noir/test_programs/acir_artifacts/double_verify_proof/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/double_verify_proof/target/witness.gz rename to noir/test_programs/acir_artifacts/double_verify_proof/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/acir.gz b/noir/test_programs/acir_artifacts/ecdsa_secp256k1/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/acir.gz rename to noir/test_programs/acir_artifacts/ecdsa_secp256k1/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/witness.gz b/noir/test_programs/acir_artifacts/ecdsa_secp256k1/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256k1/target/witness.gz rename to noir/test_programs/acir_artifacts/ecdsa_secp256k1/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/acir.gz b/noir/test_programs/acir_artifacts/ecdsa_secp256r1/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/acir.gz rename to noir/test_programs/acir_artifacts/ecdsa_secp256r1/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/witness.gz b/noir/test_programs/acir_artifacts/ecdsa_secp256r1/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/ecdsa_secp256r1/target/witness.gz rename to noir/test_programs/acir_artifacts/ecdsa_secp256r1/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz b/noir/test_programs/acir_artifacts/eddsa/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/acir.gz rename to noir/test_programs/acir_artifacts/eddsa/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/witness.gz b/noir/test_programs/acir_artifacts/eddsa/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/eddsa/target/witness.gz rename to noir/test_programs/acir_artifacts/eddsa/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz b/noir/test_programs/acir_artifacts/field_attribute/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/acir.gz rename to noir/test_programs/acir_artifacts/field_attribute/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/witness.gz b/noir/test_programs/acir_artifacts/field_attribute/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/field_attribute/target/witness.gz rename to noir/test_programs/acir_artifacts/field_attribute/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/generics/target/acir.gz b/noir/test_programs/acir_artifacts/generics/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/generics/target/acir.gz rename to noir/test_programs/acir_artifacts/generics/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/generics/target/witness.gz b/noir/test_programs/acir_artifacts/generics/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/generics/target/witness.gz rename to noir/test_programs/acir_artifacts/generics/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz b/noir/test_programs/acir_artifacts/global_consts/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/acir.gz rename to noir/test_programs/acir_artifacts/global_consts/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/witness.gz b/noir/test_programs/acir_artifacts/global_consts/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/global_consts/target/witness.gz rename to noir/test_programs/acir_artifacts/global_consts/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/acir.gz b/noir/test_programs/acir_artifacts/hash_to_field/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/acir.gz rename to noir/test_programs/acir_artifacts/hash_to_field/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/witness.gz b/noir/test_programs/acir_artifacts/hash_to_field/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/hash_to_field/target/witness.gz rename to noir/test_programs/acir_artifacts/hash_to_field/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz b/noir/test_programs/acir_artifacts/higher_order_functions/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/acir.gz rename to noir/test_programs/acir_artifacts/higher_order_functions/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz b/noir/test_programs/acir_artifacts/higher_order_functions/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/higher_order_functions/target/witness.gz rename to noir/test_programs/acir_artifacts/higher_order_functions/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz b/noir/test_programs/acir_artifacts/if_else_chain/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/acir.gz rename to noir/test_programs/acir_artifacts/if_else_chain/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/witness.gz b/noir/test_programs/acir_artifacts/if_else_chain/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/if_else_chain/target/witness.gz rename to noir/test_programs/acir_artifacts/if_else_chain/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz b/noir/test_programs/acir_artifacts/import/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/import/target/acir.gz rename to noir/test_programs/acir_artifacts/import/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/import/target/witness.gz b/noir/test_programs/acir_artifacts/import/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/import/target/witness.gz rename to noir/test_programs/acir_artifacts/import/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/acir.gz b/noir/test_programs/acir_artifacts/integer_array_indexing/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/acir.gz rename to noir/test_programs/acir_artifacts/integer_array_indexing/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/witness.gz b/noir/test_programs/acir_artifacts/integer_array_indexing/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/integer_array_indexing/target/witness.gz rename to noir/test_programs/acir_artifacts/integer_array_indexing/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz b/noir/test_programs/acir_artifacts/keccak256/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz rename to noir/test_programs/acir_artifacts/keccak256/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/witness.gz b/noir/test_programs/acir_artifacts/keccak256/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/keccak256/target/witness.gz rename to noir/test_programs/acir_artifacts/keccak256/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz b/noir/test_programs/acir_artifacts/main_bool_arg/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/acir.gz rename to noir/test_programs/acir_artifacts/main_bool_arg/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/witness.gz b/noir/test_programs/acir_artifacts/main_bool_arg/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/main_bool_arg/target/witness.gz rename to noir/test_programs/acir_artifacts/main_bool_arg/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/merkle_insert/target/acir.gz b/noir/test_programs/acir_artifacts/merkle_insert/target/acir.gz new file mode 100644 index 00000000000..5468d947456 Binary files /dev/null and b/noir/test_programs/acir_artifacts/merkle_insert/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/witness.gz b/noir/test_programs/acir_artifacts/merkle_insert/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/witness.gz rename to noir/test_programs/acir_artifacts/merkle_insert/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/mock_oracle/target/acir.gz b/noir/test_programs/acir_artifacts/mock_oracle/target/acir.gz new file mode 100644 index 00000000000..618e9cc8ad1 Binary files /dev/null and b/noir/test_programs/acir_artifacts/mock_oracle/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/witness.gz b/noir/test_programs/acir_artifacts/mock_oracle/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/witness.gz rename to noir/test_programs/acir_artifacts/mock_oracle/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz b/noir/test_programs/acir_artifacts/modules/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modules/target/acir.gz rename to noir/test_programs/acir_artifacts/modules/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modules/target/witness.gz b/noir/test_programs/acir_artifacts/modules/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modules/target/witness.gz rename to noir/test_programs/acir_artifacts/modules/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz b/noir/test_programs/acir_artifacts/modules_more/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/acir.gz rename to noir/test_programs/acir_artifacts/modules_more/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/witness.gz b/noir/test_programs/acir_artifacts/modules_more/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modules_more/target/witness.gz rename to noir/test_programs/acir_artifacts/modules_more/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz b/noir/test_programs/acir_artifacts/modulus/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz rename to noir/test_programs/acir_artifacts/modulus/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz b/noir/test_programs/acir_artifacts/modulus/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/modulus/target/witness.gz rename to noir/test_programs/acir_artifacts/modulus/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/nested_array_dynamic/target/acir.gz b/noir/test_programs/acir_artifacts/nested_array_dynamic/target/acir.gz new file mode 100644 index 00000000000..762ace26416 Binary files /dev/null and b/noir/test_programs/acir_artifacts/nested_array_dynamic/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/nested_array_dynamic/target/witness.gz b/noir/test_programs/acir_artifacts/nested_array_dynamic/target/witness.gz new file mode 100644 index 00000000000..e469a0ee7a7 Binary files /dev/null and b/noir/test_programs/acir_artifacts/nested_array_dynamic/target/witness.gz differ diff --git a/noir/test_programs/acir_artifacts/nested_arrays_from_brillig/target/acir.gz b/noir/test_programs/acir_artifacts/nested_arrays_from_brillig/target/acir.gz new file mode 100644 index 00000000000..1fba277a1f8 Binary files /dev/null and b/noir/test_programs/acir_artifacts/nested_arrays_from_brillig/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/witness.gz b/noir/test_programs/acir_artifacts/nested_arrays_from_brillig/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/witness.gz rename to noir/test_programs/acir_artifacts/nested_arrays_from_brillig/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz b/noir/test_programs/acir_artifacts/nested_slice_dynamic/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/acir.gz rename to noir/test_programs/acir_artifacts/nested_slice_dynamic/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/witness.gz b/noir/test_programs/acir_artifacts/nested_slice_dynamic/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/nested_slice_dynamic/target/witness.gz rename to noir/test_programs/acir_artifacts/nested_slice_dynamic/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/acir.gz b/noir/test_programs/acir_artifacts/pedersen_check/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/acir.gz rename to noir/test_programs/acir_artifacts/pedersen_check/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/witness.gz b/noir/test_programs/acir_artifacts/pedersen_check/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/pedersen_check/target/witness.gz rename to noir/test_programs/acir_artifacts/pedersen_check/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/acir.gz b/noir/test_programs/acir_artifacts/poseidon_bn254_hash/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/acir.gz rename to noir/test_programs/acir_artifacts/poseidon_bn254_hash/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/witness.gz b/noir/test_programs/acir_artifacts/poseidon_bn254_hash/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/poseidon_bn254_hash/target/witness.gz rename to noir/test_programs/acir_artifacts/poseidon_bn254_hash/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/acir.gz b/noir/test_programs/acir_artifacts/poseidonsponge_x5_254/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/acir.gz rename to noir/test_programs/acir_artifacts/poseidonsponge_x5_254/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/witness.gz b/noir/test_programs/acir_artifacts/poseidonsponge_x5_254/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/poseidonsponge_x5_254/target/witness.gz rename to noir/test_programs/acir_artifacts/poseidonsponge_x5_254/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz b/noir/test_programs/acir_artifacts/pred_eq/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/acir.gz rename to noir/test_programs/acir_artifacts/pred_eq/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/witness.gz b/noir/test_programs/acir_artifacts/pred_eq/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/pred_eq/target/witness.gz rename to noir/test_programs/acir_artifacts/pred_eq/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/references/target/acir.gz b/noir/test_programs/acir_artifacts/references/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/references/target/acir.gz rename to noir/test_programs/acir_artifacts/references/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/references/target/witness.gz b/noir/test_programs/acir_artifacts/references/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/references/target/witness.gz rename to noir/test_programs/acir_artifacts/references/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz b/noir/test_programs/acir_artifacts/regression/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz rename to noir/test_programs/acir_artifacts/regression/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression/target/witness.gz b/noir/test_programs/acir_artifacts/regression/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/regression/target/witness.gz rename to noir/test_programs/acir_artifacts/regression/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz b/noir/test_programs/acir_artifacts/regression_2854/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/acir.gz rename to noir/test_programs/acir_artifacts/regression_2854/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/witness.gz b/noir/test_programs/acir_artifacts/regression_2854/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/regression_2854/target/witness.gz rename to noir/test_programs/acir_artifacts/regression_2854/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/acir.gz b/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/acir.gz new file mode 100644 index 00000000000..a408771e244 Binary files /dev/null and b/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/witness.gz b/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/witness.gz new file mode 100644 index 00000000000..2d0e8a4f685 Binary files /dev/null and b/noir/test_programs/acir_artifacts/regression_mem_op_predicate/target/witness.gz differ diff --git a/noir/test_programs/acir_artifacts/regression_method_cannot_be_found/target/acir.gz b/noir/test_programs/acir_artifacts/regression_method_cannot_be_found/target/acir.gz new file mode 100644 index 00000000000..dd4d7ea5f45 Binary files /dev/null and b/noir/test_programs/acir_artifacts/regression_method_cannot_be_found/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/witness.gz b/noir/test_programs/acir_artifacts/regression_method_cannot_be_found/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/witness.gz rename to noir/test_programs/acir_artifacts/regression_method_cannot_be_found/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz b/noir/test_programs/acir_artifacts/scalar_mul/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/acir.gz rename to noir/test_programs/acir_artifacts/scalar_mul/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/witness.gz b/noir/test_programs/acir_artifacts/scalar_mul/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/scalar_mul/target/witness.gz rename to noir/test_programs/acir_artifacts/scalar_mul/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz b/noir/test_programs/acir_artifacts/schnorr/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz rename to noir/test_programs/acir_artifacts/schnorr/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz b/noir/test_programs/acir_artifacts/schnorr/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/schnorr/target/witness.gz rename to noir/test_programs/acir_artifacts/schnorr/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz b/noir/test_programs/acir_artifacts/sha256/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz rename to noir/test_programs/acir_artifacts/sha256/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/sha256/target/witness.gz b/noir/test_programs/acir_artifacts/sha256/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/sha256/target/witness.gz rename to noir/test_programs/acir_artifacts/sha256/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz b/noir/test_programs/acir_artifacts/sha2_byte/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz rename to noir/test_programs/acir_artifacts/sha2_byte/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/witness.gz b/noir/test_programs/acir_artifacts/sha2_byte/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/witness.gz rename to noir/test_programs/acir_artifacts/sha2_byte/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz b/noir/test_programs/acir_artifacts/signed_arithmetic/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/acir.gz rename to noir/test_programs/acir_artifacts/signed_arithmetic/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/witness.gz b/noir/test_programs/acir_artifacts/signed_arithmetic/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/signed_arithmetic/target/witness.gz rename to noir/test_programs/acir_artifacts/signed_arithmetic/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz b/noir/test_programs/acir_artifacts/signed_division/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/acir.gz rename to noir/test_programs/acir_artifacts/signed_division/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/witness.gz b/noir/test_programs/acir_artifacts/signed_division/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/signed_division/target/witness.gz rename to noir/test_programs/acir_artifacts/signed_division/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_2d_array/target/acir.gz b/noir/test_programs/acir_artifacts/simple_2d_array/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_2d_array/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_2d_array/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_2d_array/target/witness.gz b/noir/test_programs/acir_artifacts/simple_2d_array/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_2d_array/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_2d_array/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/acir.gz b/noir/test_programs/acir_artifacts/simple_add_and_ret_arr/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_add_and_ret_arr/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/witness.gz b/noir/test_programs/acir_artifacts/simple_add_and_ret_arr/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_add_and_ret_arr/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_add_and_ret_arr/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz b/noir/test_programs/acir_artifacts/simple_bitwise/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_bitwise/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/witness.gz b/noir/test_programs/acir_artifacts/simple_bitwise/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_bitwise/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_bitwise/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz b/noir/test_programs/acir_artifacts/simple_comparison/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_comparison/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/witness.gz b/noir/test_programs/acir_artifacts/simple_comparison/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_comparison/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_comparison/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/acir.gz b/noir/test_programs/acir_artifacts/simple_mut/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_mut/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/witness.gz b/noir/test_programs/acir_artifacts/simple_mut/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_mut/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_mut/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/acir.gz b/noir/test_programs/acir_artifacts/simple_not/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_not/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/witness.gz b/noir/test_programs/acir_artifacts/simple_not/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_not/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_not/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/simple_print/target/acir.gz b/noir/test_programs/acir_artifacts/simple_print/target/acir.gz new file mode 100644 index 00000000000..9640753adfe Binary files /dev/null and b/noir/test_programs/acir_artifacts/simple_print/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/witness.gz b/noir/test_programs/acir_artifacts/simple_print/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_print/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/acir.gz b/noir/test_programs/acir_artifacts/simple_program_addition/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_program_addition/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/witness.gz b/noir/test_programs/acir_artifacts/simple_program_addition/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_program_addition/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_program_addition/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz b/noir/test_programs/acir_artifacts/simple_radix/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_radix/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/witness.gz b/noir/test_programs/acir_artifacts/simple_radix/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_radix/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_radix/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz b/noir/test_programs/acir_artifacts/simple_shield/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_shield/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/witness.gz b/noir/test_programs/acir_artifacts/simple_shield/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_shield/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz b/noir/test_programs/acir_artifacts/simple_shift_left_right/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/acir.gz rename to noir/test_programs/acir_artifacts/simple_shift_left_right/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/witness.gz b/noir/test_programs/acir_artifacts/simple_shift_left_right/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/simple_shift_left_right/target/witness.gz rename to noir/test_programs/acir_artifacts/simple_shift_left_right/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/slice_dynamic_index/target/acir.gz b/noir/test_programs/acir_artifacts/slice_dynamic_index/target/acir.gz new file mode 100644 index 00000000000..1bbc8ea075c Binary files /dev/null and b/noir/test_programs/acir_artifacts/slice_dynamic_index/target/acir.gz differ diff --git a/noir/test_programs/acir_artifacts/slice_dynamic_index/target/witness.gz b/noir/test_programs/acir_artifacts/slice_dynamic_index/target/witness.gz new file mode 100644 index 00000000000..8c7e5f4fb95 Binary files /dev/null and b/noir/test_programs/acir_artifacts/slice_dynamic_index/target/witness.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_struct_field/target/acir.gz b/noir/test_programs/acir_artifacts/slice_struct_field/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/slice_struct_field/target/acir.gz rename to noir/test_programs/acir_artifacts/slice_struct_field/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_struct_field/target/witness.gz b/noir/test_programs/acir_artifacts/slice_struct_field/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/slice_struct_field/target/witness.gz rename to noir/test_programs/acir_artifacts/slice_struct_field/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz b/noir/test_programs/acir_artifacts/slices/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz rename to noir/test_programs/acir_artifacts/slices/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slices/target/witness.gz b/noir/test_programs/acir_artifacts/slices/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/slices/target/witness.gz rename to noir/test_programs/acir_artifacts/slices/target/witness.gz diff --git a/noir/test_programs/acir_artifacts/strings/target/acir.gz b/noir/test_programs/acir_artifacts/strings/target/acir.gz new file mode 100644 index 00000000000..c489121a9b1 Binary files /dev/null and b/noir/test_programs/acir_artifacts/strings/target/acir.gz differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/strings/target/witness.gz b/noir/test_programs/acir_artifacts/strings/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/strings/target/witness.gz rename to noir/test_programs/acir_artifacts/strings/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct/target/acir.gz b/noir/test_programs/acir_artifacts/struct/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct/target/acir.gz rename to noir/test_programs/acir_artifacts/struct/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct/target/witness.gz b/noir/test_programs/acir_artifacts/struct/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct/target/witness.gz rename to noir/test_programs/acir_artifacts/struct/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/acir.gz b/noir/test_programs/acir_artifacts/struct_array_inputs/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/acir.gz rename to noir/test_programs/acir_artifacts/struct_array_inputs/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/witness.gz b/noir/test_programs/acir_artifacts/struct_array_inputs/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_array_inputs/target/witness.gz rename to noir/test_programs/acir_artifacts/struct_array_inputs/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/acir.gz b/noir/test_programs/acir_artifacts/struct_fields_ordering/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/acir.gz rename to noir/test_programs/acir_artifacts/struct_fields_ordering/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/witness.gz b/noir/test_programs/acir_artifacts/struct_fields_ordering/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_fields_ordering/target/witness.gz rename to noir/test_programs/acir_artifacts/struct_fields_ordering/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz b/noir/test_programs/acir_artifacts/struct_inputs/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/acir.gz rename to noir/test_programs/acir_artifacts/struct_inputs/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/witness.gz b/noir/test_programs/acir_artifacts/struct_inputs/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/struct_inputs/target/witness.gz rename to noir/test_programs/acir_artifacts/struct_inputs/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/submodules/target/acir.gz b/noir/test_programs/acir_artifacts/submodules/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/submodules/target/acir.gz rename to noir/test_programs/acir_artifacts/submodules/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/submodules/target/witness.gz b/noir/test_programs/acir_artifacts/submodules/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/submodules/target/witness.gz rename to noir/test_programs/acir_artifacts/submodules/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz b/noir/test_programs/acir_artifacts/to_be_bytes/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/acir.gz rename to noir/test_programs/acir_artifacts/to_be_bytes/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz b/noir/test_programs/acir_artifacts/to_be_bytes/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_be_bytes/target/witness.gz rename to noir/test_programs/acir_artifacts/to_be_bytes/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz b/noir/test_programs/acir_artifacts/to_bytes_consistent/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/acir.gz rename to noir/test_programs/acir_artifacts/to_bytes_consistent/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/witness.gz b/noir/test_programs/acir_artifacts/to_bytes_consistent/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_consistent/target/witness.gz rename to noir/test_programs/acir_artifacts/to_bytes_consistent/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz b/noir/test_programs/acir_artifacts/to_bytes_integration/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/acir.gz rename to noir/test_programs/acir_artifacts/to_bytes_integration/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/witness.gz b/noir/test_programs/acir_artifacts/to_bytes_integration/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_bytes_integration/target/witness.gz rename to noir/test_programs/acir_artifacts/to_bytes_integration/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz b/noir/test_programs/acir_artifacts/to_le_bytes/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/acir.gz rename to noir/test_programs/acir_artifacts/to_le_bytes/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/witness.gz b/noir/test_programs/acir_artifacts/to_le_bytes/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/to_le_bytes/target/witness.gz rename to noir/test_programs/acir_artifacts/to_le_bytes/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/acir.gz b/noir/test_programs/acir_artifacts/trait_as_return_type/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/acir.gz rename to noir/test_programs/acir_artifacts/trait_as_return_type/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/witness.gz b/noir/test_programs/acir_artifacts/trait_as_return_type/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/witness.gz rename to noir/test_programs/acir_artifacts/trait_as_return_type/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/trait_impl_base_type/target/acir.gz b/noir/test_programs/acir_artifacts/trait_impl_base_type/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/trait_impl_base_type/target/acir.gz rename to noir/test_programs/acir_artifacts/trait_impl_base_type/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/trait_impl_base_type/target/witness.gz b/noir/test_programs/acir_artifacts/trait_impl_base_type/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/trait_impl_base_type/target/witness.gz rename to noir/test_programs/acir_artifacts/trait_impl_base_type/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_1/target/acir.gz b/noir/test_programs/acir_artifacts/traits_in_crates_1/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_1/target/acir.gz rename to noir/test_programs/acir_artifacts/traits_in_crates_1/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_1/target/witness.gz b/noir/test_programs/acir_artifacts/traits_in_crates_1/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_1/target/witness.gz rename to noir/test_programs/acir_artifacts/traits_in_crates_1/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_2/target/acir.gz b/noir/test_programs/acir_artifacts/traits_in_crates_2/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_2/target/acir.gz rename to noir/test_programs/acir_artifacts/traits_in_crates_2/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_2/target/witness.gz b/noir/test_programs/acir_artifacts/traits_in_crates_2/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/traits_in_crates_2/target/witness.gz rename to noir/test_programs/acir_artifacts/traits_in_crates_2/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz b/noir/test_programs/acir_artifacts/tuple_inputs/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/acir.gz rename to noir/test_programs/acir_artifacts/tuple_inputs/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz b/noir/test_programs/acir_artifacts/tuple_inputs/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/tuple_inputs/target/witness.gz rename to noir/test_programs/acir_artifacts/tuple_inputs/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz b/noir/test_programs/acir_artifacts/tuples/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/tuples/target/acir.gz rename to noir/test_programs/acir_artifacts/tuples/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz b/noir/test_programs/acir_artifacts/tuples/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/tuples/target/witness.gz rename to noir/test_programs/acir_artifacts/tuples/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz b/noir/test_programs/acir_artifacts/type_aliases/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/acir.gz rename to noir/test_programs/acir_artifacts/type_aliases/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/witness.gz b/noir/test_programs/acir_artifacts/type_aliases/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/type_aliases/target/witness.gz rename to noir/test_programs/acir_artifacts/type_aliases/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz b/noir/test_programs/acir_artifacts/xor/target/acir.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/xor/target/acir.gz rename to noir/test_programs/acir_artifacts/xor/target/acir.gz diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/xor/target/witness.gz b/noir/test_programs/acir_artifacts/xor/target/witness.gz similarity index 100% rename from noir/tooling/nargo_cli/tests/acir_artifacts/xor/target/witness.gz rename to noir/test_programs/acir_artifacts/xor/target/witness.gz diff --git a/noir/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml b/noir/test_programs/compile_failure/assert_constant_fail/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/Nargo.toml rename to noir/test_programs/compile_failure/assert_constant_fail/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr b/noir/test_programs/compile_failure/assert_constant_fail/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/assert_constant_fail/src/main.nr rename to noir/test_programs/compile_failure/assert_constant_fail/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/Nargo.toml b/noir/test_programs/compile_failure/assert_eq_struct/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/Nargo.toml rename to noir/test_programs/compile_failure/assert_eq_struct/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/src/main.nr b/noir/test_programs/compile_failure/assert_eq_struct/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/assert_eq_struct/src/main.nr rename to noir/test_programs/compile_failure/assert_eq_struct/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml b/noir/test_programs/compile_failure/brillig_assert_fail/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Nargo.toml rename to noir/test_programs/compile_failure/brillig_assert_fail/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml b/noir/test_programs/compile_failure/brillig_assert_fail/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/Prover.toml rename to noir/test_programs/compile_failure/brillig_assert_fail/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr b/noir/test_programs/compile_failure/brillig_assert_fail/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/brillig_assert_fail/src/main.nr rename to noir/test_programs/compile_failure/brillig_assert_fail/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml b/noir/test_programs/compile_failure/constrain_typo/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/constrain_typo/Nargo.toml rename to noir/test_programs/compile_failure/constrain_typo/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr b/noir/test_programs/compile_failure/constrain_typo/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/constrain_typo/src/main.nr rename to noir/test_programs/compile_failure/constrain_typo/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml b/noir/test_programs/compile_failure/custom_entry_not_found/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Nargo.toml rename to noir/test_programs/compile_failure/custom_entry_not_found/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml b/noir/test_programs/compile_failure/custom_entry_not_found/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/Prover.toml rename to noir/test_programs/compile_failure/custom_entry_not_found/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr b/noir/test_programs/compile_failure/custom_entry_not_found/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/custom_entry_not_found/src/main.nr rename to noir/test_programs/compile_failure/custom_entry_not_found/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml b/noir/test_programs/compile_failure/dep_impl_primitive/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Nargo.toml rename to noir/test_programs/compile_failure/dep_impl_primitive/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml b/noir/test_programs/compile_failure/dep_impl_primitive/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/Prover.toml rename to noir/test_programs/compile_failure/dep_impl_primitive/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr b/noir/test_programs/compile_failure/dep_impl_primitive/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dep_impl_primitive/src/main.nr rename to noir/test_programs/compile_failure/dep_impl_primitive/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml b/noir/test_programs/compile_failure/depend_on_bin/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Nargo.toml rename to noir/test_programs/compile_failure/depend_on_bin/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml b/noir/test_programs/compile_failure/depend_on_bin/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/Prover.toml rename to noir/test_programs/compile_failure/depend_on_bin/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr b/noir/test_programs/compile_failure/depend_on_bin/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/depend_on_bin/src/main.nr rename to noir/test_programs/compile_failure/depend_on_bin/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Nargo.toml b/noir/test_programs/compile_failure/div_by_zero_constants/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Nargo.toml rename to noir/test_programs/compile_failure/div_by_zero_constants/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Prover.toml b/noir/test_programs/compile_failure/div_by_zero_constants/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/Prover.toml rename to noir/test_programs/compile_failure/div_by_zero_constants/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/src/main.nr b/noir/test_programs/compile_failure/div_by_zero_constants/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_constants/src/main.nr rename to noir/test_programs/compile_failure/div_by_zero_constants/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Nargo.toml b/noir/test_programs/compile_failure/div_by_zero_modulo/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Nargo.toml rename to noir/test_programs/compile_failure/div_by_zero_modulo/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Prover.toml b/noir/test_programs/compile_failure/div_by_zero_modulo/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/Prover.toml rename to noir/test_programs/compile_failure/div_by_zero_modulo/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/src/main.nr b/noir/test_programs/compile_failure/div_by_zero_modulo/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_modulo/src/main.nr rename to noir/test_programs/compile_failure/div_by_zero_modulo/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Nargo.toml b/noir/test_programs/compile_failure/div_by_zero_numerator_witness/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Nargo.toml rename to noir/test_programs/compile_failure/div_by_zero_numerator_witness/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Prover.toml b/noir/test_programs/compile_failure/div_by_zero_numerator_witness/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/Prover.toml rename to noir/test_programs/compile_failure/div_by_zero_numerator_witness/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/src/main.nr b/noir/test_programs/compile_failure/div_by_zero_numerator_witness/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_numerator_witness/src/main.nr rename to noir/test_programs/compile_failure/div_by_zero_numerator_witness/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Nargo.toml b/noir/test_programs/compile_failure/div_by_zero_witness/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Nargo.toml rename to noir/test_programs/compile_failure/div_by_zero_witness/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Prover.toml b/noir/test_programs/compile_failure/div_by_zero_witness/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/Prover.toml rename to noir/test_programs/compile_failure/div_by_zero_witness/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/src/main.nr b/noir/test_programs/compile_failure/div_by_zero_witness/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/div_by_zero_witness/src/main.nr rename to noir/test_programs/compile_failure/div_by_zero_witness/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_implementation_4/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_implementation_4/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/Prover.toml b/noir/test_programs/compile_failure/dup_trait_implementation_4/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_implementation_4/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/main.nr b/noir/test_programs/compile_failure/dup_trait_implementation_4/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_4/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module1.nr b/noir/test_programs/compile_failure/dup_trait_implementation_4/src/module1.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module1.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_4/src/module1.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module2.nr b/noir/test_programs/compile_failure/dup_trait_implementation_4/src/module2.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module2.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_4/src/module2.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module3.nr b/noir/test_programs/compile_failure/dup_trait_implementation_4/src/module3.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_4/src/module3.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_4/src/module3.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_implementation_5/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_implementation_5/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/Prover.toml b/noir/test_programs/compile_failure/dup_trait_implementation_5/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_implementation_5/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/main.nr b/noir/test_programs/compile_failure/dup_trait_implementation_5/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_5/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module1.nr b/noir/test_programs/compile_failure/dup_trait_implementation_5/src/module1.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module1.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_5/src/module1.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module2.nr b/noir/test_programs/compile_failure/dup_trait_implementation_5/src/module2.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module2.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_5/src/module2.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module3.nr b/noir/test_programs/compile_failure/dup_trait_implementation_5/src/module3.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module3.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_5/src/module3.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module4.nr b/noir/test_programs/compile_failure/dup_trait_implementation_5/src/module4.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_implementation_5/src/module4.nr rename to noir/test_programs/compile_failure/dup_trait_implementation_5/src/module4.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_1/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_1/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_1/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_1/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_1/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_2/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_2/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_2/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_2/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_2/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_3/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_3/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_3/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_3/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_3/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_3/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_3/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_4/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_4/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_4/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_4/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_4/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_4/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_4/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_5/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_5/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_5/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_5/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_5/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_5/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_5/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/Nargo.toml b/noir/test_programs/compile_failure/dup_trait_items_6/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/Nargo.toml rename to noir/test_programs/compile_failure/dup_trait_items_6/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/Prover.toml b/noir/test_programs/compile_failure/dup_trait_items_6/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/Prover.toml rename to noir/test_programs/compile_failure/dup_trait_items_6/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/src/main.nr b/noir/test_programs/compile_failure/dup_trait_items_6/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dup_trait_items_6/src/main.nr rename to noir/test_programs/compile_failure/dup_trait_items_6/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml b/noir/test_programs/compile_failure/duplicate_declaration/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/Nargo.toml rename to noir/test_programs/compile_failure/duplicate_declaration/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr b/noir/test_programs/compile_failure/duplicate_declaration/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/duplicate_declaration/src/main.nr rename to noir/test_programs/compile_failure/duplicate_declaration/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/Nargo.toml b/noir/test_programs/compile_failure/dyn_index_fail_nested_array/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/Nargo.toml rename to noir/test_programs/compile_failure/dyn_index_fail_nested_array/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/Prover.toml b/noir/test_programs/compile_failure/dyn_index_fail_nested_array/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/Prover.toml rename to noir/test_programs/compile_failure/dyn_index_fail_nested_array/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/src/main.nr b/noir/test_programs/compile_failure/dyn_index_fail_nested_array/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dyn_index_fail_nested_array/src/main.nr rename to noir/test_programs/compile_failure/dyn_index_fail_nested_array/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml b/noir/test_programs/compile_failure/dynamic_index_failure/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Nargo.toml rename to noir/test_programs/compile_failure/dynamic_index_failure/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml b/noir/test_programs/compile_failure/dynamic_index_failure/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/Prover.toml rename to noir/test_programs/compile_failure/dynamic_index_failure/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr b/noir/test_programs/compile_failure/dynamic_index_failure/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/dynamic_index_failure/src/main.nr rename to noir/test_programs/compile_failure/dynamic_index_failure/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/field_modulo/Nargo.toml b/noir/test_programs/compile_failure/field_modulo/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/field_modulo/Nargo.toml rename to noir/test_programs/compile_failure/field_modulo/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/field_modulo/src/main.nr b/noir/test_programs/compile_failure/field_modulo/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/field_modulo/src/main.nr rename to noir/test_programs/compile_failure/field_modulo/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/integer_literal_overflow/Nargo.toml b/noir/test_programs/compile_failure/integer_literal_overflow/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/integer_literal_overflow/Nargo.toml rename to noir/test_programs/compile_failure/integer_literal_overflow/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/integer_literal_overflow/src/main.nr b/noir/test_programs/compile_failure/integer_literal_overflow/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/integer_literal_overflow/src/main.nr rename to noir/test_programs/compile_failure/integer_literal_overflow/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml b/noir/test_programs/compile_failure/invalid_dependency_name/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/Nargo.toml rename to noir/test_programs/compile_failure/invalid_dependency_name/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr b/noir/test_programs/compile_failure/invalid_dependency_name/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/invalid_dependency_name/src/main.nr rename to noir/test_programs/compile_failure/invalid_dependency_name/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/multiple_contracts/Nargo.toml b/noir/test_programs/compile_failure/multiple_contracts/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/multiple_contracts/Nargo.toml rename to noir/test_programs/compile_failure/multiple_contracts/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/multiple_contracts/src/main.nr b/noir/test_programs/compile_failure/multiple_contracts/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/multiple_contracts/src/main.nr rename to noir/test_programs/compile_failure/multiple_contracts/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/Nargo.toml b/noir/test_programs/compile_failure/multiple_primary_attributes_fail/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/Nargo.toml rename to noir/test_programs/compile_failure/multiple_primary_attributes_fail/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/src/main.nr b/noir/test_programs/compile_failure/multiple_primary_attributes_fail/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/multiple_primary_attributes_fail/src/main.nr rename to noir/test_programs/compile_failure/multiple_primary_attributes_fail/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/mutability_regression_2911/Nargo.toml b/noir/test_programs/compile_failure/mutability_regression_2911/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/mutability_regression_2911/Nargo.toml rename to noir/test_programs/compile_failure/mutability_regression_2911/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/mutability_regression_2911/src/main.nr b/noir/test_programs/compile_failure/mutability_regression_2911/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/mutability_regression_2911/src/main.nr rename to noir/test_programs/compile_failure/mutability_regression_2911/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/no_impl_from_function/Nargo.toml b/noir/test_programs/compile_failure/no_impl_from_function/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/no_impl_from_function/Nargo.toml rename to noir/test_programs/compile_failure/no_impl_from_function/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/no_impl_from_function/src/main.nr b/noir/test_programs/compile_failure/no_impl_from_function/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/no_impl_from_function/src/main.nr rename to noir/test_programs/compile_failure/no_impl_from_function/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/no_nested_impl/Nargo.toml b/noir/test_programs/compile_failure/no_nested_impl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/no_nested_impl/Nargo.toml rename to noir/test_programs/compile_failure/no_nested_impl/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/no_nested_impl/src/main.nr b/noir/test_programs/compile_failure/no_nested_impl/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/no_nested_impl/src/main.nr rename to noir/test_programs/compile_failure/no_nested_impl/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/Nargo.toml b/noir/test_programs/compile_failure/orphaned_trait_impl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/Nargo.toml rename to noir/test_programs/compile_failure/orphaned_trait_impl/Nargo.toml diff --git a/noir/compiler/integration-tests/circuits/main/Prover.toml b/noir/test_programs/compile_failure/orphaned_trait_impl/Prover.toml similarity index 100% rename from noir/compiler/integration-tests/circuits/main/Prover.toml rename to noir/test_programs/compile_failure/orphaned_trait_impl/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate1/Nargo.toml b/noir/test_programs/compile_failure/orphaned_trait_impl/crate1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate1/Nargo.toml rename to noir/test_programs/compile_failure/orphaned_trait_impl/crate1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate1/src/lib.nr b/noir/test_programs/compile_failure/orphaned_trait_impl/crate1/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate1/src/lib.nr rename to noir/test_programs/compile_failure/orphaned_trait_impl/crate1/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate2/Nargo.toml b/noir/test_programs/compile_failure/orphaned_trait_impl/crate2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate2/Nargo.toml rename to noir/test_programs/compile_failure/orphaned_trait_impl/crate2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate2/src/lib.nr b/noir/test_programs/compile_failure/orphaned_trait_impl/crate2/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/crate2/src/lib.nr rename to noir/test_programs/compile_failure/orphaned_trait_impl/crate2/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/src/main.nr b/noir/test_programs/compile_failure/orphaned_trait_impl/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/src/main.nr rename to noir/test_programs/compile_failure/orphaned_trait_impl/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml b/noir/test_programs/compile_failure/overflowing_assignment/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/Nargo.toml rename to noir/test_programs/compile_failure/overflowing_assignment/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr b/noir/test_programs/compile_failure/overflowing_assignment/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/overflowing_assignment/src/main.nr rename to noir/test_programs/compile_failure/overflowing_assignment/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/overlapping_generic_impls/Nargo.toml b/noir/test_programs/compile_failure/overlapping_generic_impls/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/overlapping_generic_impls/Nargo.toml rename to noir/test_programs/compile_failure/overlapping_generic_impls/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/overlapping_generic_impls/src/main.nr b/noir/test_programs/compile_failure/overlapping_generic_impls/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/overlapping_generic_impls/src/main.nr rename to noir/test_programs/compile_failure/overlapping_generic_impls/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml b/noir/test_programs/compile_failure/package_name_empty/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/package_name_empty/Nargo.toml rename to noir/test_programs/compile_failure/package_name_empty/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr b/noir/test_programs/compile_failure/package_name_empty/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/package_name_empty/src/main.nr rename to noir/test_programs/compile_failure/package_name_empty/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml b/noir/test_programs/compile_failure/package_name_hyphen/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/Nargo.toml rename to noir/test_programs/compile_failure/package_name_hyphen/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr b/noir/test_programs/compile_failure/package_name_hyphen/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/package_name_hyphen/src/main.nr rename to noir/test_programs/compile_failure/package_name_hyphen/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/primary_attribute_struct/Nargo.toml b/noir/test_programs/compile_failure/primary_attribute_struct/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/primary_attribute_struct/Nargo.toml rename to noir/test_programs/compile_failure/primary_attribute_struct/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/primary_attribute_struct/src/main.nr b/noir/test_programs/compile_failure/primary_attribute_struct/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/primary_attribute_struct/src/main.nr rename to noir/test_programs/compile_failure/primary_attribute_struct/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/Nargo.toml b/noir/test_programs/compile_failure/radix_non_constant_length/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/Nargo.toml rename to noir/test_programs/compile_failure/radix_non_constant_length/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/Prover.toml b/noir/test_programs/compile_failure/radix_non_constant_length/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/Prover.toml rename to noir/test_programs/compile_failure/radix_non_constant_length/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/src/main.nr b/noir/test_programs/compile_failure/radix_non_constant_length/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/radix_non_constant_length/src/main.nr rename to noir/test_programs/compile_failure/radix_non_constant_length/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml b/noir/test_programs/compile_failure/slice_access_failure/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Nargo.toml rename to noir/test_programs/compile_failure/slice_access_failure/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml b/noir/test_programs/compile_failure/slice_access_failure/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/Prover.toml rename to noir/test_programs/compile_failure/slice_access_failure/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr b/noir/test_programs/compile_failure/slice_access_failure/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_access_failure/src/main.nr rename to noir/test_programs/compile_failure/slice_access_failure/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/Nargo.toml b/noir/test_programs/compile_failure/slice_insert_failure/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/Nargo.toml rename to noir/test_programs/compile_failure/slice_insert_failure/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/Prover.toml b/noir/test_programs/compile_failure/slice_insert_failure/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/Prover.toml rename to noir/test_programs/compile_failure/slice_insert_failure/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/src/main.nr b/noir/test_programs/compile_failure/slice_insert_failure/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_insert_failure/src/main.nr rename to noir/test_programs/compile_failure/slice_insert_failure/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/Nargo.toml b/noir/test_programs/compile_failure/slice_remove_failure/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/Nargo.toml rename to noir/test_programs/compile_failure/slice_remove_failure/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/Prover.toml b/noir/test_programs/compile_failure/slice_remove_failure/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/Prover.toml rename to noir/test_programs/compile_failure/slice_remove_failure/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/src/main.nr b/noir/test_programs/compile_failure/slice_remove_failure/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/slice_remove_failure/src/main.nr rename to noir/test_programs/compile_failure/slice_remove_failure/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/trait_incorrect_generic_count/Nargo.toml b/noir/test_programs/compile_failure/trait_incorrect_generic_count/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/trait_incorrect_generic_count/Nargo.toml rename to noir/test_programs/compile_failure/trait_incorrect_generic_count/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/trait_incorrect_generic_count/src/main.nr b/noir/test_programs/compile_failure/trait_incorrect_generic_count/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/trait_incorrect_generic_count/src/main.nr rename to noir/test_programs/compile_failure/trait_incorrect_generic_count/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml b/noir/test_programs/compile_failure/workspace_fail/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/Nargo.toml rename to noir/test_programs/compile_failure/workspace_fail/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml b/noir/test_programs/compile_failure/workspace_fail/crates/a/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Nargo.toml rename to noir/test_programs/compile_failure/workspace_fail/crates/a/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml b/noir/test_programs/compile_failure/workspace_fail/crates/a/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/Prover.toml rename to noir/test_programs/compile_failure/workspace_fail/crates/a/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr b/noir/test_programs/compile_failure/workspace_fail/crates/a/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/a/src/main.nr rename to noir/test_programs/compile_failure/workspace_fail/crates/a/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml b/noir/test_programs/compile_failure/workspace_fail/crates/b/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Nargo.toml rename to noir/test_programs/compile_failure/workspace_fail/crates/b/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml b/noir/test_programs/compile_failure/workspace_fail/crates/b/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/Prover.toml rename to noir/test_programs/compile_failure/workspace_fail/crates/b/Prover.toml diff --git a/noir/compiler/integration-tests/circuits/main/src/main.nr b/noir/test_programs/compile_failure/workspace_fail/crates/b/src/main.nr similarity index 100% rename from noir/compiler/integration-tests/circuits/main/src/main.nr rename to noir/test_programs/compile_failure/workspace_fail/crates/b/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml b/noir/test_programs/compile_failure/workspace_missing_toml/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/Nargo.toml rename to noir/test_programs/compile_failure/workspace_missing_toml/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml b/noir/test_programs/compile_failure/workspace_missing_toml/crates/a/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/Prover.toml rename to noir/test_programs/compile_failure/workspace_missing_toml/crates/a/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr b/noir/test_programs/compile_failure/workspace_missing_toml/crates/a/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/src/main.nr rename to noir/test_programs/compile_failure/workspace_missing_toml/crates/a/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml b/noir/test_programs/compile_failure/workspace_missing_toml/crates/b/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Nargo.toml rename to noir/test_programs/compile_failure/workspace_missing_toml/crates/b/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml b/noir/test_programs/compile_failure/workspace_missing_toml/crates/b/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/Prover.toml rename to noir/test_programs/compile_failure/workspace_missing_toml/crates/b/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr b/noir/test_programs/compile_failure/workspace_missing_toml/crates/b/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_fail/crates/b/src/main.nr rename to noir/test_programs/compile_failure/workspace_missing_toml/crates/b/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/contract_with_impl/Nargo.toml b/noir/test_programs/compile_success_contract/contract_with_impl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/contract_with_impl/Nargo.toml rename to noir/test_programs/compile_success_contract/contract_with_impl/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/contract_with_impl/src/main.nr b/noir/test_programs/compile_success_contract/contract_with_impl/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/contract_with_impl/src/main.nr rename to noir/test_programs/compile_success_contract/contract_with_impl/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/non_entry_point_method/Nargo.toml b/noir/test_programs/compile_success_contract/non_entry_point_method/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/non_entry_point_method/Nargo.toml rename to noir/test_programs/compile_success_contract/non_entry_point_method/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/non_entry_point_method/src/main.nr b/noir/test_programs/compile_success_contract/non_entry_point_method/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/non_entry_point_method/src/main.nr rename to noir/test_programs/compile_success_contract/non_entry_point_method/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml b/noir/test_programs/compile_success_contract/simple_contract/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/simple_contract/Nargo.toml rename to noir/test_programs/compile_success_contract/simple_contract/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr b/noir/test_programs/compile_success_contract/simple_contract/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_contract/simple_contract/src/main.nr rename to noir/test_programs/compile_success_contract/simple_contract/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/Nargo.toml b/noir/test_programs/compile_success_empty/attributes_multiple/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/Nargo.toml rename to noir/test_programs/compile_success_empty/attributes_multiple/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/src/main.nr b/noir/test_programs/compile_success_empty/attributes_multiple/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/attributes_multiple/src/main.nr rename to noir/test_programs/compile_success_empty/attributes_multiple/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/attributes_struct/Nargo.toml b/noir/test_programs/compile_success_empty/attributes_struct/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/attributes_struct/Nargo.toml rename to noir/test_programs/compile_success_empty/attributes_struct/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/attributes_struct/src/main.nr b/noir/test_programs/compile_success_empty/attributes_struct/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/attributes_struct/src/main.nr rename to noir/test_programs/compile_success_empty/attributes_struct/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/auto_deref/Nargo.toml b/noir/test_programs/compile_success_empty/auto_deref/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/auto_deref/Nargo.toml rename to noir/test_programs/compile_success_empty/auto_deref/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/auto_deref/src/main.nr b/noir/test_programs/compile_success_empty/auto_deref/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/auto_deref/src/main.nr rename to noir/test_programs/compile_success_empty/auto_deref/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml b/noir/test_programs/compile_success_empty/brillig_cast/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/Nargo.toml rename to noir/test_programs/compile_success_empty/brillig_cast/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr b/noir/test_programs/compile_success_empty/brillig_cast/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_cast/src/main.nr rename to noir/test_programs/compile_success_empty/brillig_cast/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml b/noir/test_programs/compile_success_empty/brillig_field_binary_operations/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Nargo.toml rename to noir/test_programs/compile_success_empty/brillig_field_binary_operations/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml b/noir/test_programs/compile_success_empty/brillig_field_binary_operations/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/Prover.toml rename to noir/test_programs/compile_success_empty/brillig_field_binary_operations/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr b/noir/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_field_binary_operations/src/main.nr rename to noir/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml b/noir/test_programs/compile_success_empty/brillig_integer_binary_operations/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Nargo.toml rename to noir/test_programs/compile_success_empty/brillig_integer_binary_operations/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml b/noir/test_programs/compile_success_empty/brillig_integer_binary_operations/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/Prover.toml rename to noir/test_programs/compile_success_empty/brillig_integer_binary_operations/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr b/noir/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_integer_binary_operations/src/main.nr rename to noir/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml b/noir/test_programs/compile_success_empty/brillig_modulo/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Nargo.toml rename to noir/test_programs/compile_success_empty/brillig_modulo/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml b/noir/test_programs/compile_success_empty/brillig_modulo/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/Prover.toml rename to noir/test_programs/compile_success_empty/brillig_modulo/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr b/noir/test_programs/compile_success_empty/brillig_modulo/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_modulo/src/main.nr rename to noir/test_programs/compile_success_empty/brillig_modulo/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml b/noir/test_programs/compile_success_empty/brillig_to_bits/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/Nargo.toml rename to noir/test_programs/compile_success_empty/brillig_to_bits/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr b/noir/test_programs/compile_success_empty/brillig_to_bits/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/brillig_to_bits/src/main.nr rename to noir/test_programs/compile_success_empty/brillig_to_bits/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml b/noir/test_programs/compile_success_empty/closure_explicit_types/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/Nargo.toml rename to noir/test_programs/compile_success_empty/closure_explicit_types/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr b/noir/test_programs/compile_success_empty/closure_explicit_types/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/closure_explicit_types/src/main.nr rename to noir/test_programs/compile_success_empty/closure_explicit_types/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml b/noir/test_programs/compile_success_empty/comptime_recursion_regression/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Nargo.toml rename to noir/test_programs/compile_success_empty/comptime_recursion_regression/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml b/noir/test_programs/compile_success_empty/comptime_recursion_regression/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/Prover.toml rename to noir/test_programs/compile_success_empty/comptime_recursion_regression/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr b/noir/test_programs/compile_success_empty/comptime_recursion_regression/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/comptime_recursion_regression/src/main.nr rename to noir/test_programs/compile_success_empty/comptime_recursion_regression/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml b/noir/test_programs/compile_success_empty/comptime_sort/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/Nargo.toml rename to noir/test_programs/compile_success_empty/comptime_sort/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr b/noir/test_programs/compile_success_empty/comptime_sort/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/comptime_sort/src/main.nr rename to noir/test_programs/compile_success_empty/comptime_sort/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/Nargo.toml b/noir/test_programs/compile_success_empty/conditional_regression_547/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/Nargo.toml rename to noir/test_programs/compile_success_empty/conditional_regression_547/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/Prover.toml b/noir/test_programs/compile_success_empty/conditional_regression_547/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/Prover.toml rename to noir/test_programs/compile_success_empty/conditional_regression_547/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/src/main.nr b/noir/test_programs/compile_success_empty/conditional_regression_547/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_547/src/main.nr rename to noir/test_programs/compile_success_empty/conditional_regression_547/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/Nargo.toml b/noir/test_programs/compile_success_empty/conditional_regression_579/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/Nargo.toml rename to noir/test_programs/compile_success_empty/conditional_regression_579/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/Prover.toml b/noir/test_programs/compile_success_empty/conditional_regression_579/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/Prover.toml rename to noir/test_programs/compile_success_empty/conditional_regression_579/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/src/main.nr b/noir/test_programs/compile_success_empty/conditional_regression_579/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_579/src/main.nr rename to noir/test_programs/compile_success_empty/conditional_regression_579/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/Nargo.toml b/noir/test_programs/compile_success_empty/conditional_regression_to_bits/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/Nargo.toml rename to noir/test_programs/compile_success_empty/conditional_regression_to_bits/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/Prover.toml b/noir/test_programs/compile_success_empty/conditional_regression_to_bits/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/Prover.toml rename to noir/test_programs/compile_success_empty/conditional_regression_to_bits/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/src/main.nr b/noir/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/conditional_regression_to_bits/src/main.nr rename to noir/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml b/noir/test_programs/compile_success_empty/ec_baby_jubjub/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/Nargo.toml rename to noir/test_programs/compile_success_empty/ec_baby_jubjub/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr b/noir/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr similarity index 79% rename from noir/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr rename to noir/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr index 05a186be478..becd3c8927a 100644 --- a/noir/tooling/nargo_cli/tests/compile_success_empty/ec_baby_jubjub/src/main.nr +++ b/noir/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr @@ -33,31 +33,37 @@ fn main() { ); let p3_affine = bjj_affine.add(p1_affine, p2_affine); - assert(p3_affine.eq( - Gaffine::new( - 7916061937171219682591368294088513039687205273691143098332585753343424131937, - 14035240266687799601661095864649209771790948434046947201833777492504781204499 + assert( + p3_affine.eq( + Gaffine::new( + 7916061937171219682591368294088513039687205273691143098332585753343424131937, + 14035240266687799601661095864649209771790948434046947201833777492504781204499 + ) ) - )); + ); // Test scalar multiplication let p4_affine = bjj_affine.mul(2, p1_affine); - assert(p4_affine.eq( - Gaffine::new( - 6890855772600357754907169075114257697580319025794532037257385534741338397365, - 4338620300185947561074059802482547481416142213883829469920100239455078257889 + assert( + p4_affine.eq( + Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889 + ) ) - )); + ); assert(p4_affine.eq(bjj_affine.bit_mul([0, 1], p1_affine))); // Test subtraction let p5_affine = bjj_affine.subtract(p3_affine, p3_affine); assert(p5_affine.eq(Gaffine::zero())); // Check that these points are on the curve - assert(bjj_affine.contains(bjj_affine.gen) + assert( + bjj_affine.contains(bjj_affine.gen) & bjj_affine.contains(p1_affine) & bjj_affine.contains(p2_affine) & bjj_affine.contains(p3_affine) & bjj_affine.contains(p4_affine) - & bjj_affine.contains(p5_affine)); + & bjj_affine.contains(p5_affine) + ); // Test CurveGroup equivalents let bjj = bjj_affine.into_group(); // Baby Jubjub let p1 = p1_affine.into_group(); @@ -74,12 +80,14 @@ fn main() { assert(G::zero().eq(bjj.subtract(p3, p3))); assert(p5.eq(G::zero())); // Check that these points are on the curve - assert(bjj.contains(bjj.gen) + assert( + bjj.contains(bjj.gen) & bjj.contains(p1) & bjj.contains(p2) & bjj.contains(p3) & bjj.contains(p4) - & bjj.contains(p5)); + & bjj.contains(p5) + ); // Test SWCurve equivalents of the above // First the affine representation let bjj_swcurve_affine = bjj_affine.into_swcurve(); @@ -98,12 +106,14 @@ fn main() { assert(SWGaffine::zero().eq(bjj_swcurve_affine.subtract(p3_swcurve_affine, p3_swcurve_affine))); assert(p5_swcurve_affine.eq(SWGaffine::zero())); // Check that these points are on the curve - assert(bjj_swcurve_affine.contains(bjj_swcurve_affine.gen) + assert( + bjj_swcurve_affine.contains(bjj_swcurve_affine.gen) & bjj_swcurve_affine.contains(p1_swcurve_affine) & bjj_swcurve_affine.contains(p2_swcurve_affine) & bjj_swcurve_affine.contains(p3_swcurve_affine) & bjj_swcurve_affine.contains(p4_swcurve_affine) - & bjj_swcurve_affine.contains(p5_swcurve_affine)); + & bjj_swcurve_affine.contains(p5_swcurve_affine) + ); // Then the CurveGroup representation let bjj_swcurve = bjj.into_swcurve(); @@ -121,12 +131,14 @@ fn main() { assert(SWG::zero().eq(bjj_swcurve.subtract(p3_swcurve, p3_swcurve))); assert(p5_swcurve.eq(SWG::zero())); // Check that these points are on the curve - assert(bjj_swcurve.contains(bjj_swcurve.gen) + assert( + bjj_swcurve.contains(bjj_swcurve.gen) & bjj_swcurve.contains(p1_swcurve) & bjj_swcurve.contains(p2_swcurve) & bjj_swcurve.contains(p3_swcurve) & bjj_swcurve.contains(p4_swcurve) - & bjj_swcurve.contains(p5_swcurve)); + & bjj_swcurve.contains(p5_swcurve) + ); // Test MontCurve conversions // First the affine representation let bjj_montcurve_affine = bjj_affine.into_montcurve(); @@ -145,12 +157,14 @@ fn main() { assert(MGaffine::zero().eq(bjj_montcurve_affine.subtract(p3_montcurve_affine, p3_montcurve_affine))); assert(p5_montcurve_affine.eq(MGaffine::zero())); // Check that these points are on the curve - assert(bjj_montcurve_affine.contains(bjj_montcurve_affine.gen) + assert( + bjj_montcurve_affine.contains(bjj_montcurve_affine.gen) & bjj_montcurve_affine.contains(p1_montcurve_affine) & bjj_montcurve_affine.contains(p2_montcurve_affine) & bjj_montcurve_affine.contains(p3_montcurve_affine) & bjj_montcurve_affine.contains(p4_montcurve_affine) - & bjj_montcurve_affine.contains(p5_montcurve_affine)); + & bjj_montcurve_affine.contains(p5_montcurve_affine) + ); // Then the CurveGroup representation let bjj_montcurve = bjj.into_montcurve(); @@ -168,31 +182,37 @@ fn main() { assert(MG::zero().eq(bjj_montcurve.subtract(p3_montcurve, p3_montcurve))); assert(p5_montcurve.eq(MG::zero())); // Check that these points are on the curve - assert(bjj_montcurve.contains(bjj_montcurve.gen) + assert( + bjj_montcurve.contains(bjj_montcurve.gen) & bjj_montcurve.contains(p1_montcurve) & bjj_montcurve.contains(p2_montcurve) & bjj_montcurve.contains(p3_montcurve) & bjj_montcurve.contains(p4_montcurve) - & bjj_montcurve.contains(p5_montcurve)); + & bjj_montcurve.contains(p5_montcurve) + ); // Elligator 2 map-to-curve let ell2_pt_map = bjj_affine.elligator2_map(27); - assert(ell2_pt_map.eq( - MGaffine::new( - 7972459279704486422145701269802978968072470631857513331988813812334797879121, - 8142420778878030219043334189293412482212146646099536952861607542822144507872 - ).into_tecurve() - )); + assert( + ell2_pt_map.eq( + MGaffine::new( + 7972459279704486422145701269802978968072470631857513331988813812334797879121, + 8142420778878030219043334189293412482212146646099536952861607542822144507872 + ).into_tecurve() + ) + ); // SWU map-to-curve let swu_pt_map = bjj_affine.swu_map(5, 27); - assert(swu_pt_map.eq( - bjj_affine.map_from_swcurve( - SWGaffine::new( - 2162719247815120009132293839392097468339661471129795280520343931405114293888, - 5341392251743377373758788728206293080122949448990104760111875914082289313973 + assert( + swu_pt_map.eq( + bjj_affine.map_from_swcurve( + SWGaffine::new( + 2162719247815120009132293839392097468339661471129795280520343931405114293888, + 5341392251743377373758788728206293080122949448990104760111875914082289313973 + ) ) ) - )); + ); } } diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/generators/Nargo.toml b/noir/test_programs/compile_success_empty/generators/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/generators/Nargo.toml rename to noir/test_programs/compile_success_empty/generators/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/generators/src/main.nr b/noir/test_programs/compile_success_empty/generators/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/generators/src/main.nr rename to noir/test_programs/compile_success_empty/generators/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml b/noir/test_programs/compile_success_empty/higher_order_fn_selector/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/Nargo.toml rename to noir/test_programs/compile_success_empty/higher_order_fn_selector/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr b/noir/test_programs/compile_success_empty/higher_order_fn_selector/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/higher_order_fn_selector/src/main.nr rename to noir/test_programs/compile_success_empty/higher_order_fn_selector/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/impl_with_where_clause/Nargo.toml b/noir/test_programs/compile_success_empty/impl_with_where_clause/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/impl_with_where_clause/Nargo.toml rename to noir/test_programs/compile_success_empty/impl_with_where_clause/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/impl_with_where_clause/src/main.nr b/noir/test_programs/compile_success_empty/impl_with_where_clause/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/impl_with_where_clause/src/main.nr rename to noir/test_programs/compile_success_empty/impl_with_where_clause/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml b/noir/test_programs/compile_success_empty/inner_outer_cl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/Nargo.toml rename to noir/test_programs/compile_success_empty/inner_outer_cl/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr b/noir/test_programs/compile_success_empty/inner_outer_cl/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/inner_outer_cl/src/main.nr rename to noir/test_programs/compile_success_empty/inner_outer_cl/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Nargo.toml b/noir/test_programs/compile_success_empty/instruction_deduplication/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Nargo.toml rename to noir/test_programs/compile_success_empty/instruction_deduplication/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Prover.toml b/noir/test_programs/compile_success_empty/instruction_deduplication/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/Prover.toml rename to noir/test_programs/compile_success_empty/instruction_deduplication/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/src/main.nr b/noir/test_programs/compile_success_empty/instruction_deduplication/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/instruction_deduplication/src/main.nr rename to noir/test_programs/compile_success_empty/instruction_deduplication/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml b/noir/test_programs/compile_success_empty/intrinsic_die/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/Nargo.toml rename to noir/test_programs/compile_success_empty/intrinsic_die/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr b/noir/test_programs/compile_success_empty/intrinsic_die/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/intrinsic_die/src/main.nr rename to noir/test_programs/compile_success_empty/intrinsic_die/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml b/noir/test_programs/compile_success_empty/let_stmt/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Nargo.toml rename to noir/test_programs/compile_success_empty/let_stmt/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml b/noir/test_programs/compile_success_empty/let_stmt/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/Prover.toml rename to noir/test_programs/compile_success_empty/let_stmt/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr b/noir/test_programs/compile_success_empty/let_stmt/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/let_stmt/src/main.nr rename to noir/test_programs/compile_success_empty/let_stmt/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/main_return/Nargo.toml b/noir/test_programs/compile_success_empty/main_return/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/main_return/Nargo.toml rename to noir/test_programs/compile_success_empty/main_return/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/main_return/Prover.toml b/noir/test_programs/compile_success_empty/main_return/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/main_return/Prover.toml rename to noir/test_programs/compile_success_empty/main_return/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/main_return/src/main.nr b/noir/test_programs/compile_success_empty/main_return/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/main_return/src/main.nr rename to noir/test_programs/compile_success_empty/main_return/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml b/noir/test_programs/compile_success_empty/numeric_generics/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Nargo.toml rename to noir/test_programs/compile_success_empty/numeric_generics/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml b/noir/test_programs/compile_success_empty/numeric_generics/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/Prover.toml rename to noir/test_programs/compile_success_empty/numeric_generics/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr b/noir/test_programs/compile_success_empty/numeric_generics/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/numeric_generics/src/main.nr rename to noir/test_programs/compile_success_empty/numeric_generics/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/option/Nargo.toml b/noir/test_programs/compile_success_empty/option/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/option/Nargo.toml rename to noir/test_programs/compile_success_empty/option/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/option/src/main.nr b/noir/test_programs/compile_success_empty/option/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/option/src/main.nr rename to noir/test_programs/compile_success_empty/option/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Nargo.toml b/noir/test_programs/compile_success_empty/references_aliasing/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Nargo.toml rename to noir/test_programs/compile_success_empty/references_aliasing/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Prover.toml b/noir/test_programs/compile_success_empty/references_aliasing/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/Prover.toml rename to noir/test_programs/compile_success_empty/references_aliasing/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/src/main.nr b/noir/test_programs/compile_success_empty/references_aliasing/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/references_aliasing/src/main.nr rename to noir/test_programs/compile_success_empty/references_aliasing/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml b/noir/test_programs/compile_success_empty/regression_2099/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/regression_2099/Nargo.toml rename to noir/test_programs/compile_success_empty/regression_2099/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr b/noir/test_programs/compile_success_empty/regression_2099/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/regression_2099/src/main.nr rename to noir/test_programs/compile_success_empty/regression_2099/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml b/noir/test_programs/compile_success_empty/ret_fn_ret_cl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Nargo.toml rename to noir/test_programs/compile_success_empty/ret_fn_ret_cl/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml b/noir/test_programs/compile_success_empty/ret_fn_ret_cl/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/Prover.toml rename to noir/test_programs/compile_success_empty/ret_fn_ret_cl/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr b/noir/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/ret_fn_ret_cl/src/main.nr rename to noir/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/Nargo.toml b/noir/test_programs/compile_success_empty/simple_array_param/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/Nargo.toml rename to noir/test_programs/compile_success_empty/simple_array_param/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/Prover.toml b/noir/test_programs/compile_success_empty/simple_array_param/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/Prover.toml rename to noir/test_programs/compile_success_empty/simple_array_param/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/src/main.nr b/noir/test_programs/compile_success_empty/simple_array_param/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_array_param/src/main.nr rename to noir/test_programs/compile_success_empty/simple_array_param/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Nargo.toml b/noir/test_programs/compile_success_empty/simple_program_no_body/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Nargo.toml rename to noir/test_programs/compile_success_empty/simple_program_no_body/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Prover.toml b/noir/test_programs/compile_success_empty/simple_program_no_body/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/Prover.toml rename to noir/test_programs/compile_success_empty/simple_program_no_body/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/src/main.nr b/noir/test_programs/compile_success_empty/simple_program_no_body/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_program_no_body/src/main.nr rename to noir/test_programs/compile_success_empty/simple_program_no_body/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml b/noir/test_programs/compile_success_empty/simple_range/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/Nargo.toml rename to noir/test_programs/compile_success_empty/simple_range/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml b/noir/test_programs/compile_success_empty/simple_range/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/Prover.toml rename to noir/test_programs/compile_success_empty/simple_range/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr b/noir/test_programs/compile_success_empty/simple_range/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/simple_range/src/main.nr rename to noir/test_programs/compile_success_empty/simple_range/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/specialization/Nargo.toml b/noir/test_programs/compile_success_empty/specialization/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/specialization/Nargo.toml rename to noir/test_programs/compile_success_empty/specialization/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/specialization/src/main.nr b/noir/test_programs/compile_success_empty/specialization/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/specialization/src/main.nr rename to noir/test_programs/compile_success_empty/specialization/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml b/noir/test_programs/compile_success_empty/str_as_bytes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/Nargo.toml rename to noir/test_programs/compile_success_empty/str_as_bytes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr b/noir/test_programs/compile_success_empty/str_as_bytes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/str_as_bytes/src/main.nr rename to noir/test_programs/compile_success_empty/str_as_bytes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml b/noir/test_programs/compile_success_empty/to_bits/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/to_bits/Nargo.toml rename to noir/test_programs/compile_success_empty/to_bits/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr b/noir/test_programs/compile_success_empty/to_bits/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/to_bits/src/main.nr rename to noir/test_programs/compile_success_empty/to_bits/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/Nargo.toml b/noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/Prover.toml b/noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/Prover.toml rename to noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/src/main.nr b/noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_allowed_item_name_matches/src/main.nr rename to noir/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/Nargo.toml b/noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/Prover.toml b/noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/Prover.toml rename to noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/src/main.nr b/noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_associated_member_names_clashes/src/main.nr rename to noir/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/Nargo.toml b/noir/test_programs/compile_success_empty/trait_default_implementation/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_default_implementation/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/Prover.toml b/noir/test_programs/compile_success_empty/trait_default_implementation/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/Prover.toml rename to noir/test_programs/compile_success_empty/trait_default_implementation/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/src/main.nr b/noir/test_programs/compile_success_empty/trait_default_implementation/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_default_implementation/src/main.nr rename to noir/test_programs/compile_success_empty/trait_default_implementation/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/Nargo.toml b/noir/test_programs/compile_success_empty/trait_function_calls/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_function_calls/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/Prover.toml b/noir/test_programs/compile_success_empty/trait_function_calls/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/Prover.toml rename to noir/test_programs/compile_success_empty/trait_function_calls/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/src/main.nr b/noir/test_programs/compile_success_empty/trait_function_calls/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_function_calls/src/main.nr rename to noir/test_programs/compile_success_empty/trait_function_calls/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_generics/Nargo.toml b/noir/test_programs/compile_success_empty/trait_generics/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_generics/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_generics/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_generics/src/main.nr b/noir/test_programs/compile_success_empty/trait_generics/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_generics/src/main.nr rename to noir/test_programs/compile_success_empty/trait_generics/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/Nargo.toml b/noir/test_programs/compile_success_empty/trait_multi_module_test/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_multi_module_test/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/Prover.toml b/noir/test_programs/compile_success_empty/trait_multi_module_test/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/Prover.toml rename to noir/test_programs/compile_success_empty/trait_multi_module_test/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/main.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/main.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module1.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module1.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module2.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module2.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module3.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module3.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module3.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module4.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module4.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module5.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module5.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module6.nr b/noir/test_programs/compile_success_empty/trait_multi_module_test/src/module6.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_multi_module_test/src/module6.nr rename to noir/test_programs/compile_success_empty/trait_multi_module_test/src/module6.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/Nargo.toml b/noir/test_programs/compile_success_empty/trait_override_implementation/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_override_implementation/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/Prover.toml b/noir/test_programs/compile_success_empty/trait_override_implementation/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/Prover.toml rename to noir/test_programs/compile_success_empty/trait_override_implementation/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/src/main.nr b/noir/test_programs/compile_success_empty/trait_override_implementation/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_override_implementation/src/main.nr rename to noir/test_programs/compile_success_empty/trait_override_implementation/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_static_methods/Nargo.toml b/noir/test_programs/compile_success_empty/trait_static_methods/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_static_methods/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_static_methods/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_static_methods/src/main.nr b/noir/test_programs/compile_success_empty/trait_static_methods/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_static_methods/src/main.nr rename to noir/test_programs/compile_success_empty/trait_static_methods/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/Nargo.toml b/noir/test_programs/compile_success_empty/trait_where_clause/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/Nargo.toml rename to noir/test_programs/compile_success_empty/trait_where_clause/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/src/main.nr b/noir/test_programs/compile_success_empty/trait_where_clause/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/src/main.nr rename to noir/test_programs/compile_success_empty/trait_where_clause/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/src/the_trait.nr b/noir/test_programs/compile_success_empty/trait_where_clause/src/the_trait.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/trait_where_clause/src/the_trait.nr rename to noir/test_programs/compile_success_empty/trait_where_clause/src/the_trait.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/traits/Nargo.toml b/noir/test_programs/compile_success_empty/traits/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/traits/Nargo.toml rename to noir/test_programs/compile_success_empty/traits/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/traits/Prover.toml b/noir/test_programs/compile_success_empty/traits/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/traits/Prover.toml rename to noir/test_programs/compile_success_empty/traits/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/traits/src/main.nr b/noir/test_programs/compile_success_empty/traits/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/traits/src/main.nr rename to noir/test_programs/compile_success_empty/traits/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unary_operators/Nargo.toml b/noir/test_programs/compile_success_empty/unary_operators/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unary_operators/Nargo.toml rename to noir/test_programs/compile_success_empty/unary_operators/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unary_operators/src/main.nr b/noir/test_programs/compile_success_empty/unary_operators/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unary_operators/src/main.nr rename to noir/test_programs/compile_success_empty/unary_operators/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml b/noir/test_programs/compile_success_empty/unconstrained_empty/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/Nargo.toml rename to noir/test_programs/compile_success_empty/unconstrained_empty/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr b/noir/test_programs/compile_success_empty/unconstrained_empty/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unconstrained_empty/src/main.nr rename to noir/test_programs/compile_success_empty/unconstrained_empty/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unit/Nargo.toml b/noir/test_programs/compile_success_empty/unit/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unit/Nargo.toml rename to noir/test_programs/compile_success_empty/unit/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unit/src/main.nr b/noir/test_programs/compile_success_empty/unit/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unit/src/main.nr rename to noir/test_programs/compile_success_empty/unit/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml b/noir/test_programs/compile_success_empty/unused_variables/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unused_variables/Nargo.toml rename to noir/test_programs/compile_success_empty/unused_variables/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr b/noir/test_programs/compile_success_empty/unused_variables/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/unused_variables/src/main.nr rename to noir/test_programs/compile_success_empty/unused_variables/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/vectors/Nargo.toml b/noir/test_programs/compile_success_empty/vectors/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/vectors/Nargo.toml rename to noir/test_programs/compile_success_empty/vectors/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/vectors/Prover.toml b/noir/test_programs/compile_success_empty/vectors/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/vectors/Prover.toml rename to noir/test_programs/compile_success_empty/vectors/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/vectors/src/main.nr b/noir/test_programs/compile_success_empty/vectors/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/vectors/src/main.nr rename to noir/test_programs/compile_success_empty/vectors/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/Nargo.toml b/noir/test_programs/compile_success_empty/workspace_reexport_bug/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/Nargo.toml rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/binary/Nargo.toml b/noir/test_programs/compile_success_empty/workspace_reexport_bug/binary/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/binary/Nargo.toml rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/binary/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/binary/src/main.nr b/noir/test_programs/compile_success_empty/workspace_reexport_bug/binary/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/binary/src/main.nr rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/binary/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library/Nargo.toml b/noir/test_programs/compile_success_empty/workspace_reexport_bug/library/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library/Nargo.toml rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/library/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library/src/lib.nr b/noir/test_programs/compile_success_empty/workspace_reexport_bug/library/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library/src/lib.nr rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/library/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library2/Nargo.toml b/noir/test_programs/compile_success_empty/workspace_reexport_bug/library2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library2/Nargo.toml rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/library2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library2/src/lib.nr b/noir/test_programs/compile_success_empty/workspace_reexport_bug/library2/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_success_empty/workspace_reexport_bug/library2/src/lib.nr rename to noir/test_programs/compile_success_empty/workspace_reexport_bug/library2/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml b/noir/test_programs/execution_success/1327_concrete_in_generic/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Nargo.toml rename to noir/test_programs/execution_success/1327_concrete_in_generic/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml b/noir/test_programs/execution_success/1327_concrete_in_generic/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/Prover.toml rename to noir/test_programs/execution_success/1327_concrete_in_generic/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr b/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/1327_concrete_in_generic/src/main.nr rename to noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/1_mul/Nargo.toml b/noir/test_programs/execution_success/1_mul/Nargo.toml similarity index 79% rename from noir/tooling/nargo_cli/tests/execution_success/1_mul/Nargo.toml rename to noir/test_programs/execution_success/1_mul/Nargo.toml index a0fd8d98027..94b36157cca 100644 --- a/noir/tooling/nargo_cli/tests/execution_success/1_mul/Nargo.toml +++ b/noir/test_programs/execution_success/1_mul/Nargo.toml @@ -1,5 +1,6 @@ [package] name = "1_mul" +version = "0.1.0" type = "bin" authors = [""] diff --git a/noir/tooling/nargo_cli/tests/execution_success/1_mul/Prover.toml b/noir/test_programs/execution_success/1_mul/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/1_mul/Prover.toml rename to noir/test_programs/execution_success/1_mul/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/1_mul/src/main.nr b/noir/test_programs/execution_success/1_mul/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/1_mul/src/main.nr rename to noir/test_programs/execution_success/1_mul/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/2_div/Nargo.toml b/noir/test_programs/execution_success/2_div/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/2_div/Nargo.toml rename to noir/test_programs/execution_success/2_div/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/2_div/Prover.toml b/noir/test_programs/execution_success/2_div/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/2_div/Prover.toml rename to noir/test_programs/execution_success/2_div/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/2_div/src/main.nr b/noir/test_programs/execution_success/2_div/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/2_div/src/main.nr rename to noir/test_programs/execution_success/2_div/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/3_add/Nargo.toml b/noir/test_programs/execution_success/3_add/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/3_add/Nargo.toml rename to noir/test_programs/execution_success/3_add/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/3_add/Prover.toml b/noir/test_programs/execution_success/3_add/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/3_add/Prover.toml rename to noir/test_programs/execution_success/3_add/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/3_add/src/main.nr b/noir/test_programs/execution_success/3_add/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/3_add/src/main.nr rename to noir/test_programs/execution_success/3_add/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/4_sub/Nargo.toml b/noir/test_programs/execution_success/4_sub/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/4_sub/Nargo.toml rename to noir/test_programs/execution_success/4_sub/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/4_sub/Prover.toml b/noir/test_programs/execution_success/4_sub/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/4_sub/Prover.toml rename to noir/test_programs/execution_success/4_sub/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/4_sub/src/main.nr b/noir/test_programs/execution_success/4_sub/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/4_sub/src/main.nr rename to noir/test_programs/execution_success/4_sub/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/5_over/Nargo.toml b/noir/test_programs/execution_success/5_over/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/5_over/Nargo.toml rename to noir/test_programs/execution_success/5_over/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/5_over/Prover.toml b/noir/test_programs/execution_success/5_over/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/5_over/Prover.toml rename to noir/test_programs/execution_success/5_over/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/5_over/src/main.nr b/noir/test_programs/execution_success/5_over/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/5_over/src/main.nr rename to noir/test_programs/execution_success/5_over/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/6/Nargo.toml b/noir/test_programs/execution_success/6/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6/Nargo.toml rename to noir/test_programs/execution_success/6/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/6/Prover.toml b/noir/test_programs/execution_success/6/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6/Prover.toml rename to noir/test_programs/execution_success/6/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/6/src/main.nr b/noir/test_programs/execution_success/6/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6/src/main.nr rename to noir/test_programs/execution_success/6/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/6_array/Nargo.toml b/noir/test_programs/execution_success/6_array/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6_array/Nargo.toml rename to noir/test_programs/execution_success/6_array/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/6_array/Prover.toml b/noir/test_programs/execution_success/6_array/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6_array/Prover.toml rename to noir/test_programs/execution_success/6_array/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/6_array/src/main.nr b/noir/test_programs/execution_success/6_array/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/6_array/src/main.nr rename to noir/test_programs/execution_success/6_array/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/7/Nargo.toml b/noir/test_programs/execution_success/7/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7/Nargo.toml rename to noir/test_programs/execution_success/7/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/7/Prover.toml b/noir/test_programs/execution_success/7/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7/Prover.toml rename to noir/test_programs/execution_success/7/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/7/src/main.nr b/noir/test_programs/execution_success/7/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7/src/main.nr rename to noir/test_programs/execution_success/7/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/7_function/Nargo.toml b/noir/test_programs/execution_success/7_function/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7_function/Nargo.toml rename to noir/test_programs/execution_success/7_function/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/7_function/Prover.toml b/noir/test_programs/execution_success/7_function/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7_function/Prover.toml rename to noir/test_programs/execution_success/7_function/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/7_function/src/main.nr b/noir/test_programs/execution_success/7_function/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/7_function/src/main.nr rename to noir/test_programs/execution_success/7_function/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml b/noir/test_programs/execution_success/arithmetic_binary_operations/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Nargo.toml rename to noir/test_programs/execution_success/arithmetic_binary_operations/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml b/noir/test_programs/execution_success/arithmetic_binary_operations/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/Prover.toml rename to noir/test_programs/execution_success/arithmetic_binary_operations/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr b/noir/test_programs/execution_success/arithmetic_binary_operations/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/arithmetic_binary_operations/src/main.nr rename to noir/test_programs/execution_success/arithmetic_binary_operations/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml b/noir/test_programs/execution_success/array_dynamic/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_dynamic/Nargo.toml rename to noir/test_programs/execution_success/array_dynamic/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_dynamic/Prover.toml b/noir/test_programs/execution_success/array_dynamic/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_dynamic/Prover.toml rename to noir/test_programs/execution_success/array_dynamic/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_dynamic/src/main.nr b/noir/test_programs/execution_success/array_dynamic/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_dynamic/src/main.nr rename to noir/test_programs/execution_success/array_dynamic/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_eq/Nargo.toml b/noir/test_programs/execution_success/array_eq/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_eq/Nargo.toml rename to noir/test_programs/execution_success/array_eq/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_eq/Prover.toml b/noir/test_programs/execution_success/array_eq/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_eq/Prover.toml rename to noir/test_programs/execution_success/array_eq/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_eq/src/main.nr b/noir/test_programs/execution_success/array_eq/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_eq/src/main.nr rename to noir/test_programs/execution_success/array_eq/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_len/Nargo.toml b/noir/test_programs/execution_success/array_len/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_len/Nargo.toml rename to noir/test_programs/execution_success/array_len/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_len/Prover.toml b/noir/test_programs/execution_success/array_len/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_len/Prover.toml rename to noir/test_programs/execution_success/array_len/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_len/src/main.nr b/noir/test_programs/execution_success/array_len/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_len/src/main.nr rename to noir/test_programs/execution_success/array_len/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_neq/Nargo.toml b/noir/test_programs/execution_success/array_neq/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_neq/Nargo.toml rename to noir/test_programs/execution_success/array_neq/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_neq/Prover.toml b/noir/test_programs/execution_success/array_neq/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_neq/Prover.toml rename to noir/test_programs/execution_success/array_neq/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_neq/src/main.nr b/noir/test_programs/execution_success/array_neq/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_neq/src/main.nr rename to noir/test_programs/execution_success/array_neq/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_sort/Nargo.toml b/noir/test_programs/execution_success/array_sort/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_sort/Nargo.toml rename to noir/test_programs/execution_success/array_sort/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_sort/Prover.toml b/noir/test_programs/execution_success/array_sort/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_sort/Prover.toml rename to noir/test_programs/execution_success/array_sort/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/array_sort/src/main.nr b/noir/test_programs/execution_success/array_sort/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/array_sort/src/main.nr rename to noir/test_programs/execution_success/array_sort/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert/Nargo.toml b/noir/test_programs/execution_success/assert/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert/Nargo.toml rename to noir/test_programs/execution_success/assert/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert/Prover.toml b/noir/test_programs/execution_success/assert/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert/Prover.toml rename to noir/test_programs/execution_success/assert/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert/src/main.nr b/noir/test_programs/execution_success/assert/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert/src/main.nr rename to noir/test_programs/execution_success/assert/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert_statement/Nargo.toml b/noir/test_programs/execution_success/assert_statement/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert_statement/Nargo.toml rename to noir/test_programs/execution_success/assert_statement/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert_statement/Prover.toml b/noir/test_programs/execution_success/assert_statement/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert_statement/Prover.toml rename to noir/test_programs/execution_success/assert_statement/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assert_statement/src/main.nr b/noir/test_programs/execution_success/assert_statement/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assert_statement/src/main.nr rename to noir/test_programs/execution_success/assert_statement/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/assign_ex/Nargo.toml b/noir/test_programs/execution_success/assign_ex/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assign_ex/Nargo.toml rename to noir/test_programs/execution_success/assign_ex/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assign_ex/Prover.toml b/noir/test_programs/execution_success/assign_ex/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assign_ex/Prover.toml rename to noir/test_programs/execution_success/assign_ex/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/assign_ex/src/main.nr b/noir/test_programs/execution_success/assign_ex/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/assign_ex/src/main.nr rename to noir/test_programs/execution_success/assign_ex/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_and/Nargo.toml b/noir/test_programs/execution_success/bit_and/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_and/Nargo.toml rename to noir/test_programs/execution_success/bit_and/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_and/Prover.toml b/noir/test_programs/execution_success/bit_and/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_and/Prover.toml rename to noir/test_programs/execution_success/bit_and/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_and/src/main.nr b/noir/test_programs/execution_success/bit_and/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_and/src/main.nr rename to noir/test_programs/execution_success/bit_and/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml b/noir/test_programs/execution_success/bit_shifts_comptime/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Nargo.toml rename to noir/test_programs/execution_success/bit_shifts_comptime/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml b/noir/test_programs/execution_success/bit_shifts_comptime/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/Prover.toml rename to noir/test_programs/execution_success/bit_shifts_comptime/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr b/noir/test_programs/execution_success/bit_shifts_comptime/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_comptime/src/main.nr rename to noir/test_programs/execution_success/bit_shifts_comptime/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml b/noir/test_programs/execution_success/bit_shifts_runtime/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Nargo.toml rename to noir/test_programs/execution_success/bit_shifts_runtime/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml b/noir/test_programs/execution_success/bit_shifts_runtime/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/Prover.toml rename to noir/test_programs/execution_success/bit_shifts_runtime/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr b/noir/test_programs/execution_success/bit_shifts_runtime/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bit_shifts_runtime/src/main.nr rename to noir/test_programs/execution_success/bit_shifts_runtime/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_not/Nargo.toml b/noir/test_programs/execution_success/bool_not/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_not/Nargo.toml rename to noir/test_programs/execution_success/bool_not/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_not/Prover.toml b/noir/test_programs/execution_success/bool_not/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_not/Prover.toml rename to noir/test_programs/execution_success/bool_not/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_not/src/main.nr b/noir/test_programs/execution_success/bool_not/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_not/src/main.nr rename to noir/test_programs/execution_success/bool_not/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_or/Nargo.toml b/noir/test_programs/execution_success/bool_or/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_or/Nargo.toml rename to noir/test_programs/execution_success/bool_or/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_or/Prover.toml b/noir/test_programs/execution_success/bool_or/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_or/Prover.toml rename to noir/test_programs/execution_success/bool_or/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/bool_or/src/main.nr b/noir/test_programs/execution_success/bool_or/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/bool_or/src/main.nr rename to noir/test_programs/execution_success/bool_or/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml b/noir/test_programs/execution_success/brillig_acir_as_brillig/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Nargo.toml rename to noir/test_programs/execution_success/brillig_acir_as_brillig/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml b/noir/test_programs/execution_success/brillig_acir_as_brillig/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/Prover.toml rename to noir/test_programs/execution_success/brillig_acir_as_brillig/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr b/noir/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_acir_as_brillig/src/main.nr rename to noir/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml b/noir/test_programs/execution_success/brillig_arrays/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/Nargo.toml rename to noir/test_programs/execution_success/brillig_arrays/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml b/noir/test_programs/execution_success/brillig_arrays/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/Prover.toml rename to noir/test_programs/execution_success/brillig_arrays/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr b/noir/test_programs/execution_success/brillig_arrays/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_arrays/src/main.nr rename to noir/test_programs/execution_success/brillig_arrays/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml b/noir/test_programs/execution_success/brillig_assert/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_assert/Nargo.toml rename to noir/test_programs/execution_success/brillig_assert/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_assert/Prover.toml b/noir/test_programs/execution_success/brillig_assert/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_assert/Prover.toml rename to noir/test_programs/execution_success/brillig_assert/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_assert/src/main.nr b/noir/test_programs/execution_success/brillig_assert/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_assert/src/main.nr rename to noir/test_programs/execution_success/brillig_assert/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml b/noir/test_programs/execution_success/brillig_blake2s/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Nargo.toml rename to noir/test_programs/execution_success/brillig_blake2s/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml b/noir/test_programs/execution_success/brillig_blake2s/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/Prover.toml rename to noir/test_programs/execution_success/brillig_blake2s/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr b/noir/test_programs/execution_success/brillig_blake2s/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_blake2s/src/main.nr rename to noir/test_programs/execution_success/brillig_blake2s/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml b/noir/test_programs/execution_success/brillig_calls/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls/Nargo.toml rename to noir/test_programs/execution_success/brillig_calls/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls/Prover.toml b/noir/test_programs/execution_success/brillig_calls/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls/Prover.toml rename to noir/test_programs/execution_success/brillig_calls/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls/src/main.nr b/noir/test_programs/execution_success/brillig_calls/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls/src/main.nr rename to noir/test_programs/execution_success/brillig_calls/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml b/noir/test_programs/execution_success/brillig_calls_array/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Nargo.toml rename to noir/test_programs/execution_success/brillig_calls_array/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml b/noir/test_programs/execution_success/brillig_calls_array/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/Prover.toml rename to noir/test_programs/execution_success/brillig_calls_array/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr b/noir/test_programs/execution_success/brillig_calls_array/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_array/src/main.nr rename to noir/test_programs/execution_success/brillig_calls_array/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml b/noir/test_programs/execution_success/brillig_calls_conditionals/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Nargo.toml rename to noir/test_programs/execution_success/brillig_calls_conditionals/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml b/noir/test_programs/execution_success/brillig_calls_conditionals/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/Prover.toml rename to noir/test_programs/execution_success/brillig_calls_conditionals/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr b/noir/test_programs/execution_success/brillig_calls_conditionals/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_calls_conditionals/src/main.nr rename to noir/test_programs/execution_success/brillig_calls_conditionals/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml b/noir/test_programs/execution_success/brillig_conditional/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/Nargo.toml rename to noir/test_programs/execution_success/brillig_conditional/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml b/noir/test_programs/execution_success/brillig_conditional/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/Prover.toml rename to noir/test_programs/execution_success/brillig_conditional/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr b/noir/test_programs/execution_success/brillig_conditional/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_conditional/src/main.nr rename to noir/test_programs/execution_success/brillig_conditional/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml b/noir/test_programs/execution_success/brillig_ecdsa/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Nargo.toml rename to noir/test_programs/execution_success/brillig_ecdsa/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml b/noir/test_programs/execution_success/brillig_ecdsa/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/Prover.toml rename to noir/test_programs/execution_success/brillig_ecdsa/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr b/noir/test_programs/execution_success/brillig_ecdsa/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_ecdsa/src/main.nr rename to noir/test_programs/execution_success/brillig_ecdsa/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml b/noir/test_programs/execution_success/brillig_fns_as_values/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Nargo.toml rename to noir/test_programs/execution_success/brillig_fns_as_values/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml b/noir/test_programs/execution_success/brillig_fns_as_values/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/Prover.toml rename to noir/test_programs/execution_success/brillig_fns_as_values/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr b/noir/test_programs/execution_success/brillig_fns_as_values/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_fns_as_values/src/main.nr rename to noir/test_programs/execution_success/brillig_fns_as_values/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml b/noir/test_programs/execution_success/brillig_hash_to_field/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Nargo.toml rename to noir/test_programs/execution_success/brillig_hash_to_field/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml b/noir/test_programs/execution_success/brillig_hash_to_field/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/Prover.toml rename to noir/test_programs/execution_success/brillig_hash_to_field/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr b/noir/test_programs/execution_success/brillig_hash_to_field/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_hash_to_field/src/main.nr rename to noir/test_programs/execution_success/brillig_hash_to_field/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml b/noir/test_programs/execution_success/brillig_identity_function/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Nargo.toml rename to noir/test_programs/execution_success/brillig_identity_function/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml b/noir/test_programs/execution_success/brillig_identity_function/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/Prover.toml rename to noir/test_programs/execution_success/brillig_identity_function/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr b/noir/test_programs/execution_success/brillig_identity_function/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_identity_function/src/main.nr rename to noir/test_programs/execution_success/brillig_identity_function/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml b/noir/test_programs/execution_success/brillig_keccak/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/Nargo.toml rename to noir/test_programs/execution_success/brillig_keccak/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml b/noir/test_programs/execution_success/brillig_keccak/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/Prover.toml rename to noir/test_programs/execution_success/brillig_keccak/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr b/noir/test_programs/execution_success/brillig_keccak/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_keccak/src/main.nr rename to noir/test_programs/execution_success/brillig_keccak/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml b/noir/test_programs/execution_success/brillig_loop/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_loop/Nargo.toml rename to noir/test_programs/execution_success/brillig_loop/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_loop/Prover.toml b/noir/test_programs/execution_success/brillig_loop/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_loop/Prover.toml rename to noir/test_programs/execution_success/brillig_loop/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_loop/src/main.nr b/noir/test_programs/execution_success/brillig_loop/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_loop/src/main.nr rename to noir/test_programs/execution_success/brillig_loop/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml b/noir/test_programs/execution_success/brillig_nested_arrays/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Nargo.toml rename to noir/test_programs/execution_success/brillig_nested_arrays/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml b/noir/test_programs/execution_success/brillig_nested_arrays/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/Prover.toml rename to noir/test_programs/execution_success/brillig_nested_arrays/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr b/noir/test_programs/execution_success/brillig_nested_arrays/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_arrays/src/main.nr rename to noir/test_programs/execution_success/brillig_nested_arrays/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml b/noir/test_programs/execution_success/brillig_nested_slices/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Nargo.toml rename to noir/test_programs/execution_success/brillig_nested_slices/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml b/noir/test_programs/execution_success/brillig_nested_slices/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/Prover.toml rename to noir/test_programs/execution_success/brillig_nested_slices/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr b/noir/test_programs/execution_success/brillig_nested_slices/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_nested_slices/src/main.nr rename to noir/test_programs/execution_success/brillig_nested_slices/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_not/Nargo.toml b/noir/test_programs/execution_success/brillig_not/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_not/Nargo.toml rename to noir/test_programs/execution_success/brillig_not/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_not/Prover.toml b/noir/test_programs/execution_success/brillig_not/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_not/Prover.toml rename to noir/test_programs/execution_success/brillig_not/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_not/src/main.nr b/noir/test_programs/execution_success/brillig_not/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_not/src/main.nr rename to noir/test_programs/execution_success/brillig_not/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml b/noir/test_programs/execution_success/brillig_oracle/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/Nargo.toml rename to noir/test_programs/execution_success/brillig_oracle/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml b/noir/test_programs/execution_success/brillig_oracle/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/Prover.toml rename to noir/test_programs/execution_success/brillig_oracle/Prover.toml diff --git a/noir/test_programs/execution_success/brillig_oracle/src/main.nr b/noir/test_programs/execution_success/brillig_oracle/src/main.nr new file mode 100644 index 00000000000..490b7b605e3 --- /dev/null +++ b/noir/test_programs/execution_success/brillig_oracle/src/main.nr @@ -0,0 +1,42 @@ +use dep::std::slice; +use dep::std::test::OracleMock; + +// Tests oracle usage in brillig/unconstrained functions +fn main(x: Field) { + let size = 20; + // TODO: Add a method along the lines of `(0..size).to_array()`. + let mut mock_oracle_response = [0; 20]; + // TODO: Add an `array.reverse()` method. + let mut reversed_mock_oracle_response = [0; 20]; + for i in 0..size { + mock_oracle_response[i] = i; + reversed_mock_oracle_response[19 - i] = i; + } + + // TODO: this method of returning a slice feels hacky. + let _ = OracleMock::mock("get_number_sequence").with_params(size).returns((20, mock_oracle_response)); + let _ = OracleMock::mock("get_reverse_number_sequence").with_params(size).returns((20, reversed_mock_oracle_response)); + + get_number_sequence_wrapper(size); +} + +// Define oracle functions which we have mocked above +#[oracle(get_number_sequence)] +unconstrained fn get_number_sequence(_size: Field) -> [Field] {} + +#[oracle(get_reverse_number_sequence)] +unconstrained fn get_reverse_number_sequence(_size: Field) -> [Field] {} + +unconstrained fn get_number_sequence_wrapper(size: Field) { + let slice = get_number_sequence(size); + for i in 0..20 as u32 { + assert(slice[i] == i as Field); + } + + let reversed_slice = get_reverse_number_sequence(size); + // Regression test that we have not overwritten memory + for i in 0..20 as u32 { + assert(slice[i] == reversed_slice[19 - i]); + } +} + diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml b/noir/test_programs/execution_success/brillig_pedersen/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Nargo.toml rename to noir/test_programs/execution_success/brillig_pedersen/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml b/noir/test_programs/execution_success/brillig_pedersen/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/Prover.toml rename to noir/test_programs/execution_success/brillig_pedersen/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr b/noir/test_programs/execution_success/brillig_pedersen/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_pedersen/src/main.nr rename to noir/test_programs/execution_success/brillig_pedersen/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml b/noir/test_programs/execution_success/brillig_recursion/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/Nargo.toml rename to noir/test_programs/execution_success/brillig_recursion/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml b/noir/test_programs/execution_success/brillig_recursion/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/Prover.toml rename to noir/test_programs/execution_success/brillig_recursion/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr b/noir/test_programs/execution_success/brillig_recursion/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_recursion/src/main.nr rename to noir/test_programs/execution_success/brillig_recursion/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_references/Nargo.toml b/noir/test_programs/execution_success/brillig_references/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_references/Nargo.toml rename to noir/test_programs/execution_success/brillig_references/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_references/Prover.toml b/noir/test_programs/execution_success/brillig_references/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_references/Prover.toml rename to noir/test_programs/execution_success/brillig_references/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_references/src/main.nr b/noir/test_programs/execution_success/brillig_references/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_references/src/main.nr rename to noir/test_programs/execution_success/brillig_references/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml b/noir/test_programs/execution_success/brillig_scalar_mul/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Nargo.toml rename to noir/test_programs/execution_success/brillig_scalar_mul/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml b/noir/test_programs/execution_success/brillig_scalar_mul/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/Prover.toml rename to noir/test_programs/execution_success/brillig_scalar_mul/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr b/noir/test_programs/execution_success/brillig_scalar_mul/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_scalar_mul/src/main.nr rename to noir/test_programs/execution_success/brillig_scalar_mul/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml b/noir/test_programs/execution_success/brillig_schnorr/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Nargo.toml rename to noir/test_programs/execution_success/brillig_schnorr/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml b/noir/test_programs/execution_success/brillig_schnorr/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/Prover.toml rename to noir/test_programs/execution_success/brillig_schnorr/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr b/noir/test_programs/execution_success/brillig_schnorr/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_schnorr/src/main.nr rename to noir/test_programs/execution_success/brillig_schnorr/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml b/noir/test_programs/execution_success/brillig_sha256/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/Nargo.toml rename to noir/test_programs/execution_success/brillig_sha256/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml b/noir/test_programs/execution_success/brillig_sha256/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/Prover.toml rename to noir/test_programs/execution_success/brillig_sha256/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr b/noir/test_programs/execution_success/brillig_sha256/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_sha256/src/main.nr rename to noir/test_programs/execution_success/brillig_sha256/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml b/noir/test_programs/execution_success/brillig_slices/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_slices/Nargo.toml rename to noir/test_programs/execution_success/brillig_slices/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_slices/Prover.toml b/noir/test_programs/execution_success/brillig_slices/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_slices/Prover.toml rename to noir/test_programs/execution_success/brillig_slices/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_slices/src/main.nr b/noir/test_programs/execution_success/brillig_slices/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_slices/src/main.nr rename to noir/test_programs/execution_success/brillig_slices/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml b/noir/test_programs/execution_success/brillig_to_be_bytes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Nargo.toml rename to noir/test_programs/execution_success/brillig_to_be_bytes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml b/noir/test_programs/execution_success/brillig_to_be_bytes/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/Prover.toml rename to noir/test_programs/execution_success/brillig_to_be_bytes/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr b/noir/test_programs/execution_success/brillig_to_be_bytes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_be_bytes/src/main.nr rename to noir/test_programs/execution_success/brillig_to_be_bytes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml b/noir/test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Nargo.toml rename to noir/test_programs/execution_success/brillig_to_bytes_integration/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml b/noir/test_programs/execution_success/brillig_to_bytes_integration/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/Prover.toml rename to noir/test_programs/execution_success/brillig_to_bytes_integration/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr b/noir/test_programs/execution_success/brillig_to_bytes_integration/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_bytes_integration/src/main.nr rename to noir/test_programs/execution_success/brillig_to_bytes_integration/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml b/noir/test_programs/execution_success/brillig_to_le_bytes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Nargo.toml rename to noir/test_programs/execution_success/brillig_to_le_bytes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml b/noir/test_programs/execution_success/brillig_to_le_bytes/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/Prover.toml rename to noir/test_programs/execution_success/brillig_to_le_bytes/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr b/noir/test_programs/execution_success/brillig_to_le_bytes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_to_le_bytes/src/main.nr rename to noir/test_programs/execution_success/brillig_to_le_bytes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml b/noir/test_programs/execution_success/brillig_top_level/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/Nargo.toml rename to noir/test_programs/execution_success/brillig_top_level/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml b/noir/test_programs/execution_success/brillig_top_level/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/Prover.toml rename to noir/test_programs/execution_success/brillig_top_level/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr b/noir/test_programs/execution_success/brillig_top_level/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_top_level/src/main.nr rename to noir/test_programs/execution_success/brillig_top_level/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Nargo.toml b/noir/test_programs/execution_success/brillig_unitialised_arrays/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Nargo.toml rename to noir/test_programs/execution_success/brillig_unitialised_arrays/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Prover.toml b/noir/test_programs/execution_success/brillig_unitialised_arrays/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/Prover.toml rename to noir/test_programs/execution_success/brillig_unitialised_arrays/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/src/main.nr b/noir/test_programs/execution_success/brillig_unitialised_arrays/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/brillig_unitialised_arrays/src/main.nr rename to noir/test_programs/execution_success/brillig_unitialised_arrays/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/cast_bool/Nargo.toml b/noir/test_programs/execution_success/cast_bool/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/cast_bool/Nargo.toml rename to noir/test_programs/execution_success/cast_bool/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/cast_bool/Prover.toml b/noir/test_programs/execution_success/cast_bool/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/cast_bool/Prover.toml rename to noir/test_programs/execution_success/cast_bool/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/cast_bool/src/main.nr b/noir/test_programs/execution_success/cast_bool/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/cast_bool/src/main.nr rename to noir/test_programs/execution_success/cast_bool/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml b/noir/test_programs/execution_success/closures_mut_ref/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Nargo.toml rename to noir/test_programs/execution_success/closures_mut_ref/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml b/noir/test_programs/execution_success/closures_mut_ref/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/Prover.toml rename to noir/test_programs/execution_success/closures_mut_ref/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr b/noir/test_programs/execution_success/closures_mut_ref/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/closures_mut_ref/src/main.nr rename to noir/test_programs/execution_success/closures_mut_ref/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_1/Nargo.toml b/noir/test_programs/execution_success/conditional_1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_1/Nargo.toml rename to noir/test_programs/execution_success/conditional_1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_1/Prover.toml b/noir/test_programs/execution_success/conditional_1/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_1/Prover.toml rename to noir/test_programs/execution_success/conditional_1/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_1/src/main.nr b/noir/test_programs/execution_success/conditional_1/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_1/src/main.nr rename to noir/test_programs/execution_success/conditional_1/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_2/Nargo.toml b/noir/test_programs/execution_success/conditional_2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_2/Nargo.toml rename to noir/test_programs/execution_success/conditional_2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_2/Prover.toml b/noir/test_programs/execution_success/conditional_2/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_2/Prover.toml rename to noir/test_programs/execution_success/conditional_2/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_2/src/main.nr b/noir/test_programs/execution_success/conditional_2/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_2/src/main.nr rename to noir/test_programs/execution_success/conditional_2/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/Nargo.toml b/noir/test_programs/execution_success/conditional_regression_421/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/Nargo.toml rename to noir/test_programs/execution_success/conditional_regression_421/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/Prover.toml b/noir/test_programs/execution_success/conditional_regression_421/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/Prover.toml rename to noir/test_programs/execution_success/conditional_regression_421/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/src/main.nr b/noir/test_programs/execution_success/conditional_regression_421/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_421/src/main.nr rename to noir/test_programs/execution_success/conditional_regression_421/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/Nargo.toml b/noir/test_programs/execution_success/conditional_regression_661/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/Nargo.toml rename to noir/test_programs/execution_success/conditional_regression_661/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/Prover.toml b/noir/test_programs/execution_success/conditional_regression_661/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/Prover.toml rename to noir/test_programs/execution_success/conditional_regression_661/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/src/main.nr b/noir/test_programs/execution_success/conditional_regression_661/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_661/src/main.nr rename to noir/test_programs/execution_success/conditional_regression_661/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/Nargo.toml b/noir/test_programs/execution_success/conditional_regression_short_circuit/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/Nargo.toml rename to noir/test_programs/execution_success/conditional_regression_short_circuit/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/Prover.toml b/noir/test_programs/execution_success/conditional_regression_short_circuit/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/Prover.toml rename to noir/test_programs/execution_success/conditional_regression_short_circuit/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/src/main.nr b/noir/test_programs/execution_success/conditional_regression_short_circuit/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_short_circuit/src/main.nr rename to noir/test_programs/execution_success/conditional_regression_short_circuit/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/Nargo.toml b/noir/test_programs/execution_success/conditional_regression_underflow/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/Nargo.toml rename to noir/test_programs/execution_success/conditional_regression_underflow/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/Prover.toml b/noir/test_programs/execution_success/conditional_regression_underflow/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/Prover.toml rename to noir/test_programs/execution_success/conditional_regression_underflow/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/src/main.nr b/noir/test_programs/execution_success/conditional_regression_underflow/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/conditional_regression_underflow/src/main.nr rename to noir/test_programs/execution_success/conditional_regression_underflow/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/custom_entry/Nargo.toml b/noir/test_programs/execution_success/custom_entry/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/custom_entry/Nargo.toml rename to noir/test_programs/execution_success/custom_entry/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/custom_entry/Prover.toml b/noir/test_programs/execution_success/custom_entry/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/custom_entry/Prover.toml rename to noir/test_programs/execution_success/custom_entry/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr b/noir/test_programs/execution_success/custom_entry/src/foobarbaz.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/custom_entry/src/foobarbaz.nr rename to noir/test_programs/execution_success/custom_entry/src/foobarbaz.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/debug_logs/Nargo.toml b/noir/test_programs/execution_success/debug_logs/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/debug_logs/Nargo.toml rename to noir/test_programs/execution_success/debug_logs/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/debug_logs/Prover.toml b/noir/test_programs/execution_success/debug_logs/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/debug_logs/Prover.toml rename to noir/test_programs/execution_success/debug_logs/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/debug_logs/src/main.nr b/noir/test_programs/execution_success/debug_logs/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/debug_logs/src/main.nr rename to noir/test_programs/execution_success/debug_logs/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml b/noir/test_programs/execution_success/diamond_deps_0/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Nargo.toml rename to noir/test_programs/execution_success/diamond_deps_0/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml b/noir/test_programs/execution_success/diamond_deps_0/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/Prover.toml rename to noir/test_programs/execution_success/diamond_deps_0/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr b/noir/test_programs/execution_success/diamond_deps_0/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/diamond_deps_0/src/main.nr rename to noir/test_programs/execution_success/diamond_deps_0/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml b/noir/test_programs/execution_success/distinct_keyword/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/Nargo.toml rename to noir/test_programs/execution_success/distinct_keyword/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml b/noir/test_programs/execution_success/distinct_keyword/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/Prover.toml rename to noir/test_programs/execution_success/distinct_keyword/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr b/noir/test_programs/execution_success/distinct_keyword/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/distinct_keyword/src/main.nr rename to noir/test_programs/execution_success/distinct_keyword/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/Nargo.toml b/noir/test_programs/execution_success/double_verify_proof/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/Nargo.toml rename to noir/test_programs/execution_success/double_verify_proof/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/Prover.toml b/noir/test_programs/execution_success/double_verify_proof/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/Prover.toml rename to noir/test_programs/execution_success/double_verify_proof/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr b/noir/test_programs/execution_success/double_verify_proof/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/double_verify_proof/src/main.nr rename to noir/test_programs/execution_success/double_verify_proof/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml b/noir/test_programs/execution_success/ecdsa_secp256k1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Nargo.toml rename to noir/test_programs/execution_success/ecdsa_secp256k1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml b/noir/test_programs/execution_success/ecdsa_secp256k1/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/Prover.toml rename to noir/test_programs/execution_success/ecdsa_secp256k1/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr b/noir/test_programs/execution_success/ecdsa_secp256k1/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256k1/src/main.nr rename to noir/test_programs/execution_success/ecdsa_secp256k1/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml b/noir/test_programs/execution_success/ecdsa_secp256r1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Nargo.toml rename to noir/test_programs/execution_success/ecdsa_secp256r1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml b/noir/test_programs/execution_success/ecdsa_secp256r1/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/Prover.toml rename to noir/test_programs/execution_success/ecdsa_secp256r1/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr b/noir/test_programs/execution_success/ecdsa_secp256r1/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/ecdsa_secp256r1/src/main.nr rename to noir/test_programs/execution_success/ecdsa_secp256r1/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/eddsa/Nargo.toml b/noir/test_programs/execution_success/eddsa/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/eddsa/Nargo.toml rename to noir/test_programs/execution_success/eddsa/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/eddsa/Prover.toml b/noir/test_programs/execution_success/eddsa/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/eddsa/Prover.toml rename to noir/test_programs/execution_success/eddsa/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/eddsa/src/main.nr b/noir/test_programs/execution_success/eddsa/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/eddsa/src/main.nr rename to noir/test_programs/execution_success/eddsa/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/field_attribute/Nargo.toml b/noir/test_programs/execution_success/field_attribute/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/field_attribute/Nargo.toml rename to noir/test_programs/execution_success/field_attribute/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/field_attribute/Prover.toml b/noir/test_programs/execution_success/field_attribute/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/field_attribute/Prover.toml rename to noir/test_programs/execution_success/field_attribute/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/field_attribute/src/main.nr b/noir/test_programs/execution_success/field_attribute/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/field_attribute/src/main.nr rename to noir/test_programs/execution_success/field_attribute/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/generics/Nargo.toml b/noir/test_programs/execution_success/generics/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/generics/Nargo.toml rename to noir/test_programs/execution_success/generics/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/generics/Prover.toml b/noir/test_programs/execution_success/generics/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/generics/Prover.toml rename to noir/test_programs/execution_success/generics/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/generics/src/main.nr b/noir/test_programs/execution_success/generics/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/generics/src/main.nr rename to noir/test_programs/execution_success/generics/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/Nargo.toml b/noir/test_programs/execution_success/global_consts/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/Nargo.toml rename to noir/test_programs/execution_success/global_consts/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/Prover.toml b/noir/test_programs/execution_success/global_consts/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/Prover.toml rename to noir/test_programs/execution_success/global_consts/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr b/noir/test_programs/execution_success/global_consts/src/baz.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr rename to noir/test_programs/execution_success/global_consts/src/baz.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr b/noir/test_programs/execution_success/global_consts/src/foo.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr rename to noir/test_programs/execution_success/global_consts/src/foo.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr b/noir/test_programs/execution_success/global_consts/src/foo/bar.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr rename to noir/test_programs/execution_success/global_consts/src/foo/bar.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr b/noir/test_programs/execution_success/global_consts/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr rename to noir/test_programs/execution_success/global_consts/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml b/noir/test_programs/execution_success/hash_to_field/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/hash_to_field/Nargo.toml rename to noir/test_programs/execution_success/hash_to_field/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/hash_to_field/Prover.toml b/noir/test_programs/execution_success/hash_to_field/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/hash_to_field/Prover.toml rename to noir/test_programs/execution_success/hash_to_field/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/hash_to_field/src/main.nr b/noir/test_programs/execution_success/hash_to_field/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/hash_to_field/src/main.nr rename to noir/test_programs/execution_success/hash_to_field/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml b/noir/test_programs/execution_success/higher_order_functions/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/Nargo.toml rename to noir/test_programs/execution_success/higher_order_functions/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml b/noir/test_programs/execution_success/higher_order_functions/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/Prover.toml rename to noir/test_programs/execution_success/higher_order_functions/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr b/noir/test_programs/execution_success/higher_order_functions/src/main.nr similarity index 98% rename from noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr rename to noir/test_programs/execution_success/higher_order_functions/src/main.nr index 479cdbbe7bf..6583f961d58 100644 --- a/noir/tooling/nargo_cli/tests/execution_success/higher_order_functions/src/main.nr +++ b/noir/test_programs/execution_success/higher_order_functions/src/main.nr @@ -5,10 +5,12 @@ fn main(w: Field) -> pub Field { assert(twice(|x| x * 2, 5) == 20); assert((|x, y| x + y + 1)(2, 3) == 6); // nested lambdas - assert((|a, b| { + assert( + (|a, b| { a + (|c| c + 2)(b) })(0, 1) - == 3); + == 3 + ); // Closures: let a = 42; let g = || a; diff --git a/noir/tooling/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml b/noir/test_programs/execution_success/if_else_chain/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/if_else_chain/Nargo.toml rename to noir/test_programs/execution_success/if_else_chain/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/if_else_chain/Prover.toml b/noir/test_programs/execution_success/if_else_chain/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/if_else_chain/Prover.toml rename to noir/test_programs/execution_success/if_else_chain/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/if_else_chain/src/main.nr b/noir/test_programs/execution_success/if_else_chain/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/if_else_chain/src/main.nr rename to noir/test_programs/execution_success/if_else_chain/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/import/Nargo.toml b/noir/test_programs/execution_success/import/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/import/Nargo.toml rename to noir/test_programs/execution_success/import/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/import/Prover.toml b/noir/test_programs/execution_success/import/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/import/Prover.toml rename to noir/test_programs/execution_success/import/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/import/src/import.nr b/noir/test_programs/execution_success/import/src/import.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/import/src/import.nr rename to noir/test_programs/execution_success/import/src/import.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/import/src/main.nr b/noir/test_programs/execution_success/import/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/import/src/main.nr rename to noir/test_programs/execution_success/import/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml b/noir/test_programs/execution_success/integer_array_indexing/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Nargo.toml rename to noir/test_programs/execution_success/integer_array_indexing/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml b/noir/test_programs/execution_success/integer_array_indexing/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/Prover.toml rename to noir/test_programs/execution_success/integer_array_indexing/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr b/noir/test_programs/execution_success/integer_array_indexing/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/integer_array_indexing/src/main.nr rename to noir/test_programs/execution_success/integer_array_indexing/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/keccak256/Nargo.toml b/noir/test_programs/execution_success/keccak256/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/keccak256/Nargo.toml rename to noir/test_programs/execution_success/keccak256/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/keccak256/Prover.toml b/noir/test_programs/execution_success/keccak256/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/keccak256/Prover.toml rename to noir/test_programs/execution_success/keccak256/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/keccak256/src/main.nr b/noir/test_programs/execution_success/keccak256/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/keccak256/src/main.nr rename to noir/test_programs/execution_success/keccak256/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml b/noir/test_programs/execution_success/main_bool_arg/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/Nargo.toml rename to noir/test_programs/execution_success/main_bool_arg/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml b/noir/test_programs/execution_success/main_bool_arg/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/Prover.toml rename to noir/test_programs/execution_success/main_bool_arg/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr b/noir/test_programs/execution_success/main_bool_arg/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/main_bool_arg/src/main.nr rename to noir/test_programs/execution_success/main_bool_arg/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml b/noir/test_programs/execution_success/merkle_insert/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/merkle_insert/Nargo.toml rename to noir/test_programs/execution_success/merkle_insert/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/merkle_insert/Prover.toml b/noir/test_programs/execution_success/merkle_insert/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/merkle_insert/Prover.toml rename to noir/test_programs/execution_success/merkle_insert/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/merkle_insert/src/main.nr b/noir/test_programs/execution_success/merkle_insert/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/merkle_insert/src/main.nr rename to noir/test_programs/execution_success/merkle_insert/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/mock_oracle/Nargo.toml b/noir/test_programs/execution_success/mock_oracle/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/mock_oracle/Nargo.toml rename to noir/test_programs/execution_success/mock_oracle/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/mock_oracle/Prover.toml b/noir/test_programs/execution_success/mock_oracle/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/mock_oracle/Prover.toml rename to noir/test_programs/execution_success/mock_oracle/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/mock_oracle/src/main.nr b/noir/test_programs/execution_success/mock_oracle/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/mock_oracle/src/main.nr rename to noir/test_programs/execution_success/mock_oracle/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules/Nargo.toml b/noir/test_programs/execution_success/modules/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules/Nargo.toml rename to noir/test_programs/execution_success/modules/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules/Prover.toml b/noir/test_programs/execution_success/modules/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules/Prover.toml rename to noir/test_programs/execution_success/modules/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr b/noir/test_programs/execution_success/modules/src/foo.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr rename to noir/test_programs/execution_success/modules/src/foo.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules/src/main.nr b/noir/test_programs/execution_success/modules/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules/src/main.nr rename to noir/test_programs/execution_success/modules/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules_more/Nargo.toml b/noir/test_programs/execution_success/modules_more/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules_more/Nargo.toml rename to noir/test_programs/execution_success/modules_more/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules_more/Prover.toml b/noir/test_programs/execution_success/modules_more/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules_more/Prover.toml rename to noir/test_programs/execution_success/modules_more/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules_more/src/foo.nr b/noir/test_programs/execution_success/modules_more/src/foo.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules_more/src/foo.nr rename to noir/test_programs/execution_success/modules_more/src/foo.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr b/noir/test_programs/execution_success/modules_more/src/foo/bar.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr rename to noir/test_programs/execution_success/modules_more/src/foo/bar.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modules_more/src/main.nr b/noir/test_programs/execution_success/modules_more/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modules_more/src/main.nr rename to noir/test_programs/execution_success/modules_more/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/modulus/Nargo.toml b/noir/test_programs/execution_success/modulus/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modulus/Nargo.toml rename to noir/test_programs/execution_success/modulus/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modulus/Prover.toml b/noir/test_programs/execution_success/modulus/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modulus/Prover.toml rename to noir/test_programs/execution_success/modulus/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/modulus/src/main.nr b/noir/test_programs/execution_success/modulus/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/modulus/src/main.nr rename to noir/test_programs/execution_success/modulus/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/Nargo.toml b/noir/test_programs/execution_success/nested_array_dynamic/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/Nargo.toml rename to noir/test_programs/execution_success/nested_array_dynamic/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/Prover.toml b/noir/test_programs/execution_success/nested_array_dynamic/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/Prover.toml rename to noir/test_programs/execution_success/nested_array_dynamic/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/src/main.nr b/noir/test_programs/execution_success/nested_array_dynamic/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_array_dynamic/src/main.nr rename to noir/test_programs/execution_success/nested_array_dynamic/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml b/noir/test_programs/execution_success/nested_arrays_from_brillig/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Nargo.toml rename to noir/test_programs/execution_success/nested_arrays_from_brillig/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml b/noir/test_programs/execution_success/nested_arrays_from_brillig/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/Prover.toml rename to noir/test_programs/execution_success/nested_arrays_from_brillig/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr b/noir/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_arrays_from_brillig/src/main.nr rename to noir/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/Nargo.toml b/noir/test_programs/execution_success/nested_slice_dynamic/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/Nargo.toml rename to noir/test_programs/execution_success/nested_slice_dynamic/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/Prover.toml b/noir/test_programs/execution_success/nested_slice_dynamic/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/Prover.toml rename to noir/test_programs/execution_success/nested_slice_dynamic/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/src/main.nr b/noir/test_programs/execution_success/nested_slice_dynamic/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/nested_slice_dynamic/src/main.nr rename to noir/test_programs/execution_success/nested_slice_dynamic/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml b/noir/test_programs/execution_success/pedersen_check/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pedersen_check/Nargo.toml rename to noir/test_programs/execution_success/pedersen_check/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/pedersen_check/Prover.toml b/noir/test_programs/execution_success/pedersen_check/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pedersen_check/Prover.toml rename to noir/test_programs/execution_success/pedersen_check/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/pedersen_check/src/main.nr b/noir/test_programs/execution_success/pedersen_check/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pedersen_check/src/main.nr rename to noir/test_programs/execution_success/pedersen_check/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml b/noir/test_programs/execution_success/poseidon_bn254_hash/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Nargo.toml rename to noir/test_programs/execution_success/poseidon_bn254_hash/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml b/noir/test_programs/execution_success/poseidon_bn254_hash/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/Prover.toml rename to noir/test_programs/execution_success/poseidon_bn254_hash/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr b/noir/test_programs/execution_success/poseidon_bn254_hash/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidon_bn254_hash/src/main.nr rename to noir/test_programs/execution_success/poseidon_bn254_hash/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml b/noir/test_programs/execution_success/poseidonsponge_x5_254/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Nargo.toml rename to noir/test_programs/execution_success/poseidonsponge_x5_254/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml b/noir/test_programs/execution_success/poseidonsponge_x5_254/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/Prover.toml rename to noir/test_programs/execution_success/poseidonsponge_x5_254/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr b/noir/test_programs/execution_success/poseidonsponge_x5_254/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/poseidonsponge_x5_254/src/main.nr rename to noir/test_programs/execution_success/poseidonsponge_x5_254/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/pred_eq/Nargo.toml b/noir/test_programs/execution_success/pred_eq/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pred_eq/Nargo.toml rename to noir/test_programs/execution_success/pred_eq/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/pred_eq/Prover.toml b/noir/test_programs/execution_success/pred_eq/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pred_eq/Prover.toml rename to noir/test_programs/execution_success/pred_eq/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/pred_eq/src/main.nr b/noir/test_programs/execution_success/pred_eq/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/pred_eq/src/main.nr rename to noir/test_programs/execution_success/pred_eq/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/references/Nargo.toml b/noir/test_programs/execution_success/references/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/references/Nargo.toml rename to noir/test_programs/execution_success/references/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/references/Prover.toml b/noir/test_programs/execution_success/references/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/references/Prover.toml rename to noir/test_programs/execution_success/references/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/references/src/main.nr b/noir/test_programs/execution_success/references/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/references/src/main.nr rename to noir/test_programs/execution_success/references/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression/Nargo.toml b/noir/test_programs/execution_success/regression/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression/Nargo.toml rename to noir/test_programs/execution_success/regression/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression/Prover.toml b/noir/test_programs/execution_success/regression/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression/Prover.toml rename to noir/test_programs/execution_success/regression/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression/src/main.nr b/noir/test_programs/execution_success/regression/src/main.nr similarity index 98% rename from noir/tooling/nargo_cli/tests/execution_success/regression/src/main.nr rename to noir/test_programs/execution_success/regression/src/main.nr index ed3dbf23a24..08112d4c616 100644 --- a/noir/tooling/nargo_cli/tests/execution_success/regression/src/main.nr +++ b/noir/test_programs/execution_success/regression/src/main.nr @@ -89,11 +89,13 @@ fn main(x: [u8; 5], z: Field) { let enc_val1 = enc(val1, val1_length); - assert(enc_val1.0 == [ + assert( + enc_val1.0 == [ 0x94, 0xb8, 0x8f, 0x61, 0xe6, 0xfb, 0xda, 0x83, 0xfb, 0xff, 0xfa, 0xbe, 0x36, 0x41, 0x12, 0x13, 0x74, 0x80, 0x39, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - ]); + ] + ); assert(enc_val1.1 == 21); // Issue 2399 let result_0 = bitshift_literal_0(); diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_2854/Nargo.toml b/noir/test_programs/execution_success/regression_2854/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_2854/Nargo.toml rename to noir/test_programs/execution_success/regression_2854/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_2854/Prover.toml b/noir/test_programs/execution_success/regression_2854/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_2854/Prover.toml rename to noir/test_programs/execution_success/regression_2854/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_2854/src/main.nr b/noir/test_programs/execution_success/regression_2854/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_2854/src/main.nr rename to noir/test_programs/execution_success/regression_2854/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml b/noir/test_programs/execution_success/regression_mem_op_predicate/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Nargo.toml rename to noir/test_programs/execution_success/regression_mem_op_predicate/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml b/noir/test_programs/execution_success/regression_mem_op_predicate/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/Prover.toml rename to noir/test_programs/execution_success/regression_mem_op_predicate/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr b/noir/test_programs/execution_success/regression_mem_op_predicate/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_mem_op_predicate/src/main.nr rename to noir/test_programs/execution_success/regression_mem_op_predicate/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml b/noir/test_programs/execution_success/regression_method_cannot_be_found/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Nargo.toml rename to noir/test_programs/execution_success/regression_method_cannot_be_found/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml b/noir/test_programs/execution_success/regression_method_cannot_be_found/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/Prover.toml rename to noir/test_programs/execution_success/regression_method_cannot_be_found/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr b/noir/test_programs/execution_success/regression_method_cannot_be_found/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/regression_method_cannot_be_found/src/main.nr rename to noir/test_programs/execution_success/regression_method_cannot_be_found/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml b/noir/test_programs/execution_success/scalar_mul/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/scalar_mul/Nargo.toml rename to noir/test_programs/execution_success/scalar_mul/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/scalar_mul/Prover.toml b/noir/test_programs/execution_success/scalar_mul/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/scalar_mul/Prover.toml rename to noir/test_programs/execution_success/scalar_mul/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/scalar_mul/src/main.nr b/noir/test_programs/execution_success/scalar_mul/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/scalar_mul/src/main.nr rename to noir/test_programs/execution_success/scalar_mul/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/schnorr/Nargo.toml b/noir/test_programs/execution_success/schnorr/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/schnorr/Nargo.toml rename to noir/test_programs/execution_success/schnorr/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/schnorr/Prover.toml b/noir/test_programs/execution_success/schnorr/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/schnorr/Prover.toml rename to noir/test_programs/execution_success/schnorr/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/schnorr/src/main.nr b/noir/test_programs/execution_success/schnorr/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/schnorr/src/main.nr rename to noir/test_programs/execution_success/schnorr/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha256/Nargo.toml b/noir/test_programs/execution_success/sha256/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha256/Nargo.toml rename to noir/test_programs/execution_success/sha256/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha256/Prover.toml b/noir/test_programs/execution_success/sha256/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha256/Prover.toml rename to noir/test_programs/execution_success/sha256/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha256/src/main.nr b/noir/test_programs/execution_success/sha256/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha256/src/main.nr rename to noir/test_programs/execution_success/sha256/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml b/noir/test_programs/execution_success/sha2_byte/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha2_byte/Nargo.toml rename to noir/test_programs/execution_success/sha2_byte/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha2_byte/Prover.toml b/noir/test_programs/execution_success/sha2_byte/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha2_byte/Prover.toml rename to noir/test_programs/execution_success/sha2_byte/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/sha2_byte/src/main.nr b/noir/test_programs/execution_success/sha2_byte/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/sha2_byte/src/main.nr rename to noir/test_programs/execution_success/sha2_byte/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/Nargo.toml b/noir/test_programs/execution_success/signed_arithmetic/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/Nargo.toml rename to noir/test_programs/execution_success/signed_arithmetic/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/Prover.toml b/noir/test_programs/execution_success/signed_arithmetic/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/Prover.toml rename to noir/test_programs/execution_success/signed_arithmetic/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/src/main.nr b/noir/test_programs/execution_success/signed_arithmetic/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_arithmetic/src/main.nr rename to noir/test_programs/execution_success/signed_arithmetic/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_division/Nargo.toml b/noir/test_programs/execution_success/signed_division/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_division/Nargo.toml rename to noir/test_programs/execution_success/signed_division/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_division/Prover.toml b/noir/test_programs/execution_success/signed_division/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_division/Prover.toml rename to noir/test_programs/execution_success/signed_division/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/signed_division/src/main.nr b/noir/test_programs/execution_success/signed_division/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/signed_division/src/main.nr rename to noir/test_programs/execution_success/signed_division/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/Nargo.toml b/noir/test_programs/execution_success/simple_2d_array/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/Nargo.toml rename to noir/test_programs/execution_success/simple_2d_array/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/Prover.toml b/noir/test_programs/execution_success/simple_2d_array/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/Prover.toml rename to noir/test_programs/execution_success/simple_2d_array/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/src/main.nr b/noir/test_programs/execution_success/simple_2d_array/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_2d_array/src/main.nr rename to noir/test_programs/execution_success/simple_2d_array/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml b/noir/test_programs/execution_success/simple_add_and_ret_arr/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Nargo.toml rename to noir/test_programs/execution_success/simple_add_and_ret_arr/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml b/noir/test_programs/execution_success/simple_add_and_ret_arr/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/Prover.toml rename to noir/test_programs/execution_success/simple_add_and_ret_arr/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr b/noir/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_add_and_ret_arr/src/main.nr rename to noir/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml b/noir/test_programs/execution_success/simple_bitwise/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/Nargo.toml rename to noir/test_programs/execution_success/simple_bitwise/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml b/noir/test_programs/execution_success/simple_bitwise/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/Prover.toml rename to noir/test_programs/execution_success/simple_bitwise/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr b/noir/test_programs/execution_success/simple_bitwise/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_bitwise/src/main.nr rename to noir/test_programs/execution_success/simple_bitwise/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml b/noir/test_programs/execution_success/simple_comparison/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_comparison/Nargo.toml rename to noir/test_programs/execution_success/simple_comparison/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_comparison/Prover.toml b/noir/test_programs/execution_success/simple_comparison/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_comparison/Prover.toml rename to noir/test_programs/execution_success/simple_comparison/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_comparison/src/main.nr b/noir/test_programs/execution_success/simple_comparison/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_comparison/src/main.nr rename to noir/test_programs/execution_success/simple_comparison/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_mut/Nargo.toml b/noir/test_programs/execution_success/simple_mut/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_mut/Nargo.toml rename to noir/test_programs/execution_success/simple_mut/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_mut/Prover.toml b/noir/test_programs/execution_success/simple_mut/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_mut/Prover.toml rename to noir/test_programs/execution_success/simple_mut/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_mut/src/main.nr b/noir/test_programs/execution_success/simple_mut/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_mut/src/main.nr rename to noir/test_programs/execution_success/simple_mut/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_not/Nargo.toml b/noir/test_programs/execution_success/simple_not/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_not/Nargo.toml rename to noir/test_programs/execution_success/simple_not/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_not/Prover.toml b/noir/test_programs/execution_success/simple_not/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_not/Prover.toml rename to noir/test_programs/execution_success/simple_not/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_not/src/main.nr b/noir/test_programs/execution_success/simple_not/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_not/src/main.nr rename to noir/test_programs/execution_success/simple_not/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_print/Nargo.toml b/noir/test_programs/execution_success/simple_print/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_print/Nargo.toml rename to noir/test_programs/execution_success/simple_print/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/Prover.toml b/noir/test_programs/execution_success/simple_print/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/orphaned_trait_impl/Prover.toml rename to noir/test_programs/execution_success/simple_print/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_print/src/main.nr b/noir/test_programs/execution_success/simple_print/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_print/src/main.nr rename to noir/test_programs/execution_success/simple_print/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml b/noir/test_programs/execution_success/simple_program_addition/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/Nargo.toml rename to noir/test_programs/execution_success/simple_program_addition/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml b/noir/test_programs/execution_success/simple_program_addition/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/Prover.toml rename to noir/test_programs/execution_success/simple_program_addition/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr b/noir/test_programs/execution_success/simple_program_addition/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_program_addition/src/main.nr rename to noir/test_programs/execution_success/simple_program_addition/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_radix/Nargo.toml b/noir/test_programs/execution_success/simple_radix/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_radix/Nargo.toml rename to noir/test_programs/execution_success/simple_radix/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_radix/Prover.toml b/noir/test_programs/execution_success/simple_radix/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_radix/Prover.toml rename to noir/test_programs/execution_success/simple_radix/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_radix/src/main.nr b/noir/test_programs/execution_success/simple_radix/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_radix/src/main.nr rename to noir/test_programs/execution_success/simple_radix/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shield/Nargo.toml b/noir/test_programs/execution_success/simple_shield/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shield/Nargo.toml rename to noir/test_programs/execution_success/simple_shield/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shield/Prover.toml b/noir/test_programs/execution_success/simple_shield/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shield/Prover.toml rename to noir/test_programs/execution_success/simple_shield/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shield/src/main.nr b/noir/test_programs/execution_success/simple_shield/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shield/src/main.nr rename to noir/test_programs/execution_success/simple_shield/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml b/noir/test_programs/execution_success/simple_shift_left_right/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Nargo.toml rename to noir/test_programs/execution_success/simple_shift_left_right/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml b/noir/test_programs/execution_success/simple_shift_left_right/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/Prover.toml rename to noir/test_programs/execution_success/simple_shift_left_right/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr b/noir/test_programs/execution_success/simple_shift_left_right/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/simple_shift_left_right/src/main.nr rename to noir/test_programs/execution_success/simple_shift_left_right/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Nargo.toml b/noir/test_programs/execution_success/slice_dynamic_index/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Nargo.toml rename to noir/test_programs/execution_success/slice_dynamic_index/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Prover.toml b/noir/test_programs/execution_success/slice_dynamic_index/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/Prover.toml rename to noir/test_programs/execution_success/slice_dynamic_index/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr b/noir/test_programs/execution_success/slice_dynamic_index/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr rename to noir/test_programs/execution_success/slice_dynamic_index/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/Nargo.toml b/noir/test_programs/execution_success/slice_struct_field/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/Nargo.toml rename to noir/test_programs/execution_success/slice_struct_field/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/Prover.toml b/noir/test_programs/execution_success/slice_struct_field/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/Prover.toml rename to noir/test_programs/execution_success/slice_struct_field/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/src/main.nr b/noir/test_programs/execution_success/slice_struct_field/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slice_struct_field/src/main.nr rename to noir/test_programs/execution_success/slice_struct_field/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/slices/Nargo.toml b/noir/test_programs/execution_success/slices/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slices/Nargo.toml rename to noir/test_programs/execution_success/slices/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slices/Prover.toml b/noir/test_programs/execution_success/slices/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slices/Prover.toml rename to noir/test_programs/execution_success/slices/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/slices/src/main.nr b/noir/test_programs/execution_success/slices/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/slices/src/main.nr rename to noir/test_programs/execution_success/slices/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/strings/Nargo.toml b/noir/test_programs/execution_success/strings/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/strings/Nargo.toml rename to noir/test_programs/execution_success/strings/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/strings/Prover.toml b/noir/test_programs/execution_success/strings/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/strings/Prover.toml rename to noir/test_programs/execution_success/strings/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/strings/src/main.nr b/noir/test_programs/execution_success/strings/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/strings/src/main.nr rename to noir/test_programs/execution_success/strings/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct/Nargo.toml b/noir/test_programs/execution_success/struct/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct/Nargo.toml rename to noir/test_programs/execution_success/struct/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct/Prover.toml b/noir/test_programs/execution_success/struct/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct/Prover.toml rename to noir/test_programs/execution_success/struct/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct/src/main.nr b/noir/test_programs/execution_success/struct/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct/src/main.nr rename to noir/test_programs/execution_success/struct/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml b/noir/test_programs/execution_success/struct_array_inputs/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Nargo.toml rename to noir/test_programs/execution_success/struct_array_inputs/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml b/noir/test_programs/execution_success/struct_array_inputs/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/Prover.toml rename to noir/test_programs/execution_success/struct_array_inputs/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr b/noir/test_programs/execution_success/struct_array_inputs/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_array_inputs/src/main.nr rename to noir/test_programs/execution_success/struct_array_inputs/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml b/noir/test_programs/execution_success/struct_fields_ordering/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Nargo.toml rename to noir/test_programs/execution_success/struct_fields_ordering/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml b/noir/test_programs/execution_success/struct_fields_ordering/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/Prover.toml rename to noir/test_programs/execution_success/struct_fields_ordering/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr b/noir/test_programs/execution_success/struct_fields_ordering/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_fields_ordering/src/main.nr rename to noir/test_programs/execution_success/struct_fields_ordering/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml b/noir/test_programs/execution_success/struct_inputs/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_inputs/Nargo.toml rename to noir/test_programs/execution_success/struct_inputs/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_inputs/Prover.toml b/noir/test_programs/execution_success/struct_inputs/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_inputs/Prover.toml rename to noir/test_programs/execution_success/struct_inputs/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr b/noir/test_programs/execution_success/struct_inputs/src/foo.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo.nr rename to noir/test_programs/execution_success/struct_inputs/src/foo.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr b/noir/test_programs/execution_success/struct_inputs/src/foo/bar.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/foo/bar.nr rename to noir/test_programs/execution_success/struct_inputs/src/foo/bar.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/main.nr b/noir/test_programs/execution_success/struct_inputs/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/struct_inputs/src/main.nr rename to noir/test_programs/execution_success/struct_inputs/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/submodules/Nargo.toml b/noir/test_programs/execution_success/submodules/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/submodules/Nargo.toml rename to noir/test_programs/execution_success/submodules/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/submodules/Prover.toml b/noir/test_programs/execution_success/submodules/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/submodules/Prover.toml rename to noir/test_programs/execution_success/submodules/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr b/noir/test_programs/execution_success/submodules/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr rename to noir/test_programs/execution_success/submodules/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml b/noir/test_programs/execution_success/to_be_bytes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/Nargo.toml rename to noir/test_programs/execution_success/to_be_bytes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml b/noir/test_programs/execution_success/to_be_bytes/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/Prover.toml rename to noir/test_programs/execution_success/to_be_bytes/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr b/noir/test_programs/execution_success/to_be_bytes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_be_bytes/src/main.nr rename to noir/test_programs/execution_success/to_be_bytes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Nargo.toml b/noir/test_programs/execution_success/to_bytes_consistent/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Nargo.toml rename to noir/test_programs/execution_success/to_bytes_consistent/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Prover.toml b/noir/test_programs/execution_success/to_bytes_consistent/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/Prover.toml rename to noir/test_programs/execution_success/to_bytes_consistent/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/src/main.nr b/noir/test_programs/execution_success/to_bytes_consistent/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_consistent/src/main.nr rename to noir/test_programs/execution_success/to_bytes_consistent/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml b/noir/test_programs/execution_success/to_bytes_integration/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Nargo.toml rename to noir/test_programs/execution_success/to_bytes_integration/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml b/noir/test_programs/execution_success/to_bytes_integration/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/Prover.toml rename to noir/test_programs/execution_success/to_bytes_integration/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr b/noir/test_programs/execution_success/to_bytes_integration/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_bytes_integration/src/main.nr rename to noir/test_programs/execution_success/to_bytes_integration/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml b/noir/test_programs/execution_success/to_le_bytes/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/Nargo.toml rename to noir/test_programs/execution_success/to_le_bytes/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml b/noir/test_programs/execution_success/to_le_bytes/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/Prover.toml rename to noir/test_programs/execution_success/to_le_bytes/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr b/noir/test_programs/execution_success/to_le_bytes/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/to_le_bytes/src/main.nr rename to noir/test_programs/execution_success/to_le_bytes/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/Nargo.toml b/noir/test_programs/execution_success/trait_as_return_type/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/Nargo.toml rename to noir/test_programs/execution_success/trait_as_return_type/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/Prover.toml b/noir/test_programs/execution_success/trait_as_return_type/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/Prover.toml rename to noir/test_programs/execution_success/trait_as_return_type/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/src/main.nr b/noir/test_programs/execution_success/trait_as_return_type/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_as_return_type/src/main.nr rename to noir/test_programs/execution_success/trait_as_return_type/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/Nargo.toml b/noir/test_programs/execution_success/trait_impl_base_type/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/Nargo.toml rename to noir/test_programs/execution_success/trait_impl_base_type/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/Prover.toml b/noir/test_programs/execution_success/trait_impl_base_type/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/Prover.toml rename to noir/test_programs/execution_success/trait_impl_base_type/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/src/main.nr b/noir/test_programs/execution_success/trait_impl_base_type/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/trait_impl_base_type/src/main.nr rename to noir/test_programs/execution_success/trait_impl_base_type/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/Prover.toml b/noir/test_programs/execution_success/traits_in_crates_1/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/Prover.toml rename to noir/test_programs/execution_success/traits_in_crates_1/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate1/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_1/crate1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate1/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_1/crate1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate1/src/lib.nr b/noir/test_programs/execution_success/traits_in_crates_1/crate1/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate1/src/lib.nr rename to noir/test_programs/execution_success/traits_in_crates_1/crate1/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate2/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_1/crate2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate2/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_1/crate2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate2/src/lib.nr b/noir/test_programs/execution_success/traits_in_crates_1/crate2/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/crate2/src/lib.nr rename to noir/test_programs/execution_success/traits_in_crates_1/crate2/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/src/main.nr b/noir/test_programs/execution_success/traits_in_crates_1/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_1/src/main.nr rename to noir/test_programs/execution_success/traits_in_crates_1/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/Prover.toml b/noir/test_programs/execution_success/traits_in_crates_2/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/Prover.toml rename to noir/test_programs/execution_success/traits_in_crates_2/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate1/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_2/crate1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate1/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_2/crate1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate1/src/lib.nr b/noir/test_programs/execution_success/traits_in_crates_2/crate1/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate1/src/lib.nr rename to noir/test_programs/execution_success/traits_in_crates_2/crate1/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate2/Nargo.toml b/noir/test_programs/execution_success/traits_in_crates_2/crate2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate2/Nargo.toml rename to noir/test_programs/execution_success/traits_in_crates_2/crate2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate2/src/lib.nr b/noir/test_programs/execution_success/traits_in_crates_2/crate2/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/crate2/src/lib.nr rename to noir/test_programs/execution_success/traits_in_crates_2/crate2/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/src/main.nr b/noir/test_programs/execution_success/traits_in_crates_2/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/traits_in_crates_2/src/main.nr rename to noir/test_programs/execution_success/traits_in_crates_2/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/Nargo.toml b/noir/test_programs/execution_success/tuple_inputs/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/Nargo.toml rename to noir/test_programs/execution_success/tuple_inputs/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/Prover.toml b/noir/test_programs/execution_success/tuple_inputs/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/Prover.toml rename to noir/test_programs/execution_success/tuple_inputs/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/src/main.nr b/noir/test_programs/execution_success/tuple_inputs/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuple_inputs/src/main.nr rename to noir/test_programs/execution_success/tuple_inputs/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuples/Nargo.toml b/noir/test_programs/execution_success/tuples/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuples/Nargo.toml rename to noir/test_programs/execution_success/tuples/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuples/Prover.toml b/noir/test_programs/execution_success/tuples/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuples/Prover.toml rename to noir/test_programs/execution_success/tuples/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/tuples/src/main.nr b/noir/test_programs/execution_success/tuples/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/tuples/src/main.nr rename to noir/test_programs/execution_success/tuples/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/type_aliases/Nargo.toml b/noir/test_programs/execution_success/type_aliases/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/type_aliases/Nargo.toml rename to noir/test_programs/execution_success/type_aliases/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/type_aliases/Prover.toml b/noir/test_programs/execution_success/type_aliases/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/type_aliases/Prover.toml rename to noir/test_programs/execution_success/type_aliases/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/type_aliases/src/main.nr b/noir/test_programs/execution_success/type_aliases/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/type_aliases/src/main.nr rename to noir/test_programs/execution_success/type_aliases/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/Nargo.toml b/noir/test_programs/execution_success/workspace/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/Nargo.toml rename to noir/test_programs/execution_success/workspace/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/Prover.toml b/noir/test_programs/execution_success/workspace/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/Prover.toml rename to noir/test_programs/execution_success/workspace/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml b/noir/test_programs/execution_success/workspace/crates/a/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Nargo.toml rename to noir/test_programs/execution_success/workspace/crates/a/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml b/noir/test_programs/execution_success/workspace/crates/a/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/a/Prover.toml rename to noir/test_programs/execution_success/workspace/crates/a/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr b/noir/test_programs/execution_success/workspace/crates/a/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/src/main.nr rename to noir/test_programs/execution_success/workspace/crates/a/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml b/noir/test_programs/execution_success/workspace/crates/b/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Nargo.toml rename to noir/test_programs/execution_success/workspace/crates/b/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml b/noir/test_programs/execution_success/workspace/crates/b/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/Prover.toml rename to noir/test_programs/execution_success/workspace/crates/b/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr b/noir/test_programs/execution_success/workspace/crates/b/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace/crates/b/src/main.nr rename to noir/test_programs/execution_success/workspace/crates/b/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml b/noir/test_programs/execution_success/workspace_default_member/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/Nargo.toml rename to noir/test_programs/execution_success/workspace_default_member/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml b/noir/test_programs/execution_success/workspace_default_member/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/Prover.toml rename to noir/test_programs/execution_success/workspace_default_member/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml b/noir/test_programs/execution_success/workspace_default_member/a/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Nargo.toml rename to noir/test_programs/execution_success/workspace_default_member/a/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml b/noir/test_programs/execution_success/workspace_default_member/a/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/a/Prover.toml rename to noir/test_programs/execution_success/workspace_default_member/a/Prover.toml diff --git a/noir/test_programs/execution_success/workspace_default_member/a/src/main.nr b/noir/test_programs/execution_success/workspace_default_member/a/src/main.nr new file mode 100644 index 00000000000..cf72627da2e --- /dev/null +++ b/noir/test_programs/execution_success/workspace_default_member/a/src/main.nr @@ -0,0 +1,3 @@ +fn main(x: Field, y: pub Field) { + assert(x == y); +} diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml b/noir/test_programs/execution_success/workspace_default_member/b/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Nargo.toml rename to noir/test_programs/execution_success/workspace_default_member/b/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml b/noir/test_programs/execution_success/workspace_default_member/b/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/Prover.toml rename to noir/test_programs/execution_success/workspace_default_member/b/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr b/noir/test_programs/execution_success/workspace_default_member/b/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/b/src/main.nr rename to noir/test_programs/execution_success/workspace_default_member/b/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/execution_success/xor/Nargo.toml b/noir/test_programs/execution_success/xor/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/xor/Nargo.toml rename to noir/test_programs/execution_success/xor/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/xor/Prover.toml b/noir/test_programs/execution_success/xor/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/xor/Prover.toml rename to noir/test_programs/execution_success/xor/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/execution_success/xor/src/main.nr b/noir/test_programs/execution_success/xor/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/execution_success/xor/src/main.nr rename to noir/test_programs/execution_success/xor/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/gates_report.sh b/noir/test_programs/gates_report.sh similarity index 100% rename from noir/tooling/nargo_cli/tests/gates_report.sh rename to noir/test_programs/gates_report.sh diff --git a/noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/Nargo.toml b/noir/test_programs/noir_test_failure/should_fail_mismatch/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/Nargo.toml rename to noir/test_programs/noir_test_failure/should_fail_mismatch/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/Prover.toml b/noir/test_programs/noir_test_failure/should_fail_mismatch/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/Prover.toml rename to noir/test_programs/noir_test_failure/should_fail_mismatch/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/src/main.nr b/noir/test_programs/noir_test_failure/should_fail_mismatch/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_failure/should_fail_mismatch/src/main.nr rename to noir/test_programs/noir_test_failure/should_fail_mismatch/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/Nargo.toml b/noir/test_programs/noir_test_success/should_fail_with_matches/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/Nargo.toml rename to noir/test_programs/noir_test_success/should_fail_with_matches/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/Prover.toml b/noir/test_programs/noir_test_success/should_fail_with_matches/Prover.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/Prover.toml rename to noir/test_programs/noir_test_success/should_fail_with_matches/Prover.toml diff --git a/noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/src/main.nr b/noir/test_programs/noir_test_success/should_fail_with_matches/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/noir_test_success/should_fail_with_matches/src/main.nr rename to noir/test_programs/noir_test_success/should_fail_with_matches/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/rebuild.sh b/noir/test_programs/rebuild.sh similarity index 100% rename from noir/tooling/nargo_cli/tests/rebuild.sh rename to noir/test_programs/rebuild.sh diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml b/noir/test_programs/test_libraries/bad_impl/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bad_impl/Nargo.toml rename to noir/test_programs/test_libraries/bad_impl/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr b/noir/test_programs/test_libraries/bad_impl/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bad_impl/src/lib.nr rename to noir/test_programs/test_libraries/bad_impl/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bad_name/Nargo.toml b/noir/test_programs/test_libraries/bad_name/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bad_name/Nargo.toml rename to noir/test_programs/test_libraries/bad_name/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bad_name/src/lib.nr b/noir/test_programs/test_libraries/bad_name/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bad_name/src/lib.nr rename to noir/test_programs/test_libraries/bad_name/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml b/noir/test_programs/test_libraries/bin_dep/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bin_dep/Nargo.toml rename to noir/test_programs/test_libraries/bin_dep/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/test_libraries/bin_dep/src/main.nr b/noir/test_programs/test_libraries/bin_dep/src/main.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/bin_dep/src/main.nr rename to noir/test_programs/test_libraries/bin_dep/src/main.nr diff --git a/noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml b/noir/test_programs/test_libraries/diamond_deps_1/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/Nargo.toml rename to noir/test_programs/test_libraries/diamond_deps_1/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr b/noir/test_programs/test_libraries/diamond_deps_1/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr rename to noir/test_programs/test_libraries/diamond_deps_1/src/lib.nr diff --git a/noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml b/noir/test_programs/test_libraries/diamond_deps_2/Nargo.toml similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/Nargo.toml rename to noir/test_programs/test_libraries/diamond_deps_2/Nargo.toml diff --git a/noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr b/noir/test_programs/test_libraries/diamond_deps_2/src/lib.nr similarity index 100% rename from noir/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr rename to noir/test_programs/test_libraries/diamond_deps_2/src/lib.nr diff --git a/noir/tooling/bb_abstraction_leaks/build.rs b/noir/tooling/bb_abstraction_leaks/build.rs index 9c5e51a8115..166e61a5a97 100644 --- a/noir/tooling/bb_abstraction_leaks/build.rs +++ b/noir/tooling/bb_abstraction_leaks/build.rs @@ -10,7 +10,7 @@ use const_format::formatcp; const USERNAME: &str = "AztecProtocol"; const REPO: &str = "aztec-packages"; -const VERSION: &str = "0.15.1"; +const VERSION: &str = "0.16.0"; const TAG: &str = formatcp!("aztec-packages-v{}", VERSION); const API_URL: &str = diff --git a/noir/tooling/debugger/src/context.rs b/noir/tooling/debugger/src/context.rs index 35cfba497f0..4c429ca2a67 100644 --- a/noir/tooling/debugger/src/context.rs +++ b/noir/tooling/debugger/src/context.rs @@ -522,7 +522,7 @@ fn test_break_brillig_block_while_stepping_acir_opcodes() { // set breakpoint let breakpoint_location = OpcodeLocation::Brillig { acir_index: 0, brillig_index: 1 }; - assert!(context.add_breakpoint(breakpoint_location.clone())); + assert!(context.add_breakpoint(breakpoint_location)); // execute the first ACIR opcode (Brillig block) -> should reach the breakpoint instead let result = context.step_acir_opcode(); diff --git a/noir/tooling/nargo/src/ops/foreign_calls.rs b/noir/tooling/nargo/src/ops/foreign_calls.rs index 6cc78febab3..1ca270a5bf7 100644 --- a/noir/tooling/nargo/src/ops/foreign_calls.rs +++ b/noir/tooling/nargo/src/ops/foreign_calls.rs @@ -2,7 +2,6 @@ use acvm::{ acir::brillig::{ForeignCallParam, ForeignCallResult, Value}, pwg::ForeignCallWaitInfo, }; -use iter_extended::vecmap; use noirc_printable_type::{decode_string_value, ForeignCallError, PrintableValueDisplay}; pub trait ForeignCallExecutor { @@ -16,8 +15,6 @@ pub trait ForeignCallExecutor { /// After resolution of a foreign call, nargo will restart execution of the ACVM pub(crate) enum ForeignCall { Println, - Sequence, - ReverseSequence, CreateMock, SetMockParams, SetMockReturns, @@ -35,8 +32,6 @@ impl ForeignCall { pub(crate) fn name(&self) -> &'static str { match self { ForeignCall::Println => "println", - ForeignCall::Sequence => "get_number_sequence", - ForeignCall::ReverseSequence => "get_reverse_number_sequence", ForeignCall::CreateMock => "create_mock", ForeignCall::SetMockParams => "set_mock_params", ForeignCall::SetMockReturns => "set_mock_returns", @@ -48,8 +43,6 @@ impl ForeignCall { pub(crate) fn lookup(op_name: &str) -> Option { match op_name { "println" => Some(ForeignCall::Println), - "get_number_sequence" => Some(ForeignCall::Sequence), - "get_reverse_number_sequence" => Some(ForeignCall::ReverseSequence), "create_mock" => Some(ForeignCall::CreateMock), "set_mock_params" => Some(ForeignCall::SetMockParams), "set_mock_returns" => Some(ForeignCall::SetMockReturns), @@ -147,30 +140,6 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { } Ok(ForeignCallResult { values: vec![] }) } - Some(ForeignCall::Sequence) => { - let sequence_length: u128 = - foreign_call.inputs[0].unwrap_value().to_field().to_u128(); - let sequence = vecmap(0..sequence_length, Value::from); - - Ok(ForeignCallResult { - values: vec![ - ForeignCallParam::Single(sequence_length.into()), - ForeignCallParam::Array(sequence), - ], - }) - } - Some(ForeignCall::ReverseSequence) => { - let sequence_length: u128 = - foreign_call.inputs[0].unwrap_value().to_field().to_u128(); - let sequence = vecmap((0..sequence_length).rev(), Value::from); - - Ok(ForeignCallResult { - values: vec![ - ForeignCallParam::Single(sequence_length.into()), - ForeignCallParam::Array(sequence), - ], - }) - } Some(ForeignCall::CreateMock) => { let mock_oracle_name = Self::parse_string(&foreign_call.inputs[0]); assert!(ForeignCall::lookup(&mock_oracle_name).is_none()); diff --git a/noir/tooling/nargo/src/package.rs b/noir/tooling/nargo/src/package.rs index 94c7c5b9c98..ecbf3585210 100644 --- a/noir/tooling/nargo/src/package.rs +++ b/noir/tooling/nargo/src/package.rs @@ -43,6 +43,7 @@ impl Dependency { #[derive(Clone)] pub struct Package { + pub version: Option, // A semver string which specifies the compiler version required to compile this package pub compiler_required_version: Option, pub root_dir: PathBuf, diff --git a/noir/tooling/nargo_cli/build.rs b/noir/tooling/nargo_cli/build.rs index 0d1acca6ee9..27a9b83d836 100644 --- a/noir/tooling/nargo_cli/build.rs +++ b/noir/tooling/nargo_cli/build.rs @@ -33,11 +33,11 @@ fn main() { // Try to find the directory that Cargo sets when it is running; otherwise fallback to assuming the CWD // is the root of the repository and append the crate path - let manifest_dir = match std::env::var("CARGO_MANIFEST_DIR") { - Ok(dir) => PathBuf::from(dir), - Err(_) => std::env::current_dir().unwrap().join("crates").join("nargo_cli"), + let root_dir = match std::env::var("CARGO_MANIFEST_DIR") { + Ok(dir) => PathBuf::from(dir).parent().unwrap().parent().unwrap().to_path_buf(), + Err(_) => std::env::current_dir().unwrap(), }; - let test_dir = manifest_dir.join("tests"); + let test_dir = root_dir.join("test_programs"); generate_execution_success_tests(&mut test_file, &test_dir); generate_noir_test_success_tests(&mut test_file, &test_dir); diff --git a/noir/tooling/nargo_cli/src/cli/debug_cmd.rs b/noir/tooling/nargo_cli/src/cli/debug_cmd.rs index 0e7579b0721..5204e0f122c 100644 --- a/noir/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/noir/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use acvm::acir::native_types::WitnessMap; use clap::Args; @@ -64,27 +66,42 @@ pub(crate) fn run( &opcode_support, )?; - println!("[{}] Starting debugger", package.name); - let (return_value, solved_witness) = - debug_program_and_decode(compiled_program, package, &args.prover_name)?; + run_async(package, compiled_program, &args.prover_name, &args.witness_name, target_dir) +} + +fn run_async( + package: &Package, + program: CompiledProgram, + prover_name: &str, + witness_name: &Option, + target_dir: &PathBuf, +) -> Result<(), CliError> { + use tokio::runtime::Builder; + let runtime = Builder::new_current_thread().enable_all().build().unwrap(); + + runtime.block_on(async { + println!("[{}] Starting debugger", package.name); + let (return_value, solved_witness) = + debug_program_and_decode(program, package, prover_name)?; - if let Some(solved_witness) = solved_witness { - println!("[{}] Circuit witness successfully solved", package.name); + if let Some(solved_witness) = solved_witness { + println!("[{}] Circuit witness successfully solved", package.name); - if let Some(return_value) = return_value { - println!("[{}] Circuit output: {return_value:?}", package.name); - } + if let Some(return_value) = return_value { + println!("[{}] Circuit output: {return_value:?}", package.name); + } - if let Some(witness_name) = &args.witness_name { - let witness_path = save_witness_to_dir(solved_witness, witness_name, target_dir)?; + if let Some(witness_name) = witness_name { + let witness_path = save_witness_to_dir(solved_witness, witness_name, target_dir)?; - println!("[{}] Witness saved to {}", package.name, witness_path.display()); + println!("[{}] Witness saved to {}", package.name, witness_path.display()); + } + } else { + println!("Debugger execution halted."); } - } else { - println!("Debugger execution halted."); - } - Ok(()) + Ok(()) + }) } fn debug_program_and_decode( diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz deleted file mode 100644 index bb735d852d5..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz deleted file mode 100644 index b80b33eecdf..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/array_dynamic/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz deleted file mode 100644 index 69cbde31d9d..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_acir_as_brillig/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz deleted file mode 100644 index a093703d4b3..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_arrays/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz deleted file mode 100644 index 2cf3b7251e6..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_assert/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz deleted file mode 100644 index be47506c42f..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_blake2s/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz deleted file mode 100644 index b69e231774b..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz deleted file mode 100644 index 59b89c22bc3..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_array/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz deleted file mode 100644 index e4155f58ead..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_calls_conditionals/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz deleted file mode 100644 index 9117511d800..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_conditional/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz deleted file mode 100644 index cdc28517544..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_ecdsa/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz deleted file mode 100644 index d1819212993..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_fns_as_values/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz deleted file mode 100644 index 73c742a2dd1..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_hash_to_field/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz deleted file mode 100644 index 4e17ecc5d7b..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_identity_function/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz deleted file mode 100644 index 1a64fd03980..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_keccak/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz deleted file mode 100644 index f69df4781ec..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_arrays/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz deleted file mode 100644 index 100a208bcd8..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_nested_slices/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz deleted file mode 100644 index 9702ca340a5..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_not/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz deleted file mode 100644 index db158f61882..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/witness.gz deleted file mode 100644 index 3fead7f6b2e..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_oracle/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz deleted file mode 100644 index 27f6f353d25..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_pedersen/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz deleted file mode 100644 index c0c91d81546..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_recursion/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz deleted file mode 100644 index 4069ca2cb5e..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_references/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz deleted file mode 100644 index 9f5f787c655..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_scalar_mul/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz deleted file mode 100644 index 625ae64a11d..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_schnorr/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz deleted file mode 100644 index 49f7e6afcf4..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_sha256/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz deleted file mode 100644 index 57ca1d59fed..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_slices/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz deleted file mode 100644 index 1249975b27c..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_be_bytes/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz deleted file mode 100644 index fe9ac34ed17..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_bytes_integration/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz deleted file mode 100644 index 834f57e1ee7..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_to_le_bytes/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz deleted file mode 100644 index 4b2fbcd3462..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_top_level/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz deleted file mode 100644 index ac18684a07e..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/witness.gz deleted file mode 100644 index ceaf7ad008e..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/brillig_unitialised_arrays/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz deleted file mode 100644 index 46a738a97e3..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz deleted file mode 100644 index 5bafffff0d8..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz deleted file mode 100644 index ea9187f4084..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/debug_logs/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz deleted file mode 100644 index 75b1cbb5072..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/merkle_insert/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz deleted file mode 100644 index c45cd40f28e..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/mock_oracle/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz deleted file mode 100644 index 9f518522755..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/witness.gz deleted file mode 100644 index 62a1378dece..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_array_dynamic/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz deleted file mode 100644 index 270cfcaf53c..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/nested_arrays_from_brillig/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz deleted file mode 100644 index 5c0339446c5..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/witness.gz deleted file mode 100644 index 095aef252ee..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_mem_op_predicate/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz deleted file mode 100644 index f29fbef8d3f..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/regression_method_cannot_be_found/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz deleted file mode 100644 index 5a2c524f26b..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/simple_print/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz deleted file mode 100644 index 7b605a2b87b..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz deleted file mode 100644 index 148355f9335..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz b/noir/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz deleted file mode 100644 index 424f4bd2d0f..00000000000 Binary files a/noir/tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz and /dev/null differ diff --git a/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/Nargo.toml b/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/Nargo.toml new file mode 100644 index 00000000000..ecef0e2a07c --- /dev/null +++ b/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "raw_string_huge" +type = "bin" +authors = [""] +[dependencies] \ No newline at end of file diff --git a/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/src/main.nr b/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/src/main.nr new file mode 100644 index 00000000000..7bca9942e7a --- /dev/null +++ b/noir/tooling/nargo_cli/tests/compile_failure/raw_string_huge/src/main.nr @@ -0,0 +1,4 @@ +fn main() { + // Fails because of too many hashes for raw string (256+ hashes) + let _a = r##############################################################################################################################################################################################################################################################################"hello"##############################################################################################################################################################################################################################################################################; +} diff --git a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr b/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr deleted file mode 100644 index 550e5034a7b..00000000000 --- a/noir/tooling/nargo_cli/tests/compile_failure/workspace_missing_toml/crates/a/src/main.nr +++ /dev/null @@ -1,3 +0,0 @@ -fn main(x : Field, y : pub Field) { - assert(x == y); -} diff --git a/noir/compiler/integration-tests/circuits/main/Nargo.toml b/noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/Nargo.toml similarity index 71% rename from noir/compiler/integration-tests/circuits/main/Nargo.toml rename to noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/Nargo.toml index cc5a0a357fa..81147e65f34 100644 --- a/noir/compiler/integration-tests/circuits/main/Nargo.toml +++ b/noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/Nargo.toml @@ -1,5 +1,6 @@ [package] -name = "main" +name = "raw_string" type = "bin" authors = [""] + [dependencies] diff --git a/noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/src/main.nr b/noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/src/main.nr new file mode 100644 index 00000000000..ad8dfe82ae5 --- /dev/null +++ b/noir/tooling/nargo_cli/tests/compile_success_empty/raw_string/src/main.nr @@ -0,0 +1,13 @@ +global D = r#####"Hello "world""#####; + +fn main() { + let a = "Hello \"world\""; + let b = r#"Hello "world""#; + let c = r##"Hello "world""##; + assert(a == b); + assert(b == c); + assert(c == D); + let x = r#"Hello World"#; + let y = r"Hello World"; + assert(x == y); +} diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Nargo.toml b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Nargo.toml new file mode 100644 index 00000000000..d191eb53ddf --- /dev/null +++ b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "brillig_cow" +type = "bin" +authors = [""] + +[dependencies] diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Prover.toml b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Prover.toml new file mode 100644 index 00000000000..6533d218b15 --- /dev/null +++ b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/Prover.toml @@ -0,0 +1,7 @@ +original = [0, 1, 2, 3, 4] +index = 2 + +[expected_result] +original = [0, 1, 2, 3, 4] +modified_once = [0, 1, 27, 3, 4] +modified_twice = [0, 1, 27, 27, 4] diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/src/main.nr b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/src/main.nr new file mode 100644 index 00000000000..7d847e085fe --- /dev/null +++ b/noir/tooling/nargo_cli/tests/execution_success/brillig_cow/src/main.nr @@ -0,0 +1,54 @@ +// Tests the copy on write optimization for arrays. We look for cases where we are modifying an array in place when we shouldn't. + +global ARRAY_SIZE = 5; + +struct ExecutionResult { + original: [Field; ARRAY_SIZE], + modified_once: [Field; ARRAY_SIZE], + modified_twice: [Field; ARRAY_SIZE], +} + +impl ExecutionResult { + fn is_equal(self, other: ExecutionResult) -> bool { + (self.original == other.original) & + (self.modified_once == other.modified_once) & + (self.modified_twice == other.modified_twice) + } +} + +fn modify_in_inlined_constrained(original: [Field; ARRAY_SIZE], index: u64) -> ExecutionResult { + let mut modified = original; + + modified[index] = 27; + + let modified_once = modified; + + modified[index+1] = 27; + + ExecutionResult { + original, + modified_once, + modified_twice: modified + } +} + +unconstrained fn modify_in_unconstrained(original: [Field; ARRAY_SIZE], index: u64) -> ExecutionResult { + let mut modified = original; + + modified[index] = 27; + + let modified_once = modified; + + modified[index+1] = 27; + + ExecutionResult { + original, + modified_once, + modified_twice: modified + } +} + +unconstrained fn main(original: [Field; ARRAY_SIZE], index: u64, expected_result: ExecutionResult) { + assert(expected_result.is_equal(modify_in_unconstrained(original, index))); + assert(expected_result.is_equal(modify_in_inlined_constrained(original, index))); +} diff --git a/noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr b/noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr deleted file mode 100644 index 86cf6ff1498..00000000000 --- a/noir/tooling/nargo_cli/tests/execution_success/brillig_oracle/src/main.nr +++ /dev/null @@ -1,26 +0,0 @@ -use dep::std::slice; -// Tests oracle usage in brillig/unconstrained functions -fn main(x: Field) { - get_number_sequence_wrapper(20); -} -// TODO(#1911): This function does not need to be an oracle but acts -// as a useful test while we finalize code generation for slices in Brillig -#[oracle(get_number_sequence)] -unconstrained fn get_number_sequence(_size: Field) -> [Field] {} -// TODO(#1911) -#[oracle(get_reverse_number_sequence)] -unconstrained fn get_reverse_number_sequence(_size: Field) -> [Field] {} - -unconstrained fn get_number_sequence_wrapper(size: Field) { - let slice = get_number_sequence(size); - for i in 0..19 as u32 { - assert(slice[i] == i as Field); - } - - let reversed_slice = get_reverse_number_sequence(size); - // Regression test that we have not overwritten memory - for i in 0..19 as u32 { - assert(slice[i] == reversed_slice[19 - i]); - } -} - diff --git a/noir/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml b/noir/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml deleted file mode 100644 index 2c1854573a4..00000000000 --- a/noir/tooling/nargo_cli/tests/execution_success/simple_print/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = 1 -y = 2 diff --git a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr b/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr deleted file mode 100644 index 6e170de75fc..00000000000 --- a/noir/tooling/nargo_cli/tests/execution_success/workspace_default_member/b/src/main.nr +++ /dev/null @@ -1,3 +0,0 @@ -fn main(x : Field, y : pub Field) { - assert(x != y); -} diff --git a/noir/tooling/nargo_fmt/src/rewrite/array.rs b/noir/tooling/nargo_fmt/src/rewrite/array.rs index f67ae5e75fe..fc5b240f83e 100644 --- a/noir/tooling/nargo_fmt/src/rewrite/array.rs +++ b/noir/tooling/nargo_fmt/src/rewrite/array.rs @@ -2,7 +2,7 @@ use noirc_frontend::{hir::resolution::errors::Span, token::Token, Expression}; use crate::{ utils::{Expr, FindToken}, - visitor::FmtVisitor, + visitor::{expr::NewlineMode, FmtVisitor}, }; pub(crate) fn rewrite(mut visitor: FmtVisitor, array: Vec, array_span: Span) -> String { @@ -80,6 +80,6 @@ pub(crate) fn rewrite(mut visitor: FmtVisitor, array: Vec, array_spa items_str.trim().into(), nested_indent, visitor.shape(), - true, + NewlineMode::IfContainsNewLineAndWidth, ) } diff --git a/noir/tooling/nargo_fmt/src/rewrite/expr.rs b/noir/tooling/nargo_fmt/src/rewrite/expr.rs index 4d7279815df..3c46319c1aa 100644 --- a/noir/tooling/nargo_fmt/src/rewrite/expr.rs +++ b/noir/tooling/nargo_fmt/src/rewrite/expr.rs @@ -1,7 +1,7 @@ use noirc_frontend::{token::Token, ArrayLiteral, Expression, ExpressionKind, Literal, UnaryOp}; use crate::visitor::{ - expr::{format_brackets, format_parens}, + expr::{format_brackets, format_parens, NewlineMode}, ExpressionType, FmtVisitor, Indent, Shape, }; @@ -60,6 +60,7 @@ pub(crate) fn rewrite( call_expr.arguments, args_span, true, + NewlineMode::IfContainsNewLineAndWidth, ); format!("{callee}{args}") @@ -80,6 +81,7 @@ pub(crate) fn rewrite( method_call_expr.arguments, args_span, true, + NewlineMode::IfContainsNewLineAndWidth, ); format!("{object}.{method}{args}") @@ -97,13 +99,22 @@ pub(crate) fn rewrite( format!("{collection}{index}") } - ExpressionKind::Tuple(exprs) => { - format_parens(None, visitor.fork(), shape, exprs.len() == 1, exprs, span, false) - } + ExpressionKind::Tuple(exprs) => format_parens( + None, + visitor.fork(), + shape, + exprs.len() == 1, + exprs, + span, + true, + NewlineMode::Normal, + ), ExpressionKind::Literal(literal) => match literal { - Literal::Integer(_) | Literal::Bool(_) | Literal::Str(_) | Literal::FmtStr(_) => { - visitor.slice(span).to_string() - } + Literal::Integer(_) + | Literal::Bool(_) + | Literal::Str(_) + | Literal::RawStr(..) + | Literal::FmtStr(_) => visitor.slice(span).to_string(), Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => { let repeated = rewrite_sub_expr(visitor, shape, *repeated_element); let length = rewrite_sub_expr(visitor, shape, *length); diff --git a/noir/tooling/nargo_fmt/src/utils.rs b/noir/tooling/nargo_fmt/src/utils.rs index 626795959a3..0d422e57de1 100644 --- a/noir/tooling/nargo_fmt/src/utils.rs +++ b/noir/tooling/nargo_fmt/src/utils.rs @@ -120,7 +120,7 @@ impl<'me, T> Exprs<'me, T> { pub(crate) trait FindToken { fn find_token(&self, token: Token) -> Option; - fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option; + fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option; } impl FindToken for str { @@ -128,11 +128,11 @@ impl FindToken for str { Lexer::new(self).flatten().find_map(|it| (it.token() == &token).then(|| it.to_span())) } - fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option { + fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option { Lexer::new(self) .skip_comments(false) .flatten() - .find_map(|spanned| f(spanned.token()).then(|| spanned.to_span().end())) + .find_map(|spanned| f(spanned.token()).then(|| spanned.to_span())) } } @@ -142,7 +142,7 @@ pub(crate) fn find_comment_end(slice: &str, is_last: bool) -> usize { .find_token_with(|token| { matches!(token, Token::LineComment(_, _) | Token::BlockComment(_, _)) }) - .map(|index| index as usize) + .map(|index| index.end() as usize) .unwrap_or(slice.len()) } diff --git a/noir/tooling/nargo_fmt/src/visitor/expr.rs b/noir/tooling/nargo_fmt/src/visitor/expr.rs index a5e5a1c7846..586d9583e32 100644 --- a/noir/tooling/nargo_fmt/src/visitor/expr.rs +++ b/noir/tooling/nargo_fmt/src/visitor/expr.rs @@ -89,6 +89,7 @@ impl FmtVisitor<'_> { false, exprs, nested_indent, + true, ); visitor.indent.block_unindent(visitor.config); @@ -186,6 +187,7 @@ impl FmtVisitor<'_> { } } +// TODO: fixme #[allow(clippy::too_many_arguments)] pub(crate) fn format_seq( shape: Shape, @@ -196,7 +198,8 @@ pub(crate) fn format_seq( exprs: Vec, span: Span, tactic: Tactic, - soft_newline: bool, + mode: NewlineMode, + reduce: bool, ) -> String { let mut nested_indent = shape; let shape = shape; @@ -204,9 +207,9 @@ pub(crate) fn format_seq( nested_indent.indent.block_indent(visitor.config); let exprs: Vec<_> = utils::Exprs::new(&visitor, nested_indent, span, exprs).collect(); - let exprs = format_exprs(visitor.config, tactic, trailing_comma, exprs, nested_indent); + let exprs = format_exprs(visitor.config, tactic, trailing_comma, exprs, nested_indent, reduce); - wrap_exprs(prefix, suffix, exprs, nested_indent, shape, soft_newline) + wrap_exprs(prefix, suffix, exprs, nested_indent, shape, mode) } pub(crate) fn format_brackets( @@ -225,10 +228,13 @@ pub(crate) fn format_brackets( exprs, span, Tactic::LimitedHorizontalVertical(array_width), + NewlineMode::Normal, false, ) } +// TODO: fixme +#[allow(clippy::too_many_arguments)] pub(crate) fn format_parens( max_width: Option, visitor: FmtVisitor, @@ -236,10 +242,11 @@ pub(crate) fn format_parens( trailing_comma: bool, exprs: Vec, span: Span, - soft_newline: bool, + reduce: bool, + mode: NewlineMode, ) -> String { let tactic = max_width.map(Tactic::LimitedHorizontalVertical).unwrap_or(Tactic::Horizontal); - format_seq(shape, "(", ")", visitor, trailing_comma, exprs, span, tactic, soft_newline) + format_seq(shape, "(", ")", visitor, trailing_comma, exprs, span, tactic, mode, reduce) } fn format_exprs( @@ -248,11 +255,12 @@ fn format_exprs( trailing_comma: bool, exprs: Vec, shape: Shape, + reduce: bool, ) -> String { let mut result = String::new(); let indent_str = shape.indent.to_string(); - let tactic = tactic.definitive(&exprs, config.short_array_element_width_threshold); + let tactic = tactic.definitive(&exprs, config.short_array_element_width_threshold, reduce); let mut exprs = exprs.into_iter().enumerate().peekable(); let mut line_len = 0; let mut prev_expr_trailing_comment = false; @@ -325,16 +333,32 @@ fn format_exprs( result } +#[derive(PartialEq, Eq)] +pub(crate) enum NewlineMode { + IfContainsNewLine, + IfContainsNewLineAndWidth, + Normal, +} + pub(crate) fn wrap_exprs( prefix: &str, suffix: &str, exprs: String, nested_shape: Shape, shape: Shape, - soft_newline: bool, + newline_mode: NewlineMode, ) -> String { - let mut force_one_line = first_line_width(&exprs) <= shape.width; - if soft_newline && force_one_line { + let mut force_one_line = if newline_mode == NewlineMode::IfContainsNewLine { + true + } else { + first_line_width(&exprs) <= shape.width + }; + + if matches!( + newline_mode, + NewlineMode::IfContainsNewLine | NewlineMode::IfContainsNewLineAndWidth + ) && force_one_line + { force_one_line = !exprs.contains('\n'); } @@ -373,7 +397,8 @@ impl Tactic { fn definitive( self, exprs: &[Expr], - short_array_element_width_threshold: usize, + short_width_threshold: usize, + reduce: bool, ) -> DefinitiveTactic { let tactic = || { let has_single_line_comment = exprs.iter().any(|item| { @@ -407,7 +432,12 @@ impl Tactic { } }; - tactic().reduce(exprs, short_array_element_width_threshold) + let definitive_tactic = tactic(); + if reduce { + definitive_tactic.reduce(exprs, short_width_threshold) + } else { + definitive_tactic + } } } diff --git a/noir/tooling/nargo_fmt/src/visitor/item.rs b/noir/tooling/nargo_fmt/src/visitor/item.rs index af375515413..c0a255b7ef6 100644 --- a/noir/tooling/nargo_fmt/src/visitor/item.rs +++ b/noir/tooling/nargo_fmt/src/visitor/item.rs @@ -7,7 +7,7 @@ use noirc_frontend::{ use crate::{ utils::{last_line_contains_single_line_comment, last_line_used_width, FindToken}, - visitor::expr::format_seq, + visitor::expr::{format_seq, NewlineMode}, }; use super::{ @@ -54,6 +54,7 @@ impl super::FmtVisitor<'_> { generics, span, HorizontalVertical, + NewlineMode::IfContainsNewLine, false, ); @@ -63,12 +64,18 @@ impl super::FmtVisitor<'_> { let parameters = if parameters.is_empty() { self.slice(params_span).into() } else { - let fn_start = result.find_token(Token::Keyword(Keyword::Fn)).unwrap().start(); - let slice = self.slice(fn_start..result.len() as u32); + let fn_start = result + .find_token_with(|token| { + matches!(token, Token::Keyword(Keyword::Fn | Keyword::Unconstrained)) + }) + .unwrap() + .start(); + let slice = self.slice(fn_start..result.len() as u32); let indent = self.indent; let used_width = last_line_used_width(slice, indent.width()); - let one_line_budget = self.budget(used_width + return_type.len()); + let overhead = if return_type.is_empty() { 2 } else { 3 }; // 2 = `()`, 3 = `() ` + let one_line_budget = self.budget(used_width + return_type.len() + overhead); let shape = Shape { width: one_line_budget, indent }; let tactic = LimitedHorizontalVertical(one_line_budget); @@ -82,7 +89,8 @@ impl super::FmtVisitor<'_> { parameters, params_span.into(), tactic, - true, + NewlineMode::IfContainsNewLine, + false, ) }; diff --git a/noir/tooling/nargo_fmt/src/visitor/stmt.rs b/noir/tooling/nargo_fmt/src/visitor/stmt.rs index c27b7911d03..800a8656ef3 100644 --- a/noir/tooling/nargo_fmt/src/visitor/stmt.rs +++ b/noir/tooling/nargo_fmt/src/visitor/stmt.rs @@ -4,9 +4,9 @@ use noirc_frontend::{ ConstrainKind, ConstrainStatement, ExpressionKind, ForRange, Statement, StatementKind, }; -use crate::rewrite; +use crate::{rewrite, visitor::expr::wrap_exprs}; -use super::ExpressionType; +use super::{expr::NewlineMode, ExpressionType}; impl super::FmtVisitor<'_> { pub(crate) fn visit_stmts(&mut self, stmts: Vec) { @@ -33,30 +33,51 @@ impl super::FmtVisitor<'_> { self.push_rewrite(format!("{let_str} {expr_str};"), span); } StatementKind::Constrain(ConstrainStatement(expr, message, kind)) => { + let mut nested_shape = self.shape(); + let shape = nested_shape; + + nested_shape.indent.block_indent(self.config); + let message = message.map_or(String::new(), |message| format!(", \"{message}\"")); - let constrain = match kind { + + let (callee, args) = match kind { ConstrainKind::Assert => { - let assertion = rewrite::sub_expr(self, self.shape(), expr); + let assertion = rewrite::sub_expr(self, nested_shape, expr); + let args = format!("{assertion}{message}"); - format!("assert({assertion}{message});") + ("assert", args) } ConstrainKind::AssertEq => { if let ExpressionKind::Infix(infix) = expr.kind { - let lhs = rewrite::sub_expr(self, self.shape(), infix.lhs); - let rhs = rewrite::sub_expr(self, self.shape(), infix.rhs); + let lhs = rewrite::sub_expr(self, nested_shape, infix.lhs); + let rhs = rewrite::sub_expr(self, nested_shape, infix.rhs); - format!("assert_eq({lhs}, {rhs}{message});") + let args = format!("{lhs}, {rhs}{message}"); + + ("assert_eq", args) } else { unreachable!() } } ConstrainKind::Constrain => { let expr = rewrite::sub_expr(self, self.shape(), expr); - format!("constrain {expr};") + let constrain = format!("constrain {expr};"); + self.push_rewrite(constrain, span); + return; } }; + let args = wrap_exprs( + "(", + ")", + args, + nested_shape, + shape, + NewlineMode::IfContainsNewLineAndWidth, + ); + let constrain = format!("{callee}{args};"); + self.push_rewrite(constrain, span); } StatementKind::For(for_stmt) => { diff --git a/noir/tooling/nargo_fmt/tests/expected/call.nr b/noir/tooling/nargo_fmt/tests/expected/call.nr index 7824ba37089..de78d7c4edb 100644 --- a/noir/tooling/nargo_fmt/tests/expected/call.nr +++ b/noir/tooling/nargo_fmt/tests/expected/call.nr @@ -39,10 +39,12 @@ fn foo() { assert(x == y); - assert(p4_affine.eq( - Gaffine::new( - 6890855772600357754907169075114257697580319025794532037257385534741338397365, - 4338620300185947561074059802482547481416142213883829469920100239455078257889 + assert( + p4_affine.eq( + Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889 + ) ) - )); + ); } diff --git a/noir/tooling/nargo_fmt/tests/expected/fn.nr b/noir/tooling/nargo_fmt/tests/expected/fn.nr index 0e61483398c..7fd45648c67 100644 --- a/noir/tooling/nargo_fmt/tests/expected/fn.nr +++ b/noir/tooling/nargo_fmt/tests/expected/fn.nr @@ -37,3 +37,11 @@ fn apply_binary_field_op( ) -> bool {} fn main() -> distinct pub [Field;2] {} + +fn main( + message: [u8; 10], + message_field: Field, + pub_key_x: Field, + pub_key_y: Field, + signature: [u8; 64] +) {} diff --git a/noir/tooling/nargo_fmt/tests/expected/infix.nr b/noir/tooling/nargo_fmt/tests/expected/infix.nr index cbc73045fe3..228dfdf68c4 100644 --- a/noir/tooling/nargo_fmt/tests/expected/infix.nr +++ b/noir/tooling/nargo_fmt/tests/expected/infix.nr @@ -9,10 +9,12 @@ fn foo() { } fn big() { - assert(bjj_affine.contains(bjj_affine.gen) + assert( + bjj_affine.contains(bjj_affine.gen) & bjj_affine.contains(p1_affine) & bjj_affine.contains(p2_affine) & bjj_affine.contains(p3_affine) & bjj_affine.contains(p4_affine) - & bjj_affine.contains(p5_affine)); + & bjj_affine.contains(p5_affine) + ); } diff --git a/noir/tooling/nargo_fmt/tests/input/fn.nr b/noir/tooling/nargo_fmt/tests/input/fn.nr index f503db99853..45dc3370f14 100644 --- a/noir/tooling/nargo_fmt/tests/input/fn.nr +++ b/noir/tooling/nargo_fmt/tests/input/fn.nr @@ -24,3 +24,7 @@ fn main(tape: [Field; TAPE_LEN], initial_registers: [Field; REGISTER_COUNT], ini fn apply_binary_field_op(lhs: RegisterIndex, rhs: RegisterIndex, result: RegisterIndex, op: u8, registers: &mut Registers) -> bool {} fn main() -> distinct pub [Field;2] {} + +fn main( + message: [u8; 10], message_field: Field, pub_key_x: Field, pub_key_y: Field, signature: [u8; 64] +) {} diff --git a/noir/tooling/nargo_toml/src/errors.rs b/noir/tooling/nargo_toml/src/errors.rs index 490242cc9ac..da976e1b185 100644 --- a/noir/tooling/nargo_toml/src/errors.rs +++ b/noir/tooling/nargo_toml/src/errors.rs @@ -71,6 +71,7 @@ pub enum ManifestError { SemverError(SemverError), } +#[allow(clippy::enum_variant_names)] #[derive(Error, Debug, PartialEq, Eq, Clone)] pub enum SemverError { #[error("Incompatible compiler version in package {package_name}. Required compiler version is {required_compiler_version} but the compiler version is {compiler_version_found}.\n Update the compiler_version field in Nargo.toml to >={required_compiler_version} or compile this project with version {required_compiler_version}")] @@ -81,4 +82,6 @@ pub enum SemverError { }, #[error("Could not parse the required compiler version for package {package_name} in Nargo.toml. Error: {error}")] CouldNotParseRequiredVersion { package_name: String, error: String }, + #[error("Could not parse the package version for package {package_name} in Nargo.toml. Error: {error}")] + CouldNotParsePackageVersion { package_name: String, error: String }, } diff --git a/noir/tooling/nargo_toml/src/lib.rs b/noir/tooling/nargo_toml/src/lib.rs index 223ed2da081..141cb3411b3 100644 --- a/noir/tooling/nargo_toml/src/lib.rs +++ b/noir/tooling/nargo_toml/src/lib.rs @@ -8,6 +8,7 @@ use std::{ path::{Component, Path, PathBuf}, }; +use errors::SemverError; use fm::{NormalizePath, FILE_EXTENSION}; use nargo::{ package::{Dependency, Package, PackageType}, @@ -99,7 +100,7 @@ struct PackageConfig { impl PackageConfig { fn resolve_to_package(&self, root_dir: &Path) -> Result { - let name = if let Some(name) = &self.package.name { + let name: CrateName = if let Some(name) = &self.package.name { name.parse().map_err(|_| ManifestError::InvalidPackageName { toml: root_dir.join("Nargo.toml"), name: name.into(), @@ -163,7 +164,18 @@ impl PackageConfig { } }; + // If there is a package version, ensure that it is semver compatible + if let Some(version) = &self.package.version { + semver::parse_semver_compatible_version(version).map_err(|err| { + ManifestError::SemverError(SemverError::CouldNotParsePackageVersion { + package_name: name.to_string(), + error: err.to_string(), + }) + })?; + } + Ok(Package { + version: self.package.version.clone(), compiler_required_version: self.package.compiler_version.clone(), root_dir: root_dir.to_path_buf(), entry_path, @@ -225,6 +237,7 @@ struct WorkspaceConfig { #[derive(Default, Debug, Deserialize, Clone)] struct PackageMetadata { name: Option, + version: Option, #[serde(alias = "type")] package_type: Option, entry: Option, diff --git a/noir/tooling/nargo_toml/src/semver.rs b/noir/tooling/nargo_toml/src/semver.rs index de722f06bd8..6acc68afa47 100644 --- a/noir/tooling/nargo_toml/src/semver.rs +++ b/noir/tooling/nargo_toml/src/semver.rs @@ -3,14 +3,19 @@ use nargo::{ package::{Dependency, Package}, workspace::Workspace, }; -use semver::{Version, VersionReq}; +use semver::{Error, Version, VersionReq}; + +// Parse a semver compatible version string +pub(crate) fn parse_semver_compatible_version(version: &str) -> Result { + Version::parse(version) +} // Check that all of the packages in the workspace are compatible with the current compiler version pub(crate) fn semver_check_workspace( workspace: Workspace, current_compiler_version: String, ) -> Result<(), ManifestError> { - let version = Version::parse(¤t_compiler_version) + let version = parse_semver_compatible_version(¤t_compiler_version) .expect("The compiler version is not a valid semver version"); for package in &workspace.members { semver_check_package(package, &version).map_err(ManifestError::SemverError)?; @@ -83,6 +88,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("test").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; if let Err(err) = semver_check_package(&package, &compiler_version) { panic!("semver check should have passed. compiler version is 0.1.0 and required version from the package is 0.1.0\n error: {err:?}") @@ -113,6 +119,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("test").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; let valid_dependency = Package { @@ -122,6 +129,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("good_dependency").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; let invalid_dependency = Package { compiler_required_version: Some("0.2.0".to_string()), @@ -130,6 +138,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("bad_dependency").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; package.dependencies.insert( @@ -169,6 +178,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("test").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; if let Err(err) = semver_check_package(&package, &compiler_version) { @@ -187,6 +197,7 @@ mod tests { entry_path: PathBuf::new(), name: CrateName::from_str("test").unwrap(), dependencies: BTreeMap::new(), + version: Some("1.0".to_string()), }; if let Err(err) = semver_check_package(&package, &compiler_version) { diff --git a/noir/tooling/noir_codegen/package.json b/noir/tooling/noir_codegen/package.json index f2523654aab..9879991f6e7 100644 --- a/noir/tooling/noir_codegen/package.json +++ b/noir/tooling/noir_codegen/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.19.3", + "version": "0.19.4", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/noir/tooling/noir_codegen/src/noir_types.ts b/noir/tooling/noir_codegen/src/noir_types.ts index e894c831aea..d1a22a3e2da 100644 --- a/noir/tooling/noir_codegen/src/noir_types.ts +++ b/noir/tooling/noir_codegen/src/noir_types.ts @@ -70,6 +70,10 @@ function abiTypeToTs(type: AbiType, primitiveTypeMap: Map abiTypeToTs(field, primitiveTypeMap)); + return `[${field_types.join(', ')}]`; + } default: throw new Error(`Unknown ABI type ${JSON.stringify(type)}`); } diff --git a/noir/tooling/noir_codegen/test/assert_lt/src/main.nr b/noir/tooling/noir_codegen/test/assert_lt/src/main.nr index 9795fb6effb..3b3e04ddece 100644 --- a/noir/tooling/noir_codegen/test/assert_lt/src/main.nr +++ b/noir/tooling/noir_codegen/test/assert_lt/src/main.nr @@ -3,11 +3,17 @@ struct MyStruct { bar: [str<5>; 3], } -fn main(x: u64, y: pub u64, array: [u8; 5], my_struct: MyStruct, string: str<5>) -> pub u64 { +fn main( + x: u64, + y: pub u64, + array: [u8; 5], + my_struct: MyStruct, + string: str<5> +) -> pub (u64, u64, MyStruct) { assert(array.len() == 5); assert(my_struct.foo); assert(string == "12345"); assert(x < y); - x + y + (x + y, 3, my_struct) } diff --git a/noir/tooling/noir_codegen/test/assert_lt/target/assert_lt.json b/noir/tooling/noir_codegen/test/assert_lt/target/assert_lt.json index 2556278eff3..6d928a26d43 100644 --- a/noir/tooling/noir_codegen/test/assert_lt/target/assert_lt.json +++ b/noir/tooling/noir_codegen/test/assert_lt/target/assert_lt.json @@ -1 +1 @@ -{"noir_version":"0.19.2+87bb3f0d789765f2d65a1e7b7554742994da2680","hash":12941906747567599524,"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"},{"name":"array","type":{"kind":"array","length":5,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"my_struct","type":{"kind":"struct","path":"MyStruct","fields":[{"name":"foo","type":{"kind":"boolean"}},{"name":"bar","type":{"kind":"array","length":3,"type":{"kind":"string","length":5}}}]},"visibility":"private"},{"name":"string","type":{"kind":"string","length":5},"visibility":"private"}],"param_witnesses":{"array":[{"start":3,"end":8}],"my_struct":[{"start":8,"end":24}],"string":[{"start":24,"end":29}],"x":[{"start":1,"end":2}],"y":[{"start":2,"end":3}]},"return_type":{"kind":"integer","sign":"unsigned","width":64},"return_witnesses":[31]},"bytecode":"H4sIAAAAAAAA/82X206DQBCGF+qh9VDP2gO0eKlXuwVauGt8k7Ys0URTY4h9fTvprm4HJVFmEych8FE6/Ay7zP63jLF7tglnvblqPzXYRdxYb02DdxDvIt5DvK9Y35Op/BC8XoimcS8zb8jHUSQnIylCMeOjdJ7EPIrn40QkIk7ibJSEoUyiZJLO0wlPRRRKkcdpmKvETTqNXNehhepygPgQ8RHiY8RtxCeITxGfIT5HfIH4EvEV4mvEN4g7iLuIe4j7iD32NW502Bg/U6IxY1Nnh0CnzCEyqzq7ZDoXuU2dPTqd0qbOPp3OzKZOj07nAvqNy8rhEmt2GN3cd/+uS+AT3zw6WW6zrr7aD9imh+txoa+BPv/AymPGMY5ddY1bcY3zQ56WcU7/v238XvfhS8Uwb06V01eFpF6A+HQaPxcgAyOnjgZxPWxNqrq5AsJ6VtXvlzo50il8wmceEL7XGvWr/MD953lT9Z55vdiaJ7xeCMp5MmT03x2ds2+8c6gnNBhoPGAYtUmEpgDGCMwQGCAwPdAUwNyAoQETA8YFzAoYFDAlYETAfMAiGRagPXUvj203Kn08ZNtN5k7tPbWfFYV8eS2CYhnMsixYPRWPwfJdvuXPy9UHoDK8FUEPAAA="} \ No newline at end of file +{"noir_version":"0.19.3+e9322d14070fa444d77ee5c43c905dd86a67c6e3","hash":9449934793688855780,"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"},{"name":"array","type":{"kind":"array","length":5,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"my_struct","type":{"kind":"struct","path":"MyStruct","fields":[{"name":"foo","type":{"kind":"boolean"}},{"name":"bar","type":{"kind":"array","length":3,"type":{"kind":"string","length":5}}}]},"visibility":"private"},{"name":"string","type":{"kind":"string","length":5},"visibility":"private"}],"param_witnesses":{"array":[{"start":3,"end":8}],"my_struct":[{"start":8,"end":24}],"string":[{"start":24,"end":29}],"x":[{"start":1,"end":2}],"y":[{"start":2,"end":3}]},"return_type":{"kind":"tuple","fields":[{"kind":"integer","sign":"unsigned","width":64},{"kind":"integer","sign":"unsigned","width":64},{"kind":"struct","path":"MyStruct","fields":[{"name":"foo","type":{"kind":"boolean"}},{"name":"bar","type":{"kind":"array","length":3,"type":{"kind":"string","length":5}}}]}]},"return_witnesses":[31,32,33,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]},"bytecode":"H4sIAAAAAAAA/81XbU/CMBDu5hv4gopvvGw49JOJH1q2wfaN+E+AddFEgzGL/H250Go5dInumnhJ0z2jXJ9er7s+t4yxe7YyZ9lc1Y8N7CK8tWw1A28jvIPwLsJ7Cus5mfIPxquZqBlzmX5DPowiORpIEYoJH6TTJOZRPB0mIhFxEmeDJAxlEiWjdJqOeCqiUIo8TsNcOa7RceQ6DnUUl32EDxA+RPgI4QbCxwifIHyKcBPhM4TPEb5A+BLhK4RbCLcR7iDcRdhjX3mjzUb+jIlyxibPFgFPmYNlVnm2yXjOcps8O3Q8pU2eXTqemU2eHh3PGdQbl22aS8zZYXRn3/07L4FffLN0Mt9mXH3V99iqhuu80GOgzj+wzZxxjGdXjXFLxjg/+Kkb7/T/G8bvVRe/EQxzciqfvgok9QXEp+P4eQHpGT61bRHHw9ahqurrhjCeZfH7JU+OeAqfcM09wn2tEL/SD9x/Pjdl+8yr2do54dVMUJ6Ta0b/3TF92tr3gI53aJNnn3DfuwZHyE8o2FDIQYBr0Q1FFoQmiEsQlCAiociCWASBCKIQhCCIPxB8IPJA2IGYA9EBF3q4LMNcHlsv/E31XGUOyI1g2fpsvfDfqd5T/aQo5MtrERTzYJJlweKpeAzm7/Itf54vPgBYg2KL1RAAAA=="} \ No newline at end of file diff --git a/noir/tooling/noir_codegen/test/index.test.ts b/noir/tooling/noir_codegen/test/index.test.ts index e81add02566..48199c13a67 100644 --- a/noir/tooling/noir_codegen/test/index.test.ts +++ b/noir/tooling/noir_codegen/test/index.test.ts @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { assert_lt, u64 } from './codegen/index.js'; +import { assert_lt, MyStruct, u64 } from './codegen/index.js'; it('codegens a callable function', async () => { - const result: u64 = await assert_lt( + const [sum, constant, struct]: [u64, u64, MyStruct] = await assert_lt( '2', '3', [0, 0, 0, 0, 0], @@ -10,5 +10,7 @@ it('codegens a callable function', async () => { '12345', ); - expect(result).to.be.eq('0x05'); + expect(sum).to.be.eq('0x05'); + expect(constant).to.be.eq('0x03'); + expect(struct).to.be.deep.eq({ foo: true, bar: ['12345', '12345', '12345'] }); }); diff --git a/noir/tooling/noir_js/package.json b/noir/tooling/noir_js/package.json index 440bd8dec63..7818e689181 100644 --- a/noir/tooling/noir_js/package.json +++ b/noir/tooling/noir_js/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.19.3", + "version": "0.19.4", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/noir/tooling/noir_js_backend_barretenberg/.mocharc.json b/noir/tooling/noir_js_backend_barretenberg/.mocharc.json new file mode 100644 index 00000000000..e1023f56327 --- /dev/null +++ b/noir/tooling/noir_js_backend_barretenberg/.mocharc.json @@ -0,0 +1,11 @@ +{ + "require": "ts-node/register", + "loader": "ts-node/esm", + "extensions": [ + "ts", + "cjs" + ], + "spec": [ + "test/**/*.test.ts*" + ] +} diff --git a/noir/tooling/noir_js_backend_barretenberg/package.json b/noir/tooling/noir_js_backend_barretenberg/package.json index 360b3e70ec0..baf8c0f58fd 100644 --- a/noir/tooling/noir_js_backend_barretenberg/package.json +++ b/noir/tooling/noir_js_backend_barretenberg/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.19.3", + "version": "0.19.4", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", @@ -25,6 +25,7 @@ "generate:package": "bash ./fixup.sh", "build": "yarn clean && tsc && tsc -p ./tsconfig.cjs.json && yarn generate:package", "clean": "rm -rf ./lib", + "test": "mocha --timeout 25000 --exit --config ./.mocharc.json", "prettier": "prettier 'src/**/*.ts'", "prettier:fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", "nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json", @@ -32,16 +33,19 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "0.15.1", + "@aztec/bb.js": "0.16.0", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, "devDependencies": { "@types/node": "^20.6.2", "@types/prettier": "^3", + "chai": "^4.3.8", "eslint": "^8.50.0", "eslint-plugin-prettier": "^5.0.0", + "mocha": "^10.2.0", "prettier": "3.0.3", + "ts-node": "^10.9.1", "typescript": "5.1.5" } } diff --git a/noir/tooling/noir_js_backend_barretenberg/src/index.ts b/noir/tooling/noir_js_backend_barretenberg/src/index.ts index 820cda93c83..100418debd0 100644 --- a/noir/tooling/noir_js_backend_barretenberg/src/index.ts +++ b/noir/tooling/noir_js_backend_barretenberg/src/index.ts @@ -3,6 +3,9 @@ import { decompressSync as gunzip } from 'fflate'; import { acirToUint8Array } from './serialize.js'; import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; import { BackendOptions } from './types.js'; +import { deflattenPublicInputs, flattenPublicInputsAsArray } from './public_inputs.js'; + +export { flattenPublicInputs } from './public_inputs.js'; // This is the number of bytes in a UltraPlonk proof // minus the public inputs. @@ -18,7 +21,7 @@ export class BarretenbergBackend implements Backend { private acirUncompressedBytecode: Uint8Array; constructor( - acirCircuit: CompiledCircuit, + private acirCircuit: CompiledCircuit, private options: BackendOptions = { threads: 1 }, ) { const acirBytecodeBase64 = acirCircuit.bytecode; @@ -91,16 +94,8 @@ export class BarretenbergBackend implements Backend { const splitIndex = proofWithPublicInputs.length - numBytesInProofWithoutPublicInputs; const publicInputsConcatenated = proofWithPublicInputs.slice(0, splitIndex); - - const publicInputSize = 32; - const publicInputs: Uint8Array[] = []; - - for (let i = 0; i < publicInputsConcatenated.length; i += publicInputSize) { - const publicInput = publicInputsConcatenated.slice(i, i + publicInputSize); - publicInputs.push(publicInput); - } - const proof = proofWithPublicInputs.slice(splitIndex); + const publicInputs = deflattenPublicInputs(publicInputsConcatenated, this.acirCircuit.abi); return { proof, publicInputs }; } @@ -185,7 +180,7 @@ export class BarretenbergBackend implements Backend { function reconstructProofWithPublicInputs(proofData: ProofData): Uint8Array { // Flatten publicInputs - const publicInputsConcatenated = flattenUint8Arrays(proofData.publicInputs); + const publicInputsConcatenated = flattenPublicInputsAsArray(proofData.publicInputs); // Concatenate publicInputs and proof const proofWithPublicInputs = Uint8Array.from([...publicInputsConcatenated, ...proofData.proof]); @@ -193,18 +188,5 @@ function reconstructProofWithPublicInputs(proofData: ProofData): Uint8Array { return proofWithPublicInputs; } -function flattenUint8Arrays(arrays: Uint8Array[]): Uint8Array { - const totalLength = arrays.reduce((acc, val) => acc + val.length, 0); - const result = new Uint8Array(totalLength); - - let offset = 0; - for (const arr of arrays) { - result.set(arr, offset); - offset += arr.length; - } - - return result; -} - // typedoc exports export { Backend, BackendOptions, CompiledCircuit, ProofData }; diff --git a/noir/tooling/noir_js_backend_barretenberg/src/public_inputs.ts b/noir/tooling/noir_js_backend_barretenberg/src/public_inputs.ts new file mode 100644 index 00000000000..37bc5b13012 --- /dev/null +++ b/noir/tooling/noir_js_backend_barretenberg/src/public_inputs.ts @@ -0,0 +1,89 @@ +import { Abi, WitnessMap } from '@noir-lang/types'; + +export function flattenPublicInputs(publicInputs: WitnessMap): string[] { + const publicInputIndices = [...publicInputs.keys()].sort((a, b) => a - b); + const flattenedPublicInputs = publicInputIndices.map((index) => publicInputs.get(index) as string); + return flattenedPublicInputs; +} + +export function flattenPublicInputsAsArray(publicInputs: WitnessMap): Uint8Array { + const flatPublicInputs = flattenPublicInputs(publicInputs); + const flattenedPublicInputs = flatPublicInputs.map(hexToUint8Array); + return flattenUint8Arrays(flattenedPublicInputs); +} + +export function deflattenPublicInputs(flattenedPublicInputs: Uint8Array, abi: Abi): WitnessMap { + const publicInputSize = 32; + const chunkedFlattenedPublicInputs: Uint8Array[] = []; + + for (let i = 0; i < flattenedPublicInputs.length; i += publicInputSize) { + const publicInput = flattenedPublicInputs.slice(i, i + publicInputSize); + chunkedFlattenedPublicInputs.push(publicInput); + } + + const return_value_witnesses = abi.return_witnesses; + const public_parameters = abi.parameters.filter((param) => param.visibility === 'public'); + const public_parameter_witnesses: number[] = public_parameters.flatMap((param) => + abi.param_witnesses[param.name].flatMap((witness_range) => + Array.from({ length: witness_range.end - witness_range.start }, (_, i) => witness_range.start + i), + ), + ); + + // We now have an array of witness indices which have been deduplicated and sorted in ascending order. + // The elements of this array should correspond to the elements of `flattenedPublicInputs` so that we can build up a `WitnessMap`. + const public_input_witnesses = [...new Set(public_parameter_witnesses.concat(return_value_witnesses))].sort( + (a, b) => a - b, + ); + + const publicInputs: WitnessMap = new Map(); + public_input_witnesses.forEach((witness_index, index) => { + const witness_value = uint8ArrayToHex(chunkedFlattenedPublicInputs[index]); + publicInputs.set(witness_index, witness_value); + }); + + return publicInputs; +} + +function flattenUint8Arrays(arrays: Uint8Array[]): Uint8Array { + const totalLength = arrays.reduce((acc, val) => acc + val.length, 0); + const result = new Uint8Array(totalLength); + + let offset = 0; + for (const arr of arrays) { + result.set(arr, offset); + offset += arr.length; + } + + return result; +} + +function uint8ArrayToHex(buffer: Uint8Array): string { + const hex: string[] = []; + + buffer.forEach(function (i) { + let h = i.toString(16); + if (h.length % 2) { + h = '0' + h; + } + hex.push(h); + }); + + return '0x' + hex.join(''); +} + +function hexToUint8Array(hex: string): Uint8Array { + const sanitised_hex = BigInt(hex).toString(16).padStart(64, '0'); + + const len = sanitised_hex.length / 2; + const u8 = new Uint8Array(len); + + let i = 0; + let j = 0; + while (i < len) { + u8[i] = parseInt(sanitised_hex.slice(j, j + 2), 16); + i += 1; + j += 2; + } + + return u8; +} diff --git a/noir/tooling/noir_js_backend_barretenberg/test/public_input_deflattening.test.ts b/noir/tooling/noir_js_backend_barretenberg/test/public_input_deflattening.test.ts new file mode 100644 index 00000000000..98189eaed5f --- /dev/null +++ b/noir/tooling/noir_js_backend_barretenberg/test/public_input_deflattening.test.ts @@ -0,0 +1,93 @@ +import { Abi } from '@noir-lang/types'; +import { expect } from 'chai'; +import { flattenPublicInputsAsArray, deflattenPublicInputs, flattenPublicInputs } from '../src/public_inputs.js'; + +const abi: Abi = { + parameters: [ + { + name: 'array_with_returned_element', + type: { + kind: 'array', + type: { + kind: 'field', + }, + length: 10, + }, + visibility: 'private', + }, + { + name: 'pub_field', + type: { + kind: 'field', + }, + visibility: 'public', + }, + ], + param_witnesses: { + array_with_returned_element: [ + { + start: 1, + end: 11, + }, + ], + pub_field: [ + { + start: 11, + end: 12, + }, + ], + }, + return_type: { + kind: 'tuple', + fields: [ + { + kind: 'field', + }, + { + kind: 'field', + }, + { + kind: 'field', + }, + ], + }, + return_witnesses: [2, 13, 13], +}; + +it('flattens a witness map in order of its witness indices', async () => { + // Note that these are not in ascending order. This means that if we read from `witness_map` in insertion order + // then the witness values will be sorted incorrectly. + const public_input_indices = [2, 13, 11]; + + const witness_map = new Map( + public_input_indices.map((witness_index) => [ + witness_index, + '0x' + BigInt(witness_index).toString(16).padStart(64, '0'), + ]), + ); + + const flattened_public_inputs = flattenPublicInputs(witness_map); + expect(flattened_public_inputs).to.be.deep.eq([ + '0x0000000000000000000000000000000000000000000000000000000000000002', + '0x000000000000000000000000000000000000000000000000000000000000000b', + '0x000000000000000000000000000000000000000000000000000000000000000d', + ]); +}); + +it('recovers the original witness map when deflattening a public input array', async () => { + // Note that these are not in ascending order. This means that if we read from `witness_map` in insertion order + // then the witness values will be sorted incorrectly. + const public_input_indices = [2, 13, 11]; + + const witness_map = new Map( + public_input_indices.map((witness_index) => [ + witness_index, + '0x' + BigInt(witness_index).toString(16).padStart(64, '0'), + ]), + ); + + const flattened_public_inputs = flattenPublicInputsAsArray(witness_map); + const deflattened_public_inputs = deflattenPublicInputs(flattened_public_inputs, abi); + + expect(deflattened_public_inputs).to.be.deep.eq(witness_map); +}); diff --git a/noir/tooling/noir_js_types/package.json b/noir/tooling/noir_js_types/package.json index 4232358ddff..991052f1ad9 100644 --- a/noir/tooling/noir_js_types/package.json +++ b/noir/tooling/noir_js_types/package.json @@ -4,7 +4,7 @@ "The Noir Team " ], "packageManager": "yarn@3.5.1", - "version": "0.19.3", + "version": "0.19.4", "license": "(MIT OR Apache-2.0)", "files": [ "lib", diff --git a/noir/tooling/noir_js_types/src/types.ts b/noir/tooling/noir_js_types/src/types.ts index 5ed6b1721e9..b997d92425d 100644 --- a/noir/tooling/noir_js_types/src/types.ts +++ b/noir/tooling/noir_js_types/src/types.ts @@ -1,4 +1,6 @@ -import { Abi } from '@noir-lang/noirc_abi'; +import { Abi, WitnessMap } from '@noir-lang/noirc_abi'; + +export { Abi, WitnessMap } from '@noir-lang/noirc_abi'; export interface Backend { /** @@ -43,7 +45,7 @@ export interface Backend { * */ export type ProofData = { /** @description Public inputs of a proof */ - publicInputs: Uint8Array[]; + publicInputs: WitnessMap; /** @description An byte array representing the proof */ proof: Uint8Array; }; diff --git a/noir/tooling/noirc_abi_wasm/package.json b/noir/tooling/noirc_abi_wasm/package.json index d679ec37194..f1c68df8804 100644 --- a/noir/tooling/noirc_abi_wasm/package.json +++ b/noir/tooling/noirc_abi_wasm/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.19.3", + "version": "0.19.4", "license": "(MIT OR Apache-2.0)", "files": [ "nodejs", diff --git a/noir/yarn.lock b/noir/yarn.lock index 6ae655f8ce2..b21d1256eff 100644 --- a/noir/yarn.lock +++ b/noir/yarn.lock @@ -221,9 +221,9 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:0.15.1": - version: 0.15.1 - resolution: "@aztec/bb.js@npm:0.15.1" +"@aztec/bb.js@npm:0.16.0": + version: 0.16.0 + resolution: "@aztec/bb.js@npm:0.16.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -231,7 +231,7 @@ __metadata: tslib: ^2.4.0 bin: bb.js: dest/node/main.js - checksum: b3d94eb6db1d1579fa7266486d4b1c6ddc408f1d36bd2585b50e623aa90222d273e56464284b94677979840c1119c5385aa961462d3a1af6cb9a2ba1cf9655f9 + checksum: 5f68b4ad16284a3a871e0ad21fea05aed670383bc639c9d07ab3bf9b7a9d15cc8a4e5cda404a9290775ad5023924739543a8aac37d602892dd1fb5087521970b languageName: node linkType: hard @@ -3434,14 +3434,17 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": 0.15.1 + "@aztec/bb.js": 0.16.0 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3 + chai: ^4.3.8 eslint: ^8.50.0 eslint-plugin-prettier: ^5.0.0 fflate: ^0.8.0 + mocha: ^10.2.0 prettier: 3.0.3 + ts-node: ^10.9.1 typescript: 5.1.5 languageName: unknown linkType: soft diff --git a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json index 4fef4336d45..0c4d56e844c 100644 --- a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -84,7 +84,7 @@ } ], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+2dB1hUVxbHL20QxBpjQUDsXd+FAQYLDlUERETEkqwRZDQktiDGmL7Z3rN9k2zJZnvP9s3WbLb3bO+72Wzvve8mOUfPS67nGxWYM8j9Tt73/b8zh9E75/d/M2/ue3PfvScyjFkKCrfwYZxikNpmc6CNnCTtlgeV0Wiiqixhy21PUFbdG6sIohW9lTEbsxWxir6yWHl5IhaNVVX3VlcF1TZanrD7K6rL91PDOXI1BungjkAbkTRwR8Y4dy60kZsG7lxBbqwtEzQDNI5qxXwmy2exvJDls1lexPJilpewfA7LS1k+l+XzWD6f5QtYvpDli1i+mOVLWL6U5ctYvpzlK1i+kuWrWL6a5QHLLcvLWF7O8ijLK1heyfIqlsdYXs3yNSxfy/J1LF/P8hqWb2B5nOW1LK9jeT3LG1jeyPImlm9keTPLN7G8heWtLG9j+WaWt7N8C8s7WL6V5Z0s38byLpZvZ3m3k+PxpNSc3vA48JA5/fnHOItiIcXZFIsoFlMsoTiHYinFuRTnUZxPcQHFhRQXUVxMcQnFpRSXUVxOcQXFlRRXUVxNMaBoKZZRLKcYpVhBsdJpd0cSX6ro+RjFaoprKK6luI7ieoo1FDdQjFOspVhHsZ5iA8VGik0UN1JspriJYgvFVoptFDdTbKe4hWIHxa0UOyluo9hFcTvFbseXnebMTfp7bZeR/V7D/TeZ2ttBHDsp7hrliP7tTrN/l8j5Z0P/whovIQ7sc13KOLIYB/7/IIVtBudIobWZgv5mZ8j2N8/hX5AK9SyTpM4RtlYo6F/O6PoXjJR6tjlLnSNorUjQv8jo+xeMhLrYnKPOYbZWIuhf7oXxLxgu9RxznjqH0VqpoH/jLpx/wXCo55oh1DnE1uYJ+pd3Yf0Lhko93wyxziG0tkDQv/wL718wFOqFZhh1nqe1RYL+jR8b/gXno15shlnnOVpbIuhfwdjxLzgX9VIzgjrP0toyQf8mjC3/grNRLzcjrDNJaysE/Zs49vwLklGvNCnUyVpbJejfpLHpX8CpV5sU63RbE/Rv8tj1L3CprRGok1orE/Rvytj2Lwipy41QndBaVNC/qWPfP9xshWBb7jWnVP27yBP/BK8T2Yigf9M88U/wOocdJ+jfxZ74J3iebvMF/ZvuiX+C55m2QNC/GZ74J3ieZCcK+jfTE/8E+/l2sqB/szzxT7CfaqcK+lfoiX+C/Sw7TdC/2Z74J9hPsNMF/SvyxD/B7zk7U9C/Yk/8EzxO20JB/0o88U/wOGOLBP2b44l/gp8TWyLoX+ko+ZdqnU8Q3BeC7xlbOnrvv5TGX1UZufFXMcH9WuPJ+KtqIzf+ao2gfxs8GX+11siNv1on6F/ck/FX643c+KsaQf9qPRl/tcHIjb+KC/pX58n4q1ozhDqH2FqdoH/1noy/qjdDrHMIrTUI+tfgyfirRjOMOs/TWpOgf42ejL/aaIZZ5zlaaxb0r8mT8VebzAjqPEtrLYL+bfRk/FWrGWGdSVprE/Sv2ZPxV5tNCnWy1toF/dvkyfirLSbFOp3WOgT9a/Fk/NVWI1AntdYp6F+rJ+OvthmhOqG1LkH/2jy5frpdsK0aweunmz3xT/A6kY0L+tfuiX+C1zlsnaB/WzzxT/A83TYI+tfhiX+C55m2SdC/rZ74J3ieZJsF/ev0xD/Bfr5tEfRvmyf+CfZTbZugf12e+CfYz7Ltgv5t98Q/wX6C7RD0r9sT/wS/52ynoH87PPFP8DhtuwT92+nL+a+gf92C/u3yxD/Bz4ndKejfbk/GX+0R3BeC7xkr6V84P1YOtYdjztx55PaYM+dPy6SI22XmsfnlMulv4fxalzn/bi/tmyxz9i0u5E2GwxJuGcKvITguL0hXjZUe1LjHgxq7Pagx06TneCpd514je9wKtx5QAT3OA2XT40znb1mMKc95PtwizuO4TJ0VyeaLDlLc8Pg2zuEwjHciPT+F8sNHBvv3n6wfSPQMJvrajwwmXPPCg2VWkoYynL+7B9Vs58Uj7HnX2PA5dwLGR7e4EXHDum1Kv2N75NoKspKZYMb20SDDqTF8I/SC9oH6QBOS7HTDdr4gW5CuT1PE4Qg399OEz2fLvm65e1Ti7wXum3FeHz/ZxfT4QGKw43jvwf59rYmTtYf7OnoGBvt7Dtb29Q0kjh1LtvOykryQe5jkRwN3x4bPpfXTHPYn3Xcb9iP3UeyjOAmUYDVkslpS7f8LfpJswsgeSXgf192pUjWnq18h/Z5Jpwe9afJAus59Rvao//g51OPnUFI1ajuHcr94w++k/aAD5vS6A7i5XWe3O53sC1jD+Uy+w2EYb3g+M5nyxKH+wcbD+wZOHoXzmbYjB9zOSC7FnCTtuL7ilu08znH85Kc0EaeuuAxzWZ557BzOOK/tbnHncZ5TS75sLac+U+Od1wrrCl9nvPN8rlPHeNk6TvX98hm/W0OaXvcUf8F5+AuS1FEwivzu9Y18Vqf72Q+fu2Cn3Kl2ui+XqXN/tCx6RocrU9iDDEHmfiP/BZkO5kxB5is8Yc4SZL7SE+ZsQeaDnjDnCDIf8oQ5Ish82BPmXEHmI54w7xZkPuoJ8y5B5qsUMg8oZD6mkHlQIfNxhcxXK2Q+oZD5GoXMJxUyX6uQ+TqFzNcrZL5BIfONCplvUsh8s0LmJypkvkUh85MUMj9ZIfNTFDI/VSHz0xQyP10h8zMUMj9TIfOzFDI/WyHzcxQyP1ch8/MUMt+qkPn5CplfoJD5hQqZX6SQ+cUKmV+ikPmlCplfppD5NoXMtytkvkMh88sVMr9CIfMrFTK/SiHznQqZX62Q+S6FzK9RyPxahcyvU8j8eoXMb1DI/EaFzG9SyPxmhcxvUcj8VoXMb1PI/HaFzO9QyHy3QuZ3KmR+l0Lmdytkfo8nzHsFmd+rcD+/TyHz+xUyf0Ah8z0KmT+okPlDCpk/rJD5IwqZP6qQ+WMKme9VyPxxhcz3KWT+hELmT3rCfKkg86cU7udPK2T+jELmzypk/pxC5s8rZP6CQuYvKmT+kkLmLytk/opC5vsVMn9VIfPXFDJ/XSHzNzxhvlyQ+ZsK9/O3FDJ/WyHzdxQyf1ch8/cUMn9fIfMPFDL/UCHzjxQy/1gh8wMKmX+ikPlBhcw/Vcj8M4XMP1fI/AuFzL9UyPwrhcy/Vsj8G4XMv1XI/DuFzL9XyPwHhcx/VMj8J4XMf1bI/BeFzH9VyPw3T5jHCTL/3RPmPEHmf3jCnC/I/E9PmMcLMv/LE+YCQeZ/e8I8QZD5P54wTxRk/q8nzJMEmf/nCfNkQeb/e8I8RZD5IU+YpwoyP+wJ80WCzCbDD+ZpgswZnjBfLMic6QnzdEHmLEHm6dROBjFngbJBOaAIKBeE54R4joTnDNiHxj4l9rGwz4HfwfidhMdoPGbhZxjf07iPXeYZoJmgWaBC0GxQEagYVAKaAyoFzQXNA80HLQAtBC0CLQYtAS0FLQMtB60ArQStAq1GL0AWVIYeg6KgClAlqAoUA1WD1oDWgtaB1oNqQBuo1lpQHage1ABqBDWBNoKaQZtALaBWUBtoM6gdtAXUAdoK6gRtA3WBtoO6QXeQD/2gK0BXgg6CDoEOg46AjoKuAg2AjoEGQcdBV4NOgK4BnQRdC7oOdD3oBtCNoJtAN4NwDfhbQLhGOK6ZjWtI45rKuMYwrrmLa9Dimqy4Rimu2YlrWOKajrjG4a0gXAMP14TDNdJwzTBcQwvXlMI1lnDNodtAtxMPrlmCa3jgmha4xsOdIFwD4C4QzhGPc6bjHOI4pzbOMY1zLuMcxDgnL85Ri3O24hymOKcnznF5NwjnQMQ5AXGOPJwzDudQwznFcI4tnHPqHhDOSYRz9OCcNTiHC85pgnN83AvCOSDuA+EcAXjPPN5DjvdU4z3GeM8t3oOK92TiPYp4zx7ew4b3dOE9TveD8B4YvCcE75HAewZwDD2OKccx1jjmGMfg4phUHKOJYxZxDB+OacMxXg+AcAzQgyAcI4JjJnAMAf6mjr8x42+u+Bsk/iaHv1Hhbzb4GwZe08dr3HjNF6+B4jVBvEaG14zwGgpeU8BzbDznxHMwPCfBPjr2WbEPh30a/I7HDzF+B+AxEY8R4fYIuiF5tqkEAQA=", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -147,7 +147,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -164,7 +164,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -424,7 +424,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -691,7 +691,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json index 04edcd07a3a..8163729ec65 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -72,7 +72,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -135,7 +135,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -152,7 +152,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -412,7 +412,7 @@ ] } ], - "bytecode": "H4sIAAAAAAAA/+2dCZxdR3Xm3+3WVirt+67WLsu23F2SLVmSpZatJ3lfJO+2JGu3bC221LIxYDazg43ZDJjNk4FMkkkIk0kIkxCGECYBJiEMIQwQQgiTECaTySRM9r3qvjro01H5PvfPdfJup0/9fkevqm7f+v7nfPX2263nGo1G0Wi1bh9TG+c3Ot4fb3tfXOsr8q3VK8nZNUQ4u4cI54ghwjlyiHCOGiKco4cI55ghwmmGCOfYIcJphwjnuCHCOX6IcE4YIpwThwjnpCHCOXmIcE4ZIpxTM3LOBs5p8XZ6vJ0Rb2fG21nxls6ZE2/nxhxHxPE8H/N9LPCxMB6jgvT4WORjsY8lPpb6WOZjuY8VPlb6uMDHKh8X+rjIx8U+Vvu4JK7T58P5WONjrY9LfVzmY52P9T4u97HBx0Yfm3xc4WOzjy2xblt9XOnjKh/bfDR9bPexw8fVPq7xca2P63xc7+MGHzf6uCnm0hNzudnHLT52+tjl41Yft/m43ccdPu70cZePu33c4+NeH7t97PGx18d9Pvb52O/jgI+DPg75OOzjiI/7fRz18YCPB30c83HcxwkfJ1nNH/LxsI9TPk7HY5PisQEfZ3w84uNRHy/x8ZiPl/p4mY+X+3jcxyt8vNLHq3y82sdrfDzB1nqtj9f5eL2PN/h4o483+Xizj7f4eKuPJ3085eNtPp728XYf7/DxzrhWV1zrXT7ezeae8fGe2H9vvH1fvH023r4/3n4g3n4w3n4o3n443j7n49sRPLyGo/09pXF2jt5/T4Y5Oj4J5uj4RJij4xNgjo6Phzk6Pg7m6LiFOTo+FubwON3S8TEwR8dHwxwdHwVzdHwkzNHxETBHx7thjo53wRwdL2COjjeYfmj98bb3RbZRjeyPq70h517Io5HIFz+74fmOSNRlZKJ+6AcdR9/oOPqLx+mWjuN+oeO4b+g47j86jvuUjuN+puO47+k43j/oON6P6Dje3+j4VJij49Ngjo5Phzk6PgPm6PhMmKPjs2COjs+GOTpOz2Mhr1D7uXHcH297X1xzBjSoFWzcD33SDyzzBVjmDYJlPrAsyMtSvq9eGNeaAzo9mXUK0KF1aUxaFhgWCLLYhLaEDtaWWpXPPcCyKC9L+ZC6GLSIaxHUno5PA47FmWtSgCatS2PSMjA3r8MsFhgWwhz9XI8cnzOML7Sq/bMYWJZmZenrDSxLBsGyFFiWZWVpve5YnnnNsMYK4Kdcid3C8eWQ24q8HOWeXNY4t6Y0Rj5lVVZlVVZlVVZlVVZlHd6sBuYWdZgF3x8tEWPp67UJbYn3G/gZF60dPkd8P2guzJwbfsdBn00QA2l1w898YeJZLvrsfSwcXyTG6g7k/4ysrzd8DjoG+Oez3OnzIfyscQF481HIty6fJeLnfvhZW+bPF8v76DzGMo/VET9r6xJksQntOn2mGs6jfYOfNeW9j7Q8WcBYaIyfKxFDtyCLTWgL6DjDcg6tyhPSD+f1xD5+Dpz5M9E+fIyldWmMn4vi44oUi22kH6sz6zisLbUqT0g/nEefL/YA35LMdSga535O3Q9j0sJajRRksQltAR1nWM6hVXlC+uE8+pwVP/vN/Pqn9GQpY6ExvhZGBikWm9AW0HGG5RxalSekH86j9wL4GbjE6/DljIXG+DqcGEYLstiEtoCOMyzn0Ko8wfdGK2Mf36ddkLkOBejQujQmLazVGEEWm9AW0HGG5RxalSekH85bFfsrge/CzHUoQIfWpTFpYa2MIItNaAvoOMNyDq3Kkwsh94tifxXwXZy5DgXo0Lo0Ji2s1VhBFpvQFtBxhuUcWpUnpB/OWx37FwHfJZnrUIAOrUtj0sJaWUEWm9AW0HGG5RxalSekH86ja9RWA19f5jrgNbu0Lo37wAdiGCfIYhPaAjrOsJxDq/KE9MN5jhiAb03mOhSgQ+vSmLSwVuMFWWxCW0DHGZZzaFWekH44b23sO+C7NHMdCtChdWlMWlirCYIsNqEtoOMMyzm0Kk9IP5x3WeyvBb51metQgA6tS2PSwlpNFGSxCW0BHWdYzqFVeUL64bz1sX8Z8F2euQ4F6NC6NCYtrNUkQRab0BbQcYblHFqVJ6QfztsQ++uBb2PmOhSgQ+vSmLSwVpMFWWxCW0DHGZZzaFWekH44b1PsbwC+KzLXoQAdWpfGpIW1miLIYhPaAjrOsJxDq/KE9MN5m2N/E/BtyVyHAnRoXRqTFtZqqiCLTWgL6DjDcg6tyhPSx9+V3wx8WzPXoWD6/TAmLazVDEEWm9AW0HFYW2pVniDLVXlZ1gaWKwfBchWwbMvLUl6T3cy8ZlhjO/BTrsRu4XgTctuel6Pc59sa59aUxsinrMOb1TTOv191igUfD6+UY1lrE9oCOs6wnEOreqxDT3bE/jbguzovX+nJDsZCY9LCWjUFWWxCW0DHGZZzaFWeIMu1WVnWlNfoXTMIlmuB5bqsLK3nretBi7hIx8Jx3AfX5+Uo9+R1LH8aI5+yKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquy5mc1MLejwywWGK4RY1lT/i0nri2QszMs59CqrhNBT26I/euA78a8fKUnNzAWGpMW1qopyGIT2gI6zrCcQ6vyBFluzsriyuuIbhoEy83AcktWltZ1RDtBi7hIx8Jx3Ac783KUe/IWlj+NkU9ZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlXWosBqYu6HDLPhZ/E1iLK78HoZrC+TsDMs5tKrP2dGTXbF/C/Ddmpev9GQXY6ExaWGtmoIsNqEtoOMMyzm0Kk+Q5fa8LOXfNrltECy3A8sdeVnK72HuBC3iIh0Lx3Ef3JmXo9yTd7D8aYx8yjq8WQ3M7eowCz523SbHUv4dEq4toOMMyzm0qscl9OSu2L8D+O7Oy1d6chdjoTFpYa2agiw2oS2g4wzLObQqT5Dl3qwsrf8n+Z5BsNwLLLuzsrSet/aAFnGRjoXjuA/25OUo9+Rulj+NkU9ZlVVZlVVZlVVZlVVZhzergbm7OsyC72XuEWNp/Z/GXFsgZ2dYzqFVvU9BT/bG/m7guy8vX+nJXsZCY9LCWjUFWWxCW0DHYW2pVXlyH7Dsz8rSeh+7bxAs+4HlQFaW1vvYg6BFXKRj4Tjug4N5Oco9eYDlT2PkU1ZlVVZlVVZlVVZlVdbhzWpgbm+HWfC9zD4xltb7WK4tkLMzLOfQqt6noCeHYv8A8B3Oy1d6coix0Ji0sFZNQRab0BbQcYblHFqVJ8hyvwDLkUGw3A8sR/OylO9jHwAt4iIdC8dxHzyQl6Pck0dZ/jRGvqHCamDuUIdZ8D52RI7F2YS2hI5hOYdWdf9BTx6M/aPAdywvX+nJg4yFxqSFtWoKstiEtoCOMyzn0Ko8QZYTAizHB8FyAlhO5mUpH18fAi3iIh0Lx3EfPJSXo9yTJ1n+NEa+ocJqYO7BDrPgfey4HEv5+Mq1JXQMyzm0qvsPevJw7J8EvlN5+UpPHmYsNCYtrFVTkMUmtAV0nGE5h1blCemH807H/sPAN5C5DgXo0Lo0Ji2sVVOQxSa0BXScYTmHVuUJ6YfzzsT+aeB7JHMdCtChdWlMWlgrI8hiE9oCOs6wnEOr8uQRyP3R2D8DfC/JXIcCdGhdGpMW1mqsIItNaAvoOMNyDq3KE9IP5z0W+48C30sz16EAHVqXxqSFtbKCLDahLaDjDMs5tCpPSD+c97LYfwz4Xp65DgXo0Lo0fjn4QAzjBFlsQltAxxmWc2hVnpB+OO/x2H8Z8L0icx0K0KF1aUxaWKvxgiw2oS2g4wzLObQqT0g/nPfK2H8c+F6VuQ4F6NC6NCYtrNUEQRab0BbQcVhbalWevCrehvNeHfuvBL7XZK5DATq0Lo1JC2s1UZDFJrQFdJxhOYdW5Qnph/OeiP1XA99rM9ehAB1al8akhbVqCrLYhLaAjjMs59CqPCH9cN7rYv8J4Ht95joUoEPr0pi0sFZNQRab0BbQcYblHFqVJ6QfzntD7L8O+N6YuQ4F6NC6NCYtrFVTkMUmtAV0nGE5h1blCemH894U+28AvjdnrkMBOrQujUkLa9UUZLEJbQEdZ1jOoVV5QvrhvLfE/puA762Z61CADq1LY9LCWjUFWWxCW0DHGZZzaFWeIMuTeVnKa8Gfimu9BXTelrm2BejQujQmLaz/k4IsNqEtoOMMyzm0Kp9JP5z3dOw/BXxvz1yHAnRoXRqTFtbqSUEWm9AW0HGG5RxalSekH857R+w/DXzvzFyHAnRoXRqTFtbqSUEWm9AW0HGG5RxalSekH857V+y/A/jenbkOBejQujQmLaxVU5DFJrQFdJxhOYdW5Qnph/Oeif13Ad97MtehAB1al8akhbVqCrLYhLaAjjMs59CqPCH9cN57Y/8Z4Htf5joUoEPr0pi0sFZNQRab0BbQcYblHFqVJ6Qfzns29t8LfO/PXIcCdGhdGpMW1qopyGIT2gI6zrCcQ6vyhPTDeR+I/WeB74OZ61CADq1LY9LCWjUFWWxCW0DHGZZzaFWekH4470Ox/wHg+3DmOhSgQ+vSmLSwVk1BFpvQFtBxhuUcWpUnpB/Oey72PwR8/y5zHQrQoXVpTFpYq6Ygi01oC+g4rC21Kk9IP5z3I7H/HPD9+8x1KECH1qUxaWGtmoIsNqEtoOMMyzm0Kk9IP5z3kdj/EeD7aOY6FKBD69KYtLBWTUEWm9AW0HGG5RxalSekH8770dj/CPD9h8x1KECH1qUxaWGtmoIsNqEtoOMMyzm0Kk9IP5z3Y7H/o8D345nrUIAOrUtj0sJaNQVZbEJbQMcZlnNoVZ6QfjjvJ2L/x4DvP2auQwE6tC6NSQtr1RRksQltAR1nWM6hVXlC+uG8n4z9nwC+n8pchwJ0aF0akxbWqinIYhPaAjrOsJxDq/KE9MN5H4v9nwS+n85chwJ0aF0akxbWqinIYhPaAjrOsJxDq/KE9MN5H4/9jwHff8pchwJ0aF0akxbWqinIYhPaAjrOsJxDq/KE9MN5PxP7Hwe+/5y5DgXo0Lo0Ji2sVVOQxSa0BXScYTmHVuUJsvxcXpby/3b42UGw/BywfCIvS/k7gz8PWsRFOhaO4z74+bwc5Z78BMufxsinrMOb1cDcz3SYBR+7flaOpfy/Hbi2gI4zLOfQqh6X0JNPxv4ngO+/5OUrPfkkY6ExaWGtmoIsNqEtoOMMyzm0Kk+Q5RezsrjyOqhfGATLLwLLp7KytJ63fgm0iIt0LBzHffBLeTnKPfkplj+NkU9ZlVVZlVVZlVVZlVVZlVVZB9WUVVmVVVmVVVmVVVmVtYOsBuY+2WEW/Cz+F8RYXPk33bm2QM7OsJxDq/qcHT35dOx/Cvj+a16+0pNPMxYakxbWqinIYhPaAjrOsJxDq/IEWX45K0vre5jPDILll4Hls1lZWt/D/ApofSbeko6F47gPfiUvR7knP8vypzHyKauyKquyKquyKquyKquyKquyKquyKquyKquyKquyDhVWA3Of7jALfhb/GTGW1vcwXFsgZ2dYzqFVfc6Onnwu9j8LfP8tL1/pyecYC41JC2vVFGSxCW0BHWdYzqFVeYIsv5aVpa/8HuZXB8Hya8Dy+awsre9hvgBaxEU6Fo7jPvhCXo5yT36e5U9j5FNWZVVWZVVWZVVWZVXW4c1qYO5zHWbB9zK/KsbSV76P5doCOTvDcg6t6n0KevLF2P888P33vHylJ19kLDQmLaxVU5DFJrQFdJxhOYdW5Qmy/EZWltb72F8fBMtvAMuXsrK03sf+JmgRF+lYOI774DfzcpR78kssfxojn7Iqq7Iqq7Iqq7Iqq7IOb1YDc1/sMAu+l/l1MZbW+1iuLZCzMyzn0Krep6AnX479LwHf/8jLV3ryZcZCY9LCWjUFWWxCW0DHGZZzaFWeIMtvZWVpvY/9yiBYfgtYvpqVpfU+9rdBi7hIx8Jx3Ae/nZej3JNfZfnTGPmUVVmVVVmVVVmVVVmVdXizGpj7codZ8L3MV8RYWu9jubZAzs6wnEOrep+Cnnwt9r8KfP8zL1/pydcYC41JC2vVFGSxCW0BHWdYzqFVeYIs38jLUv7/MF8fBMs3gOWbeVnK97G/A1rERToWjuM++J28HOWe/CbLn8bIp6zDm9XA3Nc6zIKPXV+XYyn/fxiuLaDjDMs5tKrHJfTkW7H/TeD73bx8pSffYiw0Ji2sVVOQxSa0BXScYTmHVuUJsvxeXpbyeevbg2D5PWD5Tl6W8nnr90GLuEjHwnHcB7+fl6Pck99h+dMY+ZR1eLMamPtWh1nwsevbcizl8xbXFtBxWFtqVY9L6Ml3Y/87wPe/8vKVnnyXsdCYtLBWTUEWm9AW0HGG5RxalSfI8ocCLH8wCJY/BJbv5WUpn7f+CLSIi3QsHMd98Ed5Oco9+T2WP42Rb6iwGpj7bodZ8D72B3Iszia0JXQMyzm0qvsPevL92P8e8P3vvHylJ99nLDQmLaxVU5DFJrQFdJxhOYdW5Qnph/P+OPa/D3z/J3MdCtChdWlMWlirpiCLTWgL6DjDcg6tyhPSD+f9Sez/MfD938x1KECH1qUxaWGtmoIsNqEtoOMMyzm0Kk9IP5z3p7H/J8D3/zLXoQAdWpfGpIW1agqy2IS2gI4zLOfQqjwh/XDen8X+nwLfn2euQwE6tC6NSQtr1RRksQltAR1nWM6hVXlC+uG8H8T+nwHf/89chwJ0aF0akxbWqinIYhPaAjrOsJxDq/KE9MN5fxH7PwC+v8xchwJ0aF0akxbWqinIYhPaAjrOsJxDq/KE9MN5fxX7fwF8f525DgXo0Lo0Ji2sVVOQxSa0BXScYTmHVuUJ6Yfz/ib2/wr4/jZzHQrQoXVpTFpYq6Ygi01oC+g4w3IOrcoT0g/n/V3s/w3w/X3mOhSgQ+vSmLSwVk1BFpvQFtBxhuUcWpUnpB/O+4fY/zvg+8fMdShAh9alMWlhrZqCLDahLaDjDMs5tCpPSD+c90+x/w/A98+Z61CADq1LY9LCWjUFWWxCW0DHGZZzaFWekL6BH/wn4CuKvHUoGFA/jEkLa/WkIItNaAvoOMNyTgzP8YT0w3ldxbknBL5uAU+6mCc07gZPiAE96RbwhGsL6DjDcob0zqkDtW7wZETsdwHfSAFPRjBPaDwSPOlKeDJSwBOuLaDjDMu5nScjwZNRsT8C+EYLeDKKeULj0eAJMeDzyWgBT7i2gI4zLOd2nowGT8YQF/AZAU/GME9obMCTUQlPjIAnXFtAxxmWcztPDHgyNvbHAJ8V8GQs84TGFjwZk/DECnjCtQV0nGE5t/PEgifjYn8s8I0X8GQc84TG48GTsQlPxgt4wrUFdJxhObfzZDx4MiH2xwHfRAFPJjBPaDwRPBmX8GSigCdcW0DHGZZzO08mgieTYn8C8E0W8GQS84TGk8GTCQlPJgt4wrUFdJxhObfzZDJ4MiX2JwHfVAFPpjBPaDwVPJmU8GSqgCdcW0DHGZZzO0+mgifTYn8K8E0X8GQa84TG08GTKQlPpgt4wrUFdJxhObfzZDp4MiP2pwHfTAFPZjBPaDwTPJmW8GSmgCdcW0DHGZZzO09mgiezYn8G8M0W8GQW84TGs8GTGQlPZgt4wrUFdJxhObfzZDZ4Mif2ZwHfXAFP5jBPaDwXPJmV8GSugCdcW0DHGZZzO0/mgifzYn8O8M0X8GQe84TG88GTOQlP5gt4wrUFdJxhObfzZD54siD25wHfQgFPFjBPaLwQPJmX8GShgCdcW0DHGZZzO08Wgic9sb8A+BYJeNLDPKHxIvBkQcKTRQKecG0BHWdYzu08WQSeLI79HuBbIuDJYuYJjZeAJz0JT5YIeMK1BXScYTm382QJeLI09hcD3zIBT5YyT2i8DDxZnPBkmYAnXFtAxxmWcztPkGVFXpby922XD4JlBbCszMtS/t7SBSBOXCthH1yQ2AcXCOzJlWxP0hj5lHV4sxqYW1p0lgUfu5bLsZS/b8u1BXScYTmHVvW4hJ6sYnsm8F0o4Mkq5gmNLwRPVib2am4Wm9AW0HGG5dzOE2S5OCuLK/9O70WDYLkYWFbnrUv5vHUJiBPXatgHlyT2wSUCe3I125M0Rj5lVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVdahwmpgjj6f7hQLfhZ/kRiLK/+fCa4tkLMzLOfQ2PCcz9nRk162ZwJfn4AnvcwTGveBJ6sTezU3i01oC+g4w3Ju5wmyrMm8DwOLGwTLGmBZm7cu5fcwl4I4ca2FfXBpYh9cKrAn17I9SWPkU1ZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlVVZlHSqsBubo8+lOseBn8U6MpfU9DNcWyNkZlnNobHjO5+zoyWVszwS+dQKeXMY8ofE68GRtYq/mZrEJbQEdZ1jO7TxBlsuzsvSV38OsHwTL5cCyIW9dyu9hNoI4cW2AfbAxsQ82CuzJDWxP0hj5lFVZlVVZlVVZlVVZlXV4sxqYo9f3nWLB9zLrxVj6yvexXFsgZ2dYzqGx4TnvU9CTTWzPBL4rBDzZxDyh8RXgyYbEXs3NYhPaAjrOsJzbeYIsWzLvw8CyeRAsW4ClP29dyvexW0GcuPphH2xN7IOtAnuyn+1JGiOfsiqrsiqrsiqrsiqrsg5vVgNz9Pq+Uyz4XmazGEvrfSzXFsjZGZZzaGx4zvsU9ORKtmcC31UCnlzJPKHxVeBJf2Kv5maxCW0BHWdYzu08QZZm5n0YWLYNgqUJLNvz1qV8H7sDxIlrO+yDHYl9sENgT25ne5LGyKesyqqsyqqsyqqsyqqsw5vVwBy9vu8UC76X2SbG0nofy7UFcnaG5RwaG57zPgU9uZrtmcB3jYAnVzNPaHwNeLI9sVdzs9iEtoCOMyzndp4gy3V5Wcr/H+baQbBcByzX52Up38feAOLEdT3sgxsS++AGgT15PduTNEY+ZR3erAbmri46y4KPXdfKsZT/PwzXFtBxhuUcWtXjEnpyI9szge8mAU9uZJ7Q+Cbw5PrEXs3NYhPaAjrOsJzbeYIstwg8b908CJZbgGVnXpbyeWsXiBPXTtgHuxL7YJfAntzJ9iSNkU9Zhzergbkbi86y4GPXzXIs5fMW1xbQcYblHFrV4xJ6civbM4HvNgFPbmWe0Pg28GRnYq/mZrEJbQEdZ1jO7TxBljsEWG4fBMsdwHJnXpbyeesuECeuO2Ef3JXYB3cJ7Mk72Z6kMfINFVYDc7cWnWXB+9jtcizOJrQldAzLObSq+w96cjfbM4HvHgFP7mae0Pge8OTOxF7NzWIT2gI6zrCc23lyD3hyb+zfDXy7BTy5l3lC493gyd0JT3YLeMK1BXScYTm382Q3eLIn9u8Fvr0CnuxhntB4L3hyb8KTvQKecG0BHWdYzu082Que3Bf7e4Bvn4An9zFPaLwPPNmT8GSfgCdcW0DHGZZzO0/2gSf7Y/8+4Dsg4Ml+5gmND4An9yU8OSDgCdcW0HGG5dzOkwPgycHY3w98hwQ8Ocg8ofEh8GR/wpNDAp5wbQEdZ1jO7Tw5BJ4cjv2DwHdEwJPDzBMaHwFPDiY8OSLgCdcW0HGG5dzOkyPgyf2xfxj4jgp4cj/zhMZHwZPDCU+OCnjCtQV0nGE5t/MEWR7Iy9Ib1nwwc35hjWOQEOX6APhJxx+E3I4J7K0H2N6iMfK9UNZpjc6ySvl/PLP/4/waY6CWx1lNsd4nYn8EzON9/CGBOp+MaxYxSOME1PlhAV3SGRl1iYO0uuFnfmBbt+MbrT1IrUu4Ntj6of8Q3B+obasRy8QasYyrEYupEcuoGrF014hldo1YZtaIBZ/3Os0yvkZ1GVsjltE1YhlRI5ZZNWKZUSOW/hqxTK8Ry7QasUyoEYutEcuYGrGMrBFL0WEW0zj/8xMDx4/Bz3Wxc0Mdvzbp7PFTcb4rsc6p4vyfw9xPC+SOOv0wJq2xwHCq6DzLyBqxjKkRi60Ry4QasUyrEcv0GrH014hlRo1YZtWIZUSNWEbXiGVsjVjG14jlWFEflpk1qsvsGrF014hlVI1YTI1YxtWIZWKNWLbViKUrwTKQl6W8Nv1MXDM0ep82ABzEdAY4HsnMUTCOAnRJqxt+5p1xA4fXD0+PO8t1VSMvV7jP0uM8rR00nxHQPLT+sn371x4+/EI0r8ybZ3k9BWmhB9j6oU/6gWVrXpby+/QtmfMLa2wGfsqV2C0c3wK5bc7LUd73tzbOrSmNke+Fsk7rMKuU/1fkXfOH11NQLa9gNcV8NmbOJ6yxKa41ArQ2gublAt5tiGsVMUhjE+iuF9AlHbpGgzhIqxt+5mPxMa3qGg2J2mDrhz5pPd81Gp1mmVIjlok1YhlXIxZTI5ZRNWLprhHL7BqxbK4Ry8wasUytEcukGrGMrxHL2BqxjK4Ry4gascyqEUt/jVhm1Ihleo1YJteIZUKNWGyNWMbUiGVkjViKDrM833U0dHwzzHWxc/l1NOvifFdinXWN838Oc79MIHfU6YcxaeF1NOtqwDKyRixjasRia8QyoUYsk2vEMr1GLDNqxNJfI5ZZNWIZUSOW0TViGVsjlvE1YplUI5apNWKZWSOWzTVimV0jlu4asYyqEYupEcu4GrFMrBHLlBqxbKsRS1eC5dK8LOX38GsbZxu9l74UOIhpLXCsycxRMI4CdEmrG35mX3zhEF7j7Rl/lkviWid6TYvXHR0U0MRrndppXpk3z7V1utYprLEFtFLX+tBx/Bw/8/VRldf6bJHTLfP/t3hdlrK+cFbTOP9+1SkWC3pXybGUfyf9X+Fauj4D6+N1TJmvrytru5nVlsZXQG2JYasgi01oC+isNSzn0KqeR5BlU16W8nF0I2gR1yaoPR3H55HM1zqW+2ATy5/GyPdCWbco679J1vy6a8rXr6gbWtX9EVk2ZGVp3R8vBy3iIh0Lx9ELyeuAaV0aI5+yKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquyKquy5mfNr+vK6yNQN7Sq6yOQJfPfCSuvj1gHWsRFOhaOoxfr8nKUXqxn+dMY+ZRVWZVVWZVVWZVVWZVVWZVVWZVVWZVVWZVVWZVVWYcKq4Bu+fuwqBta1efLyJL5746Uny9fClrERToWjqMXmf/mSB/+bQ9al8bIp6zDmzW/bl/5fQ/qhlZ1f0SWtVlZWvfHNaDF/86OhePoRea/vdPH//ZOP4yRT1mVVVmVVVmVVVmVVVmHN2t+3dbrc9QNrer1ObK4rCyt1+d9oEVcpGPhOHrRl5ej9MKx/GmMfMqqrMqqrMqqrMqqrMo6vFkFdJ1huqFVvT5Hlt68LOVyl4AWcZGOhePoxSV5OUoveln+NEa+ocIqoFvuG9QNrWrfIMvqvCwlxsWgRVykY+E4enFxXo7Si9Usfxoj31BhNTDXBXN0vBvmLor9ETB3YeyPhLlVkBPNXRD7o2FuZeyPgbkVsT8D5pbHPv6d9WWxvwnmlsb+BphbEvvrYW5x7F8Gc4tify3M9cS+g7mFsd8LcwtifwvMzYc+3c6L/bEwNzf2Lcw1Y38czG2P/fEwtyP2J8Dc1bE/EeauSfCR16thjrzGvUFeXwRz5PWFMEder4I58voCmCOvV8Ic1WgFzFGNlsMc1WgZzFGNlsIc1WgJzFGNFsMc1WgRzNH/J9YDc5NjfyHMTYn9BTA3NfbR+2mxPw/m6P9EnAtztN+bMDcz9rfD3KzY3wFzs2P/apibE/vkffBiFOTQH297X1xzeD+hVvUcQfqBZUFell683/WAzry8OuXj6nyWH41JywLDAkEWm9DOr+N6MeeumNv0hO7cPLp91Am6c2D9RcBBWt3wM9+Id+rx8efnZK1Dy/u5wNMDPHOAh37mdyNPeBx9fNLZ8zLvfYfPTdSq7odye9Kdcz98ISwC++eHTWAPlE/9i4Gf70cLx3HvLs7Lcc5epHVpjHzKqqzKqqzKqqzKqqzKqqzKqqzKqqzKqqzKqqzKqqxDhRW/N13YYRYLDPPFWFyvTWhLfF6O3yfS2uG7ixPw3cX8zLmFOuP3ET3AQFrd8DPPTjrLdSr2x8Jx3BOZWQ/kr7nrDd9hjwH+uSx3/O6Y7ns9kKPEvicdWpfGuO97GJ8Ei01o43dpwXfye1Hj7NyCRJ3yfs/V96K+58r9nVTROPdxoR80UHdJXt0+1C1ikAbNd0P/KbrAAn4uNPKQmIOHcxM/h33+vauF43OFc36++wdphT36BOQ6N8E9HbjpOD4OZn5sL7nnAUdPI30tCuWyCFg69RiziNUsP0tfb+oxBq/ToZoFT98PHJLPg13MH8w/0+PYOddY4P1lEXCQFl7T8Fzc1+Eai9SeonNnw5r/GteFEEfqupCPArPA42/yuhDiSV0X8uPwGuYrbV7DSDwOzH8eVsxB8j4friFEDnyuoJ/5OPNsaWYevD6UWtXz91KozbK8LOU1JctBi7hIx8LxacCxPHNNCtCkdWmMfMsSrHh96xz2c/lZW9cZIUdoVf4tB5aVWVlaj0cXwPr9oIG6q/Lq9qEuvf4iDZrvhv4X4DXJqrPdHz7uEHPwcEXi57C/jJ1j4fgK4ZxXAkc/jEkrPK5+GnJdkeCeDdx0nPYtXneOj8UrBHJZznJZzpjxM4ZlYiytzxi4Nj4/5X/N08p/QeNs62mc/94fP5NYAFz4mUR3Zq6w5sjMa+L19NSqHq9IP3w2QNe+nx44eWrfkUM7D+07WMASI9hyXbAM9vHXOUZBKWmOfpaOjW6cj5itHlMBuivCjYh5j4riYxpnfx8g1CB8VhJeD4Tr+cOltWELhOvzw/X4U4HxyXgbnivDa+hwfX24nj5cPx/2Urifh9c64Tkr7LOwr8J9rKfRei0ZXo+E57XwnB/uc+F+Ee4T4XEmPJaGx5kLG63fiwi/LxF+jyL8/lN4Ig+/Pxd+ZyT8nYvw+yTh79GF3zUJfycy/B5K+P+INvjY2Gj9/soVjdbvtmyJtd3q40ofV/nY1mj9TsD2Ruua/3CNf7im/1of1/m43scNPm70cZOPm33c4mOnj10+bvVxm4/bfdzh404fd/m428c9Pu71sdvHHh97fdznY5+P/T4O+Djo45CPwz6O+Ljfx1EfD/h40McxH8d9nPBx0sdDPh72ccrHaR8DPs74eMTHoz5e4uMxHy/18TIfL/fxuI9X+Hilj1f5eLWP1/h4wsdrfbzOx+t9vMHHG328ycebfbzFx1sbLa+f8vE2H0/7eLuPd/h4p493+Xi3j2d8vMfHe328z8ezjdZ7uQ/4+KCPD/n4sI/nGmc3P278P493QPp9o12t+2HP6WMnB3p6e074f/cdO3by0UMHV/fgsdM9x8+cHug5PbDv1EDP4VMnj/f0rcZ1f2qczLpfj9ed0/vnfQMDh44/NNAzcNKfeGzg6EPHHut59OjA/T0nHzl06rAXwJM/POlFnPyRePK880/ed/Dg85/30/E8uhdfc+LgoZf0nDwz0HPycM/+k2dOHDz9Lx8U1URl9gIA", + "bytecode": "H4sIAAAAAAAA/+3dB3wVx50H8PckIVg9JHpvT/SOJHoXHYwpBgMG0wQSxRRhJJoL7jYugO24xjW9O71fEieXXJJLLk51LrkU55JcenJxLjmn3s3sm//xYxm/aM7/seZZ//18/rzd2bcz35nZ3bcVPZlKpdKp3FCsolvqwoHm15rPqpc2VKf58qry6SwqEGdxgThLCsTZrkCcpQXibF8gzg4F4owKxFlWIM5MgTg7FoizvECcFQXi7FQgzs4F4uxSIM6uBeLsxujsA87u5rOH+expPnuZz97mk5bpaz77mTqWmOn+KgaoGKhikJlHDZJVUalisIohKoaqGKZiuIoRKkaqGKVitIoxKsaqGKdivIoJJp9qFTUqJqqYpGKyiikqpqqYpmK6ihkqZqqYpWK2ijkq5pp2m6divooFKhaqWKRisYolKpaqWKbiIhXLVVysYoWKlSpWmbpkTV1Wq7hExRoVa1VcqmKdivUqNqi4TMVGFZtUXK5is4otKraq2KZiu4o6FTtU7FRRr6JBxS4Vu1XsUbFXxRUq9qnYr+KAioMqGhNtfkjFlSoOq2gy8zqbec0qjqg4quKYiuMqTqi4SsXVKq5Rca2KkyquU3G9ihtU3KjipkReN6u4RcWtKm5TcUrF7SruUHGnirtUnFZxRsVZFXeruEfFvSpeZfIqMnndp+L+RNoDKh404w+Zz4fN56vN5yPm81Hz+Zj5fNx8PmE+n1TxQkVuXB/DJc+1dRqt82lIo/W/CNJoWyiGNNouSiCNtpF2kEbbSymk0bbTHtL6mfEOkNYfxulzgBkvg7SBZjwDaYPMeEdIy5rxckirNOMVkDbYjHeCtCFmvDOkDTXjXSBtmBnvaj6p3nqoNZ9VL3HQeTLvV6u0nfq8G9SH+rw7pFGf94A06vOekEZ17wVp1Oe9IY36vA+kUZ/3hTTq836QRn2O6wr1+QBIoz4fCGnU54Mgjfo8C2nU55WQRn0+GNKoz4dAGrXlUEijtqR1RbfdAphPA26DeN2M0mg+boPFkCel0XzcBmk+boM0H7dBnE+fNB+3QZqP2xvNx22L+gu3I1qmK6RRf+F6R/ngOkb9hesT5Y3rDvUXrjtUHq471F+47pAB1x1a93HdIVcW0mjdx3WHrLTu6HqVgq3WfFa9tKEa97U0pBPTtTBO5ZdC/ZksE3F/3hLLALAMZG6XDLTLQCgny1wO/g61pM5ZsFQyW3Seg3nzjA9rh4Cf6krlZGB+d6jbEOa6paFMypemh4Clf8KJv/X9A/BRWhZ8Qyy+oby+mnTq/H6shemh4KO0SrAwr1M1UcKih3zbzGCwDGe1VFfhMV5LLMPBMozVktt+R/DmGR9HjmTOU+cxCtqE2o/sGZg/EtprFHN7paFMypem0SdWsYpVrGIVq1jFKta2bcXzHLxmR98bEoCP0oaBhfvcAK9xUd76OuJTUCbvNYrqKjxPpusxZKCyiuE7Xyg/53qPSStLXXhuHaXOnVNj/w1i9ef6j8qhfGl6EPioLtlEXbktlQnLK7fcmp381wmrq/R1aX2tm9angYl62K79UppeJ5+G+oZybRevfRaBj/l6b/X/93ovXqcrBh/3tqp9Ax18g8BHy+F9Fe7rtbjPaomvEny0XDvwcV/TxGunLfHZrnOWwif39TLXa3fDwEfLtQcf8+9r7Bvu4MNjJVquA/i4j0W0b6SDD49PaLkIfGM8+EY7+MaAj5YrA984D76xDr5x4BsL4+Sb4ME33sE3AUy0XEfwVXvwVaVa7qsGHy1XDr6JHnw1Dr6J4KPlKsA32YNvkoNvMvhouU7gm+rBN8XBNxV8tFxn8E334Jvm4JsOPlquC/hmevDNcPDNBB8th88ozfbgm+Xgmw0+Wq4b+OZ68M1x8M0FHy3XE3zzeH3xfdBaB988sCzktUzSlvkOloVgWcBrie+DLuLNM74Pupg5T53HEmgTaj+yZ2D+YmivJcztlYYyKV+aRp9Y27YV30siZ5S6cFtrTR+lLfBoiRIWPeTb19l82JfLeH3x78JSB98ysFzMapkYXyO+yMFyMViWs1pyvwsrePOM9+ErwU91pXIyMB/7fCVz3dJQJuVL0+gTq1jFKlaxilWsYhWrWMUqVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWs/FZtWZpwRvC9pQH4KG25R0uUsOgh33MiNh/25WpeX/xMzSoH32qwrGW11MTP1FziYFkLljWsltwzNZfy5hk/U7MO/FRXKicD87HP1zHXLQ1lUr40jT6xilWsYhWrWMUqVrGKVaxiFatYxSpWsYpVrGItFKu2rEo4I/jeqgB8lLbGoyVKWPSQ7zq7zYd9uYHXF9+TWO/g2wCWTbyW+P9/uMzBsgksG3kt8T2Jy3nzjO9JbAY/1ZXKycB87PPNzHVLQ5mUL02jT6xt26ot6xPOCL63PgAfpW30aIkSFj3k2y/ZfNiXW3l98T58i4NvK1jqWC25v2WyzcFSB5btrJbcPnwHb57xPnwn+KmuVE4G5mOf72SuWxrKpHxpGn1iFatYxSpWsYpVrGJt21Zt2ZJwRvC9LQH4KG27R0uUsOgh33mKzYd92cDri8/p6h18DWDZw2rJndPtcrDsActuVkvunG4vb57xOd0V4Ke6UjkZmI99fgVz3dJQJuVL0+gTq1jFKlaxilWsYhVr27ZqS33CGcH36gPwUdpuj5YoYdFDvvMUmw/7cj+vLz6n2+fg2w+WRg+WAw6WRrAc5LXE53SHePOMz+muBD/VlcrJwHzs8yuZ65aGMilfmkZfoVi1ZV/CGcH39gXgo7SDHi1RwqKHfNuPzYd92cTri7fvww6+JrAc9WBpdrAcBcsRXku8rznGm2e8rzkOfqorlZOB+djnx5nrloYyKV+aRl+hWLXlcMIZwfcOB+CjtCMeLVHCood824/Nh315lQffCQffVeA7YfFd48F3tYPvGvDRchH4TnrwXevgOwk+Wq4MfNd78F3n4LsefNfBOPlu9OC7wcF3I5hoOfwbozd78N3k4LsZfLRcOfhu9eC7xcF3K/houQrwnfLgu83Bdwp8tBz+jdE7PPhud/DdAT5aDvd/d3nw3enguwt8d1p8Zzz4Tjv4zoDvtMV3twffWQff3eA7a/Hd68F3j4PvXvDdY/Hd58H3KgfffWC5n9dSlQHL/VDOgx7q/ECq5XWm8jOwHPoe9uB7yMH3MPgesvge8eB7tYPvEfDRcrhOP+bB96iD7zHwPWrxPeHB97iD7wnwPW7xvcaD70kH32vA96TF9zoPvtc6+F4HvtdafG/w4Hu9g+8N4Hu9xfcmD743OvjeBL43Wnxv8eB7s4PvLeB7s8X3Ng++tzr43ga+t1p87/Dge7uD7x3ge7vF904PvqccfO8E31MW37s9+N7l4Hs3+N5l8b3Xg+89Dr73gu89Ft/7Pfje5+B7P/jeZ/F90IPvAw6+D4LvAxbfhz34PuTg+zD4PmTxfZTXF98z+IiD76Ng+TivJX4v/R8cLB8Hy8d4LfH9i0/w5hnfv3ga/FRXKicD87HPn2auWxrKpHxp+mlIF2vbtmrLRxLOCL73kQB8lPYxj5YoYdFDvv3S0xYf9uWneH3xPvyTDr5PgeUzrJbc/3f+jw6Wz4Dl06yW3D78n3jzjPfhnwU/1ZXKycB87PPPMtctDWVSvjSNPrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWsYi0Uq7Z8MuGM4HufDMBHaZ/2aIkSFj3ku85u82Fffp7XF9+T+JyD7/Ng+SKrJXdP4p8dLF8EyxdYLbl7Ev/Cm2d8T+JL4Ke6UjkZmI99/iXmuqWhTMqXptEnVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWshWLVls8lnBF873MB+CjtCx4tUcKih3zX2W0+7Msv8/riexLPOPi+DJavsVpyf+vhKw6Wr4Hlq6yW3D2Jr/PmGd+T+Ab4qa5UTgbmY59/g7luaSiT8qVp9IlVrGIVq1jFKlaxirVtW7XlmYQzgu89E4CP0r7q0RIlLHrId55i82FffpPXF5/TPevg+yZYvs1qyZ3T/auD5dtg+RarJXdO92+8ecbndN8BP9WVysnAfOzz7zDXLQ1lUr40jT6xilWsYhWrWMUqVrG2bau2PJtwRvC9ZwPwUdq3PFqihEUP+c5TbD7sy+/x+uJzuu86+L4Hlh+wWnLndN93sPwALM+xWnLndP/Om2d8TvdD8FNdqZwMzMc+/yFz3dJQJuVL0+gTq1jFKlaxilWsYhVr27Zqy3cTzgi+990AfJT2nEdLlLDoId95is2HffljXl98TvcjB9+PwfJTXkv8dwb+w8HyU7D8hNcSn9P9jDfP+Jzu5+CnulI5GZiPff5z5rqloUzKl6bRJ9a2bdWWHyWcEXzvRwH4KO0nHi1RwqKHfPslmw/78pe8vngf/gsH3y/B8hteS7wP/5WD5Tdg+TWvJd6H/ydvnvE+/Lfgp7pSORmYj33+W+a6paFMypem0SfWtm3Vll8knBF87xcB+Cjt1x4tUcKih3z7JZsP+/J3vL54H/68g+93YPmDB8t/OVj+AJbf81riffh/8+YZ78NfAD/VlcrJwHzs8xeY65aGMilfmkZfoVi15fmEM4LvPR+Aj9J+79ESJSx6yLf92HzYl3/y4Pujg+9P4PujxfcXD74/O/j+Ar4/W3x/8+D7q4Pvb+D7q8VHC3P6/ifVch/NzMBy6Cvy4EunW+4rAh8th74SD75iB18J+IotvlIPvnYOvlLwtbP4OnjwtXfwdQBfe4uvzIMvcvCVgS+y+Dp68GUcfB3Bl7H4Kjz4yh18FeArt/g6e/B1cvB1Bh8tdz/4unrwdXHwdQVfF4uvuwdfNwdfd/B1s/h6evD1cPD1BF8Py/rX24Ovl4OvN/h6WXx9Pfj6OPj6gq+Pxdffg6+fg68/+PpZfAM9+AY4+AaCb4DFl/XgG+Tgy4JvkMU32IOv0sE3GHyVFt9QD74hDr6h4Bti8Q334Bvm4BsOvmEW30gPvhEOvpHgG2HxjfbgG+XgGw2+URbfWA++MQ6+seAbY/GN9+Ab5+AbD75xFl+VB98EB18V+CZYfDUefNUOvhrwVVt8kzz4Jjr4JoFvosU3hdcXX5+e7OCj8rVlOq8lvt851cEyHSzTmPtN5zmDN8/4WvlMqBDVdQb0+UxLn89krlsayqR8aRp9Ym3bVm2hfQM5I/je5HTr+yhtmkdLlLDoId9+yebDvpztYR8+y8E3G9qqltWS+ztUcxwstWCZ62EfPs/DPnw+VIjqOg/6fL6lz+d72D7mJbYPmkafWMUqVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxFopVW+haNzkj+B7Na00fpc31aIkSFj0kJs+7zm7zYV8u5PXF9yQWOPgWQlstYbXk7kkscrAsActi5n7TeS7lzTO+J7EMKkR1XQp9vszS58s8bB9LE9sHTaNPrGIVq1jFKlaxilWsYhWrWMUqVrGKVaxiFatYC8WqLXStm5wRfI/mtaaP0hZ7tEQJix4Sk+ddZ7f6Uud8y3l98T2Jixx8y6GtVrJacn9z52IHy0qwrGDuN53nKt4843sSq6FCVNdV0OerLX2+2sP2sSqxfdA0+sQqVrGKVaxiFatYxdq2rdpC5wrkjOB7NK81fZS2wqMlSlj0kJg87zzF5sO+XMPri8/pLnHwrYG2WsdqyZ3TrXWwrAPLpcz9pvNcz5tnfE63ASpEdV0Pfb7B0ucbPGwf6xPbB02jT6xiFatYxSpWsYpVrG3bqi10rkDOCL5H81rTR2mXerRECYseEpPnnafYfNiXG3l98TndZQ6+jdBWm1ktuXO6TQ6WzWC5nLnfdJ5bePOMz+m2QoWorlugz7da+nyrh+1jS2L7oGn0iVWsYhWrWMUqVrGKtW1btYXOFcgZwfdoXmv6KO1yj5YoYdFDYvK88xSbD/tyO68vPqfb5uDbDm21k9cS/52BOgfLTrDsYO43nWc9b57xOV0DVIjqWg993mDp8wYP20d9YvugafSJtW1btYX2DXWwD6fvbUu3vo/Sdni0RAmLHvLtl2w+7MvdHvbhuxx8u6GtrvCwD9/jYLkCLHs97MP3ediH74cKUV33QZ/vt/T5fg/bx77E9kHT6BNr27ZqC+0b9sA+nL63K936Pkrb69ESJSx6yLdfsvmwLw962IcfcPAdhLa60oOl0cFyJVgOediHH/awD2+CClFdD0OfN1n6vMnD9nE4sX3QNPoKxaottA43wr6Gvncg3fo+Sjvk0RIlLHrIt/3YfNiXRzz4mh18R8DXbPEd8+A76uA7Br6jFt8JD77jDr4T4Dtu8V3twXeVg+9q8F1l8V3rwXeNg+9a8F1j8V3nwXfSwXcd+E5afDd48F3v4LsBfNdbfDd7OH640cF3M+yLb/Jw/HALb55VOs9bmdtM53EbNBK13y3QdzT/Vmiv2zz8jt6S+B2lafS11No91bpWX/1/irn/O6o8OkBbnkq0Kbb37Wa8BNJxe77TQzvfYfJMm6Aybod2vstDuVROO1MuOaisYvjO16PcZ3kqtw7SUOS5bXCohfE7YXugoWdAlh4BWXB7bW1Lp4DapWNAliggS2lAluKALL0CsvQOyFIbkKU8IEtZQJb2AVlKArL0CciyKCBL94AsFQFZMgFZOgRkaReQJd3Klih14TWZCObfBt8rSiyr2/FXFefmnzHpRZDPWTg/S+Z9BvI+bcbPpi9cFtvojIc2wnJqYZrKKgPD2XTrW9oFZOkQkCUTkKUiIEv3gCyLArL0CchSEpClfUCWsoAs5QFZagOy9A7I0isgS3FAltKALFFAlo4BWToFZKHj/hAsPQJql54BWYpeJgudm1G+pxOW1iz3bt5y42cC74Fy6Vz1bmh3Kv8ecNzL7EgnHGkol8oqhu9cbQ6U9HHk8bJzroUpXpfed9NvLOWtyzzpocyGaVPqdkzataslZc7nrWf87AqVhX2AQy2MU/nasoDXEj+7Mo83z/jZhbnMbabzmANtQu1H9gzMnwvtNYe5vdJQJuVL0+hrqbV7K1t99f9s3jz/79kVasvZiTbF+sxkro/OY5bJqwTKmgllTvfQdzNMXmkTVMYsKHeah3KpHHoehhxUVjF850Gzn8z3PIyPtsGhFsaprBd7Hqa1LT0CsswJyNI1IEungCwdA7JEAVlKA7IUB2TpFZCld0CW2oAs3QKydA7IUh6QpSwgS/uALCUBWfoEZFkUkKVLQJaKgCyZgCwdArK0C8iSbmXLiz2zRPPnQFpRYtnkM0tTTHoRLDPZjBdb8p4CaVPN+GTLsthGUxJ1qXppQ9xGWE4tTFNZ+MzS5AAs7QKydAjIkgnIUhGQpUtAlkUBWfoEZCkJyNI+IEtZQJbygCydA7J0C8hSG5Cld0CWXgFZigOylAZkiQKydAzI0ikgS9eALHMCsvQIyNIzIEvRy2Sh82fKd2rC0prlTuItN34+YSKUS9cTJkG7U/kTwVHD7EgnHGkol8oqhu+sNieo+lh/Reacy8dzZXTsgc94rfVQJj5X9vfKnM9bz0mv9OfKdB5zwW97rorm471H5mfR8j5XNddfuXH9X4nPwIm15dYMlEfOKHXhttaaPkpbABbmfUG1Loeunc2DcmbxlhPvU3Hd0EO+fSo+m8f8DGS1r2cbZ4A/+WxjBubjPnUGc93SUCblS9Poa6l1rlhfkVb++4IT4+NDLFcPLblX6KMNPDzTG2/jeF5CdaVyMjAf+3cqc93SUCblS9PoE6tYxSpWsYpVrGIVq1jFKlaxilWsYhWrWMUqVrGKVaxiFatYxSpWsYpVrPxW/mela+JnLrBcPeR75mKKxzbQeU7mzTN+5mIS+KmuVE4G5mP/Mj8bft5z+ZQvTaNPrGIVq1jFKlaxilWsYhWrWMUqVrGKVaxiFatYC8Wqy53IW+6kKFGuHvJds57osQ18/P8dOo9q8FNdqZwMzMf+rWauWxrKpHxpGn1ibdtWXW4Va7nV8X0pLFcP+bbxKo9toPOcwJtnzB0PfqorlZOB+di/45nrloYyKV+aRp9YxSpWsYpVrGIVq1jbtlWXO4613NwxP5arh3zH/OM8toHOcyxvnvEx/xjwU12pnAzMx/4dw1y3NJRJ+dI0+sQqVrGKVaxiFatYxdq2rbrc0bzl1kSJcvWQ75h/tMc20HmO4s0zPuYfCX6qK5WTgfnYvyOZ65aGMilfmkZfoVh1uSN4y43XRSxXD/nWxREe20DnOZw3z3hdHAZ+qiuVk4H52L/DmOuWhjIpX5pGX6FYI0grgjSaj39jdKgZL4G0IWa8HaQthjpR2hIz3h7SlprxDpC2zIz3hLSLzDj+3dTlZnw2pF1sxmdC2gozPgPSVprxaZC2yoxPhbTVZnwypF1ixidB2hozXgNpa814NaRdasYnQNo6Mz4e0tab8bGQtsGMj4G0y8z4KEjbaMZHQtomMz4X0i6HcfrcbMbLIG2LGc9A2lYz3hHStpnxckjbbsYrIK3OjHeCtB0WH62LwyGN1kVcd2ldHApptC4OgTRaFxdDGq2LSyCN1sWlkEZttAzSqI0ugjRqo+WQRm10MaRRG62ANGqjlZBGbbQK0uhvFK6GNPpbpJdAGv1NrTWQRn9TcC2kdTfjl0JaDzO+DtJoe1wPab3M+AZI623GL4M0+pugGyGtrxnfBGn9zDium/3N+GZIG2DGt0DaQDO+FdIGmfFtkJY149shrdKM10HaYDNO66ZeV0rhu7Xms+qlDdVYFg35frep/FKoC5OlKgOWLJQzkLWcmvhvPFHfFJmyaJ0bCOUO4Cm3mkZ0uf0h/0pwUFnF8J1nzYZabr7fn7Udcr/PAxL9SZ7+4KHvfNt49D7v2orzl2N01eA2QUO+dTILdWDqM6JU4XbcEgu2J+96mzuuZV4HqnSe/Zjz1Hn0hTZJrlMZmN8P2qsvc3vh9kb50jT6xCpWsYpVrGIVq1jFKlaxilWsYhWrWMUqVrGKtVCs2lKZcOK9rMoAfJSG91u4r23jvT/KW9+72Af3Lgaxlpm7t5SFOmXBQGUVw3feUHHO1WjGy2A+9RXeY8T+473fkes/KofypWkqqwzqgv3Hfb8D79NRvq/ccmt28m8DNVX6/r9+piBr8ktud9SneO+V0vA+n+5zWu/wuYZBibTW6g/cZgZBGo0PBh9vG1f7uIcWP7bTF/oha8apnGKYfwr2IXdUnOub5P5Cz3/YMp+GfPc18b4183NiVficWKnJd5ilXOZnFs97Pi1tgsqg9GIYf4gekoHv6YHal8x6vRtq+R6OD0wsk4H5Qz3XGZ8NrIVpKkuvJ6dhnXoYfi+5f2+wvtguPaBdaP4gaBfu7U23Cx7fZcHQDyxDEk48rsJ94FAPvhc7rhoKPkobAD6qB+5PngKrz2Og5PM12IdMvxPnPV+Dz19UgoPKwudZ3mbWa/1YS/K4JwvL9oE8X45ngpK/zfhM0LvA7OGY2fpMEHlszwS9D/YTP/s7x68DEmm+/ZTvgIQfjwsGvEyWF2tLX+dgtM/Sz6Kig8oqhu98IrFOcT8Hjs9u05DvWGMYtM1wZouH39QL3lNJ/vbjux/doW4+3v0YkWhTmkbfCIsVj6P7Jb7H/25PTZWH96HiY4kxJi+9P6JtnMophvnPwH7rK3BMTHXOQj7PWebTkG89HgXtx/v/PeR+N/D/k6iFMrBc5v97rRrLpWPm5P9vUQzj34djZvz/KbLmk8x6vRtr+R6Oj0gsk0ld+M6frzqPA0ctTFNZej35OqxTz8ExM/d2jvXFdukD7ULz8di1MvF9vT7T9oC/ydzbZTp1/nuatTA9GnyUNhLa9GfertXlXFlwZVMXXqvDa4hZcOE1xGJmV2nq3PsiXHniuyo05Nt3lcJnO2aLvh5F76o0NTcertvdsKahrj4NrJIEsQhoOI6vh9HrNPh6GL1Og6+H0fL4Khjl0wHmJZuHrf7doHJFpvASgyw1hXdInXvPR7eVvo6nj8/0aqffy9Hv4ej3bvR7Nt3AeNp86uMMfc6l35vR78no92L0eqyP//Q+QR9/6mNC/buv1/VsKrcP0NfJ9HmsPi7Qx2H6+EvvL/Q2qX9X9Paqt1O9f9H7QL2f1/tAfRCkd0z6HTT9fwbr99P0e2v6b97pd9r0u27TU7n34GaqmJXKvTun36mba9p2nor5KhaoWKhiUSr3vpR+P0q/D7UslXvfaXkq9z6Tfn9Jv6+k30/S7yPp94/0+0b6/SL9PpF+f0i/L6TfD9LvA+n3fzalcu/3bE7l3t/R7+tsS+Xex6lL5d632amiXkWDil0qdqvYo2KviitU7FOxX8UBFQdVNKo4pOJKFYdVNKloVnFExVEVx1QcV3FCxVUqrlZxjYprVZxUcZ2K61XcoOJGFTepuFnFLSpuVXGbilMqbldxh4o7VdyVyvX1GRVnVdyt4h4V96p4lYr7VNyv4gEVD6p4SMXDKl6t4hEVj6p4TMXjKp5Q8WTq3DaPK/7XzMtns8z02tz2mm3a39icrcoeVP/W7d/feKyhfnwW5zVlDxxpas42Ndcdbs7uOtx4IFs9HvN9oMxPvt8w76jQ71ldc3PDgUPN2eZGteD+5r2H9p/IHtvbvCfbeLTh8C5VAC781oqXsPA7zcL9L1y4rr7+xZf7uFmOtuJlB+sbjmcbjzRnG3dldzQeOVjf9L/ToZQwxZUCAA==", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -679,7 +679,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json index 67f2ef0ed0b..cc776fe5d4e 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json @@ -70,7 +70,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "H4sIAAAAAAAA/+1dB3gU1fedbUnoTaT3IgjoTrIkwUpRBAuCggiImraChk6wYRdQsKDYsICgIIoNxYaIgAVUQKWo2BAVG2LvBf/3wRmZbCLumnv3995/dr7vfCe7eXm5debM7NuZizIs66OQ9ffmA3cFhyu22WrqUDnzZoWzI5GinMwiO8vOC2d2yc/tHI50zs/OtXPtzrmdCzNzs7KKciO5OV3yu+SEu9iRrCI72rlLVhQTh/hsDEv4nUZzpAn4naa53+k0R7qA3+ma+92Q5mgo4HdDzf1uSnM0FfC7qeZ+t6Q5Wgr43VJzv9vSHG0F/G7L7LezcdvZjtFOZZvarzXHfPUIOwn1wQ3ADcGNwI3BTcBNwc3AzcEtwC3BrcCtwW3AbcH7gdv9j7gjoT1ypuJSE3Fpr4Fd+7vsqqVZvtT4DoSAtafe3Rv3PqAD31zhoMvOjuBOsNn5HwcQDlT/i2ATMglZhAihMyGbkEPIJXQhHEQ4mHAI4VDCYYTDMV83QndCD8IRhCMJPQlHEXoRehOOJhxDOJZwHKEP4XhCX0I/wgmEEwn9CQMIJxEGEk4mDCIMJgwhnEIYSjiVcBrhdEIeIZ9QQCgkFBGihDMIwwjDCWcSziIUE0YgBiMJNyCRlQh+q/SW5vq5Kzhcwa08/Rqu4Oa23WGl5Stbe3yzYn5fyWVHwCobg6DrvUBMPKoTqpQzZ5rr77ry+GbH9l5X18/O/3LbEtDIFt//2BZ3ji3Xe87v3bUQm3dVP1NdvZFWzt+k4+dAOXOnud5zToXTy/lbd4zSYnwJV2yzfTH/p6vrtfO/KrtsSNfAloBGtviTZIvrUsmueUMxtvwv/28G7//NdPeS5cqBFWOLs2W4bKnCaktk13GjUgK2VHHZUpnVlt3XdqryzrnrWFuNeU41R3VXTJz4VXXFyPl9NVe8qjPHy+f6n868zmu3fSlbU7ambE3ZmrI1ZWvK1pStKVtTtqZsTdmasjVla8rWlK0pW1O2pmxN2ZqyNWVrytaUrSlbU7ambE3ZmrI1ZWvK1pStKVtTtqZsTdmasjVla8rWlK0pW71taxWr9Np+h6u67Ppf2+e8V9llS1VeW8Lu78U4c6vvPhzk2/M/edeOR/7+bqMzf1eXDc7/CrjGDPLtseswMbt2r4l2ryMPxthU2Sr93Q/HDu415GqOKuXYUdnFzv+v4nrPva7dsbFazHtS9VzNZW9X1+vqLvuc+nLbxLyufa+9JbfPiaivHVo1XP83WI7/zv93xlVy/eyuq5qunx12vldaxfVebfxc1fVenRhf3d+Jcv9fp9/c/8uxuZbrPee7JLVd7zm1VMdlu7s33PVXKeY9iX7xWaX7tqvrtbtnMlx2CdmSWZ4tgRhbGL4DY8e+4a57NX83q+w+IuAaU4j9qFMn7p5xf+/OsbtKzDiJ76TE9m6G6/+6e7cG6/+N7Pp+TU1eX3btw2u54unUXk1XLpzfj3Ad30a5vqvo+JzumufCcn7vbL6Y111dP9dwxa8Or6+78raPa/6urv/h/r91ef+v7f6/PsD5H877AdfPF7gCVHfPj3/H17FZ1Xvtcsa5f64W8zdVXL+vLexzHZcdXV2vnf+l6mSsq6YudGkm7mO/2193XAKuuMQepyT6TblYyyodl9hjnFvzu4+P7hp1uLaAfTVi7HNe13bZ57xX3WWf44d7f+LW5yFWWyNZ7v/pbHvbt7i/b8r9/fAMVyzOKBrfrWT8sIHDx48sGjfO57LMsbZHOdb6XZF0Muz+prd77+q853d55LwX+41m952syoQlXLHN9sdMrvNtOppjnlGE0YQxhLGEcYTxhBLCBMLZhHMI5xLOI5xPmEi4gHAh4SLCxYRLCJcSLiNcTphEmEyYQriCcCVhKmEa4SrC1YRrECQfkqdsybD2vB4d83pMzOuxMa/HxbweH/O6JOb1hJjXZ8e8Pifm9bkxr8+LeX1+zOuJMa8viHl9Yczri2JeXxzz+pKY15fGvL4s5vXlMa8nxbyeHPN6SszrK2JeXxnzemrM62kxr6+KeX11zOtrrD0Sy9mchu0KDldsK9UzFb1V1CjGuZam8V4C+af4/Vc7i6JqC9ujmeZSuRjDGL9ntI/frqntsRWfKxM+2+MY47dM5/hF/rbTHl+xucIun+0Sxvg9q2v8MkvZaU/473OFY3y2z2aM33IN45cdLWOnfc5/myu3HJ/tcxnjt0K3+OWWa6d9XuJz5fyDz/b5jPFbqVP8cv7RTntiYnNl7sVn+wLG+D2nS/xy9mqnfWH8cxX8i8/2RYzxe16H+OX8q532xfHNFY7DZ/sSxvi98L+OXzguO+1L/32uznH6bF/GGL8X/5fxi8Rtp335XueKRBPw2Z7EGL9V/6v45SRkpz35n+fKTdBnewpj/Fb/D+LXJZqwnfYV5c8V/g8+21cyxu+lZMcv/J/stKeWncv+jz7b0xjj93Iy41f4n+20ryo9V1YFfLavZozfK0mKX2a0Qnba11h81xLd1+wqGr81SYpfuGKbzXidzV7GGL+1hsSP8TqRvZwxfusMiR/jdQ57JWP8XjUkfozn6fbzjPF7zZD4MZ5n2i8yxu91Q+LHeJ5kr2aM33pD4seo8+2XGeO3wZD4MepUew1j/DYaEj9GnWWvY4zfJkPix6gT7NcY4/eGIfFjPM7Z6xnj96Yh8WPcT9sbGeP3liHxY9zP2G8wxm+zIfFj7BObsWZszvip9WxqOW1Ha/fj2zqBnfkPsHavczsQHAbb4ExwFjgC7gzOBueAc8FdwAeBDwYfAj4UfBj4cHBXcDdwd3AP8BHgI8E9wUeBe4F7g48GHwM+FnwcuA/4eHBfcD/wCeATwf3BA8AngQeCTwYPAg8GDwGfAh4KPhV8Gvh0cB44H1wALgQXgaPgM8DDwMPBZ4LPAheDR4CbW7s3Z72jsw7SWR/prJt01lM66yyvADvrMieDnXWczvpOZ93npWBnnejFYGddqbPe1FmH6qxPddatOutZnXWuzvpXZ12ss17WWUfrrK911t0663GddbrO+l1nXe+1VumNe330tRbf/tX5uquzP4zt7ZFgtfR/eoxf/hi/KmqLnzFG0/nmCifr8ZQNLN59tbNdZ5V9HJ1llX6MH7cvVsz/iY1fdUvwCwpSyblOYN7rLb4GkvL7ev4clRJj3DsSzpjOYIylaoTY7y5J5YxprrCknfUNsbOexb9jdt+X4AbCjYSbCDcTbiHMJNxKuI1wO+EOwizCbMKd1p7vU5b3fTj39+V9rvec78I5/Zbm+puuTP4JHExKPXs3UI7fwXL8DrnYfV8CKyYG1RGHdF6bC93xtmJyERtzy5J9/qcSpQ0wV9HIMSVFJUV9S/KLhxf0LBlZMH74qJE98oqL3YXpGB77hVl34GLfdyfB+bZTyPVe7M0W3EnNcL3nTrATGB93R6u9ekOX8Uzz7pKK7gA5G7f9N1kye07meGS6YzEHPNfaUxjOV+TUpgror3Ji5nP97McY/17G+P5hnn/qfjEZ6jinHP8zxhiu/zEXAY2dt6KyZ64lU2Dc191uYvB593cAo9E5BsTPzxw/Tp/vcs1l52ZlZuZkqXG5hWE7UliQmZuZWZgfCReE8woyi7pE7C7RSGYkq6CwIJ/mzLOj4WheQZdo7m67knXOfRffXKXOue+2UufcLMm5W2DeeZbe59zK73n8OSrXVo4d3TyBeedbvI2pmnA+OFkq7WZL5iDAXBelVNo94AWWx1SaclxKpS1AQLmbZIElU2DcKu1mBp8dlXaPAfHjVmmcPt9rmafS7rV4DwbOdp+VUmksyblPYN6Flt4qTfm9kD9HIiptAWzlnvd+i7cxVRPebyVXpd1iyRwEmOuilEp7APyg5TGVphyXUmkPIqDcTfKgJVNg3CrtFgafHZX2gAHx41ZpnD4/ZJmn0h6yeA8GzvawlVJpLMl5WGDeRZbeKk35vYg/RyIq7UHYyj3vIxZvY6omfMRKrkq7w5I5CDDXRSmV9ih4seUxlaYcl1JpixFQ7iZZbMkUGLdKu4PBZ0elPWpA/LhVGqfPj1nmqbTHLN6DgbM9bqVUGktyHheY9wlLb5Wm/H6CP0ciKm0xbOWe90mLtzFVEz5pJVelzbJkDgLMdVFKpT0FXmJ5TKUpx6VU2hIElLtJllgyBcat0mYx+OyotKcMiB+3SuP0+WnLPJX2tMV7MHC2pVZKpbEkZ6nAvM9Yeqs05fcz/DkSUWlLYCv3vMss3sZUTbjMSq5Km23JHASY66KUSnsWvNzymEpTjkuptOUIKHeTLLdkCoxbpc1m8NlRac8aED9ulcbp8wrLPJW2wuI9GDjbSiul0liSs1Jg3ucsvVWa8vs5/hyJqLTlsJV73uct3sZUTfi8VVY5cOVMfRd1hkAcXhDOf7hi2647Fbwg4PcvaXrX/Q1Cfv+aZoZwYMyP/Wua3jVeXyjXf2he4zcK+f2nITXOmB/7T81rvJ5QrtXdH3Su8TuF/Palm1HjjPmxfel61/hi5NrinVfE1iUG2bo8ibZy3KJQot+Dmtf+TCG/Q4bs5xjzY4c0z/WtQrnOSFKuNTp3tDl9VvlQN8NyLgwqfa1uzToXvAD8ILgy4UXkMd3ac4exmfj9reDbwLeDF4OXgJeDaxFWueZzLka2w+9jWX1isjrB8S8lOP7lBMe/kuD4NQmOX5vg+HUJjn81wfGvJTj+9QTHr09w/IYEx29McPymBMe/keD4N13j/f8wPoPwVpzjNsc57u04x70T57h34xz3Xpzj3o9z3JY4x30Q57itcY77MM5xH8U57uM4x22Lc9wncY771DVuIMatwu/vtMqv21heDX4J/DL4FfAa8FrwOvCr4NfAr4PXgzeAN4I3gd8Avwl+C7wZ/Db4HfC74PfA74O3gD8AbwV/CP4I/DF4G/gT8KdxxifFyeEOhM+ssvvfG/D7F8GfgWsTPrdKb9zaryHjXF9YfDoydefo0nZ6/c7Rc/DzdsKXhB2ErwhfE74hfEv4jvA94QfCj4SfCD8TfiH8SviN8DvhD2v3AiPVY3/hH6gb7voJAUKQECKkEdIJGYRKhMqEKoSqhGqE6oQahJqEWoTahDqEfQh1CfsS6hHqExoQGhIaERoTmhCaEpoRmhNaEFoSWhFaE9oQ2hL2I7QjtCfsT+hA6EjoRDiAcCBBBUqtnsokZBEihM6EbEIOIZfQhXAQ4WDCIYRDCYcRDid0JXQjdCf0IBxBOJLQk3AUoRehN+FowjGEYwnHEfoQjif0JfQjnEA4kdCfMIBwEmEg4WTCIMJgwhDCKYShhFMJpxFOJ+QR8gkFhEJCESFKOIMwjDCccCbhLIK6c/MIwkjCKMJowhjCWMI4wnhCCWEC4WzCOYRzCecRzidMJFxAuJBwEeFiwiWESwmXES4nTCJMJkwhXEG4kjCVMM2XuhO53nciz7N1uxN5HcxVkFdc3Hfs8Al544uc+5D7XOY5Js8B/7+8B/kXLuOZ5k3aPch3WDLHYOZ4lFpFfBWCcLXPY6uIleNSq4hVMBVi562ogFZzMtkouop4B4PPziriq3z6x4/7wxVOn69xzWXKKuJrGPPktvdaX2oVMUtyrvXxzzudseil/J7uY8+RyKfyV8NW7nmvY25M1YRqTr+VvO96fWXJHASY66KUSrseQZjhNZV2vaBKU8GcIdAkMwxRaV8x+OyotOt9+sePW6Vx+nyDgSrtBiGVdmNKpfEk50YBlXaT5ipN+X2TISptBmzlnvdmAZV2c5JV2teWzEGAuS5KqbRbEISZXlNptwiqNBXMmQJNMtMQlfY1g8+OSrvFp3/8uFUap8+3GqjSbhVSabelVBpPcm4TUGm3a67SlN+3G6LSZsJW7nnvEFBpdyRZpf1gyRwEmOuilEqbhSDM9ppKmyWo0lQwZws0yWxDVNoPDD47Km2WT//4+Znjx+nznQaqtDuFVNqclErjSc4cAZU2V3OVpvyea4hKmw1buee9S0Cl3ZVklfajJXMQYK6LUirtbgRhntdU2t2CKk0Fc55Ak8wzRKX9yOCzo9Lu9ukfP26VxunzfANV2nwhlXZPSqXxJOceAZW2QHOVpvxeYIhKmwdbuee9V0Cl3ZtklfaTJXMQYK6LUirtPgRhoddU2n2CKk0Fc6FAkyw0RKX9xOCzo9Lu8+kfP26Vxunz/QaqtPuFVNoDKZXGk5wHBFTag5qrNOX3g4aotIWwlXvehwRU2kNJVmnThA4CzHVRSqU9jCAs8ppKe1hQpalgLhJokkWGqLRpDDtcR6U97NM/ftwqjdPnRwxUaY8IqbRHUyqNJzmPCqi0xZqrNOX3YkNU2iLYyj3vYwIq7TGf3JNinLuGcMfhcZ9s/sMV23bdmexxgfxX1vwJA9uF/K6SboZwYMyPXSVd7xqvL5Tr6prX+JdCftcwpMYZ82PX0LzG6wnlurbmNf6zkN91DKlxxvzYdTSvcaVVH0+Srg5XbNu1lN0UW+cZZOvCJNrK8VQbiX3Tvpr36TdCftczZJ/MmB+7nua5/lYo1w0NeaoN53kUp88qH+6n2qhzAXUnanVPL8UzwDPB6qk2TyCP7qfafIO/+xb8Hfh78Gz8/TzwQrB6qs2TrvmcW8Neht9fDp4EngyeAr4CXJXwlGue6ZjnSfz+Z9jxC/hX8G/g38F/gJ07cjv4C2xhPh/YDw6Ag+AQOA2cDs4AV3LiCa7i+AGuBq4OrgGu6cQNXBtcB7wPuC54X3A9cH1wA3BDcCNwY3ATcFNwM3BzcAtwS3ArcGtwG3Bb8H7gduD24P3BHcAdwZ3AB4APBIfBNjgTnAWOgDuDs8E54FxwF/BB4IPBh4APBR8GPhzcFdwN3B3cA3wE+EhwT/BR4F7g3uCjwceAjwUfB+4DPh7cF9wPfAL4RHB/8ADwSeCB4JPBg8CDwUPAp4CHgk8FnwY+HZwHzgcXgAvBReAo+AzwMPBw8Jngs8DF4BHgkeBR4NHgMeCx4HHg8eAS8ATw2eBzwOeCzwOfD54IvgB8Ifgi8MXgS8CXgp8CXwme6tQ3YYlvz37J+WBIXVdUv38C45Y4/Ux42rd7DIjtuPEF5o6dt6LHtqU+vbWHeqrI5xa/388w+p2sD0KbWLzawdmW+VIfhLIkZ5mPf95nfXp/EKr8ftbHniNRQc8Z0+V8O5KkPaqIc0ciaWdjQ+xsZPHvmBVXw88r6MVKwnOE5wkvEF4krCKsJrxEeJnwCmENYa0v9WgZvR8tEy7U7dEyDTBX0cgxJUUlRX1L8ouHFzgPl+mRV1zsLkzHcKdA/989YEbt1Zu6jGeaN2kPmHnOJ7PnZI5HqcXH6xCEV30eW3ysHJdafKyC+arAeeOrQgXGvfj4OQap5yw+XufTP37cn3Nw+vyaay5TFh+/xpgnt72vp865eZLzusA593rNz7mV3+uFzrklDhTrBQ5AG5gbUzWhmtNvJe8rYs8bqNI2IgibvKbSNgqqNBXMTQJNsskQlfY8o0rb6NM/ftwqjdPnNwxUaW8IqbQ3UyqNJzlvCqi0tzRXacrvtwxRaZtgK/e8mwVU2uYkq7QXDFRpbyMI73hNpb0tqNJUMN8RaJJ3DFFpLzCqtLd9+sePW6Vx+vyugSrtXSGV9l5KpfEk5z0Blfa+5ipN+f2+ISrtHdjKPe8WAZW2Jckq7WUDVdoHCMJWr6m0DwRVmgrmVoEm2WqISnuZUaV94NM/ftwqjdPnDw1UaR8KqbSPUiqNJzkfCai0jzVXacrvjw1RaVthK/e82wRU2rYkq7RXDFRpnyAIn3pNpX0iqNJUMD8VaJJPDVFprzCqtE98+sePW6Vx+vyZgSrtMyGV9nlKpfEk53MBlfaF5ipN+f2FISrtU9jKPe92AZW2PckqbY2BKu1LBGGH11Tal4IqTQVzh0CT7DBEpa1hVGlf+vSPH7dK4/T5KwNV2ldCKu3rlErjSc7XAirtG81VmvL7G0NU2g7Yyj3vtwIq7Vuf3K3L1XdRlwvE4TufbP7DFdt23angOwG/G2t+y1v1jX8Jv5sYcntFxvzYTTS/vWJjoRpvrnmNrxSq8RaG1DhjfuwWmtd4I6Eab615ja8VqvE2htQ4Y37sNprX+Fbk2uKdV8TWTw2ydUcSbeW4HbhEv7fTvPZfFNrPtTdkP8eYH7u95rleJZTrjobcDpzz3KSj4O3Alb5Wt6V9FbwJ/A5Y3Q78e+TRfTvwF/H7VeDV4JfAW8GfgneA1e3Af3DN51yMbGfh9tExrD4x+THB8T8lOP7nBMf/kuD4XxMc/1uC439PcPwfCY7/M8HxOxMc/1eC41WzJjLel+B4f4LjAwmOD7rG+/9hfAYhFOe4tDjHpcc5LiPOcZXiHFc5znFV4hxXNc5x1eIcVz3OcTXiHFczznG14hxXO85xdeIct49r3ECM+wH757W+8us2ln/EuJ/AP4N/Af8K/g38O/gP8J/gneC/wMpwxT6wHxwAB8EhcBo4HZwBrgSuDK4CrgquBq4OrgGuCa4Frg2uA97HH198Upwc7kCoW87+dwXq6XtwXSefhH39ZVfJcOtf9RjZhq75meblXCljx77hjkc9vKjv99hKGeX4MpezKgBdY4zj+p+qQGZY/CdJBwidJAUqZmc4xk67np/PZ3eewhXbbKn4cV9Q4Ixfg73MlZtTlB/NiWTlhSPRfJonO1qUlZfZxY7mZtH0WRE7P68oXBjJz8mOZOdGc5L2rIsGfDkvtXKmoT+1coYlOQ39Ap8SMRa9lN+N/Ow5ErkSXR+2cs8bTtIBKJzgFmsnZy01ZjwAccbPETLKvm5W8taHV+SAHC29FZRjrojqbYIXTfeieruXE7NY1dvd+nfVW948/6p6uZOk/dIu/+6kcO+gmvj5G6wpGsy9ca81Z8yX3ZRx59eMr9mjTjyb8cezTPMz1gFrPJv7efvS2bjPQOoz+tyC+YDBvc9QvddcYF+UqflHucrvFgJ+Zxlyls2YHztZPnMeHys6V0vGfaxUfbf0y+wvOHMtcYn6GR+/360Yj11KhKurLc7VGDW3uvTvQCIuUldlW/v138+3FuiDNox+B63SDxy0eGPw9z6VO7Zt/Prb2FZIc7IfnNw71orOtZ8BByeJpmxnwM5oXwG/szUX26oJ9xPwO0fPjwTLruVl7EfGXNuc8RM+iP39URJ3bXLvMyRsbO+3zDiINWWca3/Gpkk9Xry0nV5/vPgc/NyBaqwjoRPhAMKBBPXZiU1Q99jJIkQInQnZhBxCLqEL4SDCwYRDCIcSDiMcrmpWXeEldCf0IBxBOJLQk3AUoRehN+FowjGEYwnHEfoQjif0JfQjnEA4kdCfMIBwEmEg4WTCIMJgwhDCKYShhFMJpxFOJ+QR8gkFhEJCESFKOIMwjDCccCbhLEIxYQRhJGEUYTRhDGEsYRxhPKGEMIFwNuEcwrmE8wjnEyYSLiBcSLiIcDHhEsKlhMsIlxMmESYTphCuIFxJmEqYRriKcDXhGsK1hOmE6wjXE2YQbiDcSLiJcDPhFsJMwq2E2wi3E+4gzCLMJtxJmEOYS7iLcDdhHmE+4R7CAsK9hPsICwn3Ex4gPEh4iPAwYRHhEcKjhMWExwiPE54gPEl4irCE8DRhKeEZwjLCs4TlhBWElYTnCM8TXiC8SFhFWE14ifAy4RV/6nH1ej+uPs/W7XH1dTBXQV5xcd+xwyfkjS9yHlbv3sU5Jju7uv+XD6rf3+UJ07xJe1C9OuZw2VyOuVxzl7rV3Bq8WOv32AJa5bjUreZUMBW4z47XChUY98f/7kao6K3m1vj1j5+fOX6cPq9zzWXKrebWMebJbe+r/tSCWZbkvOrnn/c1xqKX8vs1AXVSnq0cO7rXBA5ArzM3pgqnmtNvJW/B5wEGqrT1eLHBayptvaBKU8HcINAkGwxRaQcwqrT1fv3jx63SOH3eaKBK2yik0jalVBpPcjYJqLQ3NFdpyu83DFFpG2Ar97xvCqi0N5Os0g40UKW9hRebvabS3hJUaSqYmwWaZLMhKu1ARpX2ll//+HGrNE6f3zZQpb0tpNLeSak0nuS8I6DS3tVcpSm/3zVEpW2Grdzzvieg0t5LskqLGKjS3seLLV5Tae8LqjQVzC0CTbLFEJUWYVRp7/v1jx+3SuP0+QMDVdoHQipta0ql8SRnq4BK+1Bzlab8/tAQlbYFtnLP+5GASvsoySqts4Eq7WO82OY1lfaxoEpTwdwm0CTbDFFpnRlV2sd+/ePHrdI4ff7EQJX2iZBK+zSl0niS86mASvtMc5Wm/P7MEJW2DbZyz/u5gEr7PMkqLdtAlfYFXmz3mkr7QlClqWBuF2iS7YaotGxGlfaFX//4cas0Tp+/NFClfSmk0nakVBpPcnYIqLSvNFdpyu+vDFFp22Er97xfC6i0r5Os0l4xUKV9gxffek2lfSOo0lQwvxVokm8NUWmvMKq0b/z6x49bpXH6/J2BKu07IZX2fUql8STnewGV9oPmKk35/YMhKu1b2Mo9748CKu1Hf1nlwJWz5b7ddw3hjsNPftn8hyu27boz2U8Cfh+Urnfdqzt8Sfh9sCH3eWfMj32w5rcZbSxU44dpXuMdhWr8cENqnDE/9uGa13gjoRrvrnmN5wjVeA9DapwxP3YPzWv8W+Ta4p1XxNYtBtm6zSBbtyfR1oruQ5SZEvumnpr3aVhon3yUIftkxvzYR2mea1so10cb8uwozvOoo5kfhKpur+pcxFTnAjut3TeUVLwBvBlcmfAz8phu7blbbRi/t8GZ4CzwFvA28HZwLcIvrvmcW8M+h98/D34B/CJ4FXg1uCrhV9c80zHPL/h9DjgX3AV8EPhg8CHgQ8GHgQ8HdwV3A3cH9wAfAT4S3BN8FLgXuDf4aPAx4GPBx4H7gI8H9wX3A58APhHcHzwAfBJ4IPhk8CDwYPAQ8CngoeBTwaeBTwfngfPBBeBCcBE4Cj4DPAw8HHwm+CxwMXgEeCR4FHg0eAx4LHgceDy4BDwBfDb4HPC54PPA54Mngi8AXwi+CHwx+BLwpeDLwJeDJ4Eng6eArwBfCZ4Knga+Cnw1+BrwteDp4OvA14NngG8A3wi+CXwz+BbwTPCt4NvAt4PvAM8CzwbfCZ4Dngu+C3w3eB54Pvge8ALwveD7wAvB94MfAD8Ifgj8MHgR+BHwo+DF4MfAj4OfAD8Jfgq8BPw0eCn4GfAy8LPg5eAV4JXgX8EvgV8G70/4zb9nv+R8MNQBv/8Z/Bu4NuF3f9kVBtzHY/Usty9c8zPNy7nKYK8Ppf4DL/70e2yVgXJ8mctZFYCuMcZx/U+nSLhF27F6PncpHGOn/Yefz2d3nsIV2+xjDTnB4Yzfzr3MlZtTlB/NiWTlhSPRfJonO1qUlZfZxY7mZtH0WRE7P68oXBjJz8mOZOdGc8LJWnWw088r1J3tL39q1QFLcv7yCwQqoPeqA+W3+6kdTPOKXBn7E7Zyz9snSQegcIJbmfwz1pIvwFdDfZivQKg0K/u6WclbW1uRA3K09FZQjrkiqtePAgsE/ln1di8nZrGqt7v176q3vHn+VfVyJ0n3ZTEqIX6BHZQ/wN9gATSYe+Nep8uYLzvAuPMLBtiaPerEM8gfz7LNH9AznqEAb186G/cZyJ+MZyBpAd4DhsQSwpDAvqiv5h8tKb/TBPzuZ8hZNmN+7H6GfJzmZ9yXpTPuY6XqOz0gs7/gzLXE1celPn6/MxiPXUqEqydXOldj1NztrD2QiovEVdlKAf3385UE+qAyo99Ba8+TTN0bZ1wlYls5oL+NVYQ0J/vB6SdG0VnVgIOTRFNWM2Bn9Luf3+/+mott1YRVBfI9QM+PBMvYWZ2xHxlzbXPGT/gg9vdHSdy1Wc2Ag1h1qYMYd0PWSKkiu4YBBVWT20ZTTuNqpQp017eRdbexdrJke7hiW6Y7mBUtzjqp4rTrGLD33MeQ4sziLM66qeK06xpQnPsaUpx2Jcar8fWYL3j8U3Iqamd95iZKs8puXPNLFWh9A5qogQn6+BkBfdwwVaBG6ONGXtTHjVPFaTc2YO/ZxIv6uGmqOO2mBhRnM1P0cWvGDwSba/6BYFOao5bAB0Qna/7BmLopYE0BvwcZ8sFYC8a6ZMy1PciAuqktUDctNf8AXfm9j4DfrQzwe18Bv1tr7rc6LkgsFDnFgP6uJ+D3UEOOC20YjwuMubaHal43ql8aCNTN6Qb0S0MBv/MM6Ze2jP3CmGs7z4B+aSRQN/sZcFxtIuB3OwP8bibgd3sD/G4u4Heh5v2trqFI3Hi/yJDjwv6MxwXGXNuc8UvWfVla8M1V6r4sHQKp+7KwJKdDgH/ejprfl0X53THAniPRr2FyxrQT51fdrVK3uPl703lHImlnc0PsbGbx75gVV8PPB1BRHEhQRxpVJJmELEKE0JmQTcgh5BK6EA4i1MXfViqnptR7wZhYqPece7M4/eb+BLArk38CB5NwJZfNgXL8Dpbjd8jFVVy/t2JiUB1xSOe1udAdbysmF7Ext1z/P83akxcmW2y1ErIB5ioaOaakqKSob0l+8fCCniUjC8YPHzWyR15xsbswHcOdAg2UE7jY991JcJZehlzvVXI56LznzJXhes+dYCcwPu6OVnv1li7jmeYNJ+suUWGpz5h57Sz1BNaDkdlDAh67N6pyXOoJrCqYhwicdx8iVGABZv/DDFLPeQLrwQH948e9BoTT50Ndc5nyBNZDGfPktvew1Dk3T3IOEzjnPlzzc27l9+FC59wSB4rDBQ5AXZkbUzWhmtNvJe9enraBKq0b6q6711RaN0GVpoLZXaBJuhui0mxGldYtoH/8uFUap889DFRpPYRU2hEplcaTnCMEVNqRmqs05feRhqi07rCVe96eAiqtZ5JVWqaBKu0o1F0vr6m0owRVmgpmL4Em6WWISstkVGlHBfSPH7dK4/S5t4EqrbeQSjs6pdJ4knO0gEo7RnOVpvw+xhCV1gu2cs97rIBKOzbJKi3HQJV2HOquj9dU2nGCKk0Fs49Ak/QxRKXlMKq04wL6x49bpXH6fLyBKu14IZXWN6XSeJLTV0Cl9dNcpSm/+xmi0vrAVu55TxBQaSckWaXlGqjSTkTd9feaSjtRUKWpYPYXaJL+hqi0XEaVdmJA//hxqzROnwcYqNIGCKm0k1IqjSc5JwmotIGaqzTl90BDVFp/2Mo978kCKu3kJKu0LgaqtEGou8FeU2mDBFWaCuZggSYZbIhK68Ko0gYF9I8ft0rj9HmIgSptiJBKOyWl0niSc4qAShuquUpTfg81RKUNhq3c854qoNJODZRVDlw5a0lzdBKIw2kB2fyHK7btulPBaQJ+D0vXu+7VN/4l/B5uyMPhGfNjD9f8FlHNhWq8WPMaP1CoxkcYUuOM+bFHaF7jzYRqfLTmNX6QUI2PMaTGGfNjj9G8xvsg1xbvvCK29jfI1sFJtLWifan6R6Lfx2te+1lC+7kSQ/ZzjPmxSzTPdUQo1+ckKdcanTvanD6rfKibYTkXBpW+3mntvv2P4u7gXuDKhNORx3Rrzx3GsvD7CLgzOBvcB9wfPBhci5Dnms/ZZbezdv8+ltUnJvkJji9IcHxhguOLEhwfTXD8GQmOH5bg+OEJjj8zwfFnJTi+OMHxIxIcPzLB8aMSHD86wfFjXOP9/zA+gzA2znHj4hw3Ps5xJXGOmxDnuLPjHHdOnOPOjXPceXGOOz/OcRPjHHdBnOMujHPcRXGOuzjOcZe4xg3EuDzsnw8KlF+3sZyPcQXgQnAROAo+AzwMPBx8JvgscDF4BHgkeBR4NHgMeCx4HHg8uAQ8AXw2+BzwueDzwOeDJ4IvAF8Ivgh8MfiSOOOT4uRwB8Kl5ex/D0CeTgdfCq5NuCxQdpUMt9Z/lgxyPxoxXLFt19N+9xc6v43d/uPcduwb7vheDtsnBTy28kY5vszl7CTXh2ncJ11O0XGfdJ2n+cmm0xzcfp8vdLIZqJid4Rg77csDfD5PYpxrYpLiF67YZjPWt81YM7ZU/LgPdpz1N3kvc+XmFOVHcyJZeeFINJ/myY4WZeVldrGjuVk0fVbEzs8rChdG8nOyI9m50ZykPXPFbXO4gpvb3imB1AouluRMCfDPewVj0Uv5fYWQYuQ+0E6CrdzzXqzpASjWTs5aupJvZ2Rzxs8RwMq+blbyvqcwqQLxiJbeCsoxV+RsaSoKbNpezpa6lxOz2LOl7ta/ny2VN8+/ni1xJ0n3JYYqIVMFdlBTA/wNNg0N5t64FTNjvuxpjDu/q/iaPerE8yr+eJZp/qmaxvNq5r50Nu4zEM6z1muYDxgSy7GvFtgXXar5VR7l9zUCfl9myFk2Y37sZPnMeXys6FzXMu5jper72oDM/oIz1xJXrRsK+D3ZgKvWbQX8nmLIU5+nM/YjY67tKQbUzX4CdXOd5vsJ5Xc7Ab+vN8Dv9gJ+z2D0W12kUEsFnavVqrdVPanYznBdhFQb937kBsb9iKafBInp6RsE6upGxroKoq5iN864SsT2xoD+Nt4kdG7PfhJwGuNJwM0GnARINOUtmh/klN+XSVxg1XwnrJrwZgG/pxlyEjCTsR8Zc21zxk/4IPb3R/bctXmLAQexmaYcxFoyznUrY9Ooho4R6CKJamHJJIrbzuaG2NmM0U73x8Fz8PNtVBS3E+4gzCLMJtxJmEOYS7iLcDdhHmE+4R7CAsK9hPsICwn3Ex4gPEh4iPAwYRHhEcKjhMWExwiPE54gPEl4irCE8DRhKeEZtX6W8CxhOWEFYSXhOcLzhBcILxJWEVYTXiK8THiFsIawlrCO8CrhNcLrhPWEDYSNhE2ENwhvEt4ibCa8TXiH8C7hPcL7hC2EDwhbCR8SPiJ8TNhG+ITwKeEzwueELwjbCV8SdhC+InxN+IbwLeE7wveEHwg/En4i/Ez4hfAr4TfC74Q/CH8SdhL+Uk1KRxIfwU8IEIKEECGNkE7IIFQiVCZUIVQlVCNUJ9Qg1CTUItQm1CHsQ6hL2JdQj1Cf0IDQkNCI0JjQhNCU0IzQnNCC0JLQitCa0IbQlrAfoR2hPWF/QgdCR0InwgGEAwnqSGgTMglZhAihMyGbkEPIJXQhHEQ4WNmGWqxUzj6qkrXnaoN72YKzXMLZf6e5/qYrU78IrLsLV3LZHCjH72A5fodcXMX1eysmBtURh3RWm/Nsd7ytmFzExtxy/f80a09eeGwJ2xk0Rx3MVZBXXNx37PAJeeOLepaMLBg/fNRI9y7OMdnZ1QXKCVns++7wZ+DnkOu9Si7XnPecuTJc77lT64TEx31sUDcBu9VlPdO8u9bTugPkbNz23yEl6njtLHVr2UNQIYcGPfYFF+W41K1lVTAVuM+O1ZxMNop+MeEOhitfzq1lDwnqHz/uJROcPh/mmsuUW8sexpgnt72HB1NfTGBJzuFB/nm7Mha9lN9dg+w5EvliwqGwlXvebsyNqZpQzem3krewfpaBKq076q6H11Rad0GVpoLZQ6BJehii0mYxqrTuQf3jx63SOH0+wkCVdoSQSjsypdJ4knOkgErrqblKU373NESl9YCt3PMeJaDSjkqySpttoErrhbrr7TWV1ktQpalg9hZokt6GqLTZjCqtV1D/+HGrNE6fjzZQpR0tpNKOSak0nuQcI6DSjtVcpSm/jzVEpfWGrdzzHieg0o5Lskq720CV1gd1d7zXVFofQZWmgnm8QJMcb4hKu5tRpfUJ6h8/bpXG6XNfA1VaXyGV1i+l0niS009ApZ2guUpTfp9giEo7HrZyz3uigEo7MckqbZ6BKq0/6m6A11Raf0GVpoI5QKBJBhii0uYxqrT+Qf3jx63SOH0+yUCVdpKQShuYUmk8yRkooNJO1lylKb9PNkSlDYCt3PMOElBpg5Ks0uYbqNIGo+6GeE2lDRZUaSqYQwSaZIghKm0+o0obHNQ/ftwqjdPnUwxUaacIqbShKZXGk5yhAirtVM1VmvL7VENU2hDYyj3vaQIq7bQkq7SDhQ4CzHVRSqWdjrrL85pKO11Qpalg5gk0SZ4hKu1ghh2uo9JOD+ofP26VxulzvoEqLV9IpRWkVBpPcgoEVFqh5ipN+V1oiErLg63c8xYJqLSiYFnlwJUz564h3HGIBmXzH67YtuvOZFGB/F+Trnfdqzt8Sfh9rSHP02DMj32t5rcZbS5U49drXuO3C9X4DENqnDE/9gzNa7yZUI3fpHmN3yNU4zcbUuOM+bFv1rzGlVaNJklXhyu27VrKboqtAwyydUgSba3oPkT1usS+6VbN+/ROoX3ybYbskxnzY9+mea7nCOV6liHP6OM8j+L0WeVD3V7V2VWqc4Gd1u4bSiruAe4NVrfoPwN5TLf23K32TvzdHPBc8F3g4/H3A8BDwLUIw1zzObeGzcLvI+DO4GxwDjgXXJUw3DXPdMwzDL+/B3YsAN8Lvg+8EHw/+AHwg+CHwA+DF4EfAT8KXgx+DPw4+Anwk+CnwEvAT4OXgp8BLwM/C14OXgFeCX4O/Dz4BfCL4FXg1eCXwC+DXwGvAa8FrwO/Cn4N/Dp4PXgDeCN4E/gN8Jvgt8CbwW+D3wG/C34P/D54C/gD8Fbwh+CPwB+Dt4E/AX8K/gz8OfgL8Hbwl+Ad4K/AX4O/AX8L/g78PfgH8I/gn8A/g38B/wr+Dfw7+A/wn+Cd4L/AFurZB/aDA+AgOAROA6eDM8CVnH4GV3H6CFwNXB1cA1zT6VtwbXAd8D7guuB9wfXA9cENwA3BjcCNwU3ATcHNwM3BLcAtwa3ArcFtwG3B+4HbgduD9wd3AHcEdwIfAD4QHAbb4EzwcHAX8EHO/IQzXfsl54Oh25DPMzDuTCeehLOCZVcYcGsP9TzRSnxrQHc9f69NYI+9TPNyrloo8zxxd3yLcQAc4bVVC8rxZS5nR7g+iOAWgU7RcYvAOw14GGkbAb/n6Pn8qnCMnXYx4wexIxjnmpuk+IUrttmM9W0z1ow915ATbc76G7mXuXJzivKjOZGsvHAkmk/zZEeLsvIyu9jR3CyaPiti5+cVhQsj+TnZkezcaE44WatfRgqtfhmVWv3Ck5xRAqtfRmu++kX5PdqQK7QjYCv3vPM1PQDF2slZS2P4dkb2fOYrYWonpuzrZiVvjfeICsQjWnorKMdckbOlsejbcXs5W+peTsxiz5a6W/9+tlTePP96tsSdJN2XZ6mEjBXYQY0VWJ43Dg3m3rgVM2O+7HGMO7/xfM0edeI5nj+eZZp/rKbxLGHuS2fjPgPhPGudwHzAkFjKWiKwL1qg+VUe5fcEAb/vNeQsmzE/9r2GfKw7lrGvz2bcx0rV99lBmf0FZ64lrlrXErh6e78BV61bCPj9gJ5XrcvYeQ5jPzLm2n7AgLppKVA352q+n1B+txLw+zwD/G4t4Pf5jH6rixRqiZBzvVH1tqonFdvzXRch1ca9H5nIuB/R9JMgMT09UUBvXMBYV0HUVezGGVeJ2F4Q1N/GC4XO7dlPAqKMJwEXGXASINGUF2t+kFN+nyXg98Oa74RVE14k4PciQ04CLmHsR8Zc25zxEz6I/f2RPXdtXmzAQewSqYMYd0NemlJF9qUGFNRlUgXFvee83AOXT0wt9E4B/W2cxF3oplznmmzGZ5qZ7iKqqM9TUkcfe4oBR58rTGhKiYuwV5rRlFmcTTk11ZT2VAOacpoJTSnxCcFVhqz+mch4gfBq5guE/1SUFf7CO/POo7JVduOa/59iEK7YZl9jwM7jWlPOJ6czFv5kxvPJKempQjfhfPI6E46S+wkcJa/34PnkjNTRx55hwNHnBhOasp1AU97owfPJm1JNad9kQFPebEJTthdoylsMOZ+8gbEpZ2q+4KQlzXG5wAKExZovvFA3mb9MwO/HDFl4cStjXTLm2n5M87pR/TJZoG6eNKBfJgn4/ZQh/XIbY78w5tp+yoB+uVKgbpYa0C9XCPj9jCH9cjtjvzDm2n7GgH65SqBulhvQL9ME/F5hSL/cwdgvjLm2VxjQLxIL5p83oF+uFvD7BUP6ZRZjvzDm2n7BgH65VqBuVhvQL9MF/H7JkH6ZzdgvjLm2XzKgX64TqJs1BvTL9QJ+rzWkX+5k7BfGXNtrDeiXGwTq5jUD+uVGAb9fN6Rf5jD2C2Ou7dcN6JebBepmowH9couA35sM6Ze5jP3CmGt7kwH9MlOgbt7S3G/1mbTEg7E3G9IvdzH2C2Oubc74Jet+9W345ip1v/q7g6n71bMk5+4g/7zzGL8kIeX3vCB7jkRvT8kZ0/mMO7iAtafp3JvOOxJJO1sbYmcri3/HrLgafr6HamwB4V7CfYSFhPsJDxAeJDxEeJiwiPAI4VFCXfxtpXJqSr0XjImFes+5Z73Tb2muv+nK5J/AwSRcyWVzoBy/g+X4HXJxFdfvrZgYVEcc0nltLnTH24rJRWzMLdf/T7P25IXJFjuD5miAuYpGjikpKinqW5JfPLygZ8nIgvHDR43skVdc7C5Mx3CnQAPlBC72fXcSMvBzyPVeJZeDznvOXBmu99wJdgLj4+5otVdv6zKead5wsp6eca/U19d47cx0x2IxKuSxoMeeNagc/zPGGK7/oYL5mMR6WaEC437ixb0MUq8IjwVYHNQ/fn7m+HH6/LhrLjs3KzMzJ0uNyy0M25HCgszczMzC/Ei4IJxXkFnUJWJ3iUYyI1kFhQX5NGeeHQ1H8wq6RHN325Wsc+7HGfPktveJ1Dk3T3KeEDjnflLzc27l95NC59wSB4onJRagMzemakI1p99K3jPO7jNQpS1B3T3tNZW2RFClqWA+LdAkTxui0u5jVGlLgvrHj1ulcfq81ECVtlRIpT2TUmk8yXlGQKUt01ylKb+XGaLSnoat3PM+K6DSnk2ySltooEpbjrpb4TWVtlxQpalgrpD4rpMhKm0ho0pbHtQ/ftwqjdPnlQaqtJVCKu25lErjSc5zAirtec1VmvL7eUNU2grYyv7lQQGV9kKSVdrDBqq0F1F3q7ym0l4UVGkqmKsEmmSVISrtYUaV9mJQ//hxqzROn1cbqNJWC6m0l1IqjSc5LwmotJc1V2nK75cNUWmrYCv3vK8IqLRXkqzSFhmo0tag7tZ6TaWtEVRpKphrBZpkrSEqbRGjSlsT1D9+3CqN0+d1Bqq0dUIq7dWUSuNJzqsCKu01zVWa8vs1Q1TaWtjKPe/rAirt9SSrtEcMVGnrUXcbvKbS1guqNBXMDQJNssEQlfYIo0pbH9Q/ftwqjdPnjQaqtI1CKm1TSqXxJGeTgEp7Q3OVpvx+wxCVtgG2cs/7poBKezNYVjlw5Ux9F3W+QBzeCsrmP1yxbdedCt4S8PvddL3rXn3jX8Lv99LNEA6M+bHf0/wWUa2FavwDzWt8gVCNbzWkxhnzY2/VvMZbCdX4x5rX+KNCNb7NkBpnzI+9TfMaX4VcW7zziti61iBbNyTR1or2peofiX7/TPPav19oP/e5Ifs5xvzYn2ue6weEcv1lknKt0bmjzemzyoe6GZazq1T6eqe1+/Y/ip8GrwCr5wRvRh7TrT13GLsfv38A/CD4IfAq8FrwBnAtwtuu+ZyLke2s3b+PZfWJyTsJjn83wfHvJTj+/QTHb0lw/AcJjt+a4PgPExz/UYLjP05w/LYEx3+S4PhPExz/WYLjP09w/Beu8f5/GJ9B2B7nuC/jHLcjznFfxTnu6zjHfRPnuG/jHPddnOO+j3PcD3GO+zHOcT/FOe7nOMf9Eue4X+Mc95tr3ECMexv750eD5ddtLL+Dce+C3wO/D94C/gC8Ffwh+CPwx+Bt4E/An4I/A38O/gK8HfwleAf4K/DX4G/A34K/A38P/gH8I/gn8M/gX8C/gn+LMz4pTg53IPxezv73HuRpM/h3cG3CH8Gyq2S4tX5H+gfuR82HK7bZnWiuu4TOb2O3/zi3HfuGO75/wvadQY+tvFGOL3M5u9P1YRr3SZdTdNwnXV9pfrLpNAe3318LnWxW8PkZ4Rg77T8ZFxPsZJzrmyTFL1yxzWasb5uxZmyp+HEf7Djr76+9zJWbU5QfzYlk5YUj0XyaJztalJWX2cWO5mbR9FkROz+vKFwYyc/JjmTnRnOS9syVv5gXivy9hVIruFiSowLJPa8vxFf0Un77Quw5EvlEZCds5Z73B00PQLF2ctaSP8RXQ5zxcwSwsq+blbzvKeyswM45WnorKMdckbOlAPo2GPrns6Xu5cQs9mypu/XvZ0vlzfOvZ0vcSdJ9iaFKSEBgBxUI8TdYEA3m3rgVM2O+7CDjzi8UYmv2qBPPEH88yzQ/Yx2wxjMtxNuXzsZ9BsJ51poe4j1gSCzHThPYF/2k+VUe5Xe6gN8/G3KWzZgfO1k+cx4fKzpXBuM+Vqq+M0Iy+wvOXEtctZ4ucPX2NwOuWs8W8Pt3Q576XImxHxlzbf+ued2ofrleoG52GtAvdwr4/Zch/VKZsV8Yc23/ZUC/3ChQN/4M/ftljoDfgQwz+qUKY78w5toOaF43ql9uEaibNAP6Za6A3+mG9EtVxn5hzLXNGT91MV1dyHY+VVUaVB1X1b6iasyTtrnjW40xvpquWBC77lNN4Ly4OuO1zSDqKnbjjKtEbKuH9LexhtA1aPaLVW8xXoSuacDFKommrBXSf2f0h4BIqKy5OFJNWFMg31UMEUe1GfuRMdc2Z/yED2J/Ly3jrs1aBhzEaptyEGvLOFcdxqZRDR2wym7ciWpjySSK287WhtjZitFO97KlOfh5H6qxuoR9CfUI9QkNCA0JjQiNCU0ITQnNCM0JLQgtCa0IrQltCG0J+xHaEdoT9id0IHQkdCIcQDiQoE4hbUImIYsQIXQmZBNyCLmELoSDCAcTDiEcSjiMcLjqB7WahNCd0INwBOFIQk/CUYRehN6EownHEI4lHEfoQzie0JfQj3AC4URCf8IAwkmEgYSTCYMIgwlDCKcQhhJOJZxGOJ2QR8gnFBAKCUWEKOEMwjDCcMKZhLMIxYQRhJGEUYTRhDGEsYRxhPGEEsIEwtmEcwjnEs4jnE+YSLiAcCHhIsLFhEsIlxIuI1xOmESYTJhCuIJwJWEqYRrhKsLVhGsI1xKmE64jXE+YQbiBcCPhJsLNhFsIMwm3Em4j3E64gzCLMJtwJ2EOYS7hLsLdhHmE+YR7CAsI9xLuIywk3E94gPAg4SHCw4RFhEcIjxIWE+qiFiuVs49S7wVjeku9F8LPzv47zfU3XZn6RWB9eLiSy+ZAOX4Hy/E75OIqrt9bMTGojjiks9qcZ7vjbcXkIjbmluv/p1l78sJjS9gmvWbVwVwFecXFfccOn5A3vqhnyciC8cNHjXTv4hyTnV1doJyQxb7vDn8Gfg653qvkcs15z5krw/WeO7VOSHzcxwZ1s8o6rsQwzRtO1tJidczhsrkcc7nmLnUL9McQ78dDHvsipnJc6hboKpgK3GfHjwsVGPdyYHcjVPQW6I+F9I+fnzl+nD4/4ZrLlFugP8GYJ7e9T4ZSX6BjSc6TIf55n2Iseim/nxJQJ+XZyrGje0rgALSEuTFVE6o5/VbyvgBWz0CV9jTqbqnXVNrTgipNBXOpQJMsNUSl1WNUaU+H9I8ft0rj9PkZA1XaM0IqbVlKpfEkZ5mASntWc5Wm/H7WEJW2FLZyz7tcQKUtT7JKq2+gSluBulvpNZW2QlClqWCuFGiSlYaotPqMKm1FSP/4cas0Tp+fM1ClPSek0p5PqTSe5DwvoNJe0FylKb9fMESlrYSt3PO+KKDSXkyySmtioEpbhbpb7TWVtkpQpalgrhZoktWGqLQmjCptVUj/+HGrNE6fXzJQpb0kpNJeTqk0nuS8LKDSXtFcpSm/XzFEpa2GrdzzrhFQaWuSrNKaGqjS1qLu1nlNpa0VVGkqmOsEmmSdISqtKaNKWxvSP37cKo3T51cNVGmvCqm011IqjSc5rwmotNc1V2nK79cNUWnrYCv3vOsFVNr6JKu0ZgaqtA2ou41eU2kbBFWaCuZGgSbZaIhKa8ao0jaE9I8ft0rj9HmTgSptk5BKeyOl0niS84aASntTc5Wm/H7TEJW2EbZyz/uWgEp7K8kqbbGBKm0z6u5tr6m0zYIqTQXzbYEmedsQlbaYUaVtDukfP26VxunzOwaqtHeEVNq7KZXGk5x3BVTae5qrNOX3e4aotLdhK/e87wuotPdDZZUDV86cu4Zwx2FLSDb/4Yptu+5MtkXA7+oZete9usOXhN81MswQDoz5sWtofpvR1kI1XlvzGq8rVON1DKlxxvzYdTSv8VZCNb6v5jXeXKjG6xlS44z5setpXuNvI9cW77witq42yNZ1Btm6MYm2VvhZTpbMvqmh5n3aQGif3MiQfTJjfuxGmue6oVCumyYp1xqd59qcPqt8qNurOhcx1bnATmv3DSUVLwWvBFcmfIA8plt77lbbAL9vCG4EbgxeDV4H3giuRdjqms+5Nez9+P0D4AfBD4EfBi8CVyV86JpnOubZit83B7cAtwS3ArcGtwG3Be8HbgduD94f3AHcEdwJfAD4QHAYbIMzwVngCLgzOBucA84FdwEfBD4YfAj4UPBh4MPBXcHdwN3BPcBHgI8E9wQfBe4F7g0+GnwM+FjwceA+4OPBfcH9wCeATwT3Bw8AnwQeCD4ZPAg8GDwEfAp4KPhU8Gng08F54HxwAbgQXASOgs8ADwMPB58JPgtcDB4BHgkeBR4NHgMeCx4HHg8uAU8Anw0+B3wu+Dzw+eCJ4AvAF4IvAl8MvgR8Kfgy8OXgSeDJ4CngK8BXgqeCp4GvAl8NvgZ8LXg6+Drw9eAZ4BvAN4JvAt8MvgU8E3wr+Dbw7eA7wLPAs8F3gueA54LvAt8NngeeD74HvAB8L/g+8ELwh+BHwI+C9yd8FNqzX3I+GNoHv/8A/BG4NuHjUNkVBtzaQz1ncSLfs7l3Pb9wVnCPvUzzcq5asGPfcMd3W2g3fxLy2KoF5fgyl7MqAF1jjOP6n07RsV/cMeDhnrME/G6h5/OrwjF22ttCfD5/wjhXyyTFL1yxzWasb5uxZuyWhpxoc9bfp3uZKzenKD+aE8nKC0ei+TRPdrQoKy+zix3NzaLpsyJ2fl5RuDCSn5Mdyc6N5oSTtfrFbXO4gpvb3s9CqdUvLMn5LMQ/7+eMRS/l9+ch9hyJXKH9BLZyz9tW0wNQrJ2ctfQF387Ibst8JUztxJR93azkrfH+pALxiJbeCsoxV+RsaTv69su9nC11LydmsWdL3a1/P1sqb55/PVviTpLuy7NUQrYL7KC2h/gb7Es0mHvjVsyM+bK/ZNz57eBr9qgTzx388SzT/Ns1jedXzH3pbNxnIJxnrV8zHzAklrJ+JbAvaqf5VR7l99cCfrc35CybMT92e0M+1t3O2NffMO5jper7m5DM/oIz1xJXrS8XuHrb0YCr1rcK+N1Jz6vWZez8lrEfGXNtd9K8blS/TBaom7AB/XKbgN+2If3yHWO/MObatg3olysF6iZiQL/cLuB3Z0P65XvGfmHMtd3ZgH65SqBucg3olzsE/O5iSL/8wNgvjLm2OeOnLqbXtPZ8qqo0qDquqn3FDyHLkozvj4zx1XTFgth1nx8Fzot/YjwvDqKuYjfOuErE9qeQ/jb+LHQNmv1i1RbGi1W/GHCxSqIpf9X8YpXy+2MBvw/RfCesmvAXAb8PNUQc/cbYj4y5tjnjJ3wQ+3tpGXdt/mrAQew3qYMYd0P+nlJF9u8GFNQfUgXFvef80wOX+U0t9PlB/W3caUqh/+WR6/POxry+IdNdjBVeUJ2Wam7OGEjZ6EszpLn9fIZq/WGCszE3dxZncwdSzW0HDGjuoCnNHWJsbl0/+XDHj/ucMY25IatbZTfuOHAXe5oBDZluSkNmMDbkb+mMFwbSU4VuwjljJVMKvTJjoe9kLPS/0i0TZCXrOWOV1FHMrmLAUayqKc1djbG5/YyyMuDBc8bqqea2qxvQ3DVMae6ajM2dxtjc6ZovJGhLc/wpsJCgq+Z+q4ea/CHgdzdDFlDUYuwXxlzb3Qzol78E6uYIA/plp4DfRxrSL7UZ+4Ux1/aRBvSL+rCGu256GdAvPgG/exvSL3UY+4Ux13ZvA/olJFA3xxrQL0EBv48zpF/2YewXxlzbxxnQL+kCddPXgH7JEPC7nyH9UpexXxhzbfczoF8qCdRNfwP6pbKA3wMM6Zd9GfuFMdf2AAP6papA3ZxsQL9UE/B7kCH9Uo+xXxhzbQ8yoF9qCNTNKQb0S00Bv4ca0i/1GfuFMdf2UM3rZl5Q5vOX0zX3W32YXEugX/IM6ZcGjP3CmGs7z4B+kfj8pdCAfqkt0C9FhvRLQ8Z+Ycy1XWRAv0h8/jLMgH6pI+D3cEP6pRFjvzDm2h5uQL9IfP5SbEC/7CPg9whD+qUxY78w5toeYUC/SHwOMdqAfqkr4PcYQ/qlCWO/MObaHmNAv0h8DjHegH7ZV8DvEkP6pSljvzDm2i4xoF8kPoc4x4B+qSfg97mG9Eszxn5hzLV9rgH9IvE5xEQD+qW+gN8XGNIvzRn7hTHXtlT8/Mz142PMRYs0M3z2M/rc0hCfA4w+tzLE5yCjz60N8TnE6HMbQ3xOY/S5rSE+pzP6vJ8hPu/P6HM7Q3xux+hzew/6vL8Hfe7gQZ87etDnTh70+QAP+nygB30Oe9Bn24M+Z3rQ5ywP+hzxoM+dPehztgd9zvGgz7ke9LmLB30+yIM+H+xBnw/xoM+HetDnwzzo8+Ee9LmrB33u5kGfu3vQ5x4e9PkID/p8pAd97ulBn4/yoM+9POhzbw/6fLQHfT7Ggz4f60Gfj/Ogz3086PPxHvS5rwd97udBn0/woM8netDn/h70eYAHfT7Jgz4P9KDPJ3vQ50Ee9HmwB30e4kGfT/Ggz0M96POpHvT5NA/6fLoHfc7zoM/5HvS5wIM+F3rQ5yIP+hz1oM9neNDnYR70ebgHfT7Tgz6f5UGfiz3o8wgP+jzSgz6P8qDPoz3o8xgP+jzWgz6P86DP4z3oc4kHfZ7gQZ/P9qDP53jQ53M96PN5HvT5fA/6PNGDPl/gQZ8v9KDPF3nQ54s96PMlHvT5Ug/6fJkHfb7cgz5P8qDPkz3o8xQP+nyFB32+0oM+T/Wgz9M86PNVHvT5ag/6fI0Hfb7Wgz5P96DP13nQ5+s96PMMD/p8gwd9vtGDPt/kQZ9v9qDPt3jQ55ke9PlWD/p8mwd9vt0Qnxuk8fl8hyE+N2T0eZYhPjdi9Hm2IT43ZvT5TkN8bsLo8xxDfG7K6PNcQ3xuxujzXYb43JzR57s9qEnmedDn+R70+R4P+rzAgz7f60Gf7/Ogzws96PP9hvicwejzA4b4XInR5wcN8bkyo88PGeJzFUafHzbE56qMPi8yxOdqjD4/YojP1Rl9ftQQn2sw+rzYEJ9rMvr8mCE+12L0+XFDfK7N6PMThvhch9HnJw3xeR9Gn58yxOe6jD4vMcTnfRl9fprR530xjw8+BwhBQohA/8ZKJ6hzQnWOpM4ZlIZWmlJpLKU51DFYHZPUPlrts1QPq5pWOd4X76utHqE+oQGhIaERoTGhCaEpoRmhOaEFoSWhFaE1oQ2hLWE/wm2YqwUZ1pLQitCa0IbQlrAfoR2hPWF/QgdCR0InwgGEAwlhgk3IJGQRIoTOhGxCDkE9N149R109V1w9Z1s9d1o9h1k9l3jXc3oJ6jmu6rmm6jmf6rmX6jmQ6rmI6jmB6rl56jly6rlq6jlj6rlb6jlU6rlM6jlF6rk96jk26rku6jkn6rkf6jkY6rkQ6jkJ6rkB6j766r7y6j7r6r7j6j7c6r7U6j7N6r7F6j6+6r626j6v6r6n6j6g6r6Y6j6R6r6J6j6C6r566j5z6r5r6j5k6r5c6j5V6r5N6j5G6r4+6j436r4v6j4o6r4g6j4Z6r4R6j4K6r4C6nv26nvn6nvY6nvJ6nu66nur6nuc6nuN6nt+6ntv6ntg6ntR6ntC6nsz6nsk6nsV6nsGat29Woeu1mWrdcpq3a5ax6rWdap1jmrdn1oHp9aFqXVSat2QWkej1pWodRZq3YH6HF59Lq0+p1WfW6rP8dTnWupzHvW5h/ocQF0XV9eJ1XVTdR1RXVdT15nUdRd1HUKdl6vzVHXeps5jlK5XOlfpPqWDlC5Qx0l13FD7UbVfUX3mc/VHFfxcgDcb43Xe+PFFI0aPbz5+VPO8wsLmZw8fP6z5qAlFY6PFo87+P0HJ4OLxxwUA", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -87,7 +87,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "H4sIAAAAAAAA/+1dB3QcRRKd1Son2zLGBgyInGFaWkkrA2aNySYnY5KtsGvJtizbki1ncs4555xzzjnnDBeAy3fcHZe5BFRJ1ai2vRaSttfaedXz3n9/eyT1/F8Td1TddXnI877yepcQcYzYT29RedBHXop+q/3aSCReVxVX1arBr6pvjNb4kZrG2qiKqppoTXNVtLo6Ho1E6+ob6+v8ehWpjqtETX11gjrOs6fRz4TvfOgjPwO+87PcdwH0UZAB3wWWfa/seE9X5xiLOkMUy0rqbzTgW8AYobwlYA3aZxiX4RSXNbJA15qAsNd7PPHF9jk22l5ffi7TuRbxWNKst7E2YB3Aul7PsbgeYH3ABoANARsBNgZsAtgUsBlgc8AWFJutAFsDtkG9AAWoAlQDIoAaQC2gDhAF1APGAbYFbAfYHjAesANpmgDYETARsBNgZ8AugF0BuwF2B+wBmATYE7AXYG/APoB9AfsB9gccADgQcBDgYMBkwCGAKYBDAYcBDqcYHAE4n3ZkESDHS17y2ecYsZ/mkur+4ae5cO2a8V5a7PV684yfFzEdYW/FGOSydWEjHuWAkhR95rO/i9nxpsxzL8Y+621xLeEs0hIaYi18H3tsnf45PxbM/Y7Hz6ns3MhP8TcF9Dmcou98ti6PPhek+Fseo3zDi5/eokLGdmKsrbdVzDQUZIGWcBZpyVlFWvTxofvNM7QM5XYL7W63ip9LHtsHnqFFL4VMS4lVLZHu+0bRALSUMC3FVrX0fLcqtdtn9722zHKf2Ec5i4mOXymLkf55GYtXueV4hdg2db+6zfU5rU6r0+q0Oq1Oq9PqtDqtTqvT6rQ6rU6r0+q0Oq1Oq9PqtDqtTqvT6rQ6rU6r0+q0Oq1Oq9PqtDqtTqvT6rQ6rU6r0+q0Oq2ytZZ4ybn9mkuZrqHWp9cVMy2ldrX4fFyM7hvHPowL9W7Tbu545Iexg7r/GNOgtxVmvzMl1KtrfMZ09eRE8zzyXENTsZc89kPrsJ1Djn2UpNBRzFhvv4St43ntWmOZsS5Tx3MZ0xtj7XKmTx9fXJPlvPY+z63MXXMiOGTQG8a2m5vCv96+/r0i9pkfV8PZZ80j6HMJW1dBn0vZupGGVz4mim9Xn298W1rzCLZOjyWpYOv0sTSSaefnBj/+iox1mThfQl7yeRtjbX7OFDJdGdJSlUpL2NBiYQyMMlfw4x77n+CteI0Is99ppuuoPk74OcPH3WndJcbvZWJMinnuFrLt8nN3mNXtRrrH1wy366X7Gj6CxVMfe8PZvtA/b2P3t3Y2VlF7LmD9LE/xc72EjHaMfR7G4jfSrtfu/bYa6z/GtsG3O8rudhXfboigt6HXh9nnZSxAo3o//hBfrRmP94oUv8c/lxl/U8J+XpFhzyOZjhhr623hcTKPHVPL2TOT7Xs/98vjEmZxMe9TmTjf0OIILzku5j2OP/Pz+yM/RjVXZEDfMEOfblcwfXpdOdOnffDrCX8+z7OqNVLNt6mXvq4tfLyp7fHhhSwW0+OdE+Z3tkxu7Zwd7+gIMWVa7cQUanNYJPUe5iO9+dVVr8thjvQ6c0Qzn0lmhbD46S0qx+g8m6fpqKR+jgRMBUwDNAAaAU2AZkAckABMB7QAWgEzADMBswBtgNmAdsAcwFzAPEAHoBMwH7AA0AVYCFgEWAxYAlgKWEZBCtHOQy2FXm97qtGeZrQbjHaj0W4y2s1GO260E0Z7utFuMdqtRnuG0Z5ptGcZ7TajPdtotxvtOUZ7rtGeZ7Q7jHan0Z5vtBcY7S6jvdBoLzLai432EqO91Ggv83ofsfSiT9gYsZ/eknTOpDsV05EW+2oI2X0FsrL4DVZnPIGLr6Za6gv3xTSL8WvM+vh1d60a0u+rijyrRovxa8rm+EV+0Kma0uvLZ55Vs8X4NWdr/KqSdKr44PvyDc8qYTF+8SyMX21iBZ1q+uD6iqbwrFosxi+RbfGLptSpWgfeV91KPKsZFuM3PZviV7dSnWrmwPqq6sOzmmUxfi3ZEr+6PnWqtv731fQjntVsi/FrzYb41f2oTtXev778fnhWcyzGb8ZQx8/vl04198f7qumnZzXPYvxmDmX8Iv3WqTr67CuSGIBn1WkxfrOGKn51A9Kp5q+8r+gAPasFFuPXNgTxq08MWKfqSt2XPwjPaqHF+M1e1fHzB6VTLVqxLzVIz2qxxfi1r8r4NQ9ap1qS3Fd1Gp7VUovxm7OK4leVSEunWubZe5fI39mlG7+5qyh+fnqLsvieTTVZjN+8gMTP4nsiFbcYv46AxM/iew413WL8OgMSP4vf01WrxfjND0j8LH7PVDMtxm9BQOJn8XuSarMYv66AxM/ic75qtxi/hQGJn8XnVDXXYvwWBSR+Fp+zVIfF+C0OSPwsPieo+RbjtyQg8bN4n1NdFuO3NCDxs3idVossxm9ZQOJn8TqjlliM3/KAxM/ieaIsHjPKZvwwnw3TabHcGZZvG0us+8dyZ5jntg7xusSVxOsRr0+8AfGGxBsRb0y8CfGmxJsRb068BfGWxFsRb028DbFPrIiriKuJI8Q1xLXEdcRR4nriccTbEm9HvD3xeOIdiGPEE4h3JJ5IvBPxzsS7EO9KvBvx7sR7EE8i3pN4L+K9ifch3pd4P+L9iQ8gPpD4IOKDiScTH0I8hfhQ4sOID2f7GRed76jzIHV+pM6b1PmUOs9S51/qvEydr6nzOHV+p8771PmgOk9U54/qvFKdb6rzUHV+qs5b1fmsLcQ6/1Xnxep8WZ1Hq/NrG4kbiKcR6/xdnde73EtebOdHL/fsXV9RGyaL6+uheW4fQYyp/0cZvnIMX+lqybEYo6Ps9eUHvTzl0cTHeMnlKY8FHAc4HnAC4ETASYCTAacATgWcBjgdcAbgTMBZgLMB5wDOBZwHOB9wAeBCwEWAiwGXAC4FXAa4HHAF4ErAVYCrAdcArgVcB7gecAPgRsBNgJsBtwBuBdwGuB1wB+BOwF2AuwH3AO4F3Ae4H/AA4EHAQ4CHAY8AHgU8Bngc8ATgScBTgKcBz1AMnvVceUpcXHnKzGgJDbEWvo89ts6Vp3TlKV15Sleekk+D0B8trjylK0/ptDqtTqvT6rQ6rU6r0+q0Oq1Oq9PqtDqtTqvT6rQ6rU6r0+q0Oq1Oq9PqtDqtTqvT6rQ6rU6r0+q0Oq1Oq9PqtDqtTqvT6rQGS6srT9mzuPKUvQv2wfPIXXnK/ukNea48JfbhylP2LPz4KzLWZeJ8CXmeK0/pJd+7JniuPGX/Flee0k9zwe268pSuPCWPiytPuaI+V55y4HErZLEQVJ5SD+s92uuZuuQYL3maomO9nlvKccTHE59AfCLxScQnE59CfCrxacSnE59BfCbxWcRnE59DfC7xecTnE19AfCHxRcQXE19CfCnxZcSXE19BfCXxVcRXE19DfC3xdcTXE99AfCPxTcQ3E99CfCvxbcS3E99BfCfxXcR3E99DfC/xfcT3Ez9A/CDxQ8QPEz9C/CjxY8SPEz9B/CTxU8RPEz/juWmK+DRFz3nJiz4hY8R+eot6jvVle5qio73kc/tZr3eaoucNXzmGr2yapuh5e335fe3LdD2/YEFnPFrb0BhJJPraN356iwpZ9PxihvaNbc85Fj2/FBDPYYueXw6I51yLnl8JiOc8i55fDYjnfIueXwuI5wKLnl8PiOc1LXp+IyCeX7Do+c2AeB5j0fNbAj2/LdDzOwI9vyvQ83sCPb8v0PMHAj1/KNDzRwI9fyzQ8ycCPX8q0PNnAj3/RKDnnwr0/DOBnn8u0PPnAj1/IdDzlwI9/0Kg518K9PwrgZ5/LdDzbwR6/q1Az78T6Pn3Aj3/QaDnrwR6/qNAz38S6PnPAj1/LdDzXwR6/qtAz38T6PnvAj3/Q6Dnfwr0/C+Bnr8R6PnfAj3/R6Dn/wr0/D+Bnv8v0PO3Aj1/J9AzDkaU5jkk0HOOQM9hgZ5zBXrOE+g5X6DnAoGeCwV6LhLouVig5xKBnksFei4T6LlcoOdhAj0PF+h5hEDPFQI9jxToeTWBnkcJ9Ly6QM+jBXoeI9DzGgI9rynQ81oCPY8V6HltgZ7XEeh5XYGeKwV6Xk+g5/UFet5AoOcNBXreSKDnjQV63kSg500Fet5MoOfNBXreQqDnLQV63kqg560Fet5GoGdfoGcl0HOVQM/VAj1HBHquEei5VqDnOoGeowI91wv0PE6g520Fet5OoOftBXoeL9DzDgI9xwR6niDQ844CPU8U6HkngZ53Fuh5F4GedxXoeTeBnncX6HkPgZ4nCfS8p0DPewn0vLdAz/sI9LyvQM/7BcRzoUXP+wfEc5FFzwcExHOxRc8HBsRziUXPBwXEc6lFzwcHxHOZRc+TA+K53KLnQwLieZhFz1MC4nm4Rc+HBsTzCIueDwuI5wqLng8PiOeRFj0fERDPq1n0fGRAPI+y6HlqQDyvbtHzNIueR1M/IfIcBuQC8gD5gAIAfifE70j4nQGfofGZEp+x8JkD78F4T8JrNF6z8BzGYxr3MXoezWJ6GfGLgJcALwNeAbwKeA3wOuANwJuAtwBvA94BvAt4D/A+4APAh4CPAB8DPgF8CvgMgHXuse471kHHuuCfA74AfAnAusJYZxfrzmIdVqxLinU6sW4l1nHEuoZY5w/r3mEdOKyL9jUA62ZhHSmsq4R1hrDuDtahwbos3wCwbgfWscC6DljnAOf9x3nwv6Og4rzhOI82ziuN8yzjvMM4Dy/OS4vztOK8pTiPJ85rifM84ryHOA8gzouH88ThvGk4jxjOq4XzTOG8SzgPEc7Lg/PU4LwtOI8JzuuB81zgvA84DwLOC4Dj5HHcOI6jxnHFOM4Wx53iOEwcl4jj9HDcGo7jwnFNOM4Hx73gOBAcF4HjBDBvHvPIMa8a84wx7xbzUDEvE/MUMW8P89gwrwvznDDvB/NguvNCAJg3gP9Hx/8r4/9Z8f+O+H84/L8U/p8G/2+B7/HxvTa+58X3nvgeEN+L4XsifG+C7xHwezV+z8TvXfg9BJ/L8TkVn9vwOQbv63ifw+s+XgfxuoDnSQ47vvPpc1Ooh8dSu6GzM942p7Oys72yobm5squ1s6WyfUF8XmJWexf+6qRB/N33BTt/y05YAQA=", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -347,7 +347,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -614,7 +614,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 0d12832b004..f6e3321211d 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -277,9 +277,9 @@ __metadata: languageName: unknown linkType: soft -"@aztec/bb.js@npm:0.15.1": - version: 0.15.1 - resolution: "@aztec/bb.js@npm:0.15.1" +"@aztec/bb.js@npm:0.16.0": + version: 0.16.0 + resolution: "@aztec/bb.js@npm:0.16.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -287,7 +287,7 @@ __metadata: tslib: ^2.4.0 bin: bb.js: dest/node/main.js - checksum: b3d94eb6db1d1579fa7266486d4b1c6ddc408f1d36bd2585b50e623aa90222d273e56464284b94677979840c1119c5385aa961462d3a1af6cb9a2ba1cf9655f9 + checksum: 5f68b4ad16284a3a871e0ad21fea05aed670383bc639c9d07ab3bf9b7a9d15cc8a4e5cda404a9290775ad5023924739543a8aac37d602892dd1fb5087521970b languageName: node linkType: hard @@ -3646,8 +3646,8 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@portal:../noir/packages/backend_barretenberg::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@aztec/bb.js": 0.15.1 - "@noir-lang/types": 0.19.3 + "@aztec/bb.js": 0.16.0 + "@noir-lang/types": 0.19.4 fflate: ^0.8.0 languageName: node linkType: soft @@ -3656,9 +3656,9 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/noir_js@portal:../noir/packages/noir_js::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@noir-lang/acvm_js": 0.34.0 - "@noir-lang/noirc_abi": 0.19.3 - "@noir-lang/types": 0.19.3 + "@noir-lang/acvm_js": 0.35.0 + "@noir-lang/noirc_abi": 0.19.4 + "@noir-lang/types": 0.19.4 languageName: node linkType: soft @@ -3666,7 +3666,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/noir_wasm@portal:../noir/packages/noir_wasm::locator=%40aztec%2Faztec3-packages%40workspace%3A." peerDependencies: - "@noir-lang/source-resolver": 0.19.3 + "@noir-lang/source-resolver": 0.19.4 languageName: node linkType: soft @@ -3686,7 +3686,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/types@portal:../noir/packages/types::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@noir-lang/noirc_abi": 0.19.3 + "@noir-lang/noirc_abi": 0.19.4 languageName: node linkType: soft