From ff28080bcfb946177010960722925973ee19646b Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:02:48 -0400 Subject: [PATCH] feat: Sync from noir (#5619) Automated pull of development from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE feat(nargo): Multiple circuits info for binary programs (https://github.com/noir-lang/noir/pull/4719) chore: update condition for clearing warning comment on release PRs (https://github.com/noir-lang/noir/pull/4739) chore(ci): fix cutting new versions of the docs (https://github.com/noir-lang/noir/pull/4737) chore(ci): replace `yarn build:js:only` script (https://github.com/noir-lang/noir/pull/4735) chore: update JS publish workflow to upload build artifacts correctly. (https://github.com/noir-lang/noir/pull/4734) feat: add `remove_enable_side_effects` SSA pass (https://github.com/noir-lang/noir/pull/4224) chore: update from vulnerable version of h2 (https://github.com/noir-lang/noir/pull/4714) chore(ci): stop updating version list before cutting new docs version (https://github.com/noir-lang/noir/pull/4726) chore: remove `FunctionInput::dummy` (https://github.com/noir-lang/noir/pull/4723) chore: remove docker CI flow (https://github.com/noir-lang/noir/pull/4724) fix: unknown slice lengths coming from as_slice (https://github.com/noir-lang/noir/pull/4725) chore: remove unused env vars from `Cross.toml` (https://github.com/noir-lang/noir/pull/4717) feat: improve nargo check cli with --override flag and feedback for existing files (https://github.com/noir-lang/noir/pull/4575) feat: Allow slices to brillig entry points (https://github.com/noir-lang/noir/pull/4713) chore: simplify how `acvm_backend.wasm` is embedded (https://github.com/noir-lang/noir/pull/4703) fix(acvm): Mark outputs of Opcode::Call solvable (https://github.com/noir-lang/noir/pull/4708) fix: Field comparisons (https://github.com/noir-lang/noir/pull/4704) feat(acvm_js): Execute program (https://github.com/noir-lang/noir/pull/4694) chore: simplify how blns is loaded into tests (https://github.com/noir-lang/noir/pull/4705) fix(ssa): Do not use get_value_max_num_bits when we want pure type information (https://github.com/noir-lang/noir/pull/4700) chore: remove conditional compilation around `acvm_js` package (https://github.com/noir-lang/noir/pull/4702) feat(docs): Documenting noir codegen (https://github.com/noir-lang/noir/pull/4454) chore: check for references to private functions during path resolution (https://github.com/noir-lang/noir/pull/4622) chore: fix clippy errors (https://github.com/noir-lang/noir/pull/4684) fix: Last use analysis & make it an SSA pass (https://github.com/noir-lang/noir/pull/4686) feat: improve SSA type-awareness in EQ and MUL instructions (https://github.com/noir-lang/noir/pull/4691) feat: improve optimisations on range constraints (https://github.com/noir-lang/noir/pull/4690) chore: remove last traces of nix (https://github.com/noir-lang/noir/pull/4679) chore: Use is_entry_point helper on RuntimeType (https://github.com/noir-lang/noir/pull/4678) END_COMMIT_OVERRIDE --------- Co-authored-by: sirasistant Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: vezenovm --- .../.github/workflows/docker-test-flow.yml | 808 ------------------ noir/noir-repo/.github/workflows/docs-pr.yml | 8 +- .../.github/workflows/gates_report.yml | 2 +- .../.github/workflows/publish-docs.yml | 7 +- .../.github/workflows/publish-es-packages.yml | 8 +- noir/noir-repo/.github/workflows/release.yml | 2 +- noir/noir-repo/Cargo.lock | 4 +- noir/noir-repo/Dockerfile.ci | 30 - .../opcodes/black_box_function_call.rs | 6 - .../acir/tests/test_program_serialization.rs | 25 +- .../acvm_js/test/shared/nested_acir_call.ts | 14 +- .../compiler/noirc_driver/src/contract.rs | 3 + .../compiler/noirc_driver/src/lib.rs | 21 +- .../compiler/noirc_driver/src/program.rs | 2 + .../compiler/noirc_evaluator/src/ssa.rs | 83 +- .../ssa/acir_gen/acir_ir/generated_acir.rs | 6 +- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 7 +- .../noirc_evaluator/src/ssa/opt/mod.rs | 1 + .../src/ssa/opt/remove_enable_side_effects.rs | 167 ++++ noir/noir-repo/docs/package.json | 5 +- noir/noir-repo/docs/scripts/cut_version.sh | 16 + noir/noir-repo/package.json | 3 +- .../fold_non_contract_method/Nargo.toml | 7 + .../fold_non_contract_method/src/main.nr | 18 + .../tooling/nargo/src/artifacts/program.rs | 4 + noir/noir-repo/tooling/nargo_cli/build.rs | 2 +- .../tooling/nargo_cli/src/cli/info_cmd.rs | 62 +- .../src/contract/artifact_hash.test.ts | 2 +- 28 files changed, 385 insertions(+), 938 deletions(-) delete mode 100644 noir/noir-repo/.github/workflows/docker-test-flow.yml delete mode 100644 noir/noir-repo/Dockerfile.ci create mode 100644 noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs create mode 100755 noir/noir-repo/docs/scripts/cut_version.sh create mode 100644 noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/Nargo.toml create mode 100644 noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/src/main.nr diff --git a/noir/noir-repo/.github/workflows/docker-test-flow.yml b/noir/noir-repo/.github/workflows/docker-test-flow.yml deleted file mode 100644 index c8b4f53fadd..00000000000 --- a/noir/noir-repo/.github/workflows/docker-test-flow.yml +++ /dev/null @@ -1,808 +0,0 @@ -name: Test Nargo and JS packages - -on: - push: - branches: - - 'master' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-base-nargo: - name: Build base nargo docker image - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Get current date - id: date - run: echo "date=$(date +'%Y.%m.%d.%H.%M')" >> $GITHUB_STATE - - name: prepare docker images tags - id: prep - run: | - REGISTRY="ghcr.io" - IMG_RAW="${REGISTRY}/${{ github.repository }}" - IMAGE=$(echo "$IMG_RAW" | tr '[:upper:]' '[:lower:]') - TAGS="${IMAGE}:${{ github.sha }}-nargo" - FULL_TAGS="${TAGS},${IMAGE}:latest-nargo,${IMAGE}:v${{ steps.date.outputs.date }}-nargo" - echo "tags=$FULL_TAGS" >> $GITHUB_OUTPUT - echo "image=$IMAGE" >> $GITHUB_OUTPUT - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build nargo base dockerfile - uses: docker/build-push-action@v5 - with: - context: . - file: Dockerfile.ci - tags: ${{ steps.prep.outputs.tags }} - target: base-nargo - cache-from: type=gha - cache-to: type=gha,mode=max - push: true - - build-base-js: - name: Build base js docker image - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Get current date - id: date - run: echo "date=$(date +'%Y.%m.%d.%H.%M')" >> $GITHUB_STATE - - name: Prepare docker image tags - id: prep - run: | - REGISTRY="ghcr.io" - IMG_RAW="${REGISTRY}/${{ github.repository }}" - IMAGE=$(echo "$IMG_RAW" | tr '[:upper:]' '[:lower:]') - TAGS="${IMAGE}:${{ github.sha }}-js" - FULL_TAGS="${TAGS},${IMAGE}:latest-js,${IMAGE}:v${{ steps.date.outputs.date }}-js" - echo "tags=$FULL_TAGS" >> $GITHUB_OUTPUT - echo "image=$IMAGE" >> $GITHUB_OUTPUT - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build js base dockerfile - uses: docker/build-push-action@v5 - with: - context: . - file: Dockerfile.ci - tags: ${{ steps.prep.outputs.tags }} - target: base-js - cache-from: type=gha - cache-to: type=gha,mode=max - push: true - - artifact-nargo: - name: Artifact nargo - runs-on: ubuntu-latest - needs: [build-base-nargo] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-nargo - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Artifact nargo - uses: actions/upload-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release/nargo - if-no-files-found: error - compression-level: 0 - - test-nargo: - name: Test nargo - runs-on: ubuntu-latest - needs: [build-base-nargo] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-nargo - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Test - working-directory: /usr/src/noir - run: | - .github/scripts/nargo-test.sh - - build-noir-wasm: - name: Build noir wasm - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-wasm-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: noir_wasm - path: /usr/src/noir/compiler/wasm - retention-days: 10 - - test-noir-wasm: - name: Test noir wasm - runs-on: ubuntu-latest - needs: [build-base-js, artifact-nargo, build-noir-wasm] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download noir_wasm artifact - uses: actions/download-artifact@v4 - with: - name: noir_wasm - path: /usr/src/noir/compiler/wasm - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-wasm-test.sh - - test-noir-wasm-browser: - name: Test noir wasm browser - runs-on: ubuntu-latest - needs: [build-base-js, artifact-nargo, build-noir-wasm] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download noir_wasm artifact - uses: actions/download-artifact@v4 - with: - name: noir_wasm - path: /usr/src/noir/compiler/wasm - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-wasm-test-browser.sh - - build-acvm_js: - name: Build acvm js - runs-on: ubuntu-latest - needs: [build-base-js] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/acvm_js-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: acvm_js - path: - /usr/src/noir/acvm-repo/acvm_js/outputs/out/acvm_js - if-no-files-found: error - compression-level: 0 - - test-acvm_js: - name: Test acvm js - runs-on: ubuntu-latest - needs: [build-base-js, build-acvm_js] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: | - /usr/src/noir/acvm-repo/acvm_js - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/acvm_js-test.sh - - test-acvm_js-browser: - name: Test acvm js browser - runs-on: ubuntu-latest - needs: [build-base-js, build-acvm_js] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: | - /usr/src/noir/acvm-repo/acvm_js - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/acvm_js-test-browser.sh - - build-noirc-abi: - name: Build noirc abi - runs-on: ubuntu-latest - needs: [build-base-js] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/noirc-abi-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: noirc_abi_wasm - path: - /usr/src/noir/tooling/noirc_abi_wasm/outputs/out/noirc_abi_wasm - if-no-files-found: error - compression-level: 0 - - test-noirc-abi: - name: Test noirc abi - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noirc-abi-test.sh - - test-noirc-abi-browser: - name: Test noirc abi browser - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noirc-abi-test-browser.sh - - build-noir-js-types: - name: Build noir js types - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-js-types-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - if-no-files-found: error - compression-level: 0 - - build-barretenberg-backend: - name: Build Barretenberg backend - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi, build-noir-js-types] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: /usr/src/noir/tooling/noir_js_types/lib/ - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/backend-barretenberg-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - if-no-files-found: error - compression-level: 0 - - test-barretenberg-backend: - name: Test Barretenberg backend - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi, build-noir-js-types, build-barretenberg-backend] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: /usr/src/noir/tooling/noir_js_types/lib/ - - name: Download Backend barretenberg - uses: actions/download-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/backend-barretenberg-test.sh - - build-noir_js: - name: Build noirjs - runs-on: ubuntu-latest - needs: [build-base-js, artifact-nargo, build-noirc-abi, build-acvm_js, build-barretenberg-backend, build-noir-js-types] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: | - /usr/src/noir/acvm-repo/acvm_js - - name: Download Barretenberg backend - uses: actions/download-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-js-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - test-noir_js: - name: Test noirjs - runs-on: ubuntu-latest - needs: [ - build-base-js, - build-noirc-abi, - artifact-nargo, - build-acvm_js, - build-barretenberg-backend, - build-noir_js, - build-noir-js-types - ] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: | - /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: | - /usr/src/noir/acvm-repo/acvm_js - - name: Download Barretenberg backend - uses: actions/download-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Download noir js - uses: actions/download-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-js-test.sh - - build-noir_codegen: - name: Build noir codegen - runs-on: ubuntu-latest - needs: [build-base-js, build-noirc-abi, build-acvm_js, build-noir-js-types, build-noir_js] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi package - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: /usr/src/noir/acvm-repo/acvm_js - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Download noir js - uses: actions/download-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - name: Build - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-codegen-build.sh - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: noir_codegen - path: - /usr/src/noir/tooling/noir_codegen/lib - - test-noir_codegen: - name: Test noir codegen - runs-on: ubuntu-latest - needs: [build-base-js, artifact-nargo, build-noirc-abi, build-acvm_js, build-noir-js-types, build-noir_js, build-noir_codegen] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: /usr/src/noir/acvm-repo/acvm_js - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Download noir js - uses: actions/download-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - name: Download noir codegen - uses: actions/download-artifact@v4 - with: - name: noir_codegen - path: - /usr/src/noir/tooling/noir_codegen/lib - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/noir-codegen-test.sh - - test-integration: - name: Integration test - runs-on: ubuntu-latest - needs: [ - build-base-js, - artifact-nargo, - build-noir-wasm, - build-noirc-abi, - build-acvm_js, - build-noir-js-types, - build-noir_js, - build-barretenberg-backend - ] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download nargo - uses: actions/download-artifact@v4 - with: - name: nargo - path: /usr/src/noir/target/release - - name: Prep downloaded artifact - run: | - chmod +x /usr/src/noir/target/release/nargo - - name: Download noir wasm - uses: actions/download-artifact@v4 - with: - name: noir_wasm - path: /usr/src/noir/compiler/wasm - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: /usr/src/noir/acvm-repo/acvm_js - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Download noir js - uses: actions/download-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - name: Download Barretenberg backend - uses: actions/download-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/integration-test-node.sh - - test-integration-browser: - name: Integration test browser - runs-on: ubuntu-latest - needs: [ - build-base-js, - build-noir-wasm, - build-noirc-abi, - build-acvm_js, - build-noir-js-types, - build-noir_js, - build-barretenberg-backend - ] - container: - image: ghcr.io/noir-lang/noir:${{ github.sha }}-js - credentials: - username: ${{ github.actor }} - password: ${{ secrets.github_token }} - steps: - - name: Download noir wasm - uses: actions/download-artifact@v4 - with: - name: noir_wasm - path: /usr/src/noir/compiler/wasm - - name: Download noirc abi - uses: actions/download-artifact@v4 - with: - name: noirc_abi_wasm - path: /usr/src/noir/tooling/noirc_abi_wasm - - name: Download acvm js - uses: actions/download-artifact@v4 - with: - name: acvm_js - path: /usr/src/noir/acvm-repo/acvm_js - - name: Download noir js types - uses: actions/download-artifact@v4 - with: - name: noir-js-types - path: | - /usr/src/noir/tooling/noir_js_types/lib - - name: Download noir js - uses: actions/download-artifact@v4 - with: - name: noir_js - path: - /usr/src/noir/tooling/noir_js/lib - - name: Download Barretenberg backend - uses: actions/download-artifact@v4 - with: - name: barretenberg-backend - path: - /usr/src/noir/tooling/noir_js_backend_barretenberg/lib - - name: Test - working-directory: /usr/src/noir - run: | - ./.github/scripts/integration-test-browser.sh - - tests-end: - name: End - runs-on: ubuntu-latest - if: ${{ always() }} - needs: - - test-nargo - - test-noirc-abi - - test-noirc-abi-browser - - test-noir-wasm - - test-noir-wasm-browser - - test-integration - - test-integration-browser - - test-noir_codegen - - test-acvm_js - - test-acvm_js-browser - - test-barretenberg-backend - - test-noir_js - - steps: - - name: Report overall success - run: | - if [[ $FAIL == true ]]; then - exit 1 - else - exit 0 - fi - env: - FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} diff --git a/noir/noir-repo/.github/workflows/docs-pr.yml b/noir/noir-repo/.github/workflows/docs-pr.yml index 5d0b72c6ad8..1f9ccdd946b 100644 --- a/noir/noir-repo/.github/workflows/docs-pr.yml +++ b/noir/noir-repo/.github/workflows/docs-pr.yml @@ -75,9 +75,11 @@ jobs: run: | npm i wasm-opt -g + - name: Query active docs versions + run: yarn workspace docs version::stables + - name: Build docs - run: - yarn workspaces foreach -Rpt --from docs run build + run: yarn workspaces foreach -Rpt --from docs run build - name: Upload artifact uses: actions/upload-artifact@v4 @@ -126,4 +128,4 @@ jobs: with: message: | FYI @noir-lang/developerrelations on Noir doc changes. - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/noir/noir-repo/.github/workflows/gates_report.yml b/noir/noir-repo/.github/workflows/gates_report.yml index f3f798fc5ea..ebf17f7374c 100644 --- a/noir/noir-repo/.github/workflows/gates_report.yml +++ b/noir/noir-repo/.github/workflows/gates_report.yml @@ -74,7 +74,7 @@ jobs: - name: Compare gates reports id: gates_diff - uses: TomAFrench/noir-gates-diff@e7cf131b7e7f044c01615f93f0b855f65ddc02d4 + uses: TomAFrench/noir-gates-diff@df05f34e2ab275ddc4f2cac065df1c88f8a05e5d with: report: gates_report.json summaryQuantile: 0.9 # only display the 10% most significant circuit size diffs in the summary (defaults to 20%) diff --git a/noir/noir-repo/.github/workflows/publish-docs.yml b/noir/noir-repo/.github/workflows/publish-docs.yml index a56583b34eb..8896e613608 100644 --- a/noir/noir-repo/.github/workflows/publish-docs.yml +++ b/noir/noir-repo/.github/workflows/publish-docs.yml @@ -28,10 +28,11 @@ jobs: run: | npm i wasm-opt -g + - name: Query active docs versions + run: yarn workspace docs version::stables + - name: Build docs for deploying - working-directory: docs - run: - yarn workspaces foreach -Rt run build + run: yarn workspaces foreach -Rpt --from docs run build - name: Deploy to Netlify uses: nwtgck/actions-netlify@v2.1 diff --git a/noir/noir-repo/.github/workflows/publish-es-packages.yml b/noir/noir-repo/.github/workflows/publish-es-packages.yml index 470db3b78f7..819be308169 100644 --- a/noir/noir-repo/.github/workflows/publish-es-packages.yml +++ b/noir/noir-repo/.github/workflows/publish-es-packages.yml @@ -44,7 +44,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: noirc_abi_wasm - path: ./tooling/noirc_abi_wasm/outputs/out/noirc_abi_wasm + path: | + ./tooling/noirc_abi_wasm/nodejs + ./tooling/noirc_abi_wasm/web retention-days: 10 build-noir_wasm: @@ -113,7 +115,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: acvm-js - path: ./acvm-repo/acvm_js/outputs/out/acvm_js + path: | + ./acvm-repo/acvm_js/nodejs + ./acvm-repo/acvm_js/web retention-days: 3 publish-es-packages: diff --git a/noir/noir-repo/.github/workflows/release.yml b/noir/noir-repo/.github/workflows/release.yml index badcd3af2dd..d27fac0e039 100644 --- a/noir/noir-repo/.github/workflows/release.yml +++ b/noir/noir-repo/.github/workflows/release.yml @@ -131,7 +131,7 @@ jobs: # We need to specify the PR on which to make the comment as workflow is triggered by push. number: ${{ fromJSON(needs.release-please.outputs.release-pr).number }} # delete the comment in case failures have been fixed - delete: ${{ !env.FAIL }} + delete: ${{ env.FAIL == false }} message: "The release workflow has not completed successfully. Releasing now will result in a broken release" - name: Report overall success diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index 8a655d1fa0e..f3803063f33 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -1983,9 +1983,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", diff --git a/noir/noir-repo/Dockerfile.ci b/noir/noir-repo/Dockerfile.ci deleted file mode 100644 index e0dc030980c..00000000000 --- a/noir/noir-repo/Dockerfile.ci +++ /dev/null @@ -1,30 +0,0 @@ -FROM rust:1.73.0-slim-bookworm as base -RUN apt-get update && apt-get upgrade -y && apt-get install build-essential git -y -WORKDIR /usr/src/noir -ENV PATH="${PATH}:/usr/src/noir/target/release" - -FROM base as base-nargo -COPY . . -RUN .github/scripts/nargo-build.sh - -FROM base as base-js -RUN apt-get install -y ca-certificates curl gnupg -RUN mkdir -p /etc/apt/keyrings -RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list -RUN apt-get update && apt-get install nodejs -y -RUN corepack enable -RUN apt-get install -y jq -COPY yarn.lock package.json .yarnrc.yml ./ -COPY .yarn/ ./.yarn/ -COPY ./acvm-repo/acvm_js/package.json ./acvm-repo/acvm_js/ -COPY ./tooling/noirc_abi_wasm/package.json ./tooling/noirc_abi_wasm/ -COPY ./compiler/wasm/package.json ./compiler/wasm/ -COPY ./tooling/noir_js_types/package.json ./tooling/noir_js_types/ -COPY ./tooling/noir_js_backend_barretenberg/package.json ./tooling/noir_js_backend_barretenberg/ -COPY ./tooling/noir_js/package.json ./tooling/noir_js/ -COPY ./tooling/noir_codegen/package.json ./tooling/noir_codegen/ -COPY ./compiler/integration-tests/package.json ./compiler/integration-tests/ -COPY ./docs/package.json ./docs/ -RUN yarn --immutable -COPY . . diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 8a0c4692282..c955e435b37 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -10,12 +10,6 @@ pub struct FunctionInput { pub num_bits: u32, } -impl FunctionInput { - pub fn dummy() -> Self { - Self { witness: Witness(0), num_bits: 0 } - } -} - #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum BlackBoxFuncCall { AND { diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index 2feb2737d28..8b9160ccf6a 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -384,13 +384,13 @@ fn nested_acir_call_circuit() { id: 1, inputs: vec![Witness(0), Witness(1)], outputs: vec![Witness(2)], - predicate: Some(Expression::one()), + predicate: None, }; let nested_call_two = Opcode::Call { id: 1, inputs: vec![Witness(0), Witness(1)], outputs: vec![Witness(3)], - predicate: Some(Expression::one()), + predicate: None, }; let assert_nested_call_results = Opcode::AssertZero(Expression { @@ -422,7 +422,7 @@ fn nested_acir_call_circuit() { id: 2, inputs: vec![Witness(2), Witness(1)], outputs: vec![Witness(3)], - predicate: Some(Expression::one()), + predicate: None, }; let nested_call = Circuit { @@ -455,16 +455,15 @@ fn nested_acir_call_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 65, 14, 3, 33, 8, 68, 77, 246, 61, 32, 186, - 139, 183, 126, 165, 166, 238, 255, 159, 208, 109, 74, 82, 229, 178, 135, 186, 77, 58, 201, - 4, 195, 97, 128, 1, 3, 188, 17, 148, 47, 44, 7, 221, 65, 15, 31, 56, 37, 104, 222, 129, - 193, 77, 35, 126, 7, 58, 43, 30, 174, 44, 222, 107, 250, 201, 218, 190, 211, 98, 92, 83, - 106, 91, 108, 196, 116, 199, 88, 170, 100, 76, 185, 174, 66, 66, 89, 242, 35, 10, 115, 147, - 36, 91, 169, 101, 195, 66, 137, 27, 237, 185, 240, 174, 98, 97, 94, 95, 8, 198, 80, 103, - 226, 128, 0, 227, 102, 174, 50, 11, 38, 154, 229, 231, 245, 21, 23, 157, 213, 119, 115, - 255, 244, 58, 237, 183, 176, 239, 0, 38, 233, 254, 108, 91, 14, 230, 158, 246, 153, 97, 3, - 158, 188, 79, 135, 232, 14, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 97, 10, 195, 32, 12, 133, 163, 66, 207, 147, + 24, 173, 241, 223, 174, 50, 153, 189, 255, 17, 214, 177, 148, 89, 17, 250, 99, 14, 246, + 224, 97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105, 217, 109, 118, 91, 248, 200, 168, + 225, 248, 191, 106, 114, 208, 233, 104, 188, 233, 139, 223, 137, 108, 51, 139, 113, 13, + 161, 38, 95, 137, 233, 142, 62, 23, 137, 24, 98, 89, 133, 132, 162, 196, 135, 23, 230, 42, + 65, 82, 46, 57, 97, 166, 192, 149, 182, 152, 121, 211, 97, 110, 222, 94, 8, 13, 132, 182, + 54, 48, 144, 235, 8, 254, 10, 22, 76, 132, 101, 231, 237, 229, 23, 189, 213, 54, 119, 15, + 83, 212, 199, 172, 175, 79, 113, 51, 48, 198, 253, 207, 84, 13, 204, 141, 224, 21, 176, + 147, 158, 66, 231, 43, 145, 6, 4, 0, 0, ]; - assert_eq!(bytes, expected_serialization); } diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts index 9f9b94b7a44..1b745ab6a79 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/nested_acir_call.ts @@ -2,13 +2,13 @@ import { WitnessMap, StackItem, WitnessStack } from '@noir-lang/acvm_js'; // See `nested_acir_call_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 65, 14, 3, 33, 8, 68, 77, 246, 61, 32, 186, 139, 183, 126, 165, 166, 238, - 255, 159, 208, 109, 74, 82, 229, 178, 135, 186, 77, 58, 201, 4, 195, 97, 128, 1, 3, 188, 17, 148, 47, 44, 7, 221, 65, - 15, 31, 56, 37, 104, 222, 129, 193, 77, 35, 126, 7, 58, 43, 30, 174, 44, 222, 107, 250, 201, 218, 190, 211, 98, 92, - 83, 106, 91, 108, 196, 116, 199, 88, 170, 100, 76, 185, 174, 66, 66, 89, 242, 35, 10, 115, 147, 36, 91, 169, 101, 195, - 66, 137, 27, 237, 185, 240, 174, 98, 97, 94, 95, 8, 198, 80, 103, 226, 128, 0, 227, 102, 174, 50, 11, 38, 154, 229, - 231, 245, 21, 23, 157, 213, 119, 115, 255, 244, 58, 237, 183, 176, 239, 0, 38, 233, 254, 108, 91, 14, 230, 158, 246, - 153, 97, 3, 158, 188, 79, 135, 232, 14, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 97, 10, 195, 32, 12, 133, 163, 66, 207, 147, 24, 173, 241, 223, 174, 50, + 153, 189, 255, 17, 214, 177, 148, 89, 17, 250, 99, 14, 246, 224, 97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105, + 217, 109, 118, 91, 248, 200, 168, 225, 248, 191, 106, 114, 208, 233, 104, 188, 233, 139, 223, 137, 108, 51, 139, 113, + 13, 161, 38, 95, 137, 233, 142, 62, 23, 137, 24, 98, 89, 133, 132, 162, 196, 135, 23, 230, 42, 65, 82, 46, 57, 97, + 166, 192, 149, 182, 152, 121, 211, 97, 110, 222, 94, 8, 13, 132, 182, 54, 48, 144, 235, 8, 254, 10, 22, 76, 132, 101, + 231, 237, 229, 23, 189, 213, 54, 119, 15, 83, 212, 199, 172, 175, 79, 113, 51, 48, 198, 253, 207, 84, 13, 204, 141, + 224, 21, 176, 147, 158, 66, 231, 43, 145, 6, 4, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ diff --git a/noir/noir-repo/compiler/noirc_driver/src/contract.rs b/noir/noir-repo/compiler/noirc_driver/src/contract.rs index 5c0f2f81b1e..a33a9b809d3 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/contract.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/contract.rs @@ -54,4 +54,7 @@ pub struct ContractFunction { pub bytecode: Program, pub debug: DebugInfo, + + /// Names of the functions in the program. These are used for more informative debugging and benchmarking. + pub names: Vec, } diff --git a/noir/noir-repo/compiler/noirc_driver/src/lib.rs b/noir/noir-repo/compiler/noirc_driver/src/lib.rs index 03ce9151552..6fe44780484 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/lib.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/lib.rs @@ -12,6 +12,7 @@ use noirc_abi::{AbiParameter, AbiType, AbiValue}; use noirc_errors::{CustomDiagnostic, FileDiagnostic}; use noirc_evaluator::create_program; use noirc_evaluator::errors::RuntimeError; +use noirc_evaluator::ssa::SsaProgramArtifact; use noirc_frontend::debug::build_debug_crate_file; use noirc_frontend::graph::{CrateId, CrateName}; use noirc_frontend::hir::def_map::{Contract, CrateDefMap}; @@ -424,6 +425,7 @@ fn compile_contract_inner( bytecode: function.program, debug: function.debug, is_unconstrained: modifiers.is_unconstrained, + names: function.names, }); } @@ -519,7 +521,14 @@ pub fn compile_no_check( } let visibility = program.return_visibility; - let (program, debug, warnings, input_witnesses, return_witnesses) = create_program( + let SsaProgramArtifact { + program, + debug, + warnings, + main_input_witnesses, + main_return_witnesses, + names, + } = create_program( program, options.show_ssa, options.show_brillig, @@ -527,8 +536,13 @@ pub fn compile_no_check( options.benchmark_codegen, )?; - let abi = - abi_gen::gen_abi(context, &main_function, input_witnesses, return_witnesses, visibility); + let abi = abi_gen::gen_abi( + context, + &main_function, + main_input_witnesses, + main_return_witnesses, + visibility, + ); let file_map = filter_relevant_files(&debug, &context.file_manager); Ok(CompiledProgram { @@ -544,5 +558,6 @@ pub fn compile_no_check( file_map, noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), warnings, + names, }) } diff --git a/noir/noir-repo/compiler/noirc_driver/src/program.rs b/noir/noir-repo/compiler/noirc_driver/src/program.rs index 6f527297dcb..9ffd2d70dda 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/program.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/program.rs @@ -27,4 +27,6 @@ pub struct CompiledProgram { pub debug: DebugInfo, pub file_map: BTreeMap, pub warnings: Vec, + /// Names of the functions in the program. These are used for more informative debugging and benchmarking. + pub names: Vec, } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs index 4b2f1060c88..fac7a7c0829 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs @@ -62,6 +62,7 @@ pub(crate) fn optimize_into_acir( // Run mem2reg once more with the flattened CFG to catch any remaining loads/stores .run_pass(Ssa::mem2reg, "After Mem2Reg:") .run_pass(Ssa::fold_constants, "After Constant Folding:") + .run_pass(Ssa::remove_enable_side_effects, "After EnableSideEffects removal:") .run_pass(Ssa::fold_constants_using_constraints, "After Constraint Folding:") .run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:") .run_pass(Ssa::array_set_optimization, "After Array Set Optimizations:") @@ -87,6 +88,29 @@ fn time(name: &str, print_timings: bool, f: impl FnOnce() -> T) -> T { result } +#[derive(Default)] +pub struct SsaProgramArtifact { + pub program: AcirProgram, + pub debug: Vec, + pub warnings: Vec, + pub main_input_witnesses: Vec, + pub main_return_witnesses: Vec, + pub names: Vec, +} + +impl SsaProgramArtifact { + fn add_circuit(&mut self, mut circuit_artifact: SsaCircuitArtifact, is_main: bool) { + self.program.functions.push(circuit_artifact.circuit); + self.debug.push(circuit_artifact.debug_info); + self.warnings.append(&mut circuit_artifact.warnings); + if is_main { + self.main_input_witnesses = circuit_artifact.input_witnesses; + self.main_return_witnesses = circuit_artifact.return_witnesses; + } + self.names.push(circuit_artifact.name); + } +} + /// Compiles the [`Program`] into [`ACIR``][acvm::acir::circuit::Program]. /// /// The output ACIR is is backend-agnostic and so must go through a transformation pass before usage in proof generation. @@ -98,8 +122,7 @@ pub fn create_program( enable_brillig_logging: bool, force_brillig_output: bool, print_codegen_timings: bool, -) -> Result<(AcirProgram, Vec, Vec, Vec, Vec), RuntimeError> -{ +) -> Result { let debug_variables = program.debug_variables.clone(); let debug_types = program.debug_types.clone(); let debug_functions = program.debug_functions.clone(); @@ -120,37 +143,33 @@ pub fn create_program( "The generated ACIRs should match the supplied function signatures" ); - let mut functions = vec![]; - let mut debug_infos = vec![]; - let mut warning_infos = vec![]; - let mut main_input_witnesses = Vec::new(); - let mut main_return_witnesses = Vec::new(); + let mut program_artifact = SsaProgramArtifact::default(); // For setting up the ABI we need separately specify main's input and return witnesses let mut is_main = true; for (acir, func_sig) in generated_acirs.into_iter().zip(func_sigs) { - let (circuit, debug_info, warnings, input_witnesses, return_witnesses) = - convert_generated_acir_into_circuit( - acir, - func_sig, - recursive, - // TODO: get rid of these clones - debug_variables.clone(), - debug_functions.clone(), - debug_types.clone(), - ); - functions.push(circuit); - debug_infos.push(debug_info); - warning_infos.extend(warnings); - if is_main { - main_input_witnesses = input_witnesses; - main_return_witnesses = return_witnesses; - } + let circuit_artifact = convert_generated_acir_into_circuit( + acir, + func_sig, + recursive, + // TODO: get rid of these clones + debug_variables.clone(), + debug_functions.clone(), + debug_types.clone(), + ); + program_artifact.add_circuit(circuit_artifact, is_main); is_main = false; } - let program = AcirProgram { functions }; + Ok(program_artifact) +} - Ok((program, debug_infos, warning_infos, main_input_witnesses, main_return_witnesses)) +pub struct SsaCircuitArtifact { + name: String, + circuit: Circuit, + debug_info: DebugInfo, + warnings: Vec, + input_witnesses: Vec, + return_witnesses: Vec, } fn convert_generated_acir_into_circuit( @@ -160,7 +179,7 @@ fn convert_generated_acir_into_circuit( debug_variables: DebugVariables, debug_functions: DebugFunctions, debug_types: DebugTypes, -) -> (Circuit, DebugInfo, Vec, Vec, Vec) { +) -> SsaCircuitArtifact { let opcodes = generated_acir.take_opcodes(); let current_witness_index = generated_acir.current_witness_index().0; let GeneratedAcir { @@ -169,6 +188,7 @@ fn convert_generated_acir_into_circuit( input_witnesses, assert_messages, warnings, + name, .. } = generated_acir; @@ -201,7 +221,14 @@ fn convert_generated_acir_into_circuit( let (optimized_circuit, transformation_map) = acvm::compiler::optimize(circuit); debug_info.update_acir(transformation_map); - (optimized_circuit, debug_info, warnings, input_witnesses, return_witnesses) + SsaCircuitArtifact { + name, + circuit: optimized_circuit, + debug_info, + warnings, + input_witnesses, + return_witnesses, + } } // Takes each function argument and partitions the circuit's inputs witnesses according to its visibility. diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 1d05e998b13..b43110b2f5b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -25,7 +25,7 @@ use iter_extended::vecmap; use num_bigint::BigUint; #[derive(Debug, Default)] -/// The output of the Acir-gen pass +/// The output of the Acir-gen pass, which should only be produced for entry point Acir functions pub(crate) struct GeneratedAcir { /// The next witness index that may be declared. /// If witness index is `None` then we have not yet created a witness @@ -58,6 +58,10 @@ pub(crate) struct GeneratedAcir { pub(crate) assert_messages: BTreeMap, pub(crate) warnings: Vec, + + /// Name for the corresponding entry point represented by this Acir-gen output. + /// Only used for debugging and benchmarking purposes + pub(crate) name: String, } impl GeneratedAcir { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index fc81ae1f901..9f2cec5c949 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -186,7 +186,10 @@ impl Ssa { // TODO: can we parallelise this? for function in self.functions.values() { let context = Context::new(); - if let Some(generated_acir) = context.convert_ssa_function(&self, function, brillig)? { + if let Some(mut generated_acir) = + context.convert_ssa_function(&self, function, brillig)? + { + generated_acir.name = function.name().to_owned(); acirs.push(generated_acir); } } @@ -253,7 +256,7 @@ impl Context { } } } - // We only want to convert entry point functions. This being `main` and those marked with `#[fold]` + // We only want to convert entry point functions. This being `main` and those marked with `InlineType::Fold` Ok(Some(self.convert_acir_main(function, ssa, brillig)?)) } RuntimeType::Brillig => { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs index f37f45b30bb..4452840a28c 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs @@ -15,5 +15,6 @@ mod inlining; mod mem2reg; mod rc; mod remove_bit_shifts; +mod remove_enable_side_effects; mod simplify_cfg; mod unrolling; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs new file mode 100644 index 00000000000..8535dc2661f --- /dev/null +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs @@ -0,0 +1,167 @@ +//! The goal of the "remove enable side effects" optimization pass is to delay any [Instruction::EnableSideEffects] +//! instructions such that they cover the minimum number of instructions possible. +//! +//! The pass works as follows: +//! - Insert instructions until an [Instruction::EnableSideEffects] is encountered, save this [InstructionId]. +//! - Continue inserting instructions until either +//! - Another [Instruction::EnableSideEffects] is encountered, if so then drop the previous [InstructionId] in favour +//! of this one. +//! - An [Instruction] with side-effects is encountered, if so then insert the currently saved [Instruction::EnableSideEffects] +//! before the [Instruction]. Continue inserting instructions until the next [Instruction::EnableSideEffects] is encountered. +use std::collections::HashSet; + +use acvm::FieldElement; + +use crate::ssa::{ + ir::{ + basic_block::BasicBlockId, + dfg::DataFlowGraph, + function::Function, + instruction::{BinaryOp, Instruction, Intrinsic}, + value::Value, + }, + ssa_gen::Ssa, +}; + +impl Ssa { + /// See [`remove_enable_side_effects`][self] module for more information. + #[tracing::instrument(level = "trace", skip(self))] + pub(crate) fn remove_enable_side_effects(mut self) -> Ssa { + for function in self.functions.values_mut() { + remove_enable_side_effects(function); + } + self + } +} + +fn remove_enable_side_effects(function: &mut Function) { + let mut context = Context::default(); + context.block_queue.push(function.entry_block()); + + while let Some(block) = context.block_queue.pop() { + if context.visited_blocks.contains(&block) { + continue; + } + + context.visited_blocks.insert(block); + context.remove_enable_side_effects_in_block(function, block); + } +} + +#[derive(Default)] +struct Context { + visited_blocks: HashSet, + block_queue: Vec, +} + +impl Context { + fn remove_enable_side_effects_in_block( + &mut self, + function: &mut Function, + block: BasicBlockId, + ) { + let instructions = function.dfg[block].take_instructions(); + + let mut last_side_effects_enabled_instruction = None; + + let mut new_instructions = Vec::with_capacity(instructions.len()); + for instruction_id in instructions { + let instruction = &function.dfg[instruction_id]; + + // If we run into another `Instruction::EnableSideEffects` before encountering any + // instructions with side effects then we can drop the instruction we're holding and + // continue with the new `Instruction::EnableSideEffects`. + if let Instruction::EnableSideEffects { condition } = instruction { + // If we're seeing an `enable_side_effects u1 1` then we want to insert it immediately. + // This is because we want to maximize the effect it will have. + if function + .dfg + .get_numeric_constant(*condition) + .map_or(false, |condition| condition.is_one()) + { + new_instructions.push(instruction_id); + last_side_effects_enabled_instruction = None; + continue; + } + + last_side_effects_enabled_instruction = Some(instruction_id); + continue; + } + + // If we hit an instruction which is affected by the side effects var then we must insert the + // `Instruction::EnableSideEffects` before we insert this new instruction. + if Self::responds_to_side_effects_var(&function.dfg, instruction) { + if let Some(enable_side_effects_instruction_id) = + last_side_effects_enabled_instruction.take() + { + new_instructions.push(enable_side_effects_instruction_id); + } + } + new_instructions.push(instruction_id); + } + + *function.dfg[block].instructions_mut() = new_instructions; + + self.block_queue.extend(function.dfg[block].successors()); + } + + fn responds_to_side_effects_var(dfg: &DataFlowGraph, instruction: &Instruction) -> bool { + use Instruction::*; + match instruction { + Binary(binary) => { + if matches!(binary.operator, BinaryOp::Div | BinaryOp::Mod) { + if let Some(rhs) = dfg.get_numeric_constant(binary.rhs) { + rhs == FieldElement::zero() + } else { + true + } + } else { + false + } + } + + Cast(_, _) + | Not(_) + | Truncate { .. } + | Constrain(..) + | RangeCheck { .. } + | IncrementRc { .. } + | DecrementRc { .. } => false, + + EnableSideEffects { .. } + | ArrayGet { .. } + | ArraySet { .. } + | Allocate + | Store { .. } + | Load { .. } => true, + + // Some `Intrinsic`s have side effects so we must check what kind of `Call` this is. + Call { func, .. } => match dfg[*func] { + Value::Intrinsic(intrinsic) => match intrinsic { + Intrinsic::SlicePushBack + | Intrinsic::SlicePushFront + | Intrinsic::SlicePopBack + | Intrinsic::SlicePopFront + | Intrinsic::SliceInsert + | Intrinsic::SliceRemove => true, + + Intrinsic::ArrayLen + | Intrinsic::AssertConstant + | Intrinsic::ApplyRangeConstraint + | Intrinsic::StrAsBytes + | Intrinsic::ToBits(_) + | Intrinsic::ToRadix(_) + | Intrinsic::BlackBox(_) + | Intrinsic::FromField + | Intrinsic::AsField + | Intrinsic::AsSlice => false, + }, + + // We must assume that functions contain a side effect as we cannot inspect more deeply. + Value::Function(_) => true, + + _ => false, + }, + } + } +} diff --git a/noir/noir-repo/docs/package.json b/noir/noir-repo/docs/package.json index 78560707795..f9e95fc02f8 100644 --- a/noir/noir-repo/docs/package.json +++ b/noir/noir-repo/docs/package.json @@ -5,10 +5,11 @@ "scripts": { "preprocess": "yarn workspace @noir-lang/acvm_js build && ./scripts/codegen_nargo_reference.sh && yarn node ./scripts/preprocess/index.js", "start": "yarn preprocess && docusaurus start", - "build": "yarn preprocess && yarn version::stables && docusaurus build", + "build": "yarn preprocess && docusaurus build", + "clean": "rm -rf ./processed-docs ./processed-docs ./build", "version::stables": "ts-node ./scripts/setStable.ts", "serve": "serve build", - "version": "yarn preprocess && docusaurus build && docusaurus docs:version" + "version": "yarn version::stables && ./scripts/cut_version.sh" }, "dependencies": { "@docusaurus/core": "^3.0.1", diff --git a/noir/noir-repo/docs/scripts/cut_version.sh b/noir/noir-repo/docs/scripts/cut_version.sh new file mode 100755 index 00000000000..4000707328c --- /dev/null +++ b/noir/noir-repo/docs/scripts/cut_version.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -eu + +cd $(dirname "$0")/.. + +VERSION=$1 + +# We assume that the new release tag has been made on github, so setStable.ts will add this to `versions.json`. +# We don't have a version of the docs for this release however (that's what we're doing right now!) so we need to remove it. +jq 'map(select(. != "'"$VERSION"'"))' versions.json > tmp.json && mv tmp.json versions.json + +# We need to build the docs in order to perform all necessary preprocessing. +yarn build + +# Finally cut the actual new docs version. +yarn docusaurus docs:version $VERSION diff --git a/noir/noir-repo/package.json b/noir/noir-repo/package.json index 30cac607010..8abaced7bdd 100644 --- a/noir/noir-repo/package.json +++ b/noir/noir-repo/package.json @@ -13,7 +13,7 @@ "docs" ], "scripts": { - "build": "yarn workspaces foreach --parallel --topological-dev --verbose run build", + "build": "yarn workspaces foreach -vp --topological-dev --exclude \"{docs,@noir-lang/root}\" run build", "test": "yarn workspaces foreach --parallel --verbose run test", "test:integration": "yarn workspace integration-tests test", "clean:workspaces": "yarn workspaces foreach --exclude @noir-lang/root run clean", @@ -22,6 +22,7 @@ "lint": "yarn workspaces foreach --verbose run lint", "spellcheck": "cspell '**/*.{md,rs}' -c ./cspell.json", "prepare:publish": "yarn clean && yarn build", + "build:js:only": "yarn workspaces foreach -vtp --exclude \"{@noir-lang/acvm_js,@noir-lang/noirc_abi,@noir-lang/noir_wasm,docs,@noir-lang/root}\" run build", "nightly:version": "yarn workspaces foreach run nightly:version", "publish:all": "yarn install && yarn workspaces foreach run publish" }, diff --git a/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/Nargo.toml b/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/Nargo.toml new file mode 100644 index 00000000000..ff64bbb6f1b --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_non_contract_method" +type = "contract" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/src/main.nr b/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/src/main.nr new file mode 100644 index 00000000000..2e00ffa1381 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_contract/fold_non_contract_method/src/main.nr @@ -0,0 +1,18 @@ +contract Foo { + use crate::times_10; + + fn double(x: Field) -> pub Field { + x * 2 + } + fn triple(x: Field) -> pub Field { + x * 3 + } + fn times_40(x: Field) -> pub Field { + times_10(x) * 4 + } +} + +#[fold] +fn times_10(x: Field) -> Field { + x * 10 +} diff --git a/noir/noir-repo/tooling/nargo/src/artifacts/program.rs b/noir/noir-repo/tooling/nargo/src/artifacts/program.rs index 046db1cd8fa..9e660cbd359 100644 --- a/noir/noir-repo/tooling/nargo/src/artifacts/program.rs +++ b/noir/noir-repo/tooling/nargo/src/artifacts/program.rs @@ -34,6 +34,8 @@ pub struct ProgramArtifact { /// Map of file Id to the source code so locations in debug info can be mapped to source code they point to. pub file_map: BTreeMap, + + pub names: Vec, } impl From for ProgramArtifact { @@ -45,6 +47,7 @@ impl From for ProgramArtifact { bytecode: compiled_program.program, debug_symbols: compiled_program.debug, file_map: compiled_program.file_map, + names: compiled_program.names, } } } @@ -59,6 +62,7 @@ impl From for CompiledProgram { debug: program.debug_symbols, file_map: program.file_map, warnings: vec![], + names: program.names, } } } diff --git a/noir/noir-repo/tooling/nargo_cli/build.rs b/noir/noir-repo/tooling/nargo_cli/build.rs index 16df29e6985..bf97dfb3e96 100644 --- a/noir/noir-repo/tooling/nargo_cli/build.rs +++ b/noir/noir-repo/tooling/nargo_cli/build.rs @@ -244,7 +244,7 @@ fn compile_success_empty_{test_name}() {{ let json: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap_or_else(|e| {{ panic!("JSON was not well-formatted {{:?}}\n\n{{:?}}", e, std::str::from_utf8(&output.stdout)) }}); - let num_opcodes = &json["programs"][0]["acir_opcodes"]; + let num_opcodes = &json["programs"][0]["functions"][0]["acir_opcodes"]; assert_eq!(num_opcodes.as_u64().expect("number of opcodes should fit in a u64"), 0); }} "#, diff --git a/noir/noir-repo/tooling/nargo_cli/src/cli/info_cmd.rs b/noir/noir-repo/tooling/nargo_cli/src/cli/info_cmd.rs index 49924622392..72784013e17 100644 --- a/noir/noir-repo/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/noir/noir-repo/tooling/nargo_cli/src/cli/info_cmd.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use acvm::acir::circuit::ExpressionWidth; +use acvm::acir::circuit::{ExpressionWidth, Program}; use backend_interface::BackendError; use clap::Args; use iter_extended::vecmap; @@ -24,9 +24,9 @@ use crate::errors::CliError; use super::{compile_cmd::compile_workspace, NargoConfig}; -/// Provides detailed information on a circuit +/// Provides detailed information on each of a program's function (represented by a single circuit) /// -/// Current information provided: +/// Current information provided per circuit: /// 1. The number of ACIR opcodes /// 2. Counts the final number gates in the circuit used by a backend #[derive(Debug, Clone, Args)] @@ -114,6 +114,7 @@ pub(crate) fn run( let binary_packages = workspace.into_iter().filter(|package| package.is_binary()).zip(compiled_programs); + let program_info = binary_packages .par_bridge() .map(|(package, program)| { @@ -134,10 +135,13 @@ pub(crate) fn run( } else { // Otherwise print human-readable table. if !info_report.programs.is_empty() { - let mut program_table = table!([Fm->"Package", Fm->"Expression Width", Fm->"ACIR Opcodes", Fm->"Backend Circuit Size"]); + let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes", Fm->"Backend Circuit Size"]); - for program in info_report.programs { - program_table.add_row(program.into()); + for program_info in info_report.programs { + let program_rows: Vec = program_info.into(); + for row in program_rows { + program_table.add_row(row); + } } program_table.printstd(); } @@ -223,18 +227,20 @@ struct ProgramInfo { name: String, #[serde(skip)] expression_width: ExpressionWidth, - acir_opcodes: usize, - circuit_size: u32, + functions: Vec, } -impl From for Row { +impl From for Vec { fn from(program_info: ProgramInfo) -> Self { - row![ - Fm->format!("{}", program_info.name), - format!("{:?}", program_info.expression_width), - Fc->format!("{}", program_info.acir_opcodes), - Fc->format!("{}", program_info.circuit_size), - ] + vecmap(program_info.functions, |function| { + row![ + Fm->format!("{}", program_info.name), + Fc->format!("{}", function.name), + format!("{:?}", program_info.expression_width), + Fc->format!("{}", function.acir_opcodes), + Fc->format!("{}", function.circuit_size), + ] + }) } } @@ -243,6 +249,7 @@ struct ContractInfo { name: String, #[serde(skip)] expression_width: ExpressionWidth, + // TODO(https://github.com/noir-lang/noir/issues/4720): Settle on how to display contract functions with non-inlined Acir calls functions: Vec, } @@ -273,13 +280,22 @@ fn count_opcodes_and_gates_in_program( package: &Package, expression_width: ExpressionWidth, ) -> Result { - Ok(ProgramInfo { - name: package.name.to_string(), - expression_width, - // TODO(https://github.com/noir-lang/noir/issues/4428) - acir_opcodes: compiled_program.program.functions[0].opcodes.len(), - circuit_size: backend.get_exact_circuit_size(&compiled_program.program)?, - }) + let functions = compiled_program + .program + .functions + .into_par_iter() + .enumerate() + .map(|(i, function)| -> Result<_, BackendError> { + Ok(FunctionInfo { + name: compiled_program.names[i].clone(), + acir_opcodes: function.opcodes.len(), + circuit_size: backend + .get_exact_circuit_size(&Program { functions: vec![function] })?, + }) + }) + .collect::>()?; + + Ok(ProgramInfo { name: package.name.to_string(), expression_width, functions }) } fn count_opcodes_and_gates_in_contract( @@ -293,7 +309,7 @@ fn count_opcodes_and_gates_in_contract( .map(|function| -> Result<_, BackendError> { Ok(FunctionInfo { name: function.name, - // TODO(https://github.com/noir-lang/noir/issues/4428) + // TODO(https://github.com/noir-lang/noir/issues/4720) acir_opcodes: function.bytecode.functions[0].opcodes.len(), circuit_size: backend.get_exact_circuit_size(&function.bytecode)?, }) diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts index 03552a66236..f1b0b0b167f 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts @@ -5,7 +5,7 @@ describe('ArtifactHash', () => { it('calculates the artifact hash', () => { const artifact = getBenchmarkContractArtifact(); expect(computeArtifactHash(artifact).toString()).toMatchInlineSnapshot( - `"0x0879735688d7e382d8d32503adbc554c755f309d03b430df401ef2c554cc71a5"`, + `"0x077417e7303df9113d0d0947b9dc8a06903cd8aa963a31891e2f28ce121d753e"`, ); }); });